ag-cortex 0.1.0

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 (162) hide show
  1. package/.agent/commands/test-browser.md +339 -0
  2. package/.agent/rules/00-constitution.md +46 -0
  3. package/.agent/rules/project-rules.md +49 -0
  4. package/.agent/skills/agent-browser/SKILL.md +223 -0
  5. package/.agent/skills/agent-native-architecture/SKILL.md +435 -0
  6. package/.agent/skills/agent-native-architecture/references/action-parity-discipline.md +409 -0
  7. package/.agent/skills/agent-native-architecture/references/agent-execution-patterns.md +467 -0
  8. package/.agent/skills/agent-native-architecture/references/agent-native-testing.md +582 -0
  9. package/.agent/skills/agent-native-architecture/references/architecture-patterns.md +478 -0
  10. package/.agent/skills/agent-native-architecture/references/dynamic-context-injection.md +338 -0
  11. package/.agent/skills/agent-native-architecture/references/files-universal-interface.md +301 -0
  12. package/.agent/skills/agent-native-architecture/references/from-primitives-to-domain-tools.md +359 -0
  13. package/.agent/skills/agent-native-architecture/references/mcp-tool-design.md +506 -0
  14. package/.agent/skills/agent-native-architecture/references/mobile-patterns.md +871 -0
  15. package/.agent/skills/agent-native-architecture/references/product-implications.md +443 -0
  16. package/.agent/skills/agent-native-architecture/references/refactoring-to-prompt-native.md +317 -0
  17. package/.agent/skills/agent-native-architecture/references/self-modification.md +269 -0
  18. package/.agent/skills/agent-native-architecture/references/shared-workspace-architecture.md +680 -0
  19. package/.agent/skills/agent-native-architecture/references/system-prompt-design.md +250 -0
  20. package/.agent/skills/agent-native-reviewer/SKILL.md +246 -0
  21. package/.agent/skills/andrew-kane-gem-writer/SKILL.md +184 -0
  22. package/.agent/skills/andrew-kane-gem-writer/references/database-adapters.md +231 -0
  23. package/.agent/skills/andrew-kane-gem-writer/references/module-organization.md +121 -0
  24. package/.agent/skills/andrew-kane-gem-writer/references/rails-integration.md +183 -0
  25. package/.agent/skills/andrew-kane-gem-writer/references/resources.md +119 -0
  26. package/.agent/skills/andrew-kane-gem-writer/references/testing-patterns.md +261 -0
  27. package/.agent/skills/ankane-readme-writer/SKILL.md +50 -0
  28. package/.agent/skills/architecture-strategist/SKILL.md +52 -0
  29. package/.agent/skills/best-practices-researcher/SKILL.md +100 -0
  30. package/.agent/skills/bug-reproduction-validator/SKILL.md +67 -0
  31. package/.agent/skills/code-simplicity-reviewer/SKILL.md +85 -0
  32. package/.agent/skills/coding-tutor/.claude-plugin/plugin.json +9 -0
  33. package/.agent/skills/coding-tutor/README.md +37 -0
  34. package/.agent/skills/coding-tutor/commands/quiz-me.md +1 -0
  35. package/.agent/skills/coding-tutor/commands/sync-tutorials.md +25 -0
  36. package/.agent/skills/coding-tutor/commands/teach-me.md +1 -0
  37. package/.agent/skills/coding-tutor/skills/coding-tutor/SKILL.md +214 -0
  38. package/.agent/skills/coding-tutor/skills/coding-tutor/scripts/create_tutorial.py +202 -0
  39. package/.agent/skills/coding-tutor/skills/coding-tutor/scripts/index_tutorials.py +203 -0
  40. package/.agent/skills/coding-tutor/skills/coding-tutor/scripts/quiz_priority.py +190 -0
  41. package/.agent/skills/coding-tutor/skills/coding-tutor/scripts/setup_tutorials.py +132 -0
  42. package/.agent/skills/compound-docs/SKILL.md +510 -0
  43. package/.agent/skills/compound-docs/assets/critical-pattern-template.md +34 -0
  44. package/.agent/skills/compound-docs/assets/resolution-template.md +93 -0
  45. package/.agent/skills/compound-docs/references/yaml-schema.md +65 -0
  46. package/.agent/skills/compound-docs/schema.yaml +176 -0
  47. package/.agent/skills/create-agent-skills/SKILL.md +299 -0
  48. package/.agent/skills/create-agent-skills/references/api-security.md +226 -0
  49. package/.agent/skills/create-agent-skills/references/be-clear-and-direct.md +531 -0
  50. package/.agent/skills/create-agent-skills/references/best-practices.md +404 -0
  51. package/.agent/skills/create-agent-skills/references/common-patterns.md +595 -0
  52. package/.agent/skills/create-agent-skills/references/core-principles.md +437 -0
  53. package/.agent/skills/create-agent-skills/references/executable-code.md +175 -0
  54. package/.agent/skills/create-agent-skills/references/iteration-and-testing.md +474 -0
  55. package/.agent/skills/create-agent-skills/references/official-spec.md +185 -0
  56. package/.agent/skills/create-agent-skills/references/recommended-structure.md +168 -0
  57. package/.agent/skills/create-agent-skills/references/skill-structure.md +372 -0
  58. package/.agent/skills/create-agent-skills/references/using-scripts.md +113 -0
  59. package/.agent/skills/create-agent-skills/references/using-templates.md +112 -0
  60. package/.agent/skills/create-agent-skills/references/workflows-and-validation.md +510 -0
  61. package/.agent/skills/create-agent-skills/templates/router-skill.md +73 -0
  62. package/.agent/skills/create-agent-skills/templates/simple-skill.md +33 -0
  63. package/.agent/skills/create-agent-skills/workflows/add-reference.md +96 -0
  64. package/.agent/skills/create-agent-skills/workflows/add-script.md +93 -0
  65. package/.agent/skills/create-agent-skills/workflows/add-template.md +74 -0
  66. package/.agent/skills/create-agent-skills/workflows/add-workflow.md +120 -0
  67. package/.agent/skills/create-agent-skills/workflows/audit-skill.md +138 -0
  68. package/.agent/skills/create-agent-skills/workflows/create-domain-expertise-skill.md +605 -0
  69. package/.agent/skills/create-agent-skills/workflows/create-new-skill.md +191 -0
  70. package/.agent/skills/create-agent-skills/workflows/get-guidance.md +121 -0
  71. package/.agent/skills/create-agent-skills/workflows/upgrade-to-router.md +161 -0
  72. package/.agent/skills/create-agent-skills/workflows/verify-skill.md +204 -0
  73. package/.agent/skills/data-integrity-guardian/SKILL.md +70 -0
  74. package/.agent/skills/data-migration-expert/SKILL.md +97 -0
  75. package/.agent/skills/deployment-verification-agent/SKILL.md +159 -0
  76. package/.agent/skills/design-implementation-reviewer/SKILL.md +85 -0
  77. package/.agent/skills/design-iterator/SKILL.md +197 -0
  78. package/.agent/skills/dhh-rails-reviewer/SKILL.md +45 -0
  79. package/.agent/skills/dhh-rails-style/SKILL.md +184 -0
  80. package/.agent/skills/dhh-rails-style/references/architecture.md +653 -0
  81. package/.agent/skills/dhh-rails-style/references/controllers.md +303 -0
  82. package/.agent/skills/dhh-rails-style/references/frontend.md +510 -0
  83. package/.agent/skills/dhh-rails-style/references/gems.md +266 -0
  84. package/.agent/skills/dhh-rails-style/references/models.md +359 -0
  85. package/.agent/skills/dhh-rails-style/references/testing.md +338 -0
  86. package/.agent/skills/dspy-ruby/SKILL.md +594 -0
  87. package/.agent/skills/dspy-ruby/assets/config-template.rb +359 -0
  88. package/.agent/skills/dspy-ruby/assets/module-template.rb +326 -0
  89. package/.agent/skills/dspy-ruby/assets/signature-template.rb +143 -0
  90. package/.agent/skills/dspy-ruby/references/core-concepts.md +265 -0
  91. package/.agent/skills/dspy-ruby/references/optimization.md +623 -0
  92. package/.agent/skills/dspy-ruby/references/providers.md +305 -0
  93. package/.agent/skills/every-style-editor/SKILL.md +134 -0
  94. package/.agent/skills/every-style-editor/references/EVERY_WRITE_STYLE.md +529 -0
  95. package/.agent/skills/figma-design-sync/SKILL.md +166 -0
  96. package/.agent/skills/file-todos/SKILL.md +251 -0
  97. package/.agent/skills/file-todos/assets/todo-template.md +155 -0
  98. package/.agent/skills/framework-docs-researcher/SKILL.md +83 -0
  99. package/.agent/skills/frontend-design/SKILL.md +42 -0
  100. package/.agent/skills/gemini-imagegen/SKILL.md +237 -0
  101. package/.agent/skills/gemini-imagegen/requirements.txt +2 -0
  102. package/.agent/skills/gemini-imagegen/scripts/compose_images.py +168 -0
  103. package/.agent/skills/gemini-imagegen/scripts/edit_image.py +157 -0
  104. package/.agent/skills/gemini-imagegen/scripts/gemini_images.py +265 -0
  105. package/.agent/skills/gemini-imagegen/scripts/generate_image.py +147 -0
  106. package/.agent/skills/gemini-imagegen/scripts/multi_turn_chat.py +215 -0
  107. package/.agent/skills/git-history-analyzer/SKILL.md +42 -0
  108. package/.agent/skills/git-worktree/SKILL.md +302 -0
  109. package/.agent/skills/git-worktree/scripts/worktree-manager.sh +345 -0
  110. package/.agent/skills/julik-frontend-races-reviewer/SKILL.md +222 -0
  111. package/.agent/skills/kieran-python-reviewer/SKILL.md +104 -0
  112. package/.agent/skills/kieran-rails-reviewer/SKILL.md +86 -0
  113. package/.agent/skills/kieran-typescript-reviewer/SKILL.md +95 -0
  114. package/.agent/skills/lint/SKILL.md +16 -0
  115. package/.agent/skills/pattern-recognition-specialist/SKILL.md +57 -0
  116. package/.agent/skills/performance-oracle/SKILL.md +110 -0
  117. package/.agent/skills/pr-comment-resolver/SKILL.md +69 -0
  118. package/.agent/skills/rclone/SKILL.md +150 -0
  119. package/.agent/skills/rclone/scripts/check_setup.sh +60 -0
  120. package/.agent/skills/repo-research-analyst/SKILL.md +113 -0
  121. package/.agent/skills/security-sentinel/SKILL.md +93 -0
  122. package/.agent/skills/skill-creator/SKILL.md +209 -0
  123. package/.agent/skills/skill-creator/scripts/init_skill.py +304 -0
  124. package/.agent/skills/skill-creator/scripts/package_skill.py +112 -0
  125. package/.agent/skills/skill-creator/scripts/quick_validate.py +72 -0
  126. package/.agent/skills/spec-flow-analyzer/SKILL.md +113 -0
  127. package/.agent/skills/test-agent/SKILL.md +4 -0
  128. package/.agent/workflows/agent-native-audit.md +277 -0
  129. package/.agent/workflows/ask-user-question.md +21 -0
  130. package/.agent/workflows/changelog.md +137 -0
  131. package/.agent/workflows/compound.md +202 -0
  132. package/.agent/workflows/create-agent-skill.md +8 -0
  133. package/.agent/workflows/deepen-plan-research.md +334 -0
  134. package/.agent/workflows/deepen-plan-synthesis.md +182 -0
  135. package/.agent/workflows/deepen-plan.md +79 -0
  136. package/.agent/workflows/feature-video.md +342 -0
  137. package/.agent/workflows/generate-command.md +162 -0
  138. package/.agent/workflows/heal-skill.md +142 -0
  139. package/.agent/workflows/lfg.md +20 -0
  140. package/.agent/workflows/plan-analysis.md +67 -0
  141. package/.agent/workflows/plan-next-steps.md +63 -0
  142. package/.agent/workflows/plan-review.md +33 -0
  143. package/.agent/workflows/plan-synthesis.md +106 -0
  144. package/.agent/workflows/plan.md +49 -0
  145. package/.agent/workflows/report-bug.md +150 -0
  146. package/.agent/workflows/reproduce-bug.md +99 -0
  147. package/.agent/workflows/resolve-parallel.md +34 -0
  148. package/.agent/workflows/resolve-pr-parallel.md +49 -0
  149. package/.agent/workflows/resolve-todo-parallel.md +35 -0
  150. package/.agent/workflows/review-analysis.md +145 -0
  151. package/.agent/workflows/review-synthesis.md +262 -0
  152. package/.agent/workflows/review.md +64 -0
  153. package/.agent/workflows/ship.md +90 -0
  154. package/.agent/workflows/test-command.md +3 -0
  155. package/.agent/workflows/triage.md +310 -0
  156. package/.agent/workflows/work.md +157 -0
  157. package/.agent/workflows/xcode-test.md +332 -0
  158. package/LICENSE +22 -0
  159. package/README.md +49 -0
  160. package/bin/ag-cortex.js +54 -0
  161. package/lib/core.js +165 -0
  162. package/package.json +31 -0
@@ -0,0 +1,359 @@
1
+ # frozen_string_literal: true
2
+
3
+ # DSPy.rb Configuration Examples
4
+ # This file demonstrates various configuration patterns for different use cases
5
+
6
+ require 'dspy'
7
+
8
+ # ============================================================================
9
+ # Basic Configuration
10
+ # ============================================================================
11
+
12
+ # Simple OpenAI configuration
13
+ DSPy.configure do |c|
14
+ c.lm = DSPy::LM.new('openai/gpt-4o-mini',
15
+ api_key: ENV['OPENAI_API_KEY'])
16
+ end
17
+
18
+ # ============================================================================
19
+ # Multi-Provider Configuration
20
+ # ============================================================================
21
+
22
+ # Google Gemini (Advanced)
23
+ DSPy.configure do |c|
24
+ c.lm = DSPy::LM.new('google/gemini-1.5-pro-latest',
25
+ api_key: ENV['GOOGLE_API_KEY'])
26
+ end
27
+
28
+ # Google Gemini
29
+ DSPy.configure do |c|
30
+ c.lm = DSPy::LM.new('gemini/gemini-1.5-pro',
31
+ api_key: ENV['GOOGLE_API_KEY'])
32
+ end
33
+
34
+ # Local Ollama
35
+ DSPy.configure do |c|
36
+ c.lm = DSPy::LM.new('ollama/llama3.1',
37
+ base_url: 'http://localhost:11434')
38
+ end
39
+
40
+ # OpenRouter (access to 200+ models)
41
+ DSPy.configure do |c|
42
+ c.lm = DSPy::LM.new('openrouter/google/gemini-1.5-pro',
43
+ api_key: ENV['OPENROUTER_API_KEY'],
44
+ base_url: 'https://openrouter.ai/api/v1')
45
+ end
46
+
47
+ # ============================================================================
48
+ # Environment-Based Configuration
49
+ # ============================================================================
50
+
51
+ # Different models for different environments
52
+ if Rails.env.development?
53
+ # Use local Ollama for development (free, private)
54
+ DSPy.configure do |c|
55
+ c.lm = DSPy::LM.new('ollama/llama3.1')
56
+ end
57
+ elsif Rails.env.test?
58
+ # Use cheap model for testing
59
+ DSPy.configure do |c|
60
+ c.lm = DSPy::LM.new('openai/gpt-4o-mini',
61
+ api_key: ENV['OPENAI_API_KEY'])
62
+ end
63
+ else
64
+ # Use powerful model for production
65
+ DSPy.configure do |c|
66
+ c.lm = DSPy::LM.new('google/gemini-1.5-pro',
67
+ api_key: ENV['GOOGLE_API_KEY'])
68
+ end
69
+ end
70
+
71
+ # ============================================================================
72
+ # Configuration with Custom Parameters
73
+ # ============================================================================
74
+
75
+ DSPy.configure do |c|
76
+ c.lm = DSPy::LM.new('openai/gpt-4o',
77
+ api_key: ENV['OPENAI_API_KEY'],
78
+ temperature: 0.7, # Creativity (0.0-2.0, default: 1.0)
79
+ max_tokens: 2000, # Maximum response length
80
+ top_p: 0.9, # Nucleus sampling
81
+ frequency_penalty: 0.0, # Reduce repetition (-2.0 to 2.0)
82
+ presence_penalty: 0.0 # Encourage new topics (-2.0 to 2.0)
83
+ )
84
+ end
85
+
86
+ # ============================================================================
87
+ # Multiple Model Configuration (Task-Specific)
88
+ # ============================================================================
89
+
90
+ # Create different language models for different tasks
91
+ module MyApp
92
+ # Fast model for simple tasks
93
+ FAST_LM = DSPy::LM.new('openai/gpt-4o-mini',
94
+ api_key: ENV['OPENAI_API_KEY'],
95
+ temperature: 0.3 # More deterministic
96
+ )
97
+
98
+ # Powerful model for complex tasks
99
+ POWERFUL_LM = DSPy::LM.new('google/gemini-1.5-pro',
100
+ api_key: ENV['GOOGLE_API_KEY'],
101
+ temperature: 0.7
102
+ )
103
+
104
+ # Creative model for content generation
105
+ CREATIVE_LM = DSPy::LM.new('openai/gpt-4o',
106
+ api_key: ENV['OPENAI_API_KEY'],
107
+ temperature: 1.2, # More creative
108
+ top_p: 0.95
109
+ )
110
+
111
+ # Vision-capable model
112
+ VISION_LM = DSPy::LM.new('openai/gpt-4o',
113
+ api_key: ENV['OPENAI_API_KEY'])
114
+ end
115
+
116
+ # Use in modules
117
+ class SimpleClassifier < DSPy::Module
118
+ def initialize
119
+ super
120
+ DSPy.configure { |c| c.lm = MyApp::FAST_LM }
121
+ @predictor = DSPy::Predict.new(SimpleSignature)
122
+ end
123
+ end
124
+
125
+ class ComplexAnalyzer < DSPy::Module
126
+ def initialize
127
+ super
128
+ DSPy.configure { |c| c.lm = MyApp::POWERFUL_LM }
129
+ @predictor = DSPy::ChainOfThought.new(ComplexSignature)
130
+ end
131
+ end
132
+
133
+ # ============================================================================
134
+ # Configuration with Observability (OpenTelemetry)
135
+ # ============================================================================
136
+
137
+ require 'opentelemetry/sdk'
138
+
139
+ # Configure OpenTelemetry
140
+ OpenTelemetry::SDK.configure do |c|
141
+ c.service_name = 'my-dspy-app'
142
+ c.use_all
143
+ end
144
+
145
+ # Configure DSPy (automatically integrates with OpenTelemetry)
146
+ DSPy.configure do |c|
147
+ c.lm = DSPy::LM.new('openai/gpt-4o-mini',
148
+ api_key: ENV['OPENAI_API_KEY'])
149
+ end
150
+
151
+ # ============================================================================
152
+ # Configuration with Langfuse Tracing
153
+ # ============================================================================
154
+
155
+ require 'dspy/langfuse'
156
+
157
+ DSPy.configure do |c|
158
+ c.lm = DSPy::LM.new('openai/gpt-4o-mini',
159
+ api_key: ENV['OPENAI_API_KEY'])
160
+
161
+ # Enable Langfuse tracing
162
+ c.langfuse = {
163
+ public_key: ENV['LANGFUSE_PUBLIC_KEY'],
164
+ secret_key: ENV['LANGFUSE_SECRET_KEY'],
165
+ host: ENV['LANGFUSE_HOST'] || 'https://cloud.langfuse.com'
166
+ }
167
+ end
168
+
169
+ # ============================================================================
170
+ # Configuration with Retry Logic
171
+ # ============================================================================
172
+
173
+ class RetryableConfig
174
+ MAX_RETRIES = 3
175
+
176
+ def self.configure
177
+ DSPy.configure do |c|
178
+ c.lm = create_lm_with_retry
179
+ end
180
+ end
181
+
182
+ def self.create_lm_with_retry
183
+ lm = DSPy::LM.new('openai/gpt-4o-mini',
184
+ api_key: ENV['OPENAI_API_KEY'])
185
+
186
+ # Wrap with retry logic
187
+ lm.extend(RetryBehavior)
188
+ lm
189
+ end
190
+
191
+ module RetryBehavior
192
+ def forward(input, retry_count: 0)
193
+ super(input)
194
+ rescue RateLimitError, TimeoutError => e
195
+ if retry_count < MAX_RETRIES
196
+ sleep(2 ** retry_count) # Exponential backoff
197
+ forward(input, retry_count: retry_count + 1)
198
+ else
199
+ raise
200
+ end
201
+ end
202
+ end
203
+ end
204
+
205
+ RetryableConfig.configure
206
+
207
+ # ============================================================================
208
+ # Configuration with Fallback Models
209
+ # ============================================================================
210
+
211
+ class FallbackConfig
212
+ def self.configure
213
+ DSPy.configure do |c|
214
+ c.lm = create_lm_with_fallback
215
+ end
216
+ end
217
+
218
+ def self.create_lm_with_fallback
219
+ primary = DSPy::LM.new('google/gemini-1.5-pro',
220
+ api_key: ENV['GOOGLE_API_KEY'])
221
+
222
+ fallback = DSPy::LM.new('openai/gpt-4o',
223
+ api_key: ENV['OPENAI_API_KEY'])
224
+
225
+ FallbackLM.new(primary, fallback)
226
+ end
227
+
228
+ class FallbackLM
229
+ def initialize(primary, fallback)
230
+ @primary = primary
231
+ @fallback = fallback
232
+ end
233
+
234
+ def forward(input)
235
+ @primary.forward(input)
236
+ rescue => e
237
+ puts "Primary model failed: #{e.message}. Falling back..."
238
+ @fallback.forward(input)
239
+ end
240
+ end
241
+ end
242
+
243
+ FallbackConfig.configure
244
+
245
+ # ============================================================================
246
+ # Configuration with Budget Tracking
247
+ # ============================================================================
248
+
249
+ class BudgetTrackedConfig
250
+ def self.configure(monthly_budget_usd:)
251
+ DSPy.configure do |c|
252
+ c.lm = BudgetTracker.new(
253
+ DSPy::LM.new('openai/gpt-4o',
254
+ api_key: ENV['OPENAI_API_KEY']),
255
+ monthly_budget_usd: monthly_budget_usd
256
+ )
257
+ end
258
+ end
259
+
260
+ class BudgetTracker
261
+ def initialize(lm, monthly_budget_usd:)
262
+ @lm = lm
263
+ @monthly_budget_usd = monthly_budget_usd
264
+ @monthly_cost = 0.0
265
+ end
266
+
267
+ def forward(input)
268
+ result = @lm.forward(input)
269
+
270
+ # Track cost (simplified - actual costs vary by model)
271
+ tokens = result.metadata[:usage][:total_tokens]
272
+ cost = estimate_cost(tokens)
273
+ @monthly_cost += cost
274
+
275
+ if @monthly_cost > @monthly_budget_usd
276
+ raise "Monthly budget of $#{@monthly_budget_usd} exceeded!"
277
+ end
278
+
279
+ result
280
+ end
281
+
282
+ private
283
+
284
+ def estimate_cost(tokens)
285
+ # Simplified cost estimation (check provider pricing)
286
+ (tokens / 1_000_000.0) * 5.0 # $5 per 1M tokens
287
+ end
288
+ end
289
+ end
290
+
291
+ BudgetTrackedConfig.configure(monthly_budget_usd: 100)
292
+
293
+ # ============================================================================
294
+ # Configuration Initializer for Rails
295
+ # ============================================================================
296
+
297
+ # Save this as config/initializers/dspy.rb
298
+ #
299
+ # require 'dspy'
300
+ #
301
+ # DSPy.configure do |c|
302
+ # # Environment-specific configuration
303
+ # model_config = case Rails.env.to_sym
304
+ # when :development
305
+ # { provider: 'ollama', model: 'llama3.1' }
306
+ # when :test
307
+ # { provider: 'openai', model: 'gpt-4o-mini', temperature: 0.0 }
308
+ # when :production
309
+ # { provider: 'google', model: 'gemini-1.5-pro' }
310
+ # end
311
+ #
312
+ # # Configure language model
313
+ # c.lm = DSPy::LM.new(
314
+ # "#{model_config[:provider]}/#{model_config[:model]}",
315
+ # api_key: ENV["#{model_config[:provider].upcase}_API_KEY"],
316
+ # **model_config.except(:provider, :model)
317
+ # )
318
+ #
319
+ # # Optional: Add observability
320
+ # if Rails.env.production?
321
+ # c.langfuse = {
322
+ # public_key: ENV['LANGFUSE_PUBLIC_KEY'],
323
+ # secret_key: ENV['LANGFUSE_SECRET_KEY']
324
+ # }
325
+ # end
326
+ # end
327
+
328
+ # ============================================================================
329
+ # Testing Configuration
330
+ # ============================================================================
331
+
332
+ # In spec/spec_helper.rb or test/test_helper.rb
333
+ #
334
+ # RSpec.configure do |config|
335
+ # config.before(:suite) do
336
+ # DSPy.configure do |c|
337
+ # c.lm = DSPy::LM.new('openai/gpt-4o-mini',
338
+ # api_key: ENV['OPENAI_API_KEY'],
339
+ # temperature: 0.0 # Deterministic for testing
340
+ # )
341
+ # end
342
+ # end
343
+ # end
344
+
345
+ # ============================================================================
346
+ # Configuration Best Practices
347
+ # ============================================================================
348
+
349
+ # 1. Use environment variables for API keys (never hardcode)
350
+ # 2. Use different models for different environments
351
+ # 3. Use cheaper/faster models for development and testing
352
+ # 4. Configure temperature based on use case:
353
+ # - 0.0-0.3: Deterministic, factual tasks
354
+ # - 0.7-1.0: Balanced creativity
355
+ # - 1.0-2.0: High creativity, content generation
356
+ # 5. Add observability in production (OpenTelemetry, Langfuse)
357
+ # 6. Implement retry logic and fallbacks for reliability
358
+ # 7. Track costs and set budgets for production
359
+ # 8. Use max_tokens to control response length and costs
@@ -0,0 +1,326 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Example DSPy Module Template
4
+ # This template demonstrates best practices for creating composable modules
5
+
6
+ # Basic module with single predictor
7
+ class BasicModule < DSPy::Module
8
+ def initialize
9
+ super
10
+ # Initialize predictor with signature
11
+ @predictor = DSPy::Predict.new(ExampleSignature)
12
+ end
13
+
14
+ def forward(input_hash)
15
+ # Forward pass through the predictor
16
+ @predictor.forward(input_hash)
17
+ end
18
+ end
19
+
20
+ # Module with Chain of Thought reasoning
21
+ class ChainOfThoughtModule < DSPy::Module
22
+ def initialize
23
+ super
24
+ # ChainOfThought automatically adds reasoning to output
25
+ @predictor = DSPy::ChainOfThought.new(EmailClassificationSignature)
26
+ end
27
+
28
+ def forward(email_subject:, email_body:)
29
+ result = @predictor.forward(
30
+ email_subject: email_subject,
31
+ email_body: email_body
32
+ )
33
+
34
+ # Result includes :reasoning field automatically
35
+ {
36
+ category: result[:category],
37
+ priority: result[:priority],
38
+ reasoning: result[:reasoning],
39
+ confidence: calculate_confidence(result)
40
+ }
41
+ end
42
+
43
+ private
44
+
45
+ def calculate_confidence(result)
46
+ # Add custom logic to calculate confidence
47
+ # For example, based on reasoning length or specificity
48
+ result[:confidence] || 0.8
49
+ end
50
+ end
51
+
52
+ # Composable module that chains multiple steps
53
+ class MultiStepPipeline < DSPy::Module
54
+ def initialize
55
+ super
56
+ # Initialize multiple predictors for different steps
57
+ @step1 = DSPy::Predict.new(Step1Signature)
58
+ @step2 = DSPy::ChainOfThought.new(Step2Signature)
59
+ @step3 = DSPy::Predict.new(Step3Signature)
60
+ end
61
+
62
+ def forward(input)
63
+ # Chain predictors together
64
+ result1 = @step1.forward(input)
65
+ result2 = @step2.forward(result1)
66
+ result3 = @step3.forward(result2)
67
+
68
+ # Combine results as needed
69
+ {
70
+ step1_output: result1,
71
+ step2_output: result2,
72
+ final_result: result3
73
+ }
74
+ end
75
+ end
76
+
77
+ # Module with conditional logic
78
+ class ConditionalModule < DSPy::Module
79
+ def initialize
80
+ super
81
+ @simple_classifier = DSPy::Predict.new(SimpleClassificationSignature)
82
+ @complex_analyzer = DSPy::ChainOfThought.new(ComplexAnalysisSignature)
83
+ end
84
+
85
+ def forward(text:, complexity_threshold: 100)
86
+ # Use different predictors based on input characteristics
87
+ if text.length < complexity_threshold
88
+ @simple_classifier.forward(text: text)
89
+ else
90
+ @complex_analyzer.forward(text: text)
91
+ end
92
+ end
93
+ end
94
+
95
+ # Module with error handling and retry logic
96
+ class RobustModule < DSPy::Module
97
+ MAX_RETRIES = 3
98
+
99
+ def initialize
100
+ super
101
+ @predictor = DSPy::Predict.new(RobustSignature)
102
+ @logger = Logger.new(STDOUT)
103
+ end
104
+
105
+ def forward(input, retry_count: 0)
106
+ @logger.info "Processing input: #{input.inspect}"
107
+
108
+ begin
109
+ result = @predictor.forward(input)
110
+ validate_result!(result)
111
+ result
112
+ rescue DSPy::ValidationError => e
113
+ @logger.error "Validation error: #{e.message}"
114
+
115
+ if retry_count < MAX_RETRIES
116
+ @logger.info "Retrying (#{retry_count + 1}/#{MAX_RETRIES})..."
117
+ sleep(2 ** retry_count) # Exponential backoff
118
+ forward(input, retry_count: retry_count + 1)
119
+ else
120
+ @logger.error "Max retries exceeded"
121
+ raise
122
+ end
123
+ end
124
+ end
125
+
126
+ private
127
+
128
+ def validate_result!(result)
129
+ # Add custom validation logic
130
+ raise DSPy::ValidationError, "Invalid result" unless result[:category]
131
+ raise DSPy::ValidationError, "Low confidence" if result[:confidence] && result[:confidence] < 0.5
132
+ end
133
+ end
134
+
135
+ # Module with ReAct agent and tools
136
+ class AgentModule < DSPy::Module
137
+ def initialize
138
+ super
139
+
140
+ # Define tools for the agent
141
+ tools = [
142
+ SearchTool.new,
143
+ CalculatorTool.new,
144
+ DatabaseQueryTool.new
145
+ ]
146
+
147
+ # ReAct provides iterative reasoning and tool usage
148
+ @agent = DSPy::ReAct.new(
149
+ AgentSignature,
150
+ tools: tools,
151
+ max_iterations: 5
152
+ )
153
+ end
154
+
155
+ def forward(task:)
156
+ # Agent will autonomously use tools to complete the task
157
+ @agent.forward(task: task)
158
+ end
159
+ end
160
+
161
+ # Tool definition example
162
+ class SearchTool < DSPy::Tool
163
+ def call(query:)
164
+ # Implement search functionality
165
+ results = perform_search(query)
166
+ { results: results }
167
+ end
168
+
169
+ private
170
+
171
+ def perform_search(query)
172
+ # Actual search implementation
173
+ # Could call external API, database, etc.
174
+ ["result1", "result2", "result3"]
175
+ end
176
+ end
177
+
178
+ # Module with state management
179
+ class StatefulModule < DSPy::Module
180
+ attr_reader :history
181
+
182
+ def initialize
183
+ super
184
+ @predictor = DSPy::ChainOfThought.new(StatefulSignature)
185
+ @history = []
186
+ end
187
+
188
+ def forward(input)
189
+ # Process with context from history
190
+ context = build_context_from_history
191
+ result = @predictor.forward(
192
+ input: input,
193
+ context: context
194
+ )
195
+
196
+ # Store in history
197
+ @history << {
198
+ input: input,
199
+ result: result,
200
+ timestamp: Time.now
201
+ }
202
+
203
+ result
204
+ end
205
+
206
+ def reset!
207
+ @history.clear
208
+ end
209
+
210
+ private
211
+
212
+ def build_context_from_history
213
+ @history.last(5).map { |h| h[:result][:summary] }.join("\n")
214
+ end
215
+ end
216
+
217
+ # Module that uses different LLMs for different tasks
218
+ class MultiModelModule < DSPy::Module
219
+ def initialize
220
+ super
221
+
222
+ # Fast, cheap model for simple classification
223
+ @fast_predictor = create_predictor(
224
+ 'openai/gpt-4o-mini',
225
+ SimpleClassificationSignature
226
+ )
227
+
228
+ # Powerful model for complex analysis
229
+ @powerful_predictor = create_predictor(
230
+ 'google/gemini-1.5-pro-20241022',
231
+ ComplexAnalysisSignature
232
+ )
233
+ end
234
+
235
+ def forward(input, use_complex: false)
236
+ if use_complex
237
+ @powerful_predictor.forward(input)
238
+ else
239
+ @fast_predictor.forward(input)
240
+ end
241
+ end
242
+
243
+ private
244
+
245
+ def create_predictor(model, signature)
246
+ lm = DSPy::LM.new(model, api_key: ENV["#{model.split('/').first.upcase}_API_KEY"])
247
+ DSPy::Predict.new(signature, lm: lm)
248
+ end
249
+ end
250
+
251
+ # Module with caching
252
+ class CachedModule < DSPy::Module
253
+ def initialize
254
+ super
255
+ @predictor = DSPy::Predict.new(CachedSignature)
256
+ @cache = {}
257
+ end
258
+
259
+ def forward(input)
260
+ # Create cache key from input
261
+ cache_key = create_cache_key(input)
262
+
263
+ # Return cached result if available
264
+ if @cache.key?(cache_key)
265
+ puts "Cache hit for #{cache_key}"
266
+ return @cache[cache_key]
267
+ end
268
+
269
+ # Compute and cache result
270
+ result = @predictor.forward(input)
271
+ @cache[cache_key] = result
272
+ result
273
+ end
274
+
275
+ def clear_cache!
276
+ @cache.clear
277
+ end
278
+
279
+ private
280
+
281
+ def create_cache_key(input)
282
+ # Create deterministic hash from input
283
+ Digest::MD5.hexdigest(input.to_s)
284
+ end
285
+ end
286
+
287
+ # Usage Examples:
288
+ #
289
+ # Basic usage:
290
+ # module = BasicModule.new
291
+ # result = module.forward(field_name: "value")
292
+ #
293
+ # Chain of Thought:
294
+ # module = ChainOfThoughtModule.new
295
+ # result = module.forward(
296
+ # email_subject: "Can't log in",
297
+ # email_body: "I'm unable to access my account"
298
+ # )
299
+ # puts result[:reasoning]
300
+ #
301
+ # Multi-step pipeline:
302
+ # pipeline = MultiStepPipeline.new
303
+ # result = pipeline.forward(input_data)
304
+ #
305
+ # With error handling:
306
+ # module = RobustModule.new
307
+ # begin
308
+ # result = module.forward(input_data)
309
+ # rescue DSPy::ValidationError => e
310
+ # puts "Failed after retries: #{e.message}"
311
+ # end
312
+ #
313
+ # Agent with tools:
314
+ # agent = AgentModule.new
315
+ # result = agent.forward(task: "Find the population of Tokyo")
316
+ #
317
+ # Stateful processing:
318
+ # module = StatefulModule.new
319
+ # result1 = module.forward("First input")
320
+ # result2 = module.forward("Second input") # Has context from first
321
+ # module.reset! # Clear history
322
+ #
323
+ # With caching:
324
+ # module = CachedModule.new
325
+ # result1 = module.forward(input) # Computes result
326
+ # result2 = module.forward(input) # Returns cached result