@every-env/compound-plugin 0.3.0 → 0.5.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 (49) hide show
  1. package/{plugins/compound-engineering → .claude}/commands/release-docs.md +0 -1
  2. package/.claude-plugin/marketplace.json +2 -2
  3. package/.github/workflows/ci.yml +1 -1
  4. package/.github/workflows/deploy-docs.yml +3 -3
  5. package/.github/workflows/publish.yml +37 -0
  6. package/README.md +12 -3
  7. package/docs/index.html +13 -13
  8. package/docs/pages/changelog.html +39 -0
  9. package/docs/plans/2026-02-08-feat-convert-local-md-settings-for-opencode-codex-plan.md +143 -0
  10. package/docs/plans/2026-02-08-feat-simplify-plugin-settings-plan.md +195 -0
  11. package/docs/plans/2026-02-09-refactor-dspy-ruby-skill-update-plan.md +104 -0
  12. package/docs/plans/2026-02-12-feat-add-cursor-cli-target-provider-plan.md +306 -0
  13. package/docs/specs/cursor.md +85 -0
  14. package/package.json +1 -1
  15. package/plugins/compound-engineering/.claude-plugin/plugin.json +2 -2
  16. package/plugins/compound-engineering/CHANGELOG.md +38 -0
  17. package/plugins/compound-engineering/README.md +5 -3
  18. package/plugins/compound-engineering/commands/workflows/brainstorm.md +6 -1
  19. package/plugins/compound-engineering/commands/workflows/compound.md +1 -0
  20. package/plugins/compound-engineering/commands/workflows/review.md +23 -21
  21. package/plugins/compound-engineering/commands/workflows/work.md +29 -15
  22. package/plugins/compound-engineering/skills/dspy-ruby/SKILL.md +539 -396
  23. package/plugins/compound-engineering/skills/dspy-ruby/assets/config-template.rb +159 -331
  24. package/plugins/compound-engineering/skills/dspy-ruby/assets/module-template.rb +210 -236
  25. package/plugins/compound-engineering/skills/dspy-ruby/assets/signature-template.rb +173 -95
  26. package/plugins/compound-engineering/skills/dspy-ruby/references/core-concepts.md +552 -143
  27. package/plugins/compound-engineering/skills/dspy-ruby/references/observability.md +366 -0
  28. package/plugins/compound-engineering/skills/dspy-ruby/references/optimization.md +440 -460
  29. package/plugins/compound-engineering/skills/dspy-ruby/references/providers.md +305 -225
  30. package/plugins/compound-engineering/skills/dspy-ruby/references/toolsets.md +502 -0
  31. package/plugins/compound-engineering/skills/setup/SKILL.md +168 -0
  32. package/src/commands/convert.ts +10 -5
  33. package/src/commands/install.ts +10 -5
  34. package/src/converters/claude-to-codex.ts +7 -2
  35. package/src/converters/claude-to-cursor.ts +166 -0
  36. package/src/converters/claude-to-droid.ts +174 -0
  37. package/src/converters/claude-to-opencode.ts +8 -2
  38. package/src/targets/cursor.ts +48 -0
  39. package/src/targets/droid.ts +50 -0
  40. package/src/targets/index.ts +18 -0
  41. package/src/types/cursor.ts +29 -0
  42. package/src/types/droid.ts +20 -0
  43. package/tests/codex-converter.test.ts +62 -0
  44. package/tests/converter.test.ts +61 -0
  45. package/tests/cursor-converter.test.ts +347 -0
  46. package/tests/cursor-writer.test.ts +137 -0
  47. package/tests/droid-converter.test.ts +277 -0
  48. package/tests/droid-writer.test.ts +100 -0
  49. package/plugins/compound-engineering/commands/technical_review.md +0 -8
@@ -1,359 +1,187 @@
1
1
  # frozen_string_literal: true
2
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
- # Anthropic Claude
23
- DSPy.configure do |c|
24
- c.lm = DSPy::LM.new('anthropic/claude-3-5-sonnet-20241022',
25
- api_key: ENV['ANTHROPIC_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/anthropic/claude-3.5-sonnet',
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('anthropic/claude-3-5-sonnet-20241022',
67
- api_key: ENV['ANTHROPIC_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('anthropic/claude-3-5-sonnet-20241022',
100
- api_key: ENV['ANTHROPIC_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
3
+ # =============================================================================
4
+ # DSPy.rb Configuration Template v0.34.3 API
5
+ #
6
+ # Rails initializer patterns for DSPy.rb with RubyLLM, observability,
7
+ # and feature-flagged model selection.
8
+ #
9
+ # Key patterns:
10
+ # - Use after_initialize for Rails setup
11
+ # - Use dspy-ruby_llm for multi-provider routing
12
+ # - Use structured_outputs: true for reliable parsing
13
+ # - Use dspy-o11y + dspy-o11y-langfuse for observability
14
+ # - Use ENV-based feature flags for model selection
15
+ # =============================================================================
16
+
17
+ # =============================================================================
18
+ # Gemfile Dependencies
19
+ # =============================================================================
20
+ #
21
+ # # Core
22
+ # gem 'dspy'
23
+ #
24
+ # # Provider adapter (choose one strategy):
25
+ #
26
+ # # Strategy A: Unified adapter via RubyLLM (recommended)
27
+ # gem 'dspy-ruby_llm'
28
+ # gem 'ruby_llm'
29
+ #
30
+ # # Strategy B: Per-provider adapters (direct SDK access)
31
+ # gem 'dspy-openai' # OpenAI, OpenRouter, Ollama
32
+ # gem 'dspy-anthropic' # Claude
33
+ # gem 'dspy-gemini' # Gemini
34
+ #
35
+ # # Observability (optional)
36
+ # gem 'dspy-o11y'
37
+ # gem 'dspy-o11y-langfuse'
38
+ #
39
+ # # Optimization (optional)
40
+ # gem 'dspy-miprov2' # MIPROv2 optimizer
41
+ # gem 'dspy-gepa' # GEPA optimizer
42
+ #
43
+ # # Schema formats (optional)
44
+ # gem 'sorbet-baml' # BAML schema format (84% token reduction)
45
+
46
+ # =============================================================================
47
+ # Rails Initializer — config/initializers/dspy.rb
48
+ # =============================================================================
49
+
50
+ Rails.application.config.after_initialize do
51
+ # Skip in test unless explicitly enabled
52
+ next if Rails.env.test? && ENV["DSPY_ENABLE_IN_TEST"].blank?
53
+
54
+ # Configure RubyLLM provider credentials
55
+ RubyLLM.configure do |config|
56
+ config.gemini_api_key = ENV["GEMINI_API_KEY"] if ENV["GEMINI_API_KEY"].present?
57
+ config.anthropic_api_key = ENV["ANTHROPIC_API_KEY"] if ENV["ANTHROPIC_API_KEY"].present?
58
+ config.openai_api_key = ENV["OPENAI_API_KEY"] if ENV["OPENAI_API_KEY"].present?
180
59
  end
181
60
 
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
61
+ # Configure DSPy with unified RubyLLM adapter
62
+ model = ENV.fetch("DSPY_MODEL", "ruby_llm/gemini-2.5-flash")
63
+ DSPy.configure do |config|
64
+ config.lm = DSPy::LM.new(model, structured_outputs: true)
65
+ config.logger = Rails.logger
189
66
  end
190
67
 
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
68
+ # Enable Langfuse observability (optional)
69
+ if ENV["LANGFUSE_PUBLIC_KEY"].present? && ENV["LANGFUSE_SECRET_KEY"].present?
70
+ DSPy::Observability.configure!
202
71
  end
203
72
  end
204
73
 
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('anthropic/claude-3-5-sonnet-20241022',
220
- api_key: ENV['ANTHROPIC_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
74
+ # =============================================================================
75
+ # Feature Flags — config/initializers/feature_flags.rb
76
+ # =============================================================================
227
77
 
228
- class FallbackLM
229
- def initialize(primary, fallback)
230
- @primary = primary
231
- @fallback = fallback
232
- end
78
+ # Use different models for different roles:
79
+ # - Fast/cheap for classification, routing, simple tasks
80
+ # - Powerful for synthesis, reasoning, complex analysis
233
81
 
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
82
+ module FeatureFlags
83
+ SELECTOR_MODEL = ENV.fetch("DSPY_SELECTOR_MODEL", "ruby_llm/gemini-2.5-flash-lite")
84
+ SYNTHESIZER_MODEL = ENV.fetch("DSPY_SYNTHESIZER_MODEL", "ruby_llm/gemini-2.5-flash")
85
+ REASONING_MODEL = ENV.fetch("DSPY_REASONING_MODEL", "ruby_llm/claude-sonnet-4-20250514")
241
86
  end
242
87
 
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
88
+ # Usage in tools/modules:
89
+ #
90
+ # class ClassifyTool < DSPy::Tools::Base
91
+ # def call(query:)
92
+ # predictor = DSPy::Predict.new(ClassifySignature)
93
+ # predictor.configure { |c| c.lm = DSPy::LM.new(FeatureFlags::SELECTOR_MODEL, structured_outputs: true) }
94
+ # predictor.call(query: query)
95
+ # end
96
+ # end
259
97
 
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
98
+ # =============================================================================
99
+ # Environment Variables — .env
100
+ # =============================================================================
101
+ #
102
+ # # Provider API keys (set the ones you need)
103
+ # GEMINI_API_KEY=...
104
+ # ANTHROPIC_API_KEY=...
105
+ # OPENAI_API_KEY=...
106
+ #
107
+ # # DSPy model configuration
108
+ # DSPY_MODEL=ruby_llm/gemini-2.5-flash
109
+ # DSPY_SELECTOR_MODEL=ruby_llm/gemini-2.5-flash-lite
110
+ # DSPY_SYNTHESIZER_MODEL=ruby_llm/gemini-2.5-flash
111
+ # DSPY_REASONING_MODEL=ruby_llm/claude-sonnet-4-20250514
112
+ #
113
+ # # Langfuse observability (optional)
114
+ # LANGFUSE_PUBLIC_KEY=pk-...
115
+ # LANGFUSE_SECRET_KEY=sk-...
116
+ # DSPY_TELEMETRY_BATCH_SIZE=5
117
+ #
118
+ # # Test environment
119
+ # DSPY_ENABLE_IN_TEST=1 # Set to enable DSPy in test env
266
120
 
267
- def forward(input)
268
- result = @lm.forward(input)
121
+ # =============================================================================
122
+ # Per-Provider Configuration (without RubyLLM)
123
+ # =============================================================================
269
124
 
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
125
+ # OpenAI (dspy-openai gem)
126
+ # DSPy.configure do |c|
127
+ # c.lm = DSPy::LM.new('openai/gpt-4o-mini', api_key: ENV['OPENAI_API_KEY'])
128
+ # end
274
129
 
275
- if @monthly_cost > @monthly_budget_usd
276
- raise "Monthly budget of $#{@monthly_budget_usd} exceeded!"
277
- end
130
+ # Anthropic (dspy-anthropic gem)
131
+ # DSPy.configure do |c|
132
+ # c.lm = DSPy::LM.new('anthropic/claude-sonnet-4-20250514', api_key: ENV['ANTHROPIC_API_KEY'])
133
+ # end
278
134
 
279
- result
280
- end
135
+ # Gemini (dspy-gemini gem)
136
+ # DSPy.configure do |c|
137
+ # c.lm = DSPy::LM.new('gemini/gemini-2.5-flash', api_key: ENV['GEMINI_API_KEY'])
138
+ # end
281
139
 
282
- private
140
+ # Ollama (dspy-openai gem, local models)
141
+ # DSPy.configure do |c|
142
+ # c.lm = DSPy::LM.new('ollama/llama3.2', base_url: 'http://localhost:11434')
143
+ # end
283
144
 
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
145
+ # OpenRouter (dspy-openai gem, 200+ models)
146
+ # DSPy.configure do |c|
147
+ # c.lm = DSPy::LM.new('openrouter/anthropic/claude-3.5-sonnet',
148
+ # api_key: ENV['OPENROUTER_API_KEY'],
149
+ # base_url: 'https://openrouter.ai/api/v1')
150
+ # end
290
151
 
291
- BudgetTrackedConfig.configure(monthly_budget_usd: 100)
152
+ # =============================================================================
153
+ # VCR Test Configuration — spec/support/dspy.rb
154
+ # =============================================================================
155
+
156
+ # VCR.configure do |config|
157
+ # config.cassette_library_dir = "spec/vcr_cassettes"
158
+ # config.hook_into :webmock
159
+ # config.configure_rspec_metadata!
160
+ # config.filter_sensitive_data('<GEMINI_API_KEY>') { ENV['GEMINI_API_KEY'] }
161
+ # config.filter_sensitive_data('<OPENAI_API_KEY>') { ENV['OPENAI_API_KEY'] }
162
+ # config.filter_sensitive_data('<ANTHROPIC_API_KEY>') { ENV['ANTHROPIC_API_KEY'] }
163
+ # end
292
164
 
293
- # ============================================================================
294
- # Configuration Initializer for Rails
295
- # ============================================================================
165
+ # =============================================================================
166
+ # Schema Format Configuration (optional)
167
+ # =============================================================================
296
168
 
297
- # Save this as config/initializers/dspy.rb
298
- #
299
- # require 'dspy'
300
- #
169
+ # BAML schema format — 84% token reduction for Enhanced Prompting mode
301
170
  # 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: 'anthropic', model: 'claude-3-5-sonnet-20241022' }
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)
171
+ # c.lm = DSPy::LM.new('openai/gpt-4o-mini',
172
+ # api_key: ENV['OPENAI_API_KEY'],
173
+ # schema_format: :baml # Requires sorbet-baml gem
317
174
  # )
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
175
  # end
327
176
 
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
177
+ # TOON schema + data format — table-oriented format
178
+ # DSPy.configure do |c|
179
+ # c.lm = DSPy::LM.new('openai/gpt-4o-mini',
180
+ # api_key: ENV['OPENAI_API_KEY'],
181
+ # schema_format: :toon, # How DSPy describes the signature
182
+ # data_format: :toon # How inputs/outputs are rendered in prompts
183
+ # )
343
184
  # 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
185
+ #
186
+ # Note: BAML and TOON apply only when structured_outputs: false.
187
+ # With structured_outputs: true, the provider receives JSON Schema directly.