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
@@ -1,269 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- # Example: Tool Calling Pattern (as documented in README)
5
- # Demonstrates the correct architecture: LLM outputs intent, agent executes tools
6
- # This matches the pattern shown in README.md lines 430-500
7
-
8
- require "json"
9
- require_relative "../lib/ollama_client"
10
-
11
- # Tool Registry - stores available tools
12
- class ToolRegistry
13
- def initialize
14
- @tools = {}
15
- end
16
-
17
- def register(name, tool)
18
- @tools[name] = tool
19
- end
20
-
21
- def fetch(name)
22
- @tools.fetch(name) { raise "Tool '#{name}' not found. Available: #{@tools.keys.join(', ')}" }
23
- end
24
-
25
- def available
26
- @tools.keys
27
- end
28
- end
29
-
30
- # Base Tool class
31
- class Tool
32
- attr_reader :name, :description
33
-
34
- def initialize(name:, description:)
35
- @name = name
36
- @description = description
37
- end
38
-
39
- def call(input:, context:)
40
- raise NotImplementedError, "Subclass must implement #call"
41
- end
42
- end
43
-
44
- # Example Tools
45
- class SearchTool < Tool
46
- def initialize
47
- super(name: "search", description: "Search for information")
48
- end
49
-
50
- def call(input:, context: nil) # rubocop:disable Lint/UnusedMethodArgument
51
- query = input["query"] || "default"
52
- # In real code, this would call your search API
53
- {
54
- query: query,
55
- results: [
56
- "Result 1 for: #{query}",
57
- "Result 2 for: #{query}",
58
- "Result 3 for: #{query}"
59
- ],
60
- count: 3
61
- }
62
- end
63
- end
64
-
65
- class CalculateTool < Tool
66
- def initialize
67
- super(name: "calculate", description: "Perform calculations")
68
- end
69
-
70
- def call(input:, context: nil) # rubocop:disable Lint/UnusedMethodArgument
71
- operation = input["operation"] || "add"
72
- a = input["a"] || 0
73
- b = input["b"] || 0
74
-
75
- result = case operation
76
- when "add" then a + b
77
- when "subtract" then a - b
78
- when "multiply" then a * b
79
- when "divide" then b.zero? ? "Error: Division by zero" : a / b
80
- else "Unknown operation: #{operation}"
81
- end
82
-
83
- {
84
- operation: operation,
85
- operands: { a: a, b: b },
86
- result: result
87
- }
88
- end
89
- end
90
-
91
- class StoreTool < Tool
92
- def initialize
93
- super(name: "store", description: "Store data")
94
- @storage = {}
95
- end
96
-
97
- def call(input:, context: nil) # rubocop:disable Lint/UnusedMethodArgument
98
- key = input["key"] || "default"
99
- value = input["value"] || {}
100
- @storage[key] = value
101
-
102
- {
103
- key: key,
104
- stored: true,
105
- message: "Data stored successfully"
106
- }
107
- end
108
- end
109
-
110
- # Tool Router - matches README example exactly
111
- class ToolRouter
112
- def initialize(llm:, registry:)
113
- @llm = llm # Ollama::Client instance
114
- @registry = registry
115
- end
116
-
117
- def step(prompt:, context: {})
118
- # LLM outputs intent (not execution)
119
- decision = @llm.generate(
120
- prompt: prompt,
121
- schema: {
122
- "type" => "object",
123
- "required" => ["action"],
124
- "properties" => {
125
- "action" => { "type" => "string" },
126
- "input" => {
127
- "type" => "object",
128
- "additionalProperties" => true
129
- }
130
- }
131
- }
132
- )
133
-
134
- return { done: true } if decision["action"] == "finish"
135
-
136
- # Agent executes tool (deterministic)
137
- tool = @registry.fetch(decision["action"])
138
- output = tool.call(input: decision["input"] || {}, context: context)
139
-
140
- { tool: tool.name, output: output }
141
- end
142
- end
143
-
144
- # Example usage
145
- if __FILE__ == $PROGRAM_NAME
146
- puts "=" * 60
147
- puts "Tool Calling Pattern Example"
148
- puts "=" * 60
149
- puts
150
-
151
- # Setup
152
- client = Ollama::Client.new
153
- registry = ToolRegistry.new
154
-
155
- # Register tools
156
- registry.register("search", SearchTool.new)
157
- registry.register("calculate", CalculateTool.new)
158
- registry.register("store", StoreTool.new)
159
-
160
- # Create router
161
- router = ToolRouter.new(llm: client, registry: registry)
162
-
163
- puts "Available tools: #{registry.available.join(', ')}"
164
- puts
165
-
166
- # Example 1: Search
167
- puts "─" * 60
168
- puts "Example 1: Search Tool"
169
- puts "─" * 60
170
- begin
171
- result = router.step(
172
- prompt: "User wants to search for 'Ruby programming'. Use the search tool with query 'Ruby programming'.",
173
- context: {}
174
- )
175
-
176
- if result[:done]
177
- puts "✅ Workflow complete"
178
- else
179
- puts "Tool: #{result[:tool]}"
180
- puts "Output: #{JSON.pretty_generate(result[:output])}"
181
- end
182
- rescue Ollama::Error => e
183
- puts "❌ Error: #{e.message}"
184
- rescue StandardError => e
185
- puts "❌ Error: #{e.class}: #{e.message}"
186
- end
187
-
188
- puts
189
-
190
- # Example 2: Calculate
191
- puts "─" * 60
192
- puts "Example 2: Calculate Tool"
193
- puts "─" * 60
194
- begin
195
- result = router.step(
196
- prompt: "User wants to calculate 15 * 7. Use the calculate tool with operation 'multiply', a=15, b=7.",
197
- context: {}
198
- )
199
-
200
- if result[:done]
201
- puts "✅ Workflow complete"
202
- else
203
- puts "Tool: #{result[:tool]}"
204
- puts "Output: #{JSON.pretty_generate(result[:output])}"
205
- end
206
- rescue Ollama::Error => e
207
- puts "❌ Error: #{e.message}"
208
- rescue StandardError => e
209
- puts "❌ Error: #{e.class}: #{e.message}"
210
- end
211
-
212
- puts
213
-
214
- # Example 3: Store
215
- puts "─" * 60
216
- puts "Example 3: Store Tool"
217
- puts "─" * 60
218
- begin
219
- result = router.step(
220
- prompt: "User wants to store data with key 'user_preferences' and value {'theme': 'dark'}. Use the store tool.",
221
- context: {}
222
- )
223
-
224
- if result[:done]
225
- puts "✅ Workflow complete"
226
- else
227
- puts "Tool: #{result[:tool]}"
228
- puts "Output: #{JSON.pretty_generate(result[:output])}"
229
- end
230
- rescue Ollama::Error => e
231
- puts "❌ Error: #{e.message}"
232
- rescue StandardError => e
233
- puts "❌ Error: #{e.class}: #{e.message}"
234
- end
235
-
236
- puts
237
-
238
- # Example 4: Finish
239
- puts "─" * 60
240
- puts "Example 4: Finish Action"
241
- puts "─" * 60
242
- begin
243
- result = router.step(
244
- prompt: "The task is complete. Use action 'finish'.",
245
- context: {}
246
- )
247
-
248
- if result[:done]
249
- puts "✅ Workflow complete"
250
- else
251
- puts "Tool: #{result[:tool]}"
252
- puts "Output: #{JSON.pretty_generate(result[:output])}"
253
- end
254
- rescue Ollama::Error => e
255
- puts "❌ Error: #{e.message}"
256
- rescue StandardError => e
257
- puts "❌ Error: #{e.class}: #{e.message}"
258
- end
259
-
260
- puts
261
- puts "=" * 60
262
- puts "Pattern demonstrated:"
263
- puts " 1. LLM outputs structured intent (via ollama-client)"
264
- puts " 2. Agent validates and routes to tool"
265
- puts " 3. Tool executes deterministically (pure Ruby)"
266
- puts " 4. Results returned to agent"
267
- puts "=" * 60
268
- end
269
-
data/exe/dhan_console DELETED
@@ -1,4 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require_relative "../examples/dhan_console"