ollama-client 0.2.5 → 0.2.6

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.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +13 -0
  3. data/README.md +138 -76
  4. data/docs/EXAMPLE_REORGANIZATION.md +412 -0
  5. data/docs/GETTING_STARTED.md +361 -0
  6. data/docs/INTEGRATION_TESTING.md +170 -0
  7. data/docs/NEXT_STEPS_SUMMARY.md +114 -0
  8. data/docs/PERSONAS.md +383 -0
  9. data/docs/QUICK_START.md +195 -0
  10. data/docs/TESTING.md +392 -170
  11. data/docs/TEST_CHECKLIST.md +450 -0
  12. data/examples/README.md +51 -66
  13. data/examples/basic_chat.rb +33 -0
  14. data/examples/basic_generate.rb +29 -0
  15. data/examples/tool_calling_parsing.rb +59 -0
  16. data/exe/ollama-client +128 -1
  17. data/lib/ollama/agent/planner.rb +7 -2
  18. data/lib/ollama/chat_session.rb +101 -0
  19. data/lib/ollama/client.rb +41 -35
  20. data/lib/ollama/config.rb +4 -1
  21. data/lib/ollama/document_loader.rb +1 -1
  22. data/lib/ollama/embeddings.rb +41 -26
  23. data/lib/ollama/errors.rb +1 -0
  24. data/lib/ollama/personas.rb +287 -0
  25. data/lib/ollama/version.rb +1 -1
  26. data/lib/ollama_client.rb +7 -0
  27. metadata +14 -48
  28. data/examples/advanced_complex_schemas.rb +0 -366
  29. data/examples/advanced_edge_cases.rb +0 -241
  30. data/examples/advanced_error_handling.rb +0 -200
  31. data/examples/advanced_multi_step_agent.rb +0 -341
  32. data/examples/advanced_performance_testing.rb +0 -186
  33. data/examples/chat_console.rb +0 -143
  34. data/examples/complete_workflow.rb +0 -245
  35. data/examples/dhan_console.rb +0 -843
  36. data/examples/dhanhq/README.md +0 -236
  37. data/examples/dhanhq/agents/base_agent.rb +0 -74
  38. data/examples/dhanhq/agents/data_agent.rb +0 -66
  39. data/examples/dhanhq/agents/orchestrator_agent.rb +0 -120
  40. data/examples/dhanhq/agents/technical_analysis_agent.rb +0 -252
  41. data/examples/dhanhq/agents/trading_agent.rb +0 -81
  42. data/examples/dhanhq/analysis/market_structure.rb +0 -138
  43. data/examples/dhanhq/analysis/pattern_recognizer.rb +0 -192
  44. data/examples/dhanhq/analysis/trend_analyzer.rb +0 -88
  45. data/examples/dhanhq/builders/market_context_builder.rb +0 -67
  46. data/examples/dhanhq/dhanhq_agent.rb +0 -829
  47. data/examples/dhanhq/indicators/technical_indicators.rb +0 -158
  48. data/examples/dhanhq/scanners/intraday_options_scanner.rb +0 -492
  49. data/examples/dhanhq/scanners/swing_scanner.rb +0 -247
  50. data/examples/dhanhq/schemas/agent_schemas.rb +0 -61
  51. data/examples/dhanhq/services/base_service.rb +0 -46
  52. data/examples/dhanhq/services/data_service.rb +0 -118
  53. data/examples/dhanhq/services/trading_service.rb +0 -59
  54. data/examples/dhanhq/technical_analysis_agentic_runner.rb +0 -411
  55. data/examples/dhanhq/technical_analysis_runner.rb +0 -420
  56. data/examples/dhanhq/test_tool_calling.rb +0 -538
  57. data/examples/dhanhq/test_tool_calling_verbose.rb +0 -251
  58. data/examples/dhanhq/utils/instrument_helper.rb +0 -32
  59. data/examples/dhanhq/utils/parameter_cleaner.rb +0 -28
  60. data/examples/dhanhq/utils/parameter_normalizer.rb +0 -45
  61. data/examples/dhanhq/utils/rate_limiter.rb +0 -23
  62. data/examples/dhanhq/utils/trading_parameter_normalizer.rb +0 -72
  63. data/examples/dhanhq_agent.rb +0 -964
  64. data/examples/dhanhq_tools.rb +0 -1663
  65. data/examples/multi_step_agent_with_external_data.rb +0 -368
  66. data/examples/structured_outputs_chat.rb +0 -72
  67. data/examples/structured_tools.rb +0 -89
  68. data/examples/test_dhanhq_tool_calling.rb +0 -375
  69. data/examples/test_tool_calling.rb +0 -160
  70. data/examples/tool_calling_direct.rb +0 -124
  71. data/examples/tool_calling_pattern.rb +0 -269
  72. data/exe/dhan_console +0 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 687a8a4fbb73c24bbc408a902cbc94312923dd5c9a42823a2a5e13111977a6b9
4
- data.tar.gz: 6c7992774151468a99a855671d2e2e17058a613377de970f5647411c9f627b81
3
+ metadata.gz: a1ba22e6a669d0617be340e290bb4009023583418afb1f4952f58b616e22369e
4
+ data.tar.gz: 33310224720f99ab82cf59b6e30166b682af648240fcecd84ecde9dc5bc88608
5
5
  SHA512:
6
- metadata.gz: c52ad58ee08f15b0014500ac9285c0d7a446447e72ec0df1da17b815ae249103adbf5f3a64ec66e83fc1c821e64d7297b84cd7e19d808c914c862fc3263e52ae
7
- data.tar.gz: fad07b8161e7e1442ecfc203b4774e23ceb5075fe660adc1636a1fe81a8ac4a8e27fad80c91bcc20964a9a13e6733a1cb88612cb6d6de2b4c01b5bbbeba6eaf2
6
+ metadata.gz: 29ff7766aebd45634c3170e6a2e8bdb09c97728f6d4dc726e17e9cc404d23c53e96c669effda77044c3a2296fcd0642e2a96bb845d84d4549f759b8de20383c0
7
+ data.tar.gz: d272a70b48a329c09c8b2ddc0baf98b61708a637eb4cbf92693af4291ccfbf42104ecdf3eef0a66b525ad45e57111c4d550baa525662c284482b15feacfcfafa
data/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.2.6] - 2026-01-26
4
+
5
+ - Reorganize examples: move agent examples to separate repository, keep minimal client examples
6
+ - Add comprehensive test coverage (increased from 65.66% to 79.59%)
7
+ - Add test suite for `Ollama::DocumentLoader` (file loading, context building)
8
+ - Add test suite for `Ollama::Embeddings` (API calls, error handling)
9
+ - Add test suite for `Ollama::ChatSession` (session management)
10
+ - Add test suite for tool classes (`Tool`, `Function`, `Parameters`, `Property`)
11
+ - Rewrite testing documentation to focus on client-only testing (transport/protocol)
12
+ - Add test checklist with specific test categories (G1-G3, C1-C3, A1-A2, F1-F3)
13
+ - Update README with enhanced "What This Gem IS NOT" section
14
+ - Fix RuboCop offenses and improve code quality
15
+
3
16
  ## [0.2.5] - 2026-01-22
4
17
 
5
18
  - Add `Ollama::DocumentLoader` for loading files as context in queries
data/README.md CHANGED
@@ -26,11 +26,15 @@ Domain tools and application logic live **outside** this gem. For convenience, i
26
26
 
27
27
  ## 🚫 What This Gem IS NOT
28
28
 
29
- * Domain tool implementations
30
- * ❌ Domain logic
31
- * ❌ Memory store
32
- * ❌ Chat UI
33
- * ❌ A promise of full Ollama API coverage (it focuses on agent workflows)
29
+ This gem is **NOT**:
30
+ * ❌ A chatbot UI framework
31
+ * ❌ A domain-specific agent implementation
32
+ * ❌ A tool execution engine
33
+ * ❌ A memory store
34
+ * ❌ A promise of full Ollama API coverage (focuses on agent workflows)
35
+ * ❌ An agent runtime (it provides transport + protocol, not agent logic)
36
+
37
+ **Domain tools and application logic live outside this gem.**
34
38
 
35
39
  This keeps it **clean and future-proof**.
36
40
 
@@ -74,19 +78,19 @@ gem install ollama-client
74
78
 
75
79
  ### Primary API: `generate()`
76
80
 
77
- **`generate(prompt:, schema: nil)`** is the **primary and recommended method** for agent-grade usage:
81
+ **`generate(prompt:, schema: nil, allow_plain_text: false)`** is the **primary and recommended method** for agent-grade usage:
78
82
 
79
83
  - ✅ Stateless, explicit state injection
80
84
  - ✅ Uses `/api/generate` endpoint
81
85
  - ✅ Ideal for: agent planning, tool routing, one-shot analysis, classification, extraction
82
86
  - ✅ No implicit memory or conversation history
83
- - ✅ Supports both structured JSON (with schema) and plain text/markdown (without schema)
87
+ - ✅ Supports both structured JSON (with schema) and plain text/markdown (with `allow_plain_text: true`)
84
88
 
85
89
  **This is the method you should use for hybrid agents.**
86
90
 
87
91
  **Usage:**
88
- - **With schema** (structured JSON): `generate(prompt: "...", schema: {...})`
89
- - **Without schema** (plain text): `generate(prompt: "...")` - returns plain text/markdown
92
+ - **With schema** (structured JSON): `generate(prompt: "...", schema: {...})` - returns Hash
93
+ - **Without schema** (plain text): `generate(prompt: "...", allow_plain_text: true)` - returns String
90
94
 
91
95
  ### Choosing the Correct API (generate vs chat)
92
96
 
@@ -260,13 +264,14 @@ require "ollama_client"
260
264
 
261
265
  client = Ollama::Client.new
262
266
 
263
- # Get plain text/markdown response (no schema required)
267
+ # Get plain text/markdown response (use allow_plain_text: true to skip schema)
264
268
  text_response = client.generate(
265
- prompt: "Explain Ruby in simple terms"
269
+ prompt: "Explain Ruby in simple terms",
270
+ allow_plain_text: true
266
271
  )
267
272
 
268
273
  puts text_response
269
- # Output: Plain text or markdown explanation
274
+ # Output: Plain text or markdown explanation (String)
270
275
  ```
271
276
 
272
277
  **Option 2: Using `chat_raw()` (for multi-turn conversations)**
@@ -289,8 +294,8 @@ puts text_response
289
294
  ```
290
295
 
291
296
  **When to use which:**
292
- - **`generate()` without schema** - Simple one-shot queries, explanations, text generation
293
- - **`generate()` with schema** - Structured JSON outputs for agents
297
+ - **`generate()` with `allow_plain_text: true`** - Simple one-shot queries, explanations, text generation
298
+ - **`generate()` with schema** - Structured JSON outputs for agents (default, recommended)
294
299
  - **`chat_raw()` without format** - Multi-turn conversations with plain text
295
300
  - **`chat_raw()` with format** - Multi-turn conversations with structured outputs
296
301
 
@@ -315,6 +320,40 @@ Within `Ollama::Agent`:
315
320
  ```ruby
316
321
  require "ollama_client"
317
322
 
323
+ client = Ollama::Client.new
324
+
325
+ # Option 1: With schema (recommended for structured outputs)
326
+ DECISION_SCHEMA = {
327
+ "type" => "object",
328
+ "required" => ["action", "reasoning"],
329
+ "properties" => {
330
+ "action" => {
331
+ "type" => "string",
332
+ "enum" => ["search", "calculate", "store", "retrieve", "finish"]
333
+ },
334
+ "reasoning" => {
335
+ "type" => "string"
336
+ }
337
+ }
338
+ }
339
+
340
+ planner = Ollama::Agent::Planner.new(client)
341
+
342
+ plan = planner.run(
343
+ prompt: "Given the user request, decide the next action.",
344
+ schema: DECISION_SCHEMA,
345
+ context: { user_request: "Plan a weekend trip to Rome" }
346
+ )
347
+
348
+ puts plan["action"] # => "search" (or one of the enum values)
349
+ puts plan["reasoning"] # => Explanation string
350
+ ```
351
+
352
+ **Option 2: Without schema (returns any JSON)**
353
+
354
+ ```ruby
355
+ require "ollama_client"
356
+
318
357
  client = Ollama::Client.new
319
358
  planner = Ollama::Agent::Planner.new(client)
320
359
 
@@ -326,7 +365,7 @@ plan = planner.run(
326
365
  context: { user_request: "Plan a weekend trip to Rome" }
327
366
  )
328
367
 
329
- puts plan
368
+ puts plan # => Any valid JSON structure
330
369
  ```
331
370
 
332
371
  ### Executor Agent (tool loop, /api/chat)
@@ -669,6 +708,61 @@ result2 = client.chat(messages: messages, format: decision_schema, allow_chat: t
669
708
  # Harder to reason about state in agent systems
670
709
  ```
671
710
 
711
+ ### Decision Table: `generate()` vs `chat()` vs `ChatSession`
712
+
713
+ > **Use `generate()` for systems. Use `chat()` or `ChatSession` for humans.**
714
+
715
+ | Use Case | Method | Schema Guarantees | Streaming | Memory | When to Use |
716
+ |----------|--------|-------------------|-----------|--------|-------------|
717
+ | **Agent planning/routing** | `generate()` | ✅ Strong | ❌ No | ❌ Stateless | Default for agents |
718
+ | **Structured extraction** | `generate()` | ✅ Strong | ❌ No | ❌ Stateless | Data extraction, classification |
719
+ | **Tool-calling loops** | `chat_raw()` | ⚠️ Weaker | ✅ Yes | ✅ Stateful | Executor agent internals |
720
+ | **UI chat interface** | `ChatSession` | ⚠️ Best-effort | ✅ Yes | ✅ Stateful | Human-facing assistants |
721
+ | **Multi-turn conversations** | `ChatSession` | ⚠️ Best-effort | ✅ Yes | ✅ Stateful | Interactive chat |
722
+
723
+ **Core Rule:** Chat must be a feature flag, not default behavior.
724
+
725
+ ### Using `ChatSession` for Human-Facing Chat
726
+
727
+ For UI assistants and interactive chat, use `ChatSession` to manage conversation state:
728
+
729
+ ```ruby
730
+ require "ollama_client"
731
+
732
+ # Enable chat in config
733
+ config = Ollama::Config.new
734
+ config.allow_chat = true
735
+ config.streaming_enabled = true
736
+
737
+ client = Ollama::Client.new(config: config)
738
+
739
+ # Create streaming observer for presentation
740
+ observer = Ollama::StreamingObserver.new do |event|
741
+ case event.type
742
+ when :token
743
+ print event.text
744
+ when :final
745
+ puts "\n--- DONE ---"
746
+ end
747
+ end
748
+
749
+ # Create chat session with system message
750
+ chat = Ollama::ChatSession.new(
751
+ client,
752
+ system: "You are a helpful assistant",
753
+ stream: observer
754
+ )
755
+
756
+ # Send messages (history is managed automatically)
757
+ chat.say("Hello")
758
+ chat.say("Explain Ruby blocks")
759
+
760
+ # Clear history if needed (keeps system message)
761
+ chat.clear
762
+ ```
763
+
764
+ **Important:** Schema validation in chat is **best-effort** for formatting, not correctness. Never use chat+schema for agent control flow.
765
+
672
766
  ### Example: Chat API (Advanced Use Case)
673
767
 
674
768
  ```ruby
@@ -1204,67 +1298,35 @@ end
1204
1298
 
1205
1299
  This keeps the `ollama-client` gem **domain-agnostic** and **reusable** across any project.
1206
1300
 
1207
- **See `examples/tool_calling_pattern.rb` for a working implementation of this pattern.**
1208
-
1209
- ## Advanced Examples
1210
-
1211
- The `examples/` directory contains advanced examples demonstrating production-grade patterns:
1212
-
1213
- ### `tool_calling_pattern.rb`
1214
- **Working implementation of the ToolRouter pattern from the Architecture section:**
1215
- - Tool registry and routing
1216
- - LLM outputs intent, agent executes tools
1217
- - Demonstrates the correct separation of concerns
1218
- - Matches the pattern shown in README.md lines 430-500
1219
-
1220
- ### `dhanhq_trading_agent.rb`
1221
- **Real-world integration: Ollama (reasoning) + DhanHQ (execution):**
1222
- - Ollama analyzes market data and makes trading decisions
1223
- - DhanHQ executes trades (place orders, check positions, etc.)
1224
- - Demonstrates proper separation: LLM = reasoning, DhanHQ = execution
1225
- - Shows risk management with super orders (SL/TP)
1226
- - Perfect example of agent-grade tool calling pattern
1227
-
1228
- ### `advanced_multi_step_agent.rb`
1229
- Multi-step agent workflow with:
1230
- - Complex nested schemas
1231
- - State management across steps
1232
- - Confidence thresholds
1233
- - Risk assessment
1234
- - Error recovery
1235
-
1236
- ### `advanced_error_handling.rb`
1237
- Comprehensive error handling patterns:
1238
- - All error types (NotFoundError, HTTPError, TimeoutError, etc.)
1239
- - Retry strategies with exponential backoff
1240
- - Fallback mechanisms
1241
- - Error statistics and observability
1242
-
1243
- ### `advanced_complex_schemas.rb`
1244
- Real-world complex schemas:
1245
- - Financial analysis (nested metrics, recommendations, risk factors)
1246
- - Code review (issues, suggestions, effort estimation)
1247
- - Research paper analysis (findings, methodology, citations)
1248
-
1249
- ### `advanced_performance_testing.rb`
1250
- Performance and observability:
1251
- - Latency measurement (min, max, avg, p95, p99)
1252
- - Throughput testing
1253
- - Error rate tracking
1254
- - Metrics export
1255
-
1256
- ### `advanced_edge_cases.rb`
1257
- Boundary and edge case testing:
1258
- - Empty/long prompts
1259
- - Special characters and unicode
1260
- - Minimal/strict schemas
1261
- - Deeply nested structures
1262
- - Enum constraints
1263
-
1264
- Run any example:
1265
- ```bash
1266
- ruby examples/advanced_multi_step_agent.rb
1267
- ```
1301
+ **See the [ollama-agent-examples](https://github.com/shubhamtaywade82/ollama-agent-examples) repository for working implementations of this pattern.**
1302
+
1303
+ ## 📚 Examples
1304
+
1305
+ ### Minimal Examples (In This Repo)
1306
+
1307
+ The `examples/` directory contains minimal examples demonstrating **client usage only**:
1308
+
1309
+ - **`basic_generate.rb`** - Basic `/generate` usage with schema validation
1310
+ - **`basic_chat.rb`** - Basic `/chat` usage
1311
+ - **`tool_calling_parsing.rb`** - Tool-call parsing (no execution)
1312
+ - **`tool_dto_example.rb`** - Tool DTO serialization
1313
+
1314
+ These examples focus on **transport and protocol correctness**, not agent behavior.
1315
+
1316
+ ### Full Agent Examples (Separate Repository)
1317
+
1318
+ For complete agent examples (trading agents, coding agents, RAG agents, multi-step workflows, tool execution patterns, etc.), see:
1319
+
1320
+ **[ollama-agent-examples](https://github.com/shubhamtaywade82/ollama-agent-examples)**
1321
+
1322
+ This separation keeps `ollama-client` focused on the transport layer while providing comprehensive examples for agent developers.
1323
+
1324
+ **Why this separation?**
1325
+ - Examples rot faster than APIs
1326
+ - Agent examples pull in domain-specific dependencies
1327
+ - Tool examples imply opinions about tool design
1328
+ - The client stays clean and maintainable
1329
+ - Users don't confuse client vs agent responsibilities
1268
1330
 
1269
1331
  ## Development
1270
1332