ollama-client 0.2.4 → 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 (80) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +21 -1
  3. data/README.md +560 -106
  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/README.md +2 -3
  11. data/docs/RELEASE_GUIDE.md +376 -0
  12. data/docs/TESTING.md +392 -170
  13. data/docs/TEST_CHECKLIST.md +450 -0
  14. data/docs/ruby_guide.md +6232 -0
  15. data/examples/README.md +51 -66
  16. data/examples/basic_chat.rb +33 -0
  17. data/examples/basic_generate.rb +29 -0
  18. data/examples/tool_calling_parsing.rb +59 -0
  19. data/exe/ollama-client +128 -1
  20. data/lib/ollama/agent/planner.rb +7 -2
  21. data/lib/ollama/chat_session.rb +101 -0
  22. data/lib/ollama/client.rb +43 -21
  23. data/lib/ollama/config.rb +4 -1
  24. data/lib/ollama/document_loader.rb +163 -0
  25. data/lib/ollama/embeddings.rb +42 -13
  26. data/lib/ollama/errors.rb +1 -0
  27. data/lib/ollama/personas.rb +287 -0
  28. data/lib/ollama/version.rb +1 -1
  29. data/lib/ollama_client.rb +8 -0
  30. metadata +31 -53
  31. data/docs/GEM_RELEASE_GUIDE.md +0 -794
  32. data/docs/GET_RUBYGEMS_SECRET.md +0 -151
  33. data/docs/QUICK_OTP_SETUP.md +0 -80
  34. data/docs/QUICK_RELEASE.md +0 -106
  35. data/docs/RUBYGEMS_OTP_SETUP.md +0 -199
  36. data/examples/advanced_complex_schemas.rb +0 -366
  37. data/examples/advanced_edge_cases.rb +0 -241
  38. data/examples/advanced_error_handling.rb +0 -200
  39. data/examples/advanced_multi_step_agent.rb +0 -341
  40. data/examples/advanced_performance_testing.rb +0 -186
  41. data/examples/chat_console.rb +0 -143
  42. data/examples/complete_workflow.rb +0 -245
  43. data/examples/dhan_console.rb +0 -843
  44. data/examples/dhanhq/README.md +0 -236
  45. data/examples/dhanhq/agents/base_agent.rb +0 -74
  46. data/examples/dhanhq/agents/data_agent.rb +0 -66
  47. data/examples/dhanhq/agents/orchestrator_agent.rb +0 -120
  48. data/examples/dhanhq/agents/technical_analysis_agent.rb +0 -252
  49. data/examples/dhanhq/agents/trading_agent.rb +0 -81
  50. data/examples/dhanhq/analysis/market_structure.rb +0 -138
  51. data/examples/dhanhq/analysis/pattern_recognizer.rb +0 -192
  52. data/examples/dhanhq/analysis/trend_analyzer.rb +0 -88
  53. data/examples/dhanhq/builders/market_context_builder.rb +0 -67
  54. data/examples/dhanhq/dhanhq_agent.rb +0 -829
  55. data/examples/dhanhq/indicators/technical_indicators.rb +0 -158
  56. data/examples/dhanhq/scanners/intraday_options_scanner.rb +0 -492
  57. data/examples/dhanhq/scanners/swing_scanner.rb +0 -247
  58. data/examples/dhanhq/schemas/agent_schemas.rb +0 -61
  59. data/examples/dhanhq/services/base_service.rb +0 -46
  60. data/examples/dhanhq/services/data_service.rb +0 -118
  61. data/examples/dhanhq/services/trading_service.rb +0 -59
  62. data/examples/dhanhq/technical_analysis_agentic_runner.rb +0 -411
  63. data/examples/dhanhq/technical_analysis_runner.rb +0 -420
  64. data/examples/dhanhq/test_tool_calling.rb +0 -538
  65. data/examples/dhanhq/test_tool_calling_verbose.rb +0 -251
  66. data/examples/dhanhq/utils/instrument_helper.rb +0 -32
  67. data/examples/dhanhq/utils/parameter_cleaner.rb +0 -28
  68. data/examples/dhanhq/utils/parameter_normalizer.rb +0 -45
  69. data/examples/dhanhq/utils/rate_limiter.rb +0 -23
  70. data/examples/dhanhq/utils/trading_parameter_normalizer.rb +0 -72
  71. data/examples/dhanhq_agent.rb +0 -964
  72. data/examples/dhanhq_tools.rb +0 -1663
  73. data/examples/multi_step_agent_with_external_data.rb +0 -368
  74. data/examples/structured_outputs_chat.rb +0 -72
  75. data/examples/structured_tools.rb +0 -89
  76. data/examples/test_dhanhq_tool_calling.rb +0 -375
  77. data/examples/test_tool_calling.rb +0 -160
  78. data/examples/tool_calling_direct.rb +0 -124
  79. data/examples/tool_calling_pattern.rb +0 -269
  80. 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"