roast-ai 0.2.2 → 0.3.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 (95) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +27 -0
  3. data/CLAUDE.md +3 -1
  4. data/Gemfile +1 -0
  5. data/Gemfile.lock +15 -10
  6. data/README.md +189 -20
  7. data/examples/bash_prototyping/README.md +53 -0
  8. data/examples/bash_prototyping/analyze_network/prompt.md +13 -0
  9. data/examples/bash_prototyping/analyze_system/prompt.md +11 -0
  10. data/examples/bash_prototyping/api_testing.yml +14 -0
  11. data/examples/bash_prototyping/check_processes/prompt.md +11 -0
  12. data/examples/bash_prototyping/generate_report/prompt.md +16 -0
  13. data/examples/bash_prototyping/process_json_response/prompt.md +24 -0
  14. data/examples/bash_prototyping/system_analysis.yml +14 -0
  15. data/examples/bash_prototyping/test_public_api/prompt.md +22 -0
  16. data/examples/cmd/README.md +99 -0
  17. data/examples/cmd/analyze_project/prompt.md +57 -0
  18. data/examples/cmd/basic_demo/prompt.md +48 -0
  19. data/examples/cmd/basic_workflow.yml +17 -0
  20. data/examples/cmd/check_repository/prompt.md +57 -0
  21. data/examples/cmd/create_and_verify/prompt.md +56 -0
  22. data/examples/cmd/dev_workflow.yml +26 -0
  23. data/examples/cmd/explore_project/prompt.md +67 -0
  24. data/examples/cmd/explorer_workflow.yml +21 -0
  25. data/examples/cmd/smart_tool_selection/prompt.md +99 -0
  26. data/examples/grading/read_dependencies/prompt.md +4 -2
  27. data/examples/grading/run_coverage.rb +9 -0
  28. data/examples/grading/workflow.yml +0 -2
  29. data/examples/mcp/README.md +223 -0
  30. data/examples/mcp/analyze_changes/prompt.md +8 -0
  31. data/examples/mcp/analyze_issues/prompt.md +4 -0
  32. data/examples/mcp/analyze_schema/prompt.md +4 -0
  33. data/examples/mcp/check_data_quality/prompt.md +5 -0
  34. data/examples/mcp/check_documentation/prompt.md +4 -0
  35. data/examples/mcp/create_recommendations/prompt.md +5 -0
  36. data/examples/mcp/database_workflow.yml +29 -0
  37. data/examples/mcp/env_demo/workflow.yml +34 -0
  38. data/examples/mcp/fetch_pr_context/prompt.md +4 -0
  39. data/examples/mcp/filesystem_demo/create_test_file/prompt.md +2 -0
  40. data/examples/mcp/filesystem_demo/list_files/prompt.md +6 -0
  41. data/examples/mcp/filesystem_demo/read_with_mcp/prompt.md +7 -0
  42. data/examples/mcp/filesystem_demo/workflow.yml +38 -0
  43. data/examples/mcp/generate_insights/prompt.md +4 -0
  44. data/examples/mcp/generate_report/prompt.md +6 -0
  45. data/examples/mcp/generate_review/prompt.md +16 -0
  46. data/examples/mcp/github_workflow.yml +32 -0
  47. data/examples/mcp/multi_mcp_workflow.yml +58 -0
  48. data/examples/mcp/post_review/prompt.md +3 -0
  49. data/examples/mcp/save_report/prompt.md +6 -0
  50. data/examples/mcp/search_issues/prompt.md +2 -0
  51. data/examples/mcp/summarize/prompt.md +1 -0
  52. data/examples/mcp/test_filesystem/prompt.md +6 -0
  53. data/examples/mcp/test_github/prompt.md +8 -0
  54. data/examples/mcp/test_read/prompt.md +1 -0
  55. data/examples/mcp/workflow.yml +35 -0
  56. data/examples/shared_config/README.md +52 -0
  57. data/examples/shared_config/example_with_shared_config/workflow.yml +6 -0
  58. data/examples/shared_config/shared.yml +7 -0
  59. data/examples/step_configuration/README.md +0 -3
  60. data/examples/step_configuration/workflow.yml +0 -3
  61. data/examples/tool_config_example/README.md +109 -0
  62. data/examples/tool_config_example/example_step/prompt.md +42 -0
  63. data/examples/tool_config_example/workflow.yml +17 -0
  64. data/examples/workflow_generator/workflow.yml +0 -1
  65. data/lib/roast/helpers/function_caching_interceptor.rb +0 -4
  66. data/lib/roast/helpers/prompt_loader.rb +0 -1
  67. data/lib/roast/tools/bash.rb +62 -0
  68. data/lib/roast/tools/cmd.rb +121 -34
  69. data/lib/roast/tools/coding_agent.rb +86 -7
  70. data/lib/roast/tools/helpers/coding_agent_message_formatter.rb +87 -0
  71. data/lib/roast/tools/search_file.rb +13 -1
  72. data/lib/roast/tools.rb +5 -5
  73. data/lib/roast/version.rb +1 -1
  74. data/lib/roast/workflow/base_iteration_step.rb +5 -4
  75. data/lib/roast/workflow/base_step.rb +30 -21
  76. data/lib/roast/workflow/base_workflow.rb +8 -10
  77. data/lib/roast/workflow/configuration.rb +12 -3
  78. data/lib/roast/workflow/configuration_loader.rb +63 -4
  79. data/lib/roast/workflow/configuration_parser.rb +0 -3
  80. data/lib/roast/workflow/error_handler.rb +0 -1
  81. data/lib/roast/workflow/file_state_repository.rb +0 -1
  82. data/lib/roast/workflow/iteration_executor.rb +4 -2
  83. data/lib/roast/workflow/output_manager.rb +0 -1
  84. data/lib/roast/workflow/step_executor_coordinator.rb +5 -3
  85. data/lib/roast/workflow/step_executors/hash_step_executor.rb +1 -1
  86. data/lib/roast/workflow/step_loader.rb +35 -8
  87. data/lib/roast/workflow/step_orchestrator.rb +4 -2
  88. data/lib/roast/workflow/workflow_execution_context.rb +0 -2
  89. data/lib/roast/workflow/workflow_executor.rb +2 -4
  90. data/lib/roast/workflow/workflow_initializer.rb +66 -2
  91. data/lib/roast/workflow/workflow_runner.rb +1 -2
  92. data/lib/roast.rb +8 -0
  93. data/package-lock.json +6 -0
  94. data/roast.gemspec +2 -1
  95. metadata +72 -3
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/string/inflections"
4
-
5
3
  module Roast
6
4
  module Workflow
7
5
  # Manages execution context across pre-processing, target workflows, and post-processing phases
@@ -1,9 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "English"
4
- require "active_support"
5
- require "active_support/isolated_execution_state"
6
- require "active_support/notifications"
4
+
7
5
  require "roast/workflow/command_executor"
8
6
  require "roast/workflow/conditional_executor"
9
7
  require "roast/workflow/error_handler"
@@ -85,7 +83,7 @@ module Roast
85
83
  @command_executor = command_executor || CommandExecutor.new(logger: @error_handler)
86
84
  @interpolator = interpolator || Interpolator.new(workflow, logger: @error_handler)
87
85
  @state_manager = state_manager || StateManager.new(workflow, logger: @error_handler)
88
- @iteration_executor = iteration_executor || IterationExecutor.new(workflow, context_path, @state_manager)
86
+ @iteration_executor = iteration_executor || IterationExecutor.new(workflow, context_path, @state_manager, config_hash)
89
87
  @conditional_executor = conditional_executor || ConditionalExecutor.new(workflow, context_path, @state_manager, self)
90
88
  @step_orchestrator = step_orchestrator || StepOrchestrator.new(workflow, @step_loader, @state_manager, @error_handler, self)
91
89
 
@@ -5,6 +5,7 @@ require "roast/initializers"
5
5
  require "roast/helpers/function_caching_interceptor"
6
6
  require "roast/helpers/logger"
7
7
  require "roast/workflow/base_workflow"
8
+ require "roast/workflow/interpolator"
8
9
 
9
10
  module Roast
10
11
  module Workflow
@@ -27,11 +28,57 @@ module Roast
27
28
  end
28
29
 
29
30
  def include_tools
30
- return unless @configuration.tools.present?
31
+ return unless @configuration.tools.present? || @configuration.mcp_tools.present?
31
32
 
32
33
  BaseWorkflow.include(Raix::FunctionDispatch)
33
34
  BaseWorkflow.include(Roast::Helpers::FunctionCachingInterceptor) # Add caching support
34
- BaseWorkflow.include(*@configuration.tools.map(&:constantize))
35
+
36
+ if @configuration.tools.present?
37
+ BaseWorkflow.include(*@configuration.tools.map(&:constantize))
38
+ end
39
+
40
+ if @configuration.mcp_tools.present?
41
+ BaseWorkflow.include(Raix::MCP)
42
+
43
+ # Create an interpolator for MCP tool configuration
44
+ # We use Object.new as the context because this interpolation happens during
45
+ # initialization, before any workflow instance exists. Since we don't have
46
+ # a workflow instance yet, we use a minimal object that can still evaluate
47
+ # Ruby expressions like ENV['HOME'] or any other valid Ruby code.
48
+ interpolator = Interpolator.new(Object.new)
49
+
50
+ @configuration.mcp_tools.each do |tool|
51
+ # Interpolate the config values
52
+ config = interpolate_config(tool.config, interpolator)
53
+
54
+ # Create the appropriate client based on config
55
+ client = if config["url"]
56
+ Raix::MCP::SseClient.new(
57
+ config["url"],
58
+ headers: config["env"] || {},
59
+ )
60
+ elsif config["command"]
61
+ args = [config["command"]]
62
+ args += config["args"] if config["args"]
63
+ Raix::MCP::StdioClient.new(*args, config["env"] || {})
64
+ end
65
+
66
+ BaseWorkflow.mcp(client: client, only: tool.only, except: tool.except)
67
+ end
68
+ end
69
+
70
+ post_configure_tools
71
+ end
72
+
73
+ def post_configure_tools
74
+ @configuration.tools.each do |tool_name|
75
+ tool_module = tool_name.constantize
76
+
77
+ if tool_module.respond_to?(:post_configuration_setup)
78
+ tool_config = @configuration.tool_config(tool_name)
79
+ tool_module.post_configuration_setup(BaseWorkflow, tool_config)
80
+ end
81
+ end
35
82
  end
36
83
 
37
84
  def configure_api_client
@@ -116,6 +163,23 @@ module Roast
116
163
  # Make a lightweight API call to validate the token
117
164
  client.models.list if client.respond_to?(:models)
118
165
  end
166
+
167
+ def interpolate_config(config, interpolator)
168
+ interpolated = {}
169
+ config.each do |key, value|
170
+ interpolated[key] = case value
171
+ when String
172
+ interpolator.interpolate(value)
173
+ when Array
174
+ value.map { |v| v.is_a?(String) ? interpolator.interpolate(v) : v }
175
+ when Hash
176
+ interpolate_config(value, interpolator)
177
+ else
178
+ value
179
+ end
180
+ end
181
+ interpolated
182
+ end
119
183
  end
120
184
  end
121
185
  end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/notifications"
4
3
  require "erb"
5
4
  require "roast/workflow/replay_handler"
6
5
  require "roast/workflow/workflow_executor"
@@ -168,7 +167,7 @@ module Roast
168
167
  context_path: @configuration.context_path,
169
168
  resource: @configuration.resource,
170
169
  session_name: @configuration.name,
171
- configuration: @configuration,
170
+ workflow_configuration: @configuration,
172
171
  pre_processing_data:,
173
172
  ).tap do |workflow|
174
173
  workflow.output_file = @options[:output] if @options[:output].present?
data/lib/roast.rb CHANGED
@@ -1,5 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_support"
4
+ require "active_support/cache"
5
+ require "active_support/notifications"
6
+ require "active_support/core_ext/hash/indifferent_access"
7
+ require "active_support/core_ext/string"
8
+ require "active_support/core_ext/string/inflections"
9
+ require "active_support/core_ext/module/delegation"
10
+ require "active_support/isolated_execution_state"
3
11
  require "fileutils"
4
12
  require "cli/ui"
5
13
  require "raix"
data/package-lock.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "name": "roast",
3
+ "lockfileVersion": 3,
4
+ "requires": true,
5
+ "packages": {}
6
+ }
data/roast.gemspec CHANGED
@@ -41,6 +41,7 @@ Gem::Specification.new do |spec|
41
41
  spec.add_dependency("diff-lcs", "~> 1.5")
42
42
  spec.add_dependency("faraday-retry")
43
43
  spec.add_dependency("json-schema")
44
- spec.add_dependency("raix", "~> 0.8.6")
44
+ spec.add_dependency("open_router", "~> 0.3")
45
+ spec.add_dependency("raix", "~> 1.0")
45
46
  spec.add_dependency("thor", "~> 1.3")
46
47
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: roast-ai
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify
@@ -79,20 +79,34 @@ dependencies:
79
79
  - - ">="
80
80
  - !ruby/object:Gem::Version
81
81
  version: '0'
82
+ - !ruby/object:Gem::Dependency
83
+ name: open_router
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '0.3'
89
+ type: :runtime
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '0.3'
82
96
  - !ruby/object:Gem::Dependency
83
97
  name: raix
84
98
  requirement: !ruby/object:Gem::Requirement
85
99
  requirements:
86
100
  - - "~>"
87
101
  - !ruby/object:Gem::Version
88
- version: 0.8.6
102
+ version: '1.0'
89
103
  type: :runtime
90
104
  prerelease: false
91
105
  version_requirements: !ruby/object:Gem::Requirement
92
106
  requirements:
93
107
  - - "~>"
94
108
  - !ruby/object:Gem::Version
95
- version: 0.8.6
109
+ version: '1.0'
96
110
  - !ruby/object:Gem::Dependency
97
111
  name: thor
98
112
  requirement: !ruby/object:Gem::Requirement
@@ -142,9 +156,28 @@ files:
142
156
  - examples/api_workflow/prompt.md
143
157
  - examples/api_workflow/transform_data/prompt.md
144
158
  - examples/api_workflow/workflow.yml
159
+ - examples/bash_prototyping/README.md
160
+ - examples/bash_prototyping/analyze_network/prompt.md
161
+ - examples/bash_prototyping/analyze_system/prompt.md
162
+ - examples/bash_prototyping/api_testing.yml
163
+ - examples/bash_prototyping/check_processes/prompt.md
164
+ - examples/bash_prototyping/generate_report/prompt.md
165
+ - examples/bash_prototyping/process_json_response/prompt.md
166
+ - examples/bash_prototyping/system_analysis.yml
167
+ - examples/bash_prototyping/test_public_api/prompt.md
145
168
  - examples/case_when/README.md
146
169
  - examples/case_when/detect_language/prompt.md
147
170
  - examples/case_when/workflow.yml
171
+ - examples/cmd/README.md
172
+ - examples/cmd/analyze_project/prompt.md
173
+ - examples/cmd/basic_demo/prompt.md
174
+ - examples/cmd/basic_workflow.yml
175
+ - examples/cmd/check_repository/prompt.md
176
+ - examples/cmd/create_and_verify/prompt.md
177
+ - examples/cmd/dev_workflow.yml
178
+ - examples/cmd/explore_project/prompt.md
179
+ - examples/cmd/explorer_workflow.yml
180
+ - examples/cmd/smart_tool_selection/prompt.md
148
181
  - examples/conditional/README.md
149
182
  - examples/conditional/check_condition/prompt.md
150
183
  - examples/conditional/simple_workflow.yml
@@ -203,6 +236,33 @@ files:
203
236
  - examples/iteration/workflow.yml
204
237
  - examples/json_handling/README.md
205
238
  - examples/json_handling/workflow.yml
239
+ - examples/mcp/README.md
240
+ - examples/mcp/analyze_changes/prompt.md
241
+ - examples/mcp/analyze_issues/prompt.md
242
+ - examples/mcp/analyze_schema/prompt.md
243
+ - examples/mcp/check_data_quality/prompt.md
244
+ - examples/mcp/check_documentation/prompt.md
245
+ - examples/mcp/create_recommendations/prompt.md
246
+ - examples/mcp/database_workflow.yml
247
+ - examples/mcp/env_demo/workflow.yml
248
+ - examples/mcp/fetch_pr_context/prompt.md
249
+ - examples/mcp/filesystem_demo/create_test_file/prompt.md
250
+ - examples/mcp/filesystem_demo/list_files/prompt.md
251
+ - examples/mcp/filesystem_demo/read_with_mcp/prompt.md
252
+ - examples/mcp/filesystem_demo/workflow.yml
253
+ - examples/mcp/generate_insights/prompt.md
254
+ - examples/mcp/generate_report/prompt.md
255
+ - examples/mcp/generate_review/prompt.md
256
+ - examples/mcp/github_workflow.yml
257
+ - examples/mcp/multi_mcp_workflow.yml
258
+ - examples/mcp/post_review/prompt.md
259
+ - examples/mcp/save_report/prompt.md
260
+ - examples/mcp/search_issues/prompt.md
261
+ - examples/mcp/summarize/prompt.md
262
+ - examples/mcp/test_filesystem/prompt.md
263
+ - examples/mcp/test_github/prompt.md
264
+ - examples/mcp/test_read/prompt.md
265
+ - examples/mcp/workflow.yml
206
266
  - examples/openrouter_example/README.md
207
267
  - examples/openrouter_example/analyze_input/prompt.md
208
268
  - examples/openrouter_example/generate_response/prompt.md
@@ -225,6 +285,9 @@ files:
225
285
  - examples/rspec_to_minitest/run_and_improve/prompt.md
226
286
  - examples/rspec_to_minitest/workflow.md
227
287
  - examples/rspec_to_minitest/workflow.yml
288
+ - examples/shared_config/README.md
289
+ - examples/shared_config/example_with_shared_config/workflow.yml
290
+ - examples/shared_config/shared.yml
228
291
  - examples/single_target_prepost/README.md
229
292
  - examples/single_target_prepost/post_processing/output.txt
230
293
  - examples/single_target_prepost/pre_processing/gather_dependencies/prompt.md
@@ -233,6 +296,9 @@ files:
233
296
  - examples/smart_coercion_defaults/workflow.yml
234
297
  - examples/step_configuration/README.md
235
298
  - examples/step_configuration/workflow.yml
299
+ - examples/tool_config_example/README.md
300
+ - examples/tool_config_example/example_step/prompt.md
301
+ - examples/tool_config_example/workflow.yml
236
302
  - examples/workflow_generator/README.md
237
303
  - examples/workflow_generator/analyze_user_request/prompt.md
238
304
  - examples/workflow_generator/create_workflow_files/prompt.md
@@ -261,9 +327,11 @@ files:
261
327
  - lib/roast/resources/url_resource.rb
262
328
  - lib/roast/tools.rb
263
329
  - lib/roast/tools/ask_user.rb
330
+ - lib/roast/tools/bash.rb
264
331
  - lib/roast/tools/cmd.rb
265
332
  - lib/roast/tools/coding_agent.rb
266
333
  - lib/roast/tools/grep.rb
334
+ - lib/roast/tools/helpers/coding_agent_message_formatter.rb
267
335
  - lib/roast/tools/read_file.rb
268
336
  - lib/roast/tools/search_file.rb
269
337
  - lib/roast/tools/update_files.rb
@@ -325,6 +393,7 @@ files:
325
393
  - lib/roast/workflow/workflow_executor.rb
326
394
  - lib/roast/workflow/workflow_initializer.rb
327
395
  - lib/roast/workflow/workflow_runner.rb
396
+ - package-lock.json
328
397
  - roast.gemspec
329
398
  - schema/workflow.json
330
399
  - shipit.rubygems.yml