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.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +22 -0
  3. data/README.md +336 -91
  4. data/RELEASE_NOTES_v0.2.6.md +41 -0
  5. data/docs/AREAS_FOR_CONSIDERATION.md +325 -0
  6. data/docs/EXAMPLE_REORGANIZATION.md +412 -0
  7. data/docs/FEATURES_ADDED.md +12 -1
  8. data/docs/GETTING_STARTED.md +361 -0
  9. data/docs/INTEGRATION_TESTING.md +170 -0
  10. data/docs/NEXT_STEPS_SUMMARY.md +114 -0
  11. data/docs/PERSONAS.md +383 -0
  12. data/docs/QUICK_START.md +195 -0
  13. data/docs/TESTING.md +392 -170
  14. data/docs/TEST_CHECKLIST.md +450 -0
  15. data/examples/README.md +62 -63
  16. data/examples/basic_chat.rb +33 -0
  17. data/examples/basic_generate.rb +29 -0
  18. data/examples/mcp_executor.rb +39 -0
  19. data/examples/mcp_http_executor.rb +45 -0
  20. data/examples/tool_calling_parsing.rb +59 -0
  21. data/examples/tool_dto_example.rb +0 -0
  22. data/exe/ollama-client +128 -1
  23. data/lib/ollama/agent/planner.rb +7 -2
  24. data/lib/ollama/chat_session.rb +101 -0
  25. data/lib/ollama/client.rb +41 -35
  26. data/lib/ollama/config.rb +9 -4
  27. data/lib/ollama/document_loader.rb +1 -1
  28. data/lib/ollama/embeddings.rb +61 -28
  29. data/lib/ollama/errors.rb +1 -0
  30. data/lib/ollama/mcp/http_client.rb +149 -0
  31. data/lib/ollama/mcp/stdio_client.rb +146 -0
  32. data/lib/ollama/mcp/tools_bridge.rb +72 -0
  33. data/lib/ollama/mcp.rb +31 -0
  34. data/lib/ollama/options.rb +3 -1
  35. data/lib/ollama/personas.rb +287 -0
  36. data/lib/ollama/version.rb +1 -1
  37. data/lib/ollama_client.rb +17 -5
  38. metadata +22 -48
  39. data/examples/advanced_complex_schemas.rb +0 -366
  40. data/examples/advanced_edge_cases.rb +0 -241
  41. data/examples/advanced_error_handling.rb +0 -200
  42. data/examples/advanced_multi_step_agent.rb +0 -341
  43. data/examples/advanced_performance_testing.rb +0 -186
  44. data/examples/chat_console.rb +0 -143
  45. data/examples/complete_workflow.rb +0 -245
  46. data/examples/dhan_console.rb +0 -843
  47. data/examples/dhanhq/README.md +0 -236
  48. data/examples/dhanhq/agents/base_agent.rb +0 -74
  49. data/examples/dhanhq/agents/data_agent.rb +0 -66
  50. data/examples/dhanhq/agents/orchestrator_agent.rb +0 -120
  51. data/examples/dhanhq/agents/technical_analysis_agent.rb +0 -252
  52. data/examples/dhanhq/agents/trading_agent.rb +0 -81
  53. data/examples/dhanhq/analysis/market_structure.rb +0 -138
  54. data/examples/dhanhq/analysis/pattern_recognizer.rb +0 -192
  55. data/examples/dhanhq/analysis/trend_analyzer.rb +0 -88
  56. data/examples/dhanhq/builders/market_context_builder.rb +0 -67
  57. data/examples/dhanhq/dhanhq_agent.rb +0 -829
  58. data/examples/dhanhq/indicators/technical_indicators.rb +0 -158
  59. data/examples/dhanhq/scanners/intraday_options_scanner.rb +0 -492
  60. data/examples/dhanhq/scanners/swing_scanner.rb +0 -247
  61. data/examples/dhanhq/schemas/agent_schemas.rb +0 -61
  62. data/examples/dhanhq/services/base_service.rb +0 -46
  63. data/examples/dhanhq/services/data_service.rb +0 -118
  64. data/examples/dhanhq/services/trading_service.rb +0 -59
  65. data/examples/dhanhq/technical_analysis_agentic_runner.rb +0 -411
  66. data/examples/dhanhq/technical_analysis_runner.rb +0 -420
  67. data/examples/dhanhq/test_tool_calling.rb +0 -538
  68. data/examples/dhanhq/test_tool_calling_verbose.rb +0 -251
  69. data/examples/dhanhq/utils/instrument_helper.rb +0 -32
  70. data/examples/dhanhq/utils/parameter_cleaner.rb +0 -28
  71. data/examples/dhanhq/utils/parameter_normalizer.rb +0 -45
  72. data/examples/dhanhq/utils/rate_limiter.rb +0 -23
  73. data/examples/dhanhq/utils/trading_parameter_normalizer.rb +0 -72
  74. data/examples/dhanhq_agent.rb +0 -964
  75. data/examples/dhanhq_tools.rb +0 -1663
  76. data/examples/multi_step_agent_with_external_data.rb +0 -368
  77. data/examples/structured_outputs_chat.rb +0 -72
  78. data/examples/structured_tools.rb +0 -89
  79. data/examples/test_dhanhq_tool_calling.rb +0 -375
  80. data/examples/test_tool_calling.rb +0 -160
  81. data/examples/tool_calling_direct.rb +0 -124
  82. data/examples/tool_calling_pattern.rb +0 -269
  83. data/exe/dhan_console +0 -4
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ollama
4
- VERSION = "0.2.5"
4
+ VERSION = "0.2.7"
5
5
  end
data/lib/ollama_client.rb CHANGED
@@ -1,5 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # Load .env file if available (.env takes precedence over shell environment variables)
4
+ require "dotenv"
5
+ Dotenv.overload
6
+
7
+ require_relative "ollama/version"
3
8
  require_relative "ollama/config"
4
9
  require_relative "ollama/errors"
5
10
  require_relative "ollama/schema_validator"
@@ -9,21 +14,27 @@ require_relative "ollama/tool"
9
14
  require_relative "ollama/client"
10
15
  require_relative "ollama/document_loader"
11
16
  require_relative "ollama/streaming_observer"
17
+ require_relative "ollama/chat_session"
12
18
  require_relative "ollama/agent/messages"
13
19
  require_relative "ollama/agent/planner"
14
20
  require_relative "ollama/agent/executor"
21
+ require_relative "ollama/mcp"
22
+ require_relative "ollama/personas"
15
23
 
16
24
  # Main entry point for OllamaClient gem
17
25
  #
18
26
  # ⚠️ THREAD SAFETY WARNING:
19
- # Global configuration via OllamaClient.configure is NOT thread-safe.
20
- # For concurrent agents or multi-threaded applications, use per-client
21
- # configuration instead:
27
+ # Global configuration access is protected by mutex, but modifying
28
+ # global config while clients are active can cause race conditions.
29
+ # For concurrent agents or multi-threaded applications, prefer
30
+ # per-client configuration (recommended):
22
31
  #
23
32
  # config = Ollama::Config.new
24
33
  # config.model = "llama3.1"
25
34
  # client = Ollama::Client.new(config: config)
26
35
  #
36
+ # Each client instance is thread-safe when using its own config.
37
+ #
27
38
  module OllamaClient
28
39
  @config_mutex = Mutex.new
29
40
  @warned_thread_config = false
@@ -37,8 +48,9 @@ module OllamaClient
37
48
  def self.configure
38
49
  if Thread.current != Thread.main && !@warned_thread_config
39
50
  @warned_thread_config = true
40
- msg = "[ollama-client] Global OllamaClient.configure is not thread-safe. " \
41
- "Prefer per-client config (Ollama::Client.new(config: ...))."
51
+ msg = "[ollama-client] Global OllamaClient.configure called from non-main thread. " \
52
+ "While access is mutex-protected, modifying global config concurrently can cause " \
53
+ "race conditions. Prefer per-client config: Ollama::Client.new(config: ...)"
42
54
  warn(msg)
43
55
  end
44
56
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ollama-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.2.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shubham Taywade
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-01-21 00:00:00.000000000 Z
11
+ date: 2026-02-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bigdecimal
@@ -60,7 +60,6 @@ description: A production-ready, agent-first Ruby client for the Ollama API with
60
60
  email:
61
61
  - shubhamtaywade82@gmail.com
62
62
  executables:
63
- - dhan_console
64
63
  - ollama-client
65
64
  extensions: []
66
65
  extra_rdoc_files: []
@@ -70,76 +69,51 @@ files:
70
69
  - CONTRIBUTING.md
71
70
  - LICENSE.txt
72
71
  - README.md
72
+ - RELEASE_NOTES_v0.2.6.md
73
73
  - Rakefile
74
+ - docs/AREAS_FOR_CONSIDERATION.md
74
75
  - docs/CLOUD.md
75
76
  - docs/CONSOLE_IMPROVEMENTS.md
77
+ - docs/EXAMPLE_REORGANIZATION.md
76
78
  - docs/FEATURES_ADDED.md
79
+ - docs/GETTING_STARTED.md
77
80
  - docs/HANDLERS_ANALYSIS.md
81
+ - docs/INTEGRATION_TESTING.md
82
+ - docs/NEXT_STEPS_SUMMARY.md
83
+ - docs/PERSONAS.md
78
84
  - docs/PRODUCTION_FIXES.md
85
+ - docs/QUICK_START.md
79
86
  - docs/README.md
80
87
  - docs/RELEASE_GUIDE.md
81
88
  - docs/SCHEMA_FIXES.md
82
89
  - docs/TESTING.md
90
+ - docs/TEST_CHECKLIST.md
83
91
  - docs/TEST_UPDATES.md
84
92
  - docs/ruby_guide.md
85
93
  - examples/README.md
86
- - examples/advanced_complex_schemas.rb
87
- - examples/advanced_edge_cases.rb
88
- - examples/advanced_error_handling.rb
89
- - examples/advanced_multi_step_agent.rb
90
- - examples/advanced_performance_testing.rb
91
- - examples/chat_console.rb
92
- - examples/complete_workflow.rb
93
- - examples/dhan_console.rb
94
- - examples/dhanhq/README.md
95
- - examples/dhanhq/agents/base_agent.rb
96
- - examples/dhanhq/agents/data_agent.rb
97
- - examples/dhanhq/agents/orchestrator_agent.rb
98
- - examples/dhanhq/agents/technical_analysis_agent.rb
99
- - examples/dhanhq/agents/trading_agent.rb
100
- - examples/dhanhq/analysis/market_structure.rb
101
- - examples/dhanhq/analysis/pattern_recognizer.rb
102
- - examples/dhanhq/analysis/trend_analyzer.rb
103
- - examples/dhanhq/builders/market_context_builder.rb
104
- - examples/dhanhq/dhanhq_agent.rb
105
- - examples/dhanhq/indicators/technical_indicators.rb
106
- - examples/dhanhq/scanners/intraday_options_scanner.rb
107
- - examples/dhanhq/scanners/swing_scanner.rb
108
- - examples/dhanhq/schemas/agent_schemas.rb
109
- - examples/dhanhq/services/base_service.rb
110
- - examples/dhanhq/services/data_service.rb
111
- - examples/dhanhq/services/trading_service.rb
112
- - examples/dhanhq/technical_analysis_agentic_runner.rb
113
- - examples/dhanhq/technical_analysis_runner.rb
114
- - examples/dhanhq/test_tool_calling.rb
115
- - examples/dhanhq/test_tool_calling_verbose.rb
116
- - examples/dhanhq/utils/instrument_helper.rb
117
- - examples/dhanhq/utils/parameter_cleaner.rb
118
- - examples/dhanhq/utils/parameter_normalizer.rb
119
- - examples/dhanhq/utils/rate_limiter.rb
120
- - examples/dhanhq/utils/trading_parameter_normalizer.rb
121
- - examples/dhanhq_agent.rb
122
- - examples/dhanhq_tools.rb
123
- - examples/multi_step_agent_with_external_data.rb
124
- - examples/structured_outputs_chat.rb
125
- - examples/structured_tools.rb
126
- - examples/test_dhanhq_tool_calling.rb
127
- - examples/test_tool_calling.rb
128
- - examples/tool_calling_direct.rb
129
- - examples/tool_calling_pattern.rb
94
+ - examples/basic_chat.rb
95
+ - examples/basic_generate.rb
96
+ - examples/mcp_executor.rb
97
+ - examples/mcp_http_executor.rb
98
+ - examples/tool_calling_parsing.rb
130
99
  - examples/tool_dto_example.rb
131
- - exe/dhan_console
132
100
  - exe/ollama-client
133
101
  - lib/ollama/agent/executor.rb
134
102
  - lib/ollama/agent/messages.rb
135
103
  - lib/ollama/agent/planner.rb
104
+ - lib/ollama/chat_session.rb
136
105
  - lib/ollama/client.rb
137
106
  - lib/ollama/config.rb
138
107
  - lib/ollama/document_loader.rb
139
108
  - lib/ollama/dto.rb
140
109
  - lib/ollama/embeddings.rb
141
110
  - lib/ollama/errors.rb
111
+ - lib/ollama/mcp.rb
112
+ - lib/ollama/mcp/http_client.rb
113
+ - lib/ollama/mcp/stdio_client.rb
114
+ - lib/ollama/mcp/tools_bridge.rb
142
115
  - lib/ollama/options.rb
116
+ - lib/ollama/personas.rb
143
117
  - lib/ollama/response.rb
144
118
  - lib/ollama/schema_validator.rb
145
119
  - lib/ollama/schemas/base.json
@@ -1,366 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- # Advanced Example: Complex Nested Schemas and Validation
5
- # Demonstrates: Deep nesting, arrays of objects, conditional validation, real-world data structures
6
-
7
- require "json"
8
- require_relative "../lib/ollama_client"
9
-
10
- # Example 1: Financial Analysis Schema
11
- class FinancialAnalyzer
12
- def initialize(client:)
13
- @client = client
14
- @schema = {
15
- "type" => "object",
16
- "required" => ["analysis_date", "summary", "metrics", "recommendations"],
17
- "properties" => {
18
- "analysis_date" => {
19
- "type" => "string",
20
- "format" => "date-time"
21
- },
22
- "summary" => {
23
- "type" => "string",
24
- "minLength" => 50,
25
- "maxLength" => 500
26
- },
27
- "metrics" => {
28
- "type" => "object",
29
- "required" => ["revenue", "profit_margin", "growth_rate"],
30
- "properties" => {
31
- "revenue" => {
32
- "type" => "number",
33
- "minimum" => 0
34
- },
35
- "profit_margin" => {
36
- "type" => "number",
37
- "minimum" => 0,
38
- "maximum" => 100,
39
- "description" => "Profit margin as percentage (0 to 100)"
40
- },
41
- "growth_rate" => {
42
- "type" => "number"
43
- },
44
- "trend" => {
45
- "type" => "string",
46
- "enum" => ["increasing", "stable", "decreasing"]
47
- }
48
- }
49
- },
50
- "recommendations" => {
51
- "type" => "array",
52
- "minItems" => 1,
53
- "maxItems" => 10,
54
- "items" => {
55
- "type" => "object",
56
- "required" => ["action", "priority", "rationale"],
57
- "properties" => {
58
- "action" => {
59
- "type" => "string"
60
- },
61
- "priority" => {
62
- "type" => "string",
63
- "enum" => ["low", "medium", "high", "critical"]
64
- },
65
- "rationale" => {
66
- "type" => "string"
67
- },
68
- "estimated_impact" => {
69
- "type" => "object",
70
- "properties" => {
71
- "revenue_impact" => {
72
- "type" => "number"
73
- },
74
- "risk_level" => {
75
- "type" => "string",
76
- "enum" => ["low", "medium", "high"]
77
- }
78
- }
79
- }
80
- }
81
- }
82
- },
83
- "risk_factors" => {
84
- "type" => "array",
85
- "items" => {
86
- "type" => "object",
87
- "required" => ["factor", "severity"],
88
- "properties" => {
89
- "factor" => { "type" => "string" },
90
- "severity" => {
91
- "type" => "string",
92
- "enum" => ["low", "medium", "high", "critical"]
93
- },
94
- "mitigation" => { "type" => "string" }
95
- }
96
- }
97
- }
98
- }
99
- }
100
- end
101
-
102
- def analyze(data:)
103
- prompt = <<~PROMPT
104
- Analyze this financial data: #{data}
105
-
106
- Return JSON with: summary (50-500 chars), metrics (revenue, profit_margin, growth_rate, trend),
107
- recommendations array (action, priority, rationale), and optional risk_factors array.
108
- PROMPT
109
-
110
- @client.generate(prompt: prompt, schema: @schema)
111
- end
112
- end
113
-
114
- # Example 2: Code Review Schema
115
- class CodeReviewer
116
- def initialize(client:)
117
- @client = client
118
- @schema = {
119
- "type" => "object",
120
- "required" => ["overall_score", "issues", "suggestions"],
121
- "properties" => {
122
- "overall_score" => {
123
- "type" => "integer",
124
- "minimum" => 0,
125
- "maximum" => 100,
126
- "description" => "Overall quality score (0 to 100)"
127
- },
128
- "issues" => {
129
- "type" => "array",
130
- "items" => {
131
- "type" => "object",
132
- "required" => ["type", "severity", "location", "description"],
133
- "properties" => {
134
- "type" => {
135
- "type" => "string",
136
- "enum" => ["bug", "security", "performance", "style", "maintainability"]
137
- },
138
- "severity" => {
139
- "type" => "string",
140
- "enum" => ["low", "medium", "high", "critical"]
141
- },
142
- "location" => {
143
- "type" => "object",
144
- "properties" => {
145
- "file" => { "type" => "string" },
146
- "line" => { "type" => "integer" },
147
- "column" => { "type" => "integer" }
148
- }
149
- },
150
- "description" => { "type" => "string" },
151
- "suggestion" => { "type" => "string" }
152
- }
153
- }
154
- },
155
- "suggestions" => {
156
- "type" => "array",
157
- "items" => {
158
- "type" => "object",
159
- "required" => ["category", "description"],
160
- "properties" => {
161
- "category" => {
162
- "type" => "string",
163
- "enum" => ["refactoring", "optimization", "documentation", "testing"]
164
- },
165
- "description" => { "type" => "string" },
166
- "priority" => {
167
- "type" => "string",
168
- "enum" => ["low", "medium", "high"]
169
- }
170
- }
171
- }
172
- },
173
- "strengths" => {
174
- "type" => "array",
175
- "items" => { "type" => "string" }
176
- },
177
- "estimated_effort" => {
178
- "type" => "object",
179
- "properties" => {
180
- "hours" => { "type" => "number", "minimum" => 0 },
181
- "complexity" => {
182
- "type" => "string",
183
- "enum" => ["simple", "moderate", "complex"]
184
- }
185
- }
186
- }
187
- }
188
- }
189
- end
190
-
191
- def review(code:)
192
- prompt = <<~PROMPT
193
- Review this Ruby code: #{code}
194
-
195
- Return JSON with: overall_score (0-100), issues array (type, severity, location, description),
196
- suggestions array (category, description, priority), optional strengths array, optional estimated_effort.
197
- PROMPT
198
-
199
- @client.generate(prompt: prompt, schema: @schema)
200
- end
201
- end
202
-
203
- # Example 3: Research Paper Analysis Schema
204
- class ResearchAnalyzer
205
- def initialize(client:)
206
- @client = client
207
- @schema = {
208
- "type" => "object",
209
- "required" => ["title", "key_findings", "methodology", "citations"],
210
- "properties" => {
211
- "title" => { "type" => "string" },
212
- "key_findings" => {
213
- "type" => "array",
214
- "minItems" => 3,
215
- "maxItems" => 10,
216
- "items" => {
217
- "type" => "object",
218
- "required" => ["finding", "significance"],
219
- "properties" => {
220
- "finding" => { "type" => "string" },
221
- "significance" => {
222
- "type" => "string",
223
- "enum" => ["low", "medium", "high", "breakthrough"]
224
- },
225
- "evidence" => { "type" => "string" }
226
- }
227
- }
228
- },
229
- "methodology" => {
230
- "type" => "object",
231
- "required" => ["type", "description"],
232
- "properties" => {
233
- "type" => {
234
- "type" => "string",
235
- "enum" => ["experimental", "observational", "theoretical", "computational", "mixed"]
236
- },
237
- "description" => { "type" => "string" },
238
- "limitations" => {
239
- "type" => "array",
240
- "items" => { "type" => "string" }
241
- }
242
- }
243
- },
244
- "citations" => {
245
- "type" => "array",
246
- "items" => {
247
- "type" => "object",
248
- "required" => ["author", "title", "year"],
249
- "properties" => {
250
- "author" => { "type" => "string" },
251
- "title" => { "type" => "string" },
252
- "year" => {
253
- "type" => "integer",
254
- "minimum" => 1900,
255
- "maximum" => 2100
256
- },
257
- "relevance" => {
258
- "type" => "string",
259
- "enum" => ["low", "medium", "high"]
260
- }
261
- }
262
- }
263
- },
264
- "reproducibility_score" => {
265
- "type" => "number",
266
- "minimum" => 0,
267
- "maximum" => 1,
268
- "description" => "Reproducibility score (0.0 to 1.0, where 1.0 means fully reproducible)"
269
- }
270
- }
271
- }
272
- end
273
-
274
- def analyze(paper_text:)
275
- prompt = <<~PROMPT
276
- Analyze this research paper: #{paper_text}
277
-
278
- Return JSON with: title, key_findings array (3-10 items: finding, significance, evidence),
279
- methodology (type, description, limitations), citations array (author, title, year, relevance),
280
- optional reproducibility_score (0-1).
281
- PROMPT
282
-
283
- @client.generate(prompt: prompt, schema: @schema)
284
- end
285
- end
286
-
287
- # Run examples
288
- if __FILE__ == $PROGRAM_NAME
289
- # Use longer timeout for complex schemas
290
- config = Ollama::Config.new
291
- config.timeout = 60 # 60 seconds for complex operations
292
- client = Ollama::Client.new(config: config)
293
-
294
- puts "=" * 60
295
- puts "Example 1: Financial Analysis"
296
- puts "=" * 60
297
- financial_data = <<~DATA
298
- Q4 2024 Financial Report:
299
- - Revenue: $2.5M (up 15% from Q3)
300
- - Operating expenses: $1.8M
301
- - Net profit: $700K
302
- - Customer base: 5,000 (up 20%)
303
- - Churn rate: 2% (down from 3%)
304
- DATA
305
-
306
- analyzer = FinancialAnalyzer.new(client: client)
307
- begin
308
- puts "⏳ Analyzing financial data (this may take 30-60 seconds)..."
309
- result = analyzer.analyze(data: financial_data)
310
- puts JSON.pretty_generate(result)
311
- rescue Ollama::TimeoutError => e
312
- puts "⏱️ Timeout: #{e.message}"
313
- puts " Try increasing timeout or using a faster model"
314
- rescue Ollama::Error => e
315
- puts "❌ Error: #{e.message}"
316
- end
317
-
318
- puts "\n" + "=" * 60
319
- puts "Example 2: Code Review"
320
- puts "=" * 60
321
- code_sample = <<~RUBY
322
- def calculate_total(items)
323
- total = 0
324
- items.each do |item|
325
- total += item.price
326
- end
327
- total
328
- end
329
- RUBY
330
-
331
- reviewer = CodeReviewer.new(client: client)
332
- begin
333
- puts "⏳ Reviewing code (this may take 30-60 seconds)..."
334
- result = reviewer.review(code: code_sample)
335
- puts JSON.pretty_generate(result)
336
- rescue Ollama::TimeoutError => e
337
- puts "⏱️ Timeout: #{e.message}"
338
- puts " Try increasing timeout or using a faster model"
339
- rescue Ollama::Error => e
340
- puts "❌ Error: #{e.message}"
341
- end
342
-
343
- puts "\n" + "=" * 60
344
- puts "Example 3: Research Paper Analysis"
345
- puts "=" * 60
346
- paper_abstract = <<~TEXT
347
- This study investigates the impact of machine learning on financial forecasting.
348
- We analyzed 10 years of market data using neural networks and found a 23% improvement
349
- in prediction accuracy. The methodology involved training on historical data and
350
- validating on out-of-sample periods. Key limitations include data quality and
351
- model interpretability challenges.
352
- TEXT
353
-
354
- research_analyzer = ResearchAnalyzer.new(client: client)
355
- begin
356
- puts "⏳ Analyzing research paper (this may take 30-60 seconds)..."
357
- result = research_analyzer.analyze(paper_text: paper_abstract)
358
- puts JSON.pretty_generate(result)
359
- rescue Ollama::TimeoutError => e
360
- puts "⏱️ Timeout: #{e.message}"
361
- puts " Try increasing timeout or using a faster model"
362
- rescue Ollama::Error => e
363
- puts "❌ Error: #{e.message}"
364
- end
365
- end
366
-