roast-ai 0.3.0 → 0.4.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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG.md +32 -0
- data/CLAUDE.md +52 -1
- data/Gemfile +3 -1
- data/Gemfile.lock +63 -16
- data/README.md +115 -5
- data/bin/roast +1 -1
- data/claude-swarm.yml +210 -0
- data/docs/AGENT_STEPS.md +264 -0
- data/examples/agent_workflow/README.md +75 -0
- data/examples/agent_workflow/apply_refactorings/prompt.md +22 -0
- data/examples/agent_workflow/identify_code_smells/prompt.md +15 -0
- data/examples/agent_workflow/summarize_improvements/prompt.md +18 -0
- data/examples/agent_workflow/workflow.yml +16 -0
- data/examples/available_tools_demo/README.md +42 -0
- data/examples/available_tools_demo/analyze_files/prompt.md +6 -0
- data/examples/available_tools_demo/explore_directory/prompt.md +6 -0
- data/examples/available_tools_demo/workflow.yml +32 -0
- data/examples/available_tools_demo/write_summary/prompt.md +6 -0
- data/examples/case_when/detect_language/prompt.md +2 -2
- data/examples/grading/README.md +71 -0
- data/examples/grading/run_coverage.rb +0 -2
- data/examples/iteration/analyze_complexity/prompt.md +2 -2
- data/examples/iteration/generate_recommendations/prompt.md +2 -2
- data/examples/iteration/implement_fix/prompt.md +2 -2
- data/examples/iteration/prioritize_issues/prompt.md +1 -1
- data/examples/iteration/prompts/analyze_file.md +2 -2
- data/examples/iteration/prompts/generate_summary.md +1 -1
- data/examples/iteration/prompts/update_report.md +3 -3
- data/examples/iteration/prompts/write_report.md +3 -3
- data/examples/iteration/read_file/prompt.md +2 -2
- data/examples/iteration/select_next_issue/prompt.md +2 -2
- data/examples/iteration/update_fix_count/prompt.md +4 -4
- data/examples/iteration/verify_fix/prompt.md +3 -3
- data/examples/mcp/README.md +3 -3
- data/examples/mcp/analyze_changes/prompt.md +1 -1
- data/examples/mcp/database_workflow.yml +1 -1
- data/examples/mcp/fetch_pr_context/prompt.md +1 -1
- data/examples/mcp/github_workflow.yml +1 -1
- data/examples/mcp/post_review/prompt.md +1 -1
- data/examples/pre_post_processing/analyze_test_file/prompt.md +1 -1
- data/examples/pre_post_processing/improve_test_coverage/prompt.md +1 -1
- data/examples/pre_post_processing/optimize_test_performance/prompt.md +1 -1
- data/examples/pre_post_processing/post_processing/aggregate_metrics/prompt.md +2 -2
- data/examples/pre_post_processing/post_processing/generate_summary_report/prompt.md +1 -1
- data/examples/pre_post_processing/pre_processing/setup_test_environment/prompt.md +1 -1
- data/examples/pre_post_processing/validate_changes/prompt.md +2 -2
- data/examples/user_input/README.md +90 -0
- data/examples/user_input/funny_name/create_backstory/prompt.md +10 -0
- data/examples/user_input/funny_name/workflow.yml +26 -0
- data/examples/user_input/generate_summary/prompt.md +11 -0
- data/examples/user_input/simple_input_demo/workflow.yml +35 -0
- data/examples/user_input/survey_workflow.yml +71 -0
- data/examples/user_input/welcome_message/prompt.md +3 -0
- data/examples/user_input/workflow.yml +73 -0
- data/examples/workflow_generator/create_workflow_files/prompt.md +1 -1
- data/lib/roast/errors.rb +6 -4
- data/lib/roast/helpers/function_caching_interceptor.rb +0 -2
- data/lib/roast/helpers/logger.rb +12 -35
- data/lib/roast/helpers/minitest_coverage_runner.rb +0 -1
- data/lib/roast/helpers/prompt_loader.rb +0 -2
- data/lib/roast/resources/api_resource.rb +0 -4
- data/lib/roast/resources/url_resource.rb +0 -3
- data/lib/roast/resources.rb +0 -8
- data/lib/roast/tools/ask_user.rb +0 -2
- data/lib/roast/tools/bash.rb +0 -3
- data/lib/roast/tools/cmd.rb +0 -3
- data/lib/roast/tools/coding_agent.rb +1 -8
- data/lib/roast/tools/grep.rb +0 -3
- data/lib/roast/tools/helpers/coding_agent_message_formatter.rb +1 -4
- data/lib/roast/tools/read_file.rb +0 -2
- data/lib/roast/tools/search_file.rb +0 -2
- data/lib/roast/tools/update_files.rb +0 -4
- data/lib/roast/tools/write_file.rb +0 -3
- data/lib/roast/tools.rb +0 -13
- data/lib/roast/value_objects/step_name.rb +14 -3
- data/lib/roast/value_objects/workflow_path.rb +0 -2
- data/lib/roast/value_objects.rb +4 -4
- data/lib/roast/version.rb +1 -1
- data/lib/roast/workflow/agent_step.rb +26 -0
- data/lib/roast/workflow/api_configuration.rb +0 -4
- data/lib/roast/workflow/base_iteration_step.rb +0 -4
- data/lib/roast/workflow/base_step.rb +54 -28
- data/lib/roast/workflow/base_workflow.rb +2 -21
- data/lib/roast/workflow/case_executor.rb +0 -1
- data/lib/roast/workflow/case_step.rb +0 -4
- data/lib/roast/workflow/command_executor.rb +0 -2
- data/lib/roast/workflow/conditional_executor.rb +0 -1
- data/lib/roast/workflow/conditional_step.rb +0 -4
- data/lib/roast/workflow/configuration.rb +3 -10
- data/lib/roast/workflow/configuration_loader.rb +0 -2
- data/lib/roast/workflow/configuration_parser.rb +1 -7
- data/lib/roast/workflow/dot_access_hash.rb +16 -1
- data/lib/roast/workflow/error_handler.rb +0 -3
- data/lib/roast/workflow/expression_evaluator.rb +0 -3
- data/lib/roast/workflow/file_state_repository.rb +0 -5
- data/lib/roast/workflow/input_executor.rb +41 -0
- data/lib/roast/workflow/input_step.rb +163 -0
- data/lib/roast/workflow/iteration_executor.rb +0 -2
- data/lib/roast/workflow/output_handler.rb +0 -2
- data/lib/roast/workflow/output_manager.rb +0 -2
- data/lib/roast/workflow/prompt_step.rb +1 -1
- data/lib/roast/workflow/replay_handler.rb +0 -3
- data/lib/roast/workflow/resource_resolver.rb +0 -3
- data/lib/roast/workflow/session_manager.rb +0 -3
- data/lib/roast/workflow/state_manager.rb +0 -2
- data/lib/roast/workflow/step_executor_coordinator.rb +34 -11
- data/lib/roast/workflow/step_executor_factory.rb +0 -5
- data/lib/roast/workflow/step_executor_registry.rb +1 -4
- data/lib/roast/workflow/step_executors/hash_step_executor.rb +0 -3
- data/lib/roast/workflow/step_executors/parallel_step_executor.rb +0 -3
- data/lib/roast/workflow/step_executors/string_step_executor.rb +0 -2
- data/lib/roast/workflow/step_factory.rb +56 -0
- data/lib/roast/workflow/step_loader.rb +30 -16
- data/lib/roast/workflow/step_orchestrator.rb +3 -2
- data/lib/roast/workflow/step_type_resolver.rb +28 -1
- data/lib/roast/workflow/validator.rb +0 -4
- data/lib/roast/workflow/workflow_executor.rb +0 -16
- data/lib/roast/workflow/workflow_initializer.rb +1 -8
- data/lib/roast/workflow/workflow_runner.rb +0 -7
- data/lib/roast/workflow.rb +0 -15
- data/lib/roast.rb +55 -10
- data/roast.gemspec +2 -1
- data/schema/workflow.json +46 -0
- metadata +44 -6
- data/lib/roast/helpers.rb +0 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0c0f1a837c5dafcaecb8443e93a4076c11566f1c3bea1d6835121628fbdf79a7
|
4
|
+
data.tar.gz: ab3679b374486831cbf90ab3a259178d48d4e53d5d5dbdc2a2d43537399e4ca9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3061d9f04b7f886e3a6d588eb729e10062f6310d5973c7ed5181975f27a385c20d8ff8880ecb7e61abd54dfbd87795211313e1c9a6d2a630269d7c4559ae7cae
|
7
|
+
data.tar.gz: 7962e4991590700003f3f8a827435214ef9aa90fa4324d34d3b421f11d5f647e43663e17189a0b43f81d6fa124bbf68a269f9674a493994832b9ab5c03f192a6
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -5,6 +5,38 @@ All notable changes to this project will be documented in this file.
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
7
|
|
8
|
+
## [0.4.0] - 2025-06-12
|
9
|
+
|
10
|
+
### Added
|
11
|
+
- **Input step type** for collecting user input during workflow execution (#154)
|
12
|
+
- Interactive prompts pause workflow execution to collect user input
|
13
|
+
- Supports multiple input types: `text` (default), `confirm`, `select`, and `password`
|
14
|
+
- `confirm` type provides yes/no prompts with boolean results
|
15
|
+
- `select` type allows choosing from a list of options
|
16
|
+
- `password` type masks input for sensitive data using io/console
|
17
|
+
- Input values are stored in workflow output and accessible via dot notation (e.g., `{{output.step_name}}`)
|
18
|
+
- Integrates with CLI::UI for consistent formatting and user experience
|
19
|
+
- **Agent step type** for direct pass-through to coding agents (#151)
|
20
|
+
- Steps prefixed with `^` send prompts directly to the CodingAgent tool
|
21
|
+
- Supports both file-based and inline agent prompts
|
22
|
+
- Bypasses LLM interpretation for precise agent instructions
|
23
|
+
|
24
|
+
### Fixed
|
25
|
+
- DotAccessHash array wrapping and template response handling
|
26
|
+
- CLI::UI formatting and color handling for better terminal output
|
27
|
+
|
28
|
+
## [0.3.1] - 2025-06-05
|
29
|
+
|
30
|
+
### Added
|
31
|
+
- Default `print_response: true` for the last step in a workflow (#100)
|
32
|
+
- The last step now automatically prints its response unless explicitly configured otherwise
|
33
|
+
- Helps newcomers who would otherwise see no output from their workflows
|
34
|
+
- Works with all step types: string steps, hash steps with variable assignment, and conditional steps
|
35
|
+
- Parallel steps and iteration steps are intelligently handled (no automatic output since there's no single "last" step)
|
36
|
+
|
37
|
+
### Fixed
|
38
|
+
- PromptStep now properly passes `print_response`, `json`, and `params` parameters to chat_completion
|
39
|
+
|
8
40
|
## [0.3.0] - 2025-06-04
|
9
41
|
|
10
42
|
### Changed
|
data/CLAUDE.md
CHANGED
@@ -4,6 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
|
4
4
|
|
5
5
|
## About the codebase
|
6
6
|
- This is a Ruby gem called Roast. Its purpose is to run AI workflows defined in a YAML file.
|
7
|
+
- Note that this project now uses Zeitwerk, which means you don't have to manually require project files anymore
|
7
8
|
|
8
9
|
## Commands
|
9
10
|
|
@@ -51,11 +52,14 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
|
51
52
|
- ConditionalExecutor handles conditionals (if, unless)
|
52
53
|
- Don't combine different responsibilities in one class
|
53
54
|
- **Do not implement prompts "inline" using a prompt: attribute nested under step names, that violates the primary design architecture of Roast**
|
55
|
+
- When faced with the choice between working around an architectural issue or code smell versus actually diving into fixing the design issue or code smell, choose the latter more principled approach
|
56
|
+
- When fixing code smells, you don't have to worry about internal backwards compatibility
|
54
57
|
|
55
58
|
## Guidance and Expectations
|
56
59
|
|
57
60
|
- Do not decide unilaterally to leave code for the sake of "backwards compatibility"... always run those decisions by me first.
|
58
61
|
- Don't ever commit and push changes unless directly told to do so
|
62
|
+
- You can't test input steps yourself, ask me to do it
|
59
63
|
|
60
64
|
## Git Workflow Practices
|
61
65
|
|
@@ -130,6 +134,48 @@ gh pr view {pr_number}
|
|
130
134
|
gh pr diff {pr_number}
|
131
135
|
```
|
132
136
|
|
137
|
+
### Issue Labeling and Project Management
|
138
|
+
|
139
|
+
When creating GitHub issues, always check available labels, projects, and milestones first:
|
140
|
+
|
141
|
+
```bash
|
142
|
+
# List all available labels
|
143
|
+
gh api repos/Shopify/roast/labels | jq '.[].name'
|
144
|
+
|
145
|
+
# List all milestones
|
146
|
+
gh api repos/Shopify/roast/milestones | jq '.[] | {title: .title, number: .number, state: .state}'
|
147
|
+
|
148
|
+
# List projects linked to the roast repository
|
149
|
+
gh api graphql -f query='
|
150
|
+
{
|
151
|
+
repository(owner: "Shopify", name: "roast") {
|
152
|
+
projectsV2(first: 10) {
|
153
|
+
nodes {
|
154
|
+
title
|
155
|
+
number
|
156
|
+
url
|
157
|
+
}
|
158
|
+
}
|
159
|
+
}
|
160
|
+
}' --jq '.data.repository.projectsV2.nodes[] | {title: .title, number: .number, url: .url}'
|
161
|
+
```
|
162
|
+
|
163
|
+
**Issue Creation Workflow**:
|
164
|
+
1. First check what labels exist and apply appropriate ones when creating the issue
|
165
|
+
2. After creating the issue, ask the user if they want it added to an existing milestone
|
166
|
+
3. Ask the user if they want it added to a particular project board
|
167
|
+
|
168
|
+
```bash
|
169
|
+
# Create issue with labels
|
170
|
+
gh api repos/Shopify/roast/issues -X POST -F title="Issue Title" -F body="Issue description" -F 'labels=["bug", "enhancement"]'
|
171
|
+
|
172
|
+
# Add issue to a milestone (after creation)
|
173
|
+
gh api repos/Shopify/roast/issues/{issue_number} -X PATCH -F milestone={milestone_number}
|
174
|
+
|
175
|
+
# Add issue to a GitHub Project
|
176
|
+
gh project item-add {project_number} --url https://github.com/Shopify/roast/issues/{issue_number}
|
177
|
+
```
|
178
|
+
|
133
179
|
#### Formatting Tips for GitHub API
|
134
180
|
1. Use literal newlines in the body text instead of `\n` escape sequences
|
135
181
|
2. When formatting is stripped (like backticks), use alternatives:
|
@@ -167,4 +213,9 @@ gh pr diff {pr_number}
|
|
167
213
|
- Avoid premature optimization outside of hot paths
|
168
214
|
- Consider the tradeoff between readability and performance
|
169
215
|
- Suggest optimizations that improve both clarity and performance
|
170
|
-
|
216
|
+
|
217
|
+
## CLI::UI Formatting Tips
|
218
|
+
- To apply color to terminal output using CLI::UI, use the following syntax:
|
219
|
+
```ruby
|
220
|
+
puts ::CLI::UI.fmt("{{red:This field is required. Please provide a value.}}")
|
221
|
+
```
|
data/Gemfile
CHANGED
@@ -8,7 +8,7 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
|
8
8
|
gemspec
|
9
9
|
|
10
10
|
gem "cgi"
|
11
|
-
gem "cli-ui"
|
11
|
+
gem "cli-ui", "2.3.0"
|
12
12
|
gem "dotenv"
|
13
13
|
gem "guard"
|
14
14
|
gem "guard-minitest"
|
@@ -18,3 +18,5 @@ gem "rubocop-shopify", require: false
|
|
18
18
|
gem "vcr", require: false
|
19
19
|
gem "webmock", require: false
|
20
20
|
gem "minitest-rg"
|
21
|
+
|
22
|
+
gem "claude_swarm"
|
data/Gemfile.lock
CHANGED
@@ -1,15 +1,16 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
roast-ai (0.
|
4
|
+
roast-ai (0.4.0)
|
5
5
|
activesupport (>= 7.0)
|
6
|
-
cli-ui
|
6
|
+
cli-ui (= 2.3.0)
|
7
7
|
diff-lcs (~> 1.5)
|
8
8
|
faraday-retry
|
9
9
|
json-schema
|
10
10
|
open_router (~> 0.3)
|
11
11
|
raix (~> 1.0)
|
12
12
|
thor (~> 1.3)
|
13
|
+
zeitwerk (~> 2.6)
|
13
14
|
|
14
15
|
GEM
|
15
16
|
remote: https://rubygems.org/
|
@@ -33,17 +34,49 @@ GEM
|
|
33
34
|
base64 (0.3.0)
|
34
35
|
benchmark (0.4.1)
|
35
36
|
bigdecimal (3.2.2)
|
36
|
-
cgi (0.
|
37
|
-
|
37
|
+
cgi (0.5.0)
|
38
|
+
claude_swarm (0.1.15)
|
39
|
+
fast-mcp-annotations
|
40
|
+
thor (~> 1.3)
|
41
|
+
cli-ui (2.3.0)
|
38
42
|
coderay (1.1.3)
|
39
43
|
concurrent-ruby (1.3.5)
|
40
44
|
connection_pool (2.5.3)
|
41
45
|
crack (1.0.0)
|
42
46
|
bigdecimal
|
43
47
|
rexml
|
44
|
-
diff-lcs (1.6.
|
48
|
+
diff-lcs (1.6.2)
|
45
49
|
dotenv (3.1.8)
|
46
50
|
drb (2.2.3)
|
51
|
+
dry-configurable (1.3.0)
|
52
|
+
dry-core (~> 1.1)
|
53
|
+
zeitwerk (~> 2.6)
|
54
|
+
dry-core (1.1.0)
|
55
|
+
concurrent-ruby (~> 1.0)
|
56
|
+
logger
|
57
|
+
zeitwerk (~> 2.6)
|
58
|
+
dry-inflector (1.2.0)
|
59
|
+
dry-initializer (3.2.0)
|
60
|
+
dry-logic (1.6.0)
|
61
|
+
bigdecimal
|
62
|
+
concurrent-ruby (~> 1.0)
|
63
|
+
dry-core (~> 1.1)
|
64
|
+
zeitwerk (~> 2.6)
|
65
|
+
dry-schema (1.14.1)
|
66
|
+
concurrent-ruby (~> 1.0)
|
67
|
+
dry-configurable (~> 1.0, >= 1.0.1)
|
68
|
+
dry-core (~> 1.1)
|
69
|
+
dry-initializer (~> 3.2)
|
70
|
+
dry-logic (~> 1.5)
|
71
|
+
dry-types (~> 1.8)
|
72
|
+
zeitwerk (~> 2.6)
|
73
|
+
dry-types (1.8.3)
|
74
|
+
bigdecimal (~> 3.0)
|
75
|
+
concurrent-ruby (~> 1.0)
|
76
|
+
dry-core (~> 1.0)
|
77
|
+
dry-inflector (~> 1.0)
|
78
|
+
dry-logic (~> 1.4)
|
79
|
+
zeitwerk (~> 2.6)
|
47
80
|
event_stream_parser (1.0.0)
|
48
81
|
faraday (2.13.1)
|
49
82
|
faraday-net_http (>= 2.0, < 3.5)
|
@@ -55,6 +88,13 @@ GEM
|
|
55
88
|
net-http (>= 0.5.0)
|
56
89
|
faraday-retry (2.3.1)
|
57
90
|
faraday (~> 2.0)
|
91
|
+
fast-mcp-annotations (1.5.2)
|
92
|
+
addressable (~> 2.8)
|
93
|
+
base64
|
94
|
+
dry-schema (~> 1.14)
|
95
|
+
json (~> 2.0)
|
96
|
+
mime-types (~> 3.4)
|
97
|
+
rack (~> 3.1)
|
58
98
|
ffi (1.17.2-arm64-darwin)
|
59
99
|
ffi (1.17.2-x86_64-linux-gnu)
|
60
100
|
formatador (1.1.0)
|
@@ -73,14 +113,14 @@ GEM
|
|
73
113
|
guard-minitest (2.4.6)
|
74
114
|
guard-compat (~> 1.2)
|
75
115
|
minitest (>= 3.0)
|
76
|
-
hashdiff (1.
|
116
|
+
hashdiff (1.2.0)
|
77
117
|
i18n (1.14.7)
|
78
118
|
concurrent-ruby (~> 1.0)
|
79
119
|
json (2.12.2)
|
80
120
|
json-schema (5.1.1)
|
81
121
|
addressable (~> 2.8)
|
82
122
|
bigdecimal (~> 3.1)
|
83
|
-
language_server-protocol (3.17.0.
|
123
|
+
language_server-protocol (3.17.0.5)
|
84
124
|
lint_roller (1.1.0)
|
85
125
|
listen (3.9.0)
|
86
126
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
@@ -88,6 +128,10 @@ GEM
|
|
88
128
|
logger (1.7.0)
|
89
129
|
lumberjack (1.2.10)
|
90
130
|
method_source (1.1.0)
|
131
|
+
mime-types (3.7.0)
|
132
|
+
logger
|
133
|
+
mime-types-data (~> 3.2025, >= 3.2025.0507)
|
134
|
+
mime-types-data (3.2025.0603)
|
91
135
|
minitest (5.25.5)
|
92
136
|
minitest-rg (5.3.0)
|
93
137
|
minitest (~> 5.0)
|
@@ -114,22 +158,23 @@ GEM
|
|
114
158
|
pry (0.15.2)
|
115
159
|
coderay (~> 1.1)
|
116
160
|
method_source (~> 1.0)
|
117
|
-
public_suffix (6.0.
|
161
|
+
public_suffix (6.0.2)
|
118
162
|
racc (1.8.1)
|
163
|
+
rack (3.1.16)
|
119
164
|
rainbow (3.1.1)
|
120
|
-
raix (1.0.
|
165
|
+
raix (1.0.1)
|
121
166
|
activesupport (>= 6.0)
|
122
167
|
faraday-retry (~> 2.0)
|
123
168
|
open_router (~> 0.2)
|
124
169
|
ostruct
|
125
170
|
ruby-openai (~> 7)
|
126
|
-
rake (13.
|
171
|
+
rake (13.3.0)
|
127
172
|
rb-fsevent (0.11.2)
|
128
173
|
rb-inotify (0.11.1)
|
129
174
|
ffi (~> 1.0)
|
130
175
|
regexp_parser (2.10.0)
|
131
176
|
rexml (3.4.1)
|
132
|
-
rubocop (1.
|
177
|
+
rubocop (1.76.0)
|
133
178
|
json (~> 2.3)
|
134
179
|
language_server-protocol (~> 3.17.0.2)
|
135
180
|
lint_roller (~> 1.1.0)
|
@@ -137,13 +182,13 @@ GEM
|
|
137
182
|
parser (>= 3.3.0.2)
|
138
183
|
rainbow (>= 2.2.2, < 4.0)
|
139
184
|
regexp_parser (>= 2.9.3, < 3.0)
|
140
|
-
rubocop-ast (>= 1.
|
185
|
+
rubocop-ast (>= 1.45.0, < 2.0)
|
141
186
|
ruby-progressbar (~> 1.7)
|
142
187
|
unicode-display_width (>= 2.4.0, < 4.0)
|
143
|
-
rubocop-ast (1.
|
188
|
+
rubocop-ast (1.45.0)
|
144
189
|
parser (>= 3.3.7.2)
|
145
190
|
prism (~> 1.4)
|
146
|
-
rubocop-shopify (2.17.
|
191
|
+
rubocop-shopify (2.17.1)
|
147
192
|
rubocop (~> 1.62)
|
148
193
|
ruby-openai (7.4.0)
|
149
194
|
event_stream_parser (>= 0.3.0, < 2.0.0)
|
@@ -166,14 +211,16 @@ GEM
|
|
166
211
|
addressable (>= 2.8.0)
|
167
212
|
crack (>= 0.3.2)
|
168
213
|
hashdiff (>= 0.4.0, < 2.0.0)
|
214
|
+
zeitwerk (2.7.3)
|
169
215
|
|
170
216
|
PLATFORMS
|
171
|
-
arm64-darwin
|
217
|
+
arm64-darwin
|
172
218
|
x86_64-linux
|
173
219
|
|
174
220
|
DEPENDENCIES
|
175
221
|
cgi
|
176
|
-
|
222
|
+
claude_swarm
|
223
|
+
cli-ui (= 2.3.0)
|
177
224
|
dotenv
|
178
225
|
guard
|
179
226
|
guard-minitest
|
data/README.md
CHANGED
@@ -82,13 +82,13 @@ steps:
|
|
82
82
|
|
83
83
|
## Try it
|
84
84
|
|
85
|
-
If you don
|
85
|
+
If you don’t have one already, get an OpenAI key from [here](https://platform.openai.com/settings/organization/api-keys). You will need an account with a credit card and credits applied to the associated project. Make sure that a basic completion works:
|
86
86
|
|
87
87
|
```bash
|
88
88
|
export OPENAI_API_KEY=sk-proj-....
|
89
89
|
|
90
90
|
curl -H "Content-Type: application/json" \
|
91
|
-
-H "Authorization: Bearer $
|
91
|
+
-H "Authorization: Bearer $OPENAI_API_KEY" \
|
92
92
|
-d '{"model":"gpt-4.1-mini","messages":[{"role":"user","content":"What is 1+1?"}]}' \
|
93
93
|
https://api.openai.com/v1/chat/completions
|
94
94
|
```
|
@@ -270,6 +270,70 @@ Roast supports several types of steps:
|
|
270
270
|
```
|
271
271
|
This creates a simple prompt-response interaction without tool calls or looping. It's detected by the presence of spaces in the step name and is useful for summarization or simple questions at the end of a workflow.
|
272
272
|
|
273
|
+
8. **Agent step**: Direct pass-through to coding agents (e.g., Claude Code)
|
274
|
+
```yaml
|
275
|
+
steps:
|
276
|
+
- ^fix_linting_errors # File-based agent prompt
|
277
|
+
- ^Review the code and identify any performance issues # Inline agent prompt
|
278
|
+
- regular_analysis # Normal step through LLM
|
279
|
+
```
|
280
|
+
Agent steps are prefixed with `^` and send the prompt content directly to the CodingAgent tool without LLM translation. This is useful when you want to give precise instructions to a coding agent without the intermediate interpretation layer. Agent steps support both file-based prompts (`fix_linting_errors/prompt.md`) and inline prompts (text with spaces).
|
281
|
+
|
282
|
+
9. **Input step**: Interactive prompts for user input during workflow execution
|
283
|
+
```yaml
|
284
|
+
steps:
|
285
|
+
- analyze_code
|
286
|
+
- get_user_feedback:
|
287
|
+
prompt: "Should we proceed with the refactoring? (yes/no)"
|
288
|
+
type: confirm
|
289
|
+
- review_changes:
|
290
|
+
prompt: "Enter your review comments"
|
291
|
+
type: text
|
292
|
+
- select_strategy:
|
293
|
+
prompt: "Choose optimization strategy"
|
294
|
+
type: select
|
295
|
+
options:
|
296
|
+
- "Performance optimization"
|
297
|
+
- "Memory optimization"
|
298
|
+
- "Code clarity"
|
299
|
+
- api_configuration:
|
300
|
+
prompt: "Enter API key"
|
301
|
+
type: password
|
302
|
+
```
|
303
|
+
|
304
|
+
Input steps pause workflow execution to collect user input. They support several types:
|
305
|
+
- `text`: Free-form text input (default if type not specified)
|
306
|
+
- `confirm`: Yes/No confirmation prompts
|
307
|
+
- `select`: Choice from a list of options
|
308
|
+
- `password`: Masked input for sensitive data
|
309
|
+
|
310
|
+
The user's input is stored in the workflow output using the step name as the key and can be accessed in subsequent steps via interpolation (e.g., `{{output.get_user_feedback}}`).
|
311
|
+
|
312
|
+
#### Step Configuration
|
313
|
+
|
314
|
+
Steps can be configured with various options to control their behavior:
|
315
|
+
|
316
|
+
```yaml
|
317
|
+
steps:
|
318
|
+
- analyze_code # Simple step reference
|
319
|
+
- generate_report: # Step with configuration
|
320
|
+
model: gpt-4o # Override the global model for this step
|
321
|
+
print_response: true # Explicitly control output printing
|
322
|
+
json: true # Request JSON-formatted response
|
323
|
+
params: # Additional parameters for the API call
|
324
|
+
temperature: 0.8
|
325
|
+
```
|
326
|
+
|
327
|
+
**Configuration options:**
|
328
|
+
- `model`: Override the workflow's default model for this specific step
|
329
|
+
- `print_response`: Control whether the step's response is included in the final output (default: `false`, except for the last step which defaults to `true` as of v0.3.1)
|
330
|
+
- `json`: Request a JSON-formatted response from the model
|
331
|
+
- `params`: Additional parameters passed to the model API (temperature, max_tokens, etc.)
|
332
|
+
- `path`: Custom directory path for the step's prompt files
|
333
|
+
- `coerce_to`: Type coercion for the step result (`:boolean`, `:llm_boolean`, `:iterable`)
|
334
|
+
|
335
|
+
**Automatic Last Step Output**: As of version 0.3.1, the last step in a workflow automatically has `print_response: true` unless explicitly configured otherwise. This ensures that newcomers to Roast see output from their workflows by default.
|
336
|
+
|
273
337
|
#### Shared Configuration
|
274
338
|
|
275
339
|
Roast supports sharing common configuration and steps across multiple workflows using a `shared.yml` file.
|
@@ -633,6 +697,52 @@ tools:
|
|
633
697
|
|
634
698
|
Custom descriptions help the LLM understand when and how to use each command, making your workflows more effective.
|
635
699
|
|
700
|
+
### Step-Level Tool Filtering
|
701
|
+
|
702
|
+
You can restrict which tools are available to specific steps using the `available_tools` configuration:
|
703
|
+
|
704
|
+
```yaml
|
705
|
+
# Define all tools globally
|
706
|
+
tools:
|
707
|
+
- Roast::Tools::Grep
|
708
|
+
- Roast::Tools::ReadFile
|
709
|
+
- Roast::Tools::WriteFile
|
710
|
+
- Roast::Tools::Cmd:
|
711
|
+
allowed_commands:
|
712
|
+
- pwd
|
713
|
+
- ls
|
714
|
+
- echo
|
715
|
+
|
716
|
+
# Configure steps with specific tool access
|
717
|
+
explore_directory:
|
718
|
+
available_tools:
|
719
|
+
- pwd
|
720
|
+
- ls
|
721
|
+
|
722
|
+
analyze_files:
|
723
|
+
available_tools:
|
724
|
+
- grep
|
725
|
+
- read_file
|
726
|
+
|
727
|
+
write_summary:
|
728
|
+
available_tools:
|
729
|
+
- write_file
|
730
|
+
- echo
|
731
|
+
```
|
732
|
+
|
733
|
+
This feature provides:
|
734
|
+
- **Security**: Each step only has access to the tools it needs
|
735
|
+
- **Performance**: Reduces the tool list sent to the LLM
|
736
|
+
- **Clarity**: Makes tool usage explicit for each step
|
737
|
+
|
738
|
+
Key points:
|
739
|
+
- Use snake_case tool names (e.g., `read_file` for `Roast::Tools::ReadFile`)
|
740
|
+
- For `Cmd` tool, use the specific command names (e.g., `pwd`, `ls`)
|
741
|
+
- When `available_tools` is not specified, all tools remain available (backward compatible)
|
742
|
+
- Empty array (`available_tools: []`) means no tools for that step
|
743
|
+
|
744
|
+
See the [available_tools_demo](examples/available_tools_demo/) for a complete example.
|
745
|
+
|
636
746
|
#### ReadFile
|
637
747
|
|
638
748
|
Reads the contents of a file from the filesystem.
|
@@ -811,14 +921,14 @@ tools:
|
|
811
921
|
- Documentation:
|
812
922
|
url: https://gitmcp.io/myorg/myrepo/docs
|
813
923
|
env:
|
814
|
-
- "Authorization: Bearer {{
|
924
|
+
- "Authorization: Bearer {{ENV['API_TOKEN']}}"
|
815
925
|
|
816
926
|
# MCP tools with stdio
|
817
927
|
- GitHub:
|
818
928
|
command: npx
|
819
929
|
args: ["-y", "@modelcontextprotocol/server-github"]
|
820
930
|
env:
|
821
|
-
GITHUB_PERSONAL_ACCESS_TOKEN: "{{
|
931
|
+
GITHUB_PERSONAL_ACCESS_TOKEN: "{{ENV['GITHUB_TOKEN']}}"
|
822
932
|
only:
|
823
933
|
- search_repositories
|
824
934
|
- get_issue
|
@@ -847,7 +957,7 @@ Connect to local processes implementing the MCP protocol:
|
|
847
957
|
command: docker
|
848
958
|
args: ["run", "-i", "--rm", "ghcr.io/example/mcp-server"]
|
849
959
|
env:
|
850
|
-
API_KEY: "{{
|
960
|
+
API_KEY: "{{ENV['API_KEY']}}"
|
851
961
|
```
|
852
962
|
|
853
963
|
See the [MCP tools example](examples/mcp/) for complete documentation and more examples.
|
data/bin/roast
CHANGED
@@ -8,7 +8,7 @@
|
|
8
8
|
# this file is here to facilitate running it.
|
9
9
|
#
|
10
10
|
|
11
|
-
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("
|
11
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
|
12
12
|
|
13
13
|
bundle_binstub = File.expand_path("bundle", __dir__)
|
14
14
|
|