ollama-client 0.2.7 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.cursor/.gitignore +1 -0
- data/.rubocop_todo.yml +66 -0
- data/API_CONTRACT.md +166 -0
- data/CHANGELOG.md +26 -40
- data/CLAUDE.md +56 -0
- data/README.md +223 -1383
- data/SECURITY.md +17 -0
- data/devagent_proper.rb +430 -0
- data/docs/API_GAPS.md +143 -0
- data/docs/AREAS_FOR_CONSIDERATION.md +3 -3
- data/docs/CONSOLE_IMPROVEMENTS.md +1 -1
- data/docs/GETTING_STARTED.md +25 -7
- data/docs/INTEGRATION_TESTING.md +9 -9
- data/docs/PRODUCTION_FIXES.md +1 -1
- data/docs/QUICK_START.md +2 -2
- data/examples/agent_loop.rb +120 -0
- data/examples/failure_modes/invalid_json_repair.rb +42 -0
- data/examples/production/rails_agent.rb +62 -0
- data/examples/timeout_retry.rb +40 -0
- data/exe/ollama-client +187 -110
- data/lib/ollama/capabilities.rb +60 -0
- data/lib/ollama/client/chat.rb +140 -0
- data/lib/ollama/client/generate.rb +389 -0
- data/lib/ollama/client/model_management.rb +206 -0
- data/lib/ollama/client.rb +51 -804
- data/lib/ollama/config.rb +51 -7
- data/lib/ollama/embeddings.rb +25 -6
- data/lib/ollama/errors.rb +3 -0
- data/lib/ollama/options.rb +93 -15
- data/lib/ollama/response.rb +89 -7
- data/lib/ollama/version.rb +1 -1
- data/lib/ollama_client.rb +0 -9
- data/market.jpg +0 -0
- data/print_capabilities.rb +20 -0
- data/schema.json +1 -0
- data/test_tool.rb +26 -0
- metadata +26 -44
- data/examples/README.md +0 -91
- data/examples/basic_chat.rb +0 -33
- data/examples/basic_generate.rb +0 -29
- data/examples/mcp_executor.rb +0 -39
- data/examples/mcp_http_executor.rb +0 -45
- data/examples/tool_calling_parsing.rb +0 -59
- data/examples/tool_dto_example.rb +0 -94
- data/lib/ollama/agent/executor.rb +0 -258
- data/lib/ollama/agent/messages.rb +0 -31
- data/lib/ollama/agent/planner.rb +0 -52
- data/lib/ollama/chat_session.rb +0 -101
- data/lib/ollama/document_loader.rb +0 -163
- data/lib/ollama/mcp/http_client.rb +0 -149
- data/lib/ollama/mcp/stdio_client.rb +0 -146
- data/lib/ollama/mcp/tools_bridge.rb +0 -72
- data/lib/ollama/mcp.rb +0 -31
- data/lib/ollama/personas.rb +0 -287
- data/lib/ollama/streaming_observer.rb +0 -22
- data/lib/ollama/tool/function/parameters/property.rb +0 -72
- data/lib/ollama/tool/function/parameters.rb +0 -101
- data/lib/ollama/tool/function.rb +0 -78
- data/lib/ollama/tool.rb +0 -60
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 35dd7d6fe83f10045ed0ea1efa14f5ffc7547b8f132a5a504ad5fcbad40843ec
|
|
4
|
+
data.tar.gz: ca238782d4431c3c0beeee0615dca25699d479a66fe44c88509f8905803656a6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 51ece11f047b2ed872a0860b04d3e0cc2cfbbf443259deef5edddbf8511ac94318d8e7ea3ccfb6251945e1d38abe96fc31b366d6905c9ed45cc452530ad01b61
|
|
7
|
+
data.tar.gz: c5f8cf9f1296768c13740e4462abe3bbe0aaa48e936da720a061c55f6c9456362e32b7a1aa5fcaac09c630e0e4beac36b3990e6673367434defb234eb2895dc4
|
data/.cursor/.gitignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
plans/
|
data/.rubocop_todo.yml
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# This configuration was generated by
|
|
2
|
+
# `rubocop --auto-gen-config`
|
|
3
|
+
# on 2026-02-22 07:05:15 UTC using RuboCop version 1.82.1.
|
|
4
|
+
# The point is for the user to remove these configuration records
|
|
5
|
+
# one by one as the offenses are removed from the code base.
|
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
|
8
|
+
|
|
9
|
+
# Offense count: 1
|
|
10
|
+
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns, inherit_mode.
|
|
11
|
+
# AllowedMethods: refine
|
|
12
|
+
Metrics/BlockLength:
|
|
13
|
+
Max: 26
|
|
14
|
+
|
|
15
|
+
# Offense count: 0 (resolved via module extraction in lib/ollama/client/)
|
|
16
|
+
# Metrics/ClassLength - no longer needed
|
|
17
|
+
|
|
18
|
+
# Offense count: 1
|
|
19
|
+
# Configuration parameters: CountComments, Max, CountAsOne, AllowedMethods, AllowedPatterns.
|
|
20
|
+
Metrics/MethodLength:
|
|
21
|
+
Exclude:
|
|
22
|
+
- 'spec/**/*'
|
|
23
|
+
- 'examples/**/*'
|
|
24
|
+
- 'devagent_proper.rb'
|
|
25
|
+
|
|
26
|
+
# Offense count: 1
|
|
27
|
+
# Configuration parameters: CountKeywordArgs, MaxOptionalParameters.
|
|
28
|
+
Metrics/ParameterLists:
|
|
29
|
+
Max: 6
|
|
30
|
+
|
|
31
|
+
# Offense count: 1
|
|
32
|
+
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
33
|
+
# Configuration parameters: SkipBlocks, EnforcedStyle, OnlyStaticConstants.
|
|
34
|
+
# SupportedStyles: described_class, explicit
|
|
35
|
+
RSpec/DescribedClass:
|
|
36
|
+
Exclude:
|
|
37
|
+
- 'spec/ollama/errors_spec.rb'
|
|
38
|
+
- 'spec/integration/client_integration_spec.rb'
|
|
39
|
+
|
|
40
|
+
# Offense count: 1
|
|
41
|
+
# Configuration parameters: CustomTransform, IgnoreMethods, IgnoreMetadata, InflectorPath, EnforcedInflector.
|
|
42
|
+
# SupportedInflectors: default, active_support
|
|
43
|
+
RSpec/SpecFilePathFormat:
|
|
44
|
+
Exclude:
|
|
45
|
+
- 'spec/ollama/client_model_suggestions_spec.rb'
|
|
46
|
+
- 'spec/integration/client_integration_spec.rb'
|
|
47
|
+
|
|
48
|
+
# Offense count: 4
|
|
49
|
+
# Configuration parameters: AllowedConstants.
|
|
50
|
+
Style/Documentation:
|
|
51
|
+
Exclude:
|
|
52
|
+
- 'examples/**/*'
|
|
53
|
+
- 'devagent_proper.rb'
|
|
54
|
+
|
|
55
|
+
# Offense count: 2
|
|
56
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
57
|
+
Style/IfUnlessModifier:
|
|
58
|
+
Exclude:
|
|
59
|
+
- 'lib/ollama/schema_validator.rb'
|
|
60
|
+
|
|
61
|
+
# Offense count: 2
|
|
62
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
63
|
+
# Configuration parameters: AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings.
|
|
64
|
+
# URISchemes: http, https
|
|
65
|
+
Layout/LineLength:
|
|
66
|
+
Max: 136
|
data/API_CONTRACT.md
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# API Contract — v1.0.0
|
|
2
|
+
|
|
3
|
+
This document defines the **public API surface** of `ollama-client` v1.0.
|
|
4
|
+
Everything listed here is guaranteed stable until `v2.0.0`.
|
|
5
|
+
|
|
6
|
+
## Public Methods
|
|
7
|
+
|
|
8
|
+
### `Ollama::Client`
|
|
9
|
+
|
|
10
|
+
```ruby
|
|
11
|
+
client = Ollama::Client.new(config: Ollama::Config.new)
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
#### Chat
|
|
15
|
+
|
|
16
|
+
| Method | Signature | Returns |
|
|
17
|
+
|---|---|---|
|
|
18
|
+
| `chat` | `(messages:, model: nil, format: nil, tools: nil, stream: nil, think: nil, keep_alive: nil, options: nil, logprobs: nil, top_logprobs: nil, hooks: {})` | `Ollama::Response` |
|
|
19
|
+
|
|
20
|
+
#### Generate
|
|
21
|
+
|
|
22
|
+
| Method | Signature | Returns |
|
|
23
|
+
|---|---|---|
|
|
24
|
+
| `generate` | `(prompt:, schema: nil, model: nil, strict: config.strict_json, return_meta: false, system: nil, images: nil, think: nil, return_reasoning: false, keep_alive: nil, suffix: nil, raw: nil, options: nil, hooks: {})` | `String` (no schema) or `Hash` (with schema) |
|
|
25
|
+
|
|
26
|
+
When `think: true` and `return_reasoning: true`, the return value is a `Hash` with:
|
|
27
|
+
|
|
28
|
+
- `"reasoning"` — the extracted reasoning text (may be empty string)
|
|
29
|
+
- `"final"` — either a `String` (no schema) or a `Hash` (when `schema:` is provided)
|
|
30
|
+
|
|
31
|
+
#### Model Management
|
|
32
|
+
|
|
33
|
+
| Method | Signature | Returns |
|
|
34
|
+
|---|---|---|
|
|
35
|
+
| `list_models` | `()` | `Array<Hash>` |
|
|
36
|
+
| `list_model_names` | `()` | `Array<String>` |
|
|
37
|
+
| `list_running` / `ps` | `()` | `Array<Hash>` |
|
|
38
|
+
| `show_model` | `(model:, verbose: false)` | `Hash` |
|
|
39
|
+
| `pull` | `(model_name)` | `true` |
|
|
40
|
+
| `delete_model` | `(model:)` | `true` |
|
|
41
|
+
| `copy_model` | `(source:, destination:)` | `true` |
|
|
42
|
+
| `create_model` | `(model:, from:, system: nil, template: nil, license: nil, parameters: nil, messages: nil, quantize: nil, stream: false)` | `Hash` |
|
|
43
|
+
| `push_model` | `(model:, insecure: false, stream: false)` | `Hash` |
|
|
44
|
+
| `version` | `()` | `String` |
|
|
45
|
+
| `embeddings` | _(attr_reader)_ | `Ollama::Embeddings` instance |
|
|
46
|
+
|
|
47
|
+
### `Ollama::Embeddings`
|
|
48
|
+
|
|
49
|
+
```ruby
|
|
50
|
+
client.embeddings.embed(model: "nomic-embed-text:latest", input: "text")
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
| Method | Signature | Returns |
|
|
54
|
+
|---|---|---|
|
|
55
|
+
| `embed` | `(model:, input:, truncate: nil, dimensions: nil, keep_alive: nil, options: nil)` | `Array<Float>` (single) or `Array<Array<Float>>` (batch) |
|
|
56
|
+
|
|
57
|
+
### `Ollama::Response`
|
|
58
|
+
|
|
59
|
+
Returned by `chat`. Wraps the API response with accessor methods:
|
|
60
|
+
|
|
61
|
+
| Method | Returns | Description |
|
|
62
|
+
|---|---|---|
|
|
63
|
+
| `message` | `Ollama::Response::Message` | Message wrapper |
|
|
64
|
+
| `content` | `String` | Shorthand for `message.content` |
|
|
65
|
+
| `done?` | `Boolean` | Whether generation finished |
|
|
66
|
+
| `done_reason` | `String` | Why generation stopped (`"stop"`, etc.) |
|
|
67
|
+
| `model` | `String` | Model name used |
|
|
68
|
+
| `total_duration` | `Integer` | Total time (nanoseconds) |
|
|
69
|
+
| `load_duration` | `Integer` | Model load time |
|
|
70
|
+
| `prompt_eval_count` | `Integer` | Prompt token count |
|
|
71
|
+
| `eval_count` | `Integer` | Response token count |
|
|
72
|
+
| `logprobs` | `Array` | Log probabilities (when enabled) |
|
|
73
|
+
|
|
74
|
+
#### `Ollama::Response::Message`
|
|
75
|
+
|
|
76
|
+
| Method | Returns | Description |
|
|
77
|
+
|---|---|---|
|
|
78
|
+
| `content` | `String` | Message content |
|
|
79
|
+
| `thinking` | `String` | Thinking output (when `think: true`) |
|
|
80
|
+
| `role` | `String` | `"assistant"` |
|
|
81
|
+
| `tool_calls` | `Array<ToolCall>` | Function calls |
|
|
82
|
+
| `images` | `Array<String>` | Base64 images |
|
|
83
|
+
|
|
84
|
+
### `Ollama::Options`
|
|
85
|
+
|
|
86
|
+
Type-safe runtime options passed via `options:` parameter:
|
|
87
|
+
|
|
88
|
+
```ruby
|
|
89
|
+
Ollama::Options.new(temperature: 0.7, num_predict: 256)
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Valid keys: `temperature`, `top_p`, `top_k`, `num_ctx`, `repeat_penalty`, `seed`, `num_predict`, `stop`, `tfs_z`, `mirostat`, `mirostat_tau`, `mirostat_eta`, `num_gpu`, `num_thread`, `num_keep`, `typical_p`, `presence_penalty`, `frequency_penalty`.
|
|
93
|
+
|
|
94
|
+
### `Ollama::Config`
|
|
95
|
+
|
|
96
|
+
All attributes are read/write via `attr_accessor`:
|
|
97
|
+
|
|
98
|
+
| Attribute | Type | Default | Description |
|
|
99
|
+
|---|---|---|---|
|
|
100
|
+
| `base_url` | `String` | `"http://localhost:11434"` | Ollama server URL |
|
|
101
|
+
| `api_key` | `String, nil` | `nil` | Optional Bearer token for Ollama Cloud (`https://ollama.com`) |
|
|
102
|
+
| `model` | `String` | `"llama3.2:3b"` | Default model for generation |
|
|
103
|
+
| `timeout` | `Integer` | `30` | HTTP read/open timeout in seconds |
|
|
104
|
+
| `retries` | `Integer` | `2` | Max retry attempts |
|
|
105
|
+
| `strict_json` | `Boolean` | `true` | Enable JSON validation + repair |
|
|
106
|
+
| `temperature` | `Float` | `0.2` | Sampling temperature |
|
|
107
|
+
| `top_p` | `Float` | `0.9` | Nucleus sampling |
|
|
108
|
+
| `num_ctx` | `Integer` | `8192` | Context window size |
|
|
109
|
+
| `on_response` | `Proc/nil` | `nil` | Global response callback |
|
|
110
|
+
|
|
111
|
+
## Error Classes
|
|
112
|
+
|
|
113
|
+
All errors inherit from `Ollama::Error < StandardError`.
|
|
114
|
+
|
|
115
|
+
| Error | Raised When | Retryable? |
|
|
116
|
+
|---|---|---|
|
|
117
|
+
| `Ollama::Error` | Base class / connection failures | **No** — fast fail |
|
|
118
|
+
| `Ollama::TimeoutError` | `Net::ReadTimeout` / `Net::OpenTimeout` | **Yes** — exponential backoff |
|
|
119
|
+
| `Ollama::InvalidJSONError` | Response cannot be parsed as JSON | **Yes** — repair prompt retry |
|
|
120
|
+
| `Ollama::SchemaViolationError` | Parsed JSON fails schema validation | **Yes** — repair prompt retry |
|
|
121
|
+
| `Ollama::RetryExhaustedError` | All retry attempts exhausted | **No** — terminal |
|
|
122
|
+
| `Ollama::HTTPError` | Non-200 HTTP response | Depends on status code |
|
|
123
|
+
| `Ollama::NotFoundError` | HTTP 404 (model not found) | **Auto-handled** — triggers pull |
|
|
124
|
+
| `Ollama::StreamError` | `{"error": "..."}` in NDJSON stream | **No** — immediate |
|
|
125
|
+
|
|
126
|
+
## Recovery Behaviors (Guaranteed)
|
|
127
|
+
|
|
128
|
+
| Scenario | Behavior |
|
|
129
|
+
|---|---|
|
|
130
|
+
| Model missing (404) | Auto-pull once → retry original request |
|
|
131
|
+
| Timeout | Exponential backoff: `sleep(2 ** attempt)` |
|
|
132
|
+
| Invalid JSON (strict mode) | Append repair prompt → retry |
|
|
133
|
+
| Schema violation (strict mode) | Append repair prompt → retry |
|
|
134
|
+
| Server unreachable (ECONNREFUSED) | Immediate `Ollama::Error` — no retries |
|
|
135
|
+
| All retries exhausted | `Ollama::RetryExhaustedError` |
|
|
136
|
+
| Streaming error | `Ollama::StreamError` with server message |
|
|
137
|
+
|
|
138
|
+
## Streaming Hooks
|
|
139
|
+
|
|
140
|
+
Passed via `hooks:` parameter on `generate` and `chat`:
|
|
141
|
+
|
|
142
|
+
```ruby
|
|
143
|
+
hooks: {
|
|
144
|
+
on_token: ->(token) { ... }, # Called per token chunk
|
|
145
|
+
on_error: ->(error) { ... }, # Called on stream error
|
|
146
|
+
on_complete: -> { ... } # Called when stream finishes
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Hooks are **observer-only** — they cannot modify the response. Streaming is auto-enabled when any hook is present.
|
|
151
|
+
|
|
152
|
+
## What Will NOT Change Before v2.0
|
|
153
|
+
|
|
154
|
+
1. Method signatures listed above
|
|
155
|
+
2. Error class hierarchy
|
|
156
|
+
3. Default config values
|
|
157
|
+
4. Recovery behaviors (auto-pull, backoff, repair)
|
|
158
|
+
5. JSON schema validation via `json-schema` gem
|
|
159
|
+
6. Observer-style hooks interface
|
|
160
|
+
|
|
161
|
+
## What MAY Change (Minor Versions)
|
|
162
|
+
|
|
163
|
+
- New optional keyword arguments on existing methods
|
|
164
|
+
- New error subclasses (always inheriting from existing hierarchy)
|
|
165
|
+
- Additional config attributes (always with backwards-compatible defaults)
|
|
166
|
+
- Performance improvements to retry/backoff timing
|
data/CHANGELOG.md
CHANGED
|
@@ -1,49 +1,35 @@
|
|
|
1
|
-
|
|
1
|
+
# Changelog
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
- Add `Ollama::MCP::HttpClient` for remote MCP servers over HTTP (e.g. [gitmcp.io](https://gitmcp.io)/owner/repo)
|
|
8
|
-
- Add `Ollama::MCP::ToolsBridge` to expose MCP tools to `Ollama::Agent::Executor` (`client:` or `stdio_client:`)
|
|
9
|
-
- Add examples: `examples/mcp_executor.rb` (stdio), `examples/mcp_http_executor.rb` (URL)
|
|
10
|
-
- Document MCP usage and GitMCP URL in README; fix RuboCop offenses in MCP code
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
11
7
|
|
|
12
|
-
## [
|
|
8
|
+
## [1.1.0] - 2026-03-17
|
|
13
9
|
|
|
14
|
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
- Add test suite for `Ollama::ChatSession` (session management)
|
|
19
|
-
- Add test suite for tool classes (`Tool`, `Function`, `Parameters`, `Property`)
|
|
20
|
-
- Rewrite testing documentation to focus on client-only testing (transport/protocol)
|
|
21
|
-
- Add test checklist with specific test categories (G1-G3, C1-C3, A1-A2, F1-F3)
|
|
22
|
-
- Update README with enhanced "What This Gem IS NOT" section
|
|
23
|
-
- Fix RuboCop offenses and improve code quality
|
|
10
|
+
### Added
|
|
11
|
+
- Ollama Cloud support via `Ollama::Config#api_key` and HTTPS `base_url` (e.g. `https://ollama.com`).
|
|
12
|
+
- `Ollama::Config#http_connection_options` to centralize Net::HTTP connection options (including SSL and timeouts).
|
|
13
|
+
- `Ollama::Config#inspect` now redacts `api_key` while keeping other attributes visible.
|
|
24
14
|
|
|
25
|
-
|
|
15
|
+
### Changed
|
|
16
|
+
- Chat, generate, embeddings, and model management HTTP calls now share connection-option logic but keep existing behavior.
|
|
26
17
|
|
|
27
|
-
|
|
28
|
-
- Enhance README with context provision methods and examples
|
|
29
|
-
- Improve embeddings error handling and model usage guidance
|
|
30
|
-
- Add comprehensive Ruby guide documentation
|
|
31
|
-
- Update `generate()` method with enhanced functionality and usage examples
|
|
32
|
-
- Improve error handling across client and embeddings modules
|
|
18
|
+
## [1.0.0] - 2026-02-22
|
|
33
19
|
|
|
34
|
-
|
|
20
|
+
### Changed
|
|
21
|
+
- **Massive surface area reduction:** Removed `chat`, `chat_raw`, `call_chat_api`, `call_chat_api_raw`, and related endpoints.
|
|
22
|
+
- **Architectural Shift:** Removed all chatbot UI logic (`ChatSession`, `Personas`), abstract Agent implementations (`Planner`, `Executor`), and `DocumentLoader` to enforce strict low-level determinism.
|
|
23
|
+
- **API Contracts:** `Client#generate` now handles strict JSON schemas directly and implements resilient auto-recovery.
|
|
24
|
+
- **Defaults:** Opinionated defaults out-of-the-box (`timeout: 30`, `retries: 2`, `strict_json: true`).
|
|
25
|
+
- **Streaming Hooks:** Deprecated raw SSE streaming over `chat` in favor of safe observer callbacks (`on_token`, `on_error`, `on_complete`) on `generate`.
|
|
26
|
+
- **Model Auto-Pulling:** If `generate` receives a 404 Model Not Found, it attempts to synchronously `/pull` the model once, and then automatically retries generation.
|
|
27
|
+
- **JSON Repair Loop:** Provided `strict_json: true`, if a model hallucinates malformed JSON formatting (like wrapping in markdown code blocks), the client automatically loops a retry with a CRITICAL repair prompt to seamlessly fix the output.
|
|
28
|
+
- **Backoff:** Encountering a `Net::ReadTimeout` now triggers an exponential backoff sleep (`2 ** attempt`) between retries rather than immediately re-hammering the server.
|
|
35
29
|
|
|
36
|
-
|
|
37
|
-
-
|
|
38
|
-
-
|
|
30
|
+
### Security
|
|
31
|
+
- **Strict Error Boundaries:** Malformed payloads can no longer leak into application state due to strict `SchemaViolationError` bounding.
|
|
32
|
+
- **Fast-fail Networking:** Encountering `Errno::ECONNREFUSED` fast-fails immediately.
|
|
39
33
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
- Add `Ollama::Agent::Planner` (stateless `/api/generate`)
|
|
43
|
-
- Add `Ollama::Agent::Executor` (stateful `/api/chat` tool loop)
|
|
44
|
-
- Add `Ollama::StreamingObserver` + disciplined streaming support (Executor only)
|
|
45
|
-
- Add `Ollama::Client#chat_raw` (full response body, supports tool calls)
|
|
46
|
-
|
|
47
|
-
## [0.1.0] - 2026-01-04
|
|
48
|
-
|
|
49
|
-
- Initial release
|
|
34
|
+
### Rationale
|
|
35
|
+
Version `1.0.0` repositions `ollama-client` away from a bloated general-purpose wrapper toward a production-safe, failure-aware adapter intentionally crafted for Headless Rails Jobs and Agent Systems. By severing chat tools and abstractions, the gem commits to a strictly deterministic API that doesn't collapse under back-pressure, missing models, or temporary JSON formatting hallucinations.
|
data/CLAUDE.md
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# ollama-client
|
|
2
|
+
|
|
3
|
+
Ruby gem — Ollama HTTP client for agent-grade usage. Provides `chat`, `generate`, embeddings, and full model management. Stable public API defined in `API_CONTRACT.md`.
|
|
4
|
+
|
|
5
|
+
## Stack
|
|
6
|
+
|
|
7
|
+
- Ruby gem (no Rails)
|
|
8
|
+
- Zeitwerk autoloader
|
|
9
|
+
- RSpec + WebMock + Timecop + SimpleCov
|
|
10
|
+
- RuboCop
|
|
11
|
+
|
|
12
|
+
## Commands
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
bundle exec rspec
|
|
16
|
+
COVERAGE=true bundle exec rspec
|
|
17
|
+
bundle exec rubocop
|
|
18
|
+
bundle exec rake
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Architecture
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
lib/ollama/
|
|
25
|
+
client.rb # Top-level entry point
|
|
26
|
+
client/
|
|
27
|
+
chat.rb # chat() method
|
|
28
|
+
generate.rb # generate() method
|
|
29
|
+
model_management.rb # list, pull, delete, copy, create, push, version
|
|
30
|
+
config.rb # Ollama::Config (base_url, model, timeout, retries, strict_json, etc.)
|
|
31
|
+
response.rb # Ollama::Response wrapper
|
|
32
|
+
embeddings.rb # client.embeddings.embed()
|
|
33
|
+
options.rb # Model options (temperature, top_p, num_ctx)
|
|
34
|
+
dto.rb # Data transfer objects
|
|
35
|
+
schema_validator.rb # JSON schema validation for structured output
|
|
36
|
+
schemas/ # Built-in JSON schemas
|
|
37
|
+
capabilities.rb # Model capability detection
|
|
38
|
+
errors.rb # Error hierarchy
|
|
39
|
+
version.rb
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Public API (stable — see API_CONTRACT.md)
|
|
43
|
+
|
|
44
|
+
- `client.chat(messages:, model:, tools:, stream:, think:, ...)` → `Ollama::Response`
|
|
45
|
+
- `client.generate(prompt:, schema:, model:, strict:, ...)` → `String` or `Hash`
|
|
46
|
+
- `client.embeddings.embed(model:, input:)` → `Array<Float>`
|
|
47
|
+
- Model management: `list_models`, `pull`, `delete_model`, `copy_model`, `create_model`, `push_model`, `version`
|
|
48
|
+
|
|
49
|
+
## Key rules
|
|
50
|
+
|
|
51
|
+
- **Never break the public API** — changes to method signatures require a version bump and API_CONTRACT.md update
|
|
52
|
+
- All HTTP calls must be mockable with WebMock — never require live Ollama in tests
|
|
53
|
+
- `Ollama::Config` defaults to `localhost:11434` — config is per-client, not global (thread-safe)
|
|
54
|
+
- `generate` with `schema:` returns a parsed Hash; without `schema:` returns raw String — never mix
|
|
55
|
+
- `strict_json: true` (default) — do not disable in production code
|
|
56
|
+
- Thread safety: per-client config is safe; modifying global config while clients are active is not
|