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
@@ -0,0 +1,71 @@
|
|
1
|
+
name: developer_survey
|
2
|
+
description: Collect developer feedback through an interactive survey
|
3
|
+
model: anthropic:claude-3-5-sonnet
|
4
|
+
|
5
|
+
steps:
|
6
|
+
- welcome_message
|
7
|
+
|
8
|
+
# Basic information
|
9
|
+
- input:
|
10
|
+
prompt: "What's your name?"
|
11
|
+
name: developer_name
|
12
|
+
required: true
|
13
|
+
|
14
|
+
- input:
|
15
|
+
prompt: "How long have you been using Roast? (e.g., '2 weeks', '3 months')"
|
16
|
+
name: usage_duration
|
17
|
+
|
18
|
+
# Experience rating
|
19
|
+
- input:
|
20
|
+
prompt: "How would you rate your experience with Roast?"
|
21
|
+
type: choice
|
22
|
+
options:
|
23
|
+
- "⭐ Poor"
|
24
|
+
- "⭐⭐ Below Average"
|
25
|
+
- "⭐⭐⭐ Average"
|
26
|
+
- "⭐⭐⭐⭐ Good"
|
27
|
+
- "⭐⭐⭐⭐⭐ Excellent"
|
28
|
+
name: experience_rating
|
29
|
+
required: true
|
30
|
+
|
31
|
+
# Feature usage
|
32
|
+
- input:
|
33
|
+
prompt: "Which Roast features do you use most? (select primary feature)"
|
34
|
+
type: choice
|
35
|
+
options:
|
36
|
+
- "AI-powered workflows"
|
37
|
+
- "File processing and manipulation"
|
38
|
+
- "Conditional execution (if/case)"
|
39
|
+
- "Iteration features (each/repeat)"
|
40
|
+
- "Tool integrations"
|
41
|
+
- "Other"
|
42
|
+
name: primary_feature
|
43
|
+
|
44
|
+
# Feedback collection
|
45
|
+
- input:
|
46
|
+
prompt: "Would you like to provide additional feedback?"
|
47
|
+
type: boolean
|
48
|
+
default: true
|
49
|
+
name: wants_feedback
|
50
|
+
|
51
|
+
- if: "{{workflow.output.wants_feedback}}"
|
52
|
+
then:
|
53
|
+
- input:
|
54
|
+
prompt: "Please share your feedback (press Enter twice when done):"
|
55
|
+
name: user_feedback
|
56
|
+
|
57
|
+
- input:
|
58
|
+
prompt: "May we contact you about your feedback?"
|
59
|
+
type: boolean
|
60
|
+
default: false
|
61
|
+
name: allow_contact
|
62
|
+
|
63
|
+
- if: "{{workflow.output.allow_contact}}"
|
64
|
+
then:
|
65
|
+
- input:
|
66
|
+
prompt: "Please enter your email:"
|
67
|
+
name: user_email
|
68
|
+
required: true
|
69
|
+
|
70
|
+
# Generate summary
|
71
|
+
- generate_summary
|
@@ -0,0 +1,73 @@
|
|
1
|
+
name: interactive_deployment
|
2
|
+
description: Interactive deployment workflow with user confirmations
|
3
|
+
model: gpt-4o
|
4
|
+
|
5
|
+
steps:
|
6
|
+
# Collect deployment information
|
7
|
+
- input:
|
8
|
+
prompt: "Which environment do you want to deploy to?"
|
9
|
+
name: environment
|
10
|
+
type: choice
|
11
|
+
options:
|
12
|
+
- development
|
13
|
+
- staging
|
14
|
+
- production
|
15
|
+
required: true
|
16
|
+
|
17
|
+
- input:
|
18
|
+
prompt: "Enter the deployment tag/version:"
|
19
|
+
name: deploy_tag
|
20
|
+
required: true
|
21
|
+
default: "latest"
|
22
|
+
|
23
|
+
# Show deployment plan
|
24
|
+
- bash:
|
25
|
+
command: |
|
26
|
+
echo "==================================="
|
27
|
+
echo " DEPLOYMENT PLAN"
|
28
|
+
echo "==================================="
|
29
|
+
echo "Environment: {{workflow.output.environment}}"
|
30
|
+
echo "Version: {{workflow.output.deploy_tag}}"
|
31
|
+
echo "Timestamp: {{Date.today}}"
|
32
|
+
echo "==================================="
|
33
|
+
|
34
|
+
# Confirm deployment
|
35
|
+
- input:
|
36
|
+
prompt: "Deploy {{workflow.output.deploy_tag}} to {{workflow.output.environment}}?"
|
37
|
+
type: boolean
|
38
|
+
default: false
|
39
|
+
name: confirm_deploy
|
40
|
+
|
41
|
+
# Execute deployment if confirmed
|
42
|
+
- if: "{{workflow.output.confirm_deploy}}"
|
43
|
+
then:
|
44
|
+
- bash:
|
45
|
+
command: echo "🚀 Starting deployment to {{workflow.output.environment}}..."
|
46
|
+
|
47
|
+
# Simulate deployment steps
|
48
|
+
- bash:
|
49
|
+
command: |
|
50
|
+
echo "🚀 Deploying version {{workflow.output.deploy_tag}} to {{workflow.output.environment}}"
|
51
|
+
echo "📦 Pulling Docker image: myapp:{{workflow.output.deploy_tag}}"
|
52
|
+
sleep 2
|
53
|
+
echo "🔄 Rolling out to {{workflow.output.environment}} cluster"
|
54
|
+
sleep 2
|
55
|
+
echo "✅ Deployment completed successfully!"
|
56
|
+
|
57
|
+
# Post-deployment verification
|
58
|
+
- input:
|
59
|
+
prompt: "Run smoke tests?"
|
60
|
+
type: boolean
|
61
|
+
default: true
|
62
|
+
name: run_tests
|
63
|
+
|
64
|
+
- if: "{{workflow.output.run_tests}}"
|
65
|
+
then:
|
66
|
+
- bash:
|
67
|
+
command: |
|
68
|
+
echo "🧪 Running smoke tests..."
|
69
|
+
sleep 1
|
70
|
+
echo "✅ All tests passed!"
|
71
|
+
else:
|
72
|
+
- bash:
|
73
|
+
command: echo "❌ Deployment cancelled by user."
|
@@ -15,7 +15,7 @@ Extract the workflow name from the user input JSON and create the workflow in th
|
|
15
15
|
|
16
16
|
Steps to complete:
|
17
17
|
|
18
|
-
1. **Create the main directory**: Use Cmd to create the "
|
18
|
+
1. **Create the main directory**: Use Cmd to create the "<%= workflow_name %>" directory
|
19
19
|
2. **Create step directories**: Create subdirectories for each workflow step
|
20
20
|
3. **Create workflow.yml**: Write the main workflow configuration file
|
21
21
|
4. **Create step prompt files**: Write each step's prompt.md file
|
data/lib/roast/errors.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Roast
|
4
|
-
|
5
|
-
|
4
|
+
module Errors
|
5
|
+
# Custom error for API resource not found (404) responses
|
6
|
+
class ResourceNotFoundError < StandardError; end
|
6
7
|
|
7
|
-
|
8
|
-
|
8
|
+
# Custom error for when API authentication fails
|
9
|
+
class AuthenticationError < StandardError; end
|
10
|
+
end
|
9
11
|
end
|
data/lib/roast/helpers/logger.rb
CHANGED
@@ -1,54 +1,26 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "logger"
|
4
|
-
require "forwardable"
|
5
|
-
|
6
3
|
module Roast
|
7
4
|
module Helpers
|
8
5
|
# Central logger for the Roast application
|
9
6
|
class Logger
|
10
|
-
extend Forwardable
|
11
7
|
VALID_LOG_LEVELS = ["DEBUG", "INFO", "WARN", "ERROR", "FATAL"].freeze
|
12
8
|
|
13
|
-
|
14
|
-
|
15
|
-
# Delegate info and warn methods to the underlying logger
|
16
|
-
def_delegators :logger, :info, :warn
|
17
|
-
|
18
|
-
# Create a specialized debug method that ensures proper functionality
|
19
|
-
def debug(message)
|
20
|
-
logger.debug(message)
|
21
|
-
end
|
22
|
-
|
23
|
-
def error(message)
|
24
|
-
# Add any custom error handling logic here
|
25
|
-
logger.error(message)
|
26
|
-
end
|
27
|
-
|
28
|
-
def fatal(message)
|
29
|
-
# Add any custom fatal error handling logic here
|
30
|
-
logger.fatal(message)
|
31
|
-
end
|
32
|
-
|
33
|
-
def initialize(stdout: $stdout, log_level: ENV["ROAST_LOG_LEVEL"] || "INFO")
|
34
|
-
@log_level = validate_log_level(log_level)
|
35
|
-
@logger = create_logger(stdout)
|
36
|
-
end
|
9
|
+
delegate_missing_to :@logger
|
37
10
|
|
38
|
-
|
39
|
-
@log_level = validate_log_level(level)
|
40
|
-
logger.level = ::Logger.const_get(@log_level)
|
41
|
-
end
|
11
|
+
attr_reader :logger
|
42
12
|
|
43
13
|
class << self
|
44
|
-
|
14
|
+
delegate_missing_to :instance
|
45
15
|
|
46
16
|
def instance
|
47
17
|
@instance ||= new
|
48
18
|
end
|
49
19
|
|
50
|
-
#
|
51
|
-
|
20
|
+
# Override Kernel#warn to ensure proper delegation
|
21
|
+
def warn(*args)
|
22
|
+
instance.warn(*args)
|
23
|
+
end
|
52
24
|
|
53
25
|
# For testing purposes
|
54
26
|
def reset
|
@@ -58,6 +30,11 @@ module Roast
|
|
58
30
|
|
59
31
|
private
|
60
32
|
|
33
|
+
def initialize(stdout: $stdout, log_level: ENV["ROAST_LOG_LEVEL"] || "INFO")
|
34
|
+
@log_level = validate_log_level(log_level)
|
35
|
+
@logger = create_logger(stdout)
|
36
|
+
end
|
37
|
+
|
61
38
|
def validate_log_level(level)
|
62
39
|
level_str = level.to_s.upcase
|
63
40
|
unless VALID_LOG_LEVELS.include?(level_str)
|
data/lib/roast/resources.rb
CHANGED
@@ -1,13 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "roast/resources/base_resource"
|
4
|
-
require "roast/resources/file_resource"
|
5
|
-
require "roast/resources/directory_resource"
|
6
|
-
require "roast/resources/url_resource"
|
7
|
-
require "roast/resources/api_resource"
|
8
|
-
require "roast/resources/none_resource"
|
9
|
-
require "uri"
|
10
|
-
|
11
3
|
module Roast
|
12
4
|
# The Resources module contains classes for handling different types of resources
|
13
5
|
# that workflows can operate on. Each resource type implements a common interface.
|
data/lib/roast/tools/ask_user.rb
CHANGED
data/lib/roast/tools/bash.rb
CHANGED
data/lib/roast/tools/cmd.rb
CHANGED
@@ -1,12 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "roast/helpers/logger"
|
4
|
-
require "roast/tools/helpers/coding_agent_message_formatter"
|
5
|
-
require "json"
|
6
|
-
require "open3"
|
7
|
-
require "tempfile"
|
8
|
-
require "securerandom"
|
9
|
-
|
10
3
|
module Roast
|
11
4
|
module Tools
|
12
5
|
module CodingAgent
|
@@ -110,7 +103,7 @@ module Roast
|
|
110
103
|
def handle_intermediate_message(json)
|
111
104
|
case json["type"]
|
112
105
|
when "assistant", "user"
|
113
|
-
CodingAgentMessageFormatter.format_messages(json).each(&method(:log_message))
|
106
|
+
Roast::Tools::Helpers::CodingAgentMessageFormatter.format_messages(json).each(&method(:log_message))
|
114
107
|
when "result", "system"
|
115
108
|
# Ignore these message types
|
116
109
|
else
|
data/lib/roast/tools/grep.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "roast/helpers/logger"
|
4
|
-
|
5
3
|
module Roast
|
6
4
|
module Tools
|
7
5
|
module Grep
|
@@ -30,7 +28,6 @@ module Roast
|
|
30
28
|
Roast::Helpers::Logger.info("🔍 Grepping for string: #{string}\n")
|
31
29
|
|
32
30
|
# Use Open3 to safely pass the string as an argument, avoiding shell injection
|
33
|
-
require "open3"
|
34
31
|
cmd = ["rg", "-C", "4", "--trim", "--color=never", "--heading", "-F", "--", string, "."]
|
35
32
|
stdout, _stderr, _status = Open3.capture3(*cmd)
|
36
33
|
|
data/lib/roast/tools.rb
CHANGED
@@ -1,18 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "English"
|
4
|
-
require "fileutils"
|
5
|
-
|
6
|
-
require "roast/tools/ask_user"
|
7
|
-
require "roast/tools/bash"
|
8
|
-
require "roast/tools/cmd"
|
9
|
-
require "roast/tools/coding_agent"
|
10
|
-
require "roast/tools/grep"
|
11
|
-
require "roast/tools/read_file"
|
12
|
-
require "roast/tools/search_file"
|
13
|
-
require "roast/tools/update_files"
|
14
|
-
require "roast/tools/write_file"
|
15
|
-
|
16
3
|
module Roast
|
17
4
|
module Tools
|
18
5
|
extend self
|
@@ -24,12 +24,23 @@ module Roast
|
|
24
24
|
@value
|
25
25
|
end
|
26
26
|
|
27
|
+
# Enables implicit conversion to String
|
28
|
+
alias_method :to_str, :to_s
|
29
|
+
|
27
30
|
def ==(other)
|
28
|
-
|
31
|
+
case other
|
32
|
+
when StepName
|
33
|
+
value == other.value
|
34
|
+
when String
|
35
|
+
value == other
|
36
|
+
else
|
37
|
+
false
|
38
|
+
end
|
39
|
+
end
|
29
40
|
|
30
|
-
|
41
|
+
def eql?(other)
|
42
|
+
other.is_a?(StepName) && value == other.value
|
31
43
|
end
|
32
|
-
alias_method :eql?, :==
|
33
44
|
|
34
45
|
def hash
|
35
46
|
[self.class, @value].hash
|
data/lib/roast/value_objects.rb
CHANGED
data/lib/roast/version.rb
CHANGED
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Roast
|
4
|
+
module Workflow
|
5
|
+
class AgentStep < BaseStep
|
6
|
+
def call
|
7
|
+
# For inline prompts (detected by plain text step names), use the name as the prompt
|
8
|
+
# For file-based steps, load from the prompt file
|
9
|
+
prompt_content = if name.plain_text?
|
10
|
+
name.to_s
|
11
|
+
else
|
12
|
+
read_sidecar_prompt
|
13
|
+
end
|
14
|
+
|
15
|
+
# Call CodingAgent directly with the prompt content
|
16
|
+
result = Roast::Tools::CodingAgent.call(prompt_content)
|
17
|
+
|
18
|
+
# Process output if print_response is enabled
|
19
|
+
process_output(result, print_response:)
|
20
|
+
|
21
|
+
# Apply coercion if configured
|
22
|
+
apply_coercion(result)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -1,9 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "roast/factories/api_provider_factory"
|
4
|
-
require "roast/workflow/resource_resolver"
|
5
|
-
require "roast/value_objects/uri_base"
|
6
|
-
|
7
3
|
module Roast
|
8
4
|
module Workflow
|
9
5
|
# Handles API-related configuration including tokens and providers
|