roast-ai 0.2.0 → 0.2.1

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.
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "roast/workflow/case_executor"
3
4
  require "roast/workflow/conditional_executor"
4
5
  require "roast/workflow/step_executor_factory"
5
6
  require "roast/workflow/step_type_resolver"
@@ -68,6 +69,8 @@ module Roast
68
69
  execute_iteration_step(step)
69
70
  when StepTypeResolver::CONDITIONAL_STEP
70
71
  execute_conditional_step(step)
72
+ when StepTypeResolver::CASE_STEP
73
+ execute_case_step(step)
71
74
  when StepTypeResolver::HASH_STEP
72
75
  execute_hash_step(step)
73
76
  when StepTypeResolver::PARALLEL_STEP
@@ -105,6 +108,15 @@ module Roast
105
108
  dependencies[:conditional_executor]
106
109
  end
107
110
 
111
+ def case_executor
112
+ @case_executor ||= dependencies[:case_executor] || CaseExecutor.new(
113
+ context.workflow,
114
+ context.context_path,
115
+ dependencies[:state_manager] || dependencies[:workflow_executor].state_manager,
116
+ workflow_executor,
117
+ )
118
+ end
119
+
108
120
  def step_orchestrator
109
121
  dependencies[:step_orchestrator]
110
122
  end
@@ -154,6 +166,10 @@ module Roast
154
166
  conditional_executor.execute_conditional(step)
155
167
  end
156
168
 
169
+ def execute_case_step(step)
170
+ case_executor.execute_case(step)
171
+ end
172
+
157
173
  def execute_hash_step(step)
158
174
  name, command = step.to_a.flatten
159
175
  interpolated_name = interpolator.interpolate(name)
@@ -51,7 +51,7 @@ module Roast
51
51
 
52
52
  # First check for a prompt step (contains spaces)
53
53
  if name.plain_text?
54
- step = Roast::Workflow::PromptStep.new(workflow, name: name.to_s, auto_loop: false)
54
+ step = Roast::Workflow::PromptStep.new(workflow, name: name.to_s, auto_loop: true)
55
55
  configure_step(step, name.to_s)
56
56
  return step
57
57
  end
@@ -144,10 +144,11 @@ module Roast
144
144
 
145
145
  # Apply configuration settings to a step
146
146
  def apply_step_configuration(step, step_config)
147
- step.print_response = step_config["print_response"] if step_config["print_response"].present?
148
- step.auto_loop = step_config["loop"] if step_config["loop"].present?
149
- step.json = step_config["json"] if step_config["json"].present?
150
- step.params = step_config["params"] if step_config["params"].present?
147
+ step.print_response = step_config["print_response"] if step_config.key?("print_response")
148
+ step.auto_loop = step_config["loop"] if step_config.key?("loop")
149
+ step.json = step_config["json"] if step_config.key?("json")
150
+ step.params = step_config["params"] if step_config.key?("params")
151
+ step.coerce_to = step_config["coerce_to"].to_sym if step_config.key?("coerce_to")
151
152
  end
152
153
  end
153
154
  end
@@ -9,6 +9,7 @@ module Roast
9
9
  GLOB_STEP = :glob
10
10
  ITERATION_STEP = :iteration
11
11
  CONDITIONAL_STEP = :conditional
12
+ CASE_STEP = :case
12
13
  HASH_STEP = :hash
13
14
  PARALLEL_STEP = :parallel
14
15
  STRING_STEP = :string
@@ -20,6 +21,9 @@ module Roast
20
21
  # Special step names for conditionals
21
22
  CONDITIONAL_STEPS = ["if", "unless"].freeze
22
23
 
24
+ # Special step name for case statements
25
+ CASE_STEPS = ["case"].freeze
26
+
23
27
  class << self
24
28
  # Resolve the type of a step
25
29
  # @param step [String, Hash, Array] The step to analyze
@@ -76,6 +80,16 @@ module Roast
76
80
  CONDITIONAL_STEPS.include?(step_name)
77
81
  end
78
82
 
83
+ # Check if a step is a case step
84
+ # @param step [Hash] The step to check
85
+ # @return [Boolean] true if it's a case step
86
+ def case_step?(step)
87
+ return false unless step.is_a?(Hash)
88
+
89
+ step_name = step.keys.first
90
+ CASE_STEPS.include?(step_name)
91
+ end
92
+
79
93
  # Extract the step name from various step formats
80
94
  # @param step [String, Hash, Array] The step
81
95
  # @return [String, nil] The step name or nil
@@ -107,6 +121,8 @@ module Roast
107
121
  ITERATION_STEP
108
122
  elsif conditional_step?(step)
109
123
  CONDITIONAL_STEP
124
+ elsif case_step?(step)
125
+ CASE_STEP
110
126
  else
111
127
  HASH_STEP
112
128
  end
data/schema/workflow.json CHANGED
@@ -172,6 +172,33 @@
172
172
  }
173
173
  },
174
174
  "required": ["unless", "then"]
175
+ },
176
+ {
177
+ "type": "object",
178
+ "properties": {
179
+ "case": {
180
+ "type": "string",
181
+ "description": "Expression to evaluate. Can be a Ruby expression in {{...}}, a bash command in $(...), a step name, or prompt content."
182
+ },
183
+ "when": {
184
+ "type": "object",
185
+ "description": "Map of case values to steps to execute when matched",
186
+ "additionalProperties": {
187
+ "type": "array",
188
+ "items": {
189
+ "$ref": "#/properties/steps/items"
190
+ }
191
+ }
192
+ },
193
+ "else": {
194
+ "type": "array",
195
+ "items": {
196
+ "$ref": "#/properties/steps/items"
197
+ },
198
+ "description": "Steps to execute when no when clauses match"
199
+ }
200
+ },
201
+ "required": ["case", "when"]
175
202
  }
176
203
  ]
177
204
  }
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.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify
@@ -124,6 +124,7 @@ files:
124
124
  - ".ruby-version"
125
125
  - CHANGELOG.md
126
126
  - CLAUDE.md
127
+ - CLAUDE_NOTES.md
127
128
  - CODE_OF_CONDUCT.md
128
129
  - CONTRIBUTING.md
129
130
  - Gemfile
@@ -141,10 +142,15 @@ files:
141
142
  - examples/api_workflow/prompt.md
142
143
  - examples/api_workflow/transform_data/prompt.md
143
144
  - examples/api_workflow/workflow.yml
145
+ - examples/case_when/README.md
146
+ - examples/case_when/detect_language/prompt.md
147
+ - examples/case_when/workflow.yml
144
148
  - examples/conditional/README.md
145
149
  - examples/conditional/check_condition/prompt.md
146
150
  - examples/conditional/simple_workflow.yml
147
151
  - examples/conditional/workflow.yml
152
+ - examples/direct_coerce_syntax/README.md
153
+ - examples/direct_coerce_syntax/workflow.yml
148
154
  - examples/dot_notation/README.md
149
155
  - examples/dot_notation/workflow.yml
150
156
  - examples/exit_on_error/README.md
@@ -195,6 +201,8 @@ files:
195
201
  - examples/iteration/update_fix_count/prompt.md
196
202
  - examples/iteration/verify_fix/prompt.md
197
203
  - examples/iteration/workflow.yml
204
+ - examples/json_handling/README.md
205
+ - examples/json_handling/workflow.yml
198
206
  - examples/openrouter_example/README.md
199
207
  - examples/openrouter_example/analyze_input/prompt.md
200
208
  - examples/openrouter_example/generate_response/prompt.md
@@ -205,6 +213,10 @@ files:
205
213
  - examples/rspec_to_minitest/run_and_improve/prompt.md
206
214
  - examples/rspec_to_minitest/workflow.md
207
215
  - examples/rspec_to_minitest/workflow.yml
216
+ - examples/smart_coercion_defaults/README.md
217
+ - examples/smart_coercion_defaults/workflow.yml
218
+ - examples/step_configuration/README.md
219
+ - examples/step_configuration/workflow.yml
208
220
  - examples/workflow_generator/README.md
209
221
  - examples/workflow_generator/analyze_user_request/prompt.md
210
222
  - examples/workflow_generator/create_workflow_files/prompt.md
@@ -248,6 +260,8 @@ files:
248
260
  - lib/roast/workflow/base_iteration_step.rb
249
261
  - lib/roast/workflow/base_step.rb
250
262
  - lib/roast/workflow/base_workflow.rb
263
+ - lib/roast/workflow/case_executor.rb
264
+ - lib/roast/workflow/case_step.rb
251
265
  - lib/roast/workflow/command_executor.rb
252
266
  - lib/roast/workflow/conditional_executor.rb
253
267
  - lib/roast/workflow/conditional_step.rb
@@ -258,6 +272,7 @@ files:
258
272
  - lib/roast/workflow/dot_access_hash.rb
259
273
  - lib/roast/workflow/each_step.rb
260
274
  - lib/roast/workflow/error_handler.rb
275
+ - lib/roast/workflow/expression_evaluator.rb
261
276
  - lib/roast/workflow/expression_utils.rb
262
277
  - lib/roast/workflow/file_state_repository.rb
263
278
  - lib/roast/workflow/interpolator.rb