ollama-client 0.2.5 → 0.2.7
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/CHANGELOG.md +22 -0
- data/README.md +336 -91
- data/RELEASE_NOTES_v0.2.6.md +41 -0
- data/docs/AREAS_FOR_CONSIDERATION.md +325 -0
- data/docs/EXAMPLE_REORGANIZATION.md +412 -0
- data/docs/FEATURES_ADDED.md +12 -1
- data/docs/GETTING_STARTED.md +361 -0
- data/docs/INTEGRATION_TESTING.md +170 -0
- data/docs/NEXT_STEPS_SUMMARY.md +114 -0
- data/docs/PERSONAS.md +383 -0
- data/docs/QUICK_START.md +195 -0
- data/docs/TESTING.md +392 -170
- data/docs/TEST_CHECKLIST.md +450 -0
- data/examples/README.md +62 -63
- data/examples/basic_chat.rb +33 -0
- data/examples/basic_generate.rb +29 -0
- data/examples/mcp_executor.rb +39 -0
- data/examples/mcp_http_executor.rb +45 -0
- data/examples/tool_calling_parsing.rb +59 -0
- data/examples/tool_dto_example.rb +0 -0
- data/exe/ollama-client +128 -1
- data/lib/ollama/agent/planner.rb +7 -2
- data/lib/ollama/chat_session.rb +101 -0
- data/lib/ollama/client.rb +41 -35
- data/lib/ollama/config.rb +9 -4
- data/lib/ollama/document_loader.rb +1 -1
- data/lib/ollama/embeddings.rb +61 -28
- data/lib/ollama/errors.rb +1 -0
- data/lib/ollama/mcp/http_client.rb +149 -0
- data/lib/ollama/mcp/stdio_client.rb +146 -0
- data/lib/ollama/mcp/tools_bridge.rb +72 -0
- data/lib/ollama/mcp.rb +31 -0
- data/lib/ollama/options.rb +3 -1
- data/lib/ollama/personas.rb +287 -0
- data/lib/ollama/version.rb +1 -1
- data/lib/ollama_client.rb +17 -5
- metadata +22 -48
- data/examples/advanced_complex_schemas.rb +0 -366
- data/examples/advanced_edge_cases.rb +0 -241
- data/examples/advanced_error_handling.rb +0 -200
- data/examples/advanced_multi_step_agent.rb +0 -341
- data/examples/advanced_performance_testing.rb +0 -186
- data/examples/chat_console.rb +0 -143
- data/examples/complete_workflow.rb +0 -245
- data/examples/dhan_console.rb +0 -843
- data/examples/dhanhq/README.md +0 -236
- data/examples/dhanhq/agents/base_agent.rb +0 -74
- data/examples/dhanhq/agents/data_agent.rb +0 -66
- data/examples/dhanhq/agents/orchestrator_agent.rb +0 -120
- data/examples/dhanhq/agents/technical_analysis_agent.rb +0 -252
- data/examples/dhanhq/agents/trading_agent.rb +0 -81
- data/examples/dhanhq/analysis/market_structure.rb +0 -138
- data/examples/dhanhq/analysis/pattern_recognizer.rb +0 -192
- data/examples/dhanhq/analysis/trend_analyzer.rb +0 -88
- data/examples/dhanhq/builders/market_context_builder.rb +0 -67
- data/examples/dhanhq/dhanhq_agent.rb +0 -829
- data/examples/dhanhq/indicators/technical_indicators.rb +0 -158
- data/examples/dhanhq/scanners/intraday_options_scanner.rb +0 -492
- data/examples/dhanhq/scanners/swing_scanner.rb +0 -247
- data/examples/dhanhq/schemas/agent_schemas.rb +0 -61
- data/examples/dhanhq/services/base_service.rb +0 -46
- data/examples/dhanhq/services/data_service.rb +0 -118
- data/examples/dhanhq/services/trading_service.rb +0 -59
- data/examples/dhanhq/technical_analysis_agentic_runner.rb +0 -411
- data/examples/dhanhq/technical_analysis_runner.rb +0 -420
- data/examples/dhanhq/test_tool_calling.rb +0 -538
- data/examples/dhanhq/test_tool_calling_verbose.rb +0 -251
- data/examples/dhanhq/utils/instrument_helper.rb +0 -32
- data/examples/dhanhq/utils/parameter_cleaner.rb +0 -28
- data/examples/dhanhq/utils/parameter_normalizer.rb +0 -45
- data/examples/dhanhq/utils/rate_limiter.rb +0 -23
- data/examples/dhanhq/utils/trading_parameter_normalizer.rb +0 -72
- data/examples/dhanhq_agent.rb +0 -964
- data/examples/dhanhq_tools.rb +0 -1663
- data/examples/multi_step_agent_with_external_data.rb +0 -368
- data/examples/structured_outputs_chat.rb +0 -72
- data/examples/structured_tools.rb +0 -89
- data/examples/test_dhanhq_tool_calling.rb +0 -375
- data/examples/test_tool_calling.rb +0 -160
- data/examples/tool_calling_direct.rb +0 -124
- data/examples/tool_calling_pattern.rb +0 -269
- data/exe/dhan_console +0 -4
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
# Areas for Consideration
|
|
2
|
+
|
|
3
|
+
This document addresses three key areas that warrant attention in the `ollama-client` codebase.
|
|
4
|
+
|
|
5
|
+
## ⚠️ 1. Complex Client Class
|
|
6
|
+
|
|
7
|
+
### Current State
|
|
8
|
+
|
|
9
|
+
- **File:** `lib/ollama/client.rb`
|
|
10
|
+
- **Size:** 860 lines
|
|
11
|
+
- **RuboCop Disables:**
|
|
12
|
+
- `Metrics/ClassLength` (entire class)
|
|
13
|
+
- `Metrics/MethodLength` (multiple methods)
|
|
14
|
+
- `Metrics/ParameterLists` (multiple methods)
|
|
15
|
+
- `Metrics/AbcSize` (multiple methods)
|
|
16
|
+
- `Metrics/CyclomaticComplexity` (multiple methods)
|
|
17
|
+
- `Metrics/PerceivedComplexity` (multiple methods)
|
|
18
|
+
- `Metrics/BlockLength` (multiple methods)
|
|
19
|
+
|
|
20
|
+
### Responsibilities
|
|
21
|
+
|
|
22
|
+
The `Client` class currently handles:
|
|
23
|
+
1. HTTP communication with Ollama API
|
|
24
|
+
2. JSON parsing and validation
|
|
25
|
+
3. Schema validation
|
|
26
|
+
4. Retry logic
|
|
27
|
+
5. Error handling and enhancement
|
|
28
|
+
6. Tool normalization
|
|
29
|
+
7. Response formatting
|
|
30
|
+
8. Streaming response parsing
|
|
31
|
+
9. Model suggestion logic
|
|
32
|
+
10. Response hooks/callbacks
|
|
33
|
+
|
|
34
|
+
### Recommendations
|
|
35
|
+
|
|
36
|
+
#### Option A: Extract Service Objects (Recommended)
|
|
37
|
+
|
|
38
|
+
Break down into focused service classes:
|
|
39
|
+
|
|
40
|
+
```ruby
|
|
41
|
+
# lib/ollama/http_client.rb
|
|
42
|
+
class HttpClient
|
|
43
|
+
# Handles all HTTP communication
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# lib/ollama/response_parser.rb
|
|
47
|
+
class ResponseParser
|
|
48
|
+
# Handles JSON parsing, markdown stripping, etc.
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# lib/ollama/retry_handler.rb
|
|
52
|
+
class RetryHandler
|
|
53
|
+
# Handles retry logic and error classification
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# lib/ollama/client.rb (simplified)
|
|
57
|
+
class Client
|
|
58
|
+
def initialize(config: nil)
|
|
59
|
+
@config = config || default_config
|
|
60
|
+
@http_client = HttpClient.new(@config)
|
|
61
|
+
@response_parser = ResponseParser.new
|
|
62
|
+
@retry_handler = RetryHandler.new(@config)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**Benefits:**
|
|
68
|
+
- Single Responsibility Principle
|
|
69
|
+
- Easier to test
|
|
70
|
+
- Easier to maintain
|
|
71
|
+
- Can enable RuboCop metrics
|
|
72
|
+
|
|
73
|
+
**Trade-offs:**
|
|
74
|
+
- More files to navigate
|
|
75
|
+
- Slightly more complex initialization
|
|
76
|
+
|
|
77
|
+
#### Option B: Extract Concerns into Modules
|
|
78
|
+
|
|
79
|
+
Keep single file but organize with modules:
|
|
80
|
+
|
|
81
|
+
```ruby
|
|
82
|
+
class Client
|
|
83
|
+
include HTTPCommunication
|
|
84
|
+
include ResponseParsing
|
|
85
|
+
include RetryHandling
|
|
86
|
+
include ErrorEnhancement
|
|
87
|
+
end
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**Benefits:**
|
|
91
|
+
- Still one file
|
|
92
|
+
- Better organization
|
|
93
|
+
- Can test modules independently
|
|
94
|
+
|
|
95
|
+
**Trade-offs:**
|
|
96
|
+
- Still a large file
|
|
97
|
+
- RuboCop metrics still problematic
|
|
98
|
+
|
|
99
|
+
#### Option C: Accept Complexity (Current State)
|
|
100
|
+
|
|
101
|
+
**Rationale:**
|
|
102
|
+
- Client is the core API surface
|
|
103
|
+
- All methods are public API
|
|
104
|
+
- Breaking it up might make usage more complex
|
|
105
|
+
- Current structure is functional
|
|
106
|
+
|
|
107
|
+
**Action Items:**
|
|
108
|
+
- Document why metrics are disabled
|
|
109
|
+
- Add architectural decision record (ADR)
|
|
110
|
+
- Consider refactoring in future major version
|
|
111
|
+
|
|
112
|
+
### Recommended Approach
|
|
113
|
+
|
|
114
|
+
**Short-term:** Document the decision (Option C)
|
|
115
|
+
**Medium-term:** Extract HTTP client (Option A, partial)
|
|
116
|
+
**Long-term:** Full service object extraction (Option A)
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## ⚠️ 2. Thread Safety
|
|
121
|
+
|
|
122
|
+
### Current State
|
|
123
|
+
|
|
124
|
+
**Global Configuration:**
|
|
125
|
+
```ruby
|
|
126
|
+
module OllamaClient
|
|
127
|
+
@config_mutex = Mutex.new
|
|
128
|
+
|
|
129
|
+
def self.configure
|
|
130
|
+
@config_mutex.synchronize do
|
|
131
|
+
@config ||= Ollama::Config.new
|
|
132
|
+
yield(@config)
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**Issues:**
|
|
139
|
+
1. Mutex protects global config access, but warning says "not thread-safe"
|
|
140
|
+
2. Confusing messaging - mutex IS present but warning suggests it's not safe
|
|
141
|
+
3. Per-client config is recommended but not enforced
|
|
142
|
+
|
|
143
|
+
### Analysis
|
|
144
|
+
|
|
145
|
+
**What's Actually Thread-Safe:**
|
|
146
|
+
- ✅ Global config access (protected by mutex)
|
|
147
|
+
- ✅ Per-client instances (each has own config)
|
|
148
|
+
- ✅ Client methods (stateless, use instance config)
|
|
149
|
+
|
|
150
|
+
**What's NOT Thread-Safe:**
|
|
151
|
+
- ⚠️ Modifying global config while clients are using it
|
|
152
|
+
- ⚠️ Shared config objects between threads (if mutated)
|
|
153
|
+
|
|
154
|
+
### Recommendations
|
|
155
|
+
|
|
156
|
+
#### Option A: Clarify Documentation (Recommended)
|
|
157
|
+
|
|
158
|
+
Update warnings to be more accurate:
|
|
159
|
+
|
|
160
|
+
```ruby
|
|
161
|
+
# ⚠️ THREAD SAFETY WARNING:
|
|
162
|
+
# Global configuration access is protected by mutex, but modifying
|
|
163
|
+
# global config while clients are active can cause race conditions.
|
|
164
|
+
# For concurrent agents, prefer per-client configuration:
|
|
165
|
+
#
|
|
166
|
+
# config = Ollama::Config.new
|
|
167
|
+
# config.model = "llama3.1"
|
|
168
|
+
# client = Ollama::Client.new(config: config)
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
#### Option B: Make Global Config Immutable
|
|
172
|
+
|
|
173
|
+
```ruby
|
|
174
|
+
def self.configure
|
|
175
|
+
@config_mutex.synchronize do
|
|
176
|
+
@config ||= Ollama::Config.new
|
|
177
|
+
frozen_config = @config.dup.freeze
|
|
178
|
+
yield(frozen_config)
|
|
179
|
+
@config = frozen_config.dup # Create new instance
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
#### Option C: Deprecate Global Config
|
|
185
|
+
|
|
186
|
+
```ruby
|
|
187
|
+
def self.configure
|
|
188
|
+
warn "[DEPRECATED] OllamaClient.configure is deprecated. " \
|
|
189
|
+
"Use per-client config: Ollama::Client.new(config: ...)"
|
|
190
|
+
# ... existing implementation
|
|
191
|
+
end
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Recommended Approach
|
|
195
|
+
|
|
196
|
+
**Immediate:** Clarify documentation (Option A)
|
|
197
|
+
**Future:** Consider deprecation path (Option C) if usage patterns show global config is rarely needed
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## ⚠️ 3. Learning Curve
|
|
202
|
+
|
|
203
|
+
### Current State
|
|
204
|
+
|
|
205
|
+
The gem provides two agent patterns:
|
|
206
|
+
|
|
207
|
+
1. **Planner** (`Ollama::Agent::Planner`)
|
|
208
|
+
- Stateless
|
|
209
|
+
- Uses `/api/generate`
|
|
210
|
+
- Returns structured JSON
|
|
211
|
+
- For: routing, classification, decisions
|
|
212
|
+
|
|
213
|
+
2. **Executor** (`Ollama::Agent::Executor`)
|
|
214
|
+
- Stateful
|
|
215
|
+
- Uses `/api/chat`
|
|
216
|
+
- Tool-calling loops
|
|
217
|
+
- For: multi-step workflows
|
|
218
|
+
|
|
219
|
+
### Challenges for Beginners
|
|
220
|
+
|
|
221
|
+
1. **Conceptual Complexity:**
|
|
222
|
+
- Two different patterns (why?)
|
|
223
|
+
- When to use which?
|
|
224
|
+
- Stateless vs stateful concepts
|
|
225
|
+
|
|
226
|
+
2. **API Surface:**
|
|
227
|
+
- `generate()` vs `chat()` vs `chat_raw()`
|
|
228
|
+
- When to use schema vs plain text
|
|
229
|
+
- Tool calling setup
|
|
230
|
+
|
|
231
|
+
3. **Documentation:**
|
|
232
|
+
- README is comprehensive but dense
|
|
233
|
+
- Examples are minimal
|
|
234
|
+
- Agent patterns require understanding of concepts
|
|
235
|
+
|
|
236
|
+
### Recommendations
|
|
237
|
+
|
|
238
|
+
#### Option A: Enhanced Quick Start Guide
|
|
239
|
+
|
|
240
|
+
Create a step-by-step guide:
|
|
241
|
+
|
|
242
|
+
```markdown
|
|
243
|
+
# Quick Start Guide
|
|
244
|
+
|
|
245
|
+
## Step 1: Simple Text Generation
|
|
246
|
+
[Example]
|
|
247
|
+
|
|
248
|
+
## Step 2: Structured Outputs
|
|
249
|
+
[Example]
|
|
250
|
+
|
|
251
|
+
## Step 3: Agent Planning
|
|
252
|
+
[Example]
|
|
253
|
+
|
|
254
|
+
## Step 4: Tool Calling
|
|
255
|
+
[Example]
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
#### Option B: Decision Tree / Flowchart
|
|
259
|
+
|
|
260
|
+
```
|
|
261
|
+
Need structured output?
|
|
262
|
+
├─ Yes → Use generate() with schema
|
|
263
|
+
└─ No → Need conversation?
|
|
264
|
+
├─ Yes → Use chat_raw() or ChatSession
|
|
265
|
+
└─ No → Use generate() with allow_plain_text: true
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
#### Option C: Simplified Wrapper API
|
|
269
|
+
|
|
270
|
+
```ruby
|
|
271
|
+
# High-level API for beginners
|
|
272
|
+
class SimpleAgent
|
|
273
|
+
def initialize(model: "llama3.1:8b")
|
|
274
|
+
@client = Ollama::Client.new
|
|
275
|
+
@model = model
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
def ask(question, schema: nil)
|
|
279
|
+
if schema
|
|
280
|
+
@client.generate(prompt: question, schema: schema)
|
|
281
|
+
else
|
|
282
|
+
@client.generate(prompt: question, allow_plain_text: true)
|
|
283
|
+
end
|
|
284
|
+
end
|
|
285
|
+
end
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
#### Option D: Video Tutorials / Interactive Examples
|
|
289
|
+
|
|
290
|
+
- Video walkthrough
|
|
291
|
+
- Interactive REPL examples
|
|
292
|
+
- Common patterns cookbook
|
|
293
|
+
|
|
294
|
+
### Recommended Approach
|
|
295
|
+
|
|
296
|
+
**Immediate:**
|
|
297
|
+
1. Add "Quick Start" section to README (Option A)
|
|
298
|
+
2. Add decision tree diagram (Option B)
|
|
299
|
+
|
|
300
|
+
**Short-term:**
|
|
301
|
+
3. Create `examples/quick_start/` directory with progressive examples
|
|
302
|
+
4. Add "Common Patterns" section
|
|
303
|
+
|
|
304
|
+
**Long-term:**
|
|
305
|
+
5. Consider simplified API wrapper (Option C) if demand exists
|
|
306
|
+
6. Create video tutorials if community requests
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
## Summary
|
|
311
|
+
|
|
312
|
+
| Area | Current State | Recommended Action | Priority |
|
|
313
|
+
|------|--------------|-------------------|----------|
|
|
314
|
+
| **Complex Client** | 860 lines, metrics disabled | Document decision, plan extraction | Medium |
|
|
315
|
+
| **Thread Safety** | Mutex present but confusing docs | Clarify documentation | High |
|
|
316
|
+
| **Learning Curve** | Comprehensive but dense | Add quick start guide + decision tree | High |
|
|
317
|
+
|
|
318
|
+
## Next Steps
|
|
319
|
+
|
|
320
|
+
1. ✅ Create this document (done)
|
|
321
|
+
2. Update thread safety documentation
|
|
322
|
+
3. Add quick start guide to README
|
|
323
|
+
4. Create decision tree diagram
|
|
324
|
+
5. Consider ADR for Client class architecture
|
|
325
|
+
6. Gather user feedback on learning curve
|