roast-ai 0.4.10 → 0.5.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.
- checksums.yaml +4 -4
- data/.claude/commands/docs/write-comments.md +36 -0
- data/.github/CODEOWNERS +1 -1
- data/.github/workflows/ci.yaml +10 -6
- data/.gitignore +0 -1
- data/.rubocop.yml +7 -1
- data/.ruby-version +1 -1
- data/CLAUDE.md +2 -2
- data/CONTRIBUTING.md +2 -0
- data/Gemfile +19 -18
- data/Gemfile.lock +35 -58
- data/README.md +118 -1432
- data/README_LEGACY.md +1464 -0
- data/Rakefile +39 -4
- data/dev.yml +29 -0
- data/dsl/agent_sessions.rb +20 -0
- data/dsl/async_cogs.rb +49 -0
- data/dsl/async_cogs_complex.rb +67 -0
- data/dsl/call.rb +44 -0
- data/dsl/collect_from.rb +72 -0
- data/dsl/json_output.rb +28 -0
- data/dsl/map.rb +55 -0
- data/dsl/map_reduce.rb +37 -0
- data/dsl/map_with_index.rb +49 -0
- data/dsl/next_break.rb +45 -0
- data/dsl/next_break_parallel.rb +44 -0
- data/dsl/outputs.rb +39 -0
- data/dsl/outputs_bang.rb +36 -0
- data/dsl/parallel_map.rb +37 -0
- data/dsl/prompts/simple_prompt.md.erb +3 -0
- data/dsl/prototype.rb +5 -7
- data/dsl/repeat_loop_results.rb +53 -0
- data/dsl/ruby_cog.rb +72 -0
- data/dsl/simple_agent.rb +18 -0
- data/dsl/simple_chat.rb +15 -1
- data/dsl/simple_repeat.rb +29 -0
- data/dsl/skip.rb +36 -0
- data/dsl/step_communication.rb +2 -3
- data/dsl/targets_and_params.rb +57 -0
- data/dsl/temperature.rb +17 -0
- data/dsl/temporary_directory.rb +22 -0
- data/dsl/tutorial/01_your_first_workflow/README.md +179 -0
- data/dsl/tutorial/01_your_first_workflow/configured_chat.rb +33 -0
- data/dsl/tutorial/01_your_first_workflow/hello.rb +23 -0
- data/dsl/tutorial/02_chaining_cogs/README.md +310 -0
- data/dsl/tutorial/02_chaining_cogs/code_review.rb +104 -0
- data/dsl/tutorial/02_chaining_cogs/session_resumption.rb +92 -0
- data/dsl/tutorial/02_chaining_cogs/simple_chain.rb +84 -0
- data/dsl/tutorial/03_targets_and_params/README.md +230 -0
- data/dsl/tutorial/03_targets_and_params/multiple_targets.rb +65 -0
- data/dsl/tutorial/03_targets_and_params/single_target.rb +65 -0
- data/dsl/tutorial/04_configuration_options/README.md +209 -0
- data/dsl/tutorial/04_configuration_options/control_display_and_temperature.rb +104 -0
- data/dsl/tutorial/04_configuration_options/simple_config.rb +68 -0
- data/dsl/tutorial/05_control_flow/README.md +156 -0
- data/dsl/tutorial/05_control_flow/conditional_execution.rb +62 -0
- data/dsl/tutorial/05_control_flow/handling_failures.rb +77 -0
- data/dsl/tutorial/06_reusable_scopes/README.md +172 -0
- data/dsl/tutorial/06_reusable_scopes/accessing_scope_outputs.rb +126 -0
- data/dsl/tutorial/06_reusable_scopes/basic_scope.rb +63 -0
- data/dsl/tutorial/06_reusable_scopes/parameterized_scope.rb +78 -0
- data/dsl/tutorial/07_processing_collections/README.md +152 -0
- data/dsl/tutorial/07_processing_collections/basic_map.rb +70 -0
- data/dsl/tutorial/07_processing_collections/parallel_map.rb +74 -0
- data/dsl/tutorial/08_iterative_workflows/README.md +231 -0
- data/dsl/tutorial/08_iterative_workflows/basic_repeat.rb +57 -0
- data/dsl/tutorial/08_iterative_workflows/conditional_break.rb +57 -0
- data/dsl/tutorial/09_async_cogs/README.md +197 -0
- data/dsl/tutorial/09_async_cogs/basic_async.rb +38 -0
- data/dsl/tutorial/README.md +222 -0
- data/dsl/working_directory.rb +16 -0
- data/exe/roast +1 -1
- data/internal/documentation/architectural-notes.md +115 -0
- data/internal/documentation/doc-comments-external.md +686 -0
- data/internal/documentation/doc-comments-internal.md +342 -0
- data/internal/documentation/doc-comments.md +211 -0
- data/lib/roast/dsl/cog/config.rb +274 -3
- data/lib/roast/dsl/cog/input.rb +53 -10
- data/lib/roast/dsl/cog/output.rb +297 -8
- data/lib/roast/dsl/cog/registry.rb +35 -3
- data/lib/roast/dsl/cog/stack.rb +1 -1
- data/lib/roast/dsl/cog/store.rb +5 -5
- data/lib/roast/dsl/cog.rb +70 -14
- data/lib/roast/dsl/cog_input_context.rb +36 -1
- data/lib/roast/dsl/cog_input_manager.rb +116 -7
- data/lib/roast/dsl/cogs/agent/config.rb +465 -0
- data/lib/roast/dsl/cogs/agent/input.rb +81 -0
- data/lib/roast/dsl/cogs/agent/output.rb +59 -0
- data/lib/roast/dsl/cogs/agent/provider.rb +51 -0
- data/lib/roast/dsl/cogs/agent/providers/claude/claude_invocation.rb +185 -0
- data/lib/roast/dsl/cogs/agent/providers/claude/message.rb +73 -0
- data/lib/roast/dsl/cogs/agent/providers/claude/messages/assistant_message.rb +36 -0
- data/lib/roast/dsl/cogs/agent/providers/claude/messages/result_message.rb +61 -0
- data/lib/roast/dsl/cogs/agent/providers/claude/messages/system_message.rb +47 -0
- data/lib/roast/dsl/cogs/agent/providers/claude/messages/text_message.rb +36 -0
- data/lib/roast/dsl/cogs/agent/providers/claude/messages/tool_result_message.rb +47 -0
- data/lib/roast/dsl/cogs/agent/providers/claude/messages/tool_use_message.rb +46 -0
- data/lib/roast/dsl/cogs/agent/providers/claude/messages/unknown_message.rb +27 -0
- data/lib/roast/dsl/cogs/agent/providers/claude/messages/user_message.rb +37 -0
- data/lib/roast/dsl/cogs/agent/providers/claude/tool_result.rb +51 -0
- data/lib/roast/dsl/cogs/agent/providers/claude/tool_use.rb +48 -0
- data/lib/roast/dsl/cogs/agent/providers/claude.rb +31 -0
- data/lib/roast/dsl/cogs/agent/stats.rb +92 -0
- data/lib/roast/dsl/cogs/agent/usage.rb +62 -0
- data/lib/roast/dsl/cogs/agent.rb +75 -0
- data/lib/roast/dsl/cogs/chat/config.rb +453 -0
- data/lib/roast/dsl/cogs/chat/input.rb +92 -0
- data/lib/roast/dsl/cogs/chat/output.rb +64 -0
- data/lib/roast/dsl/cogs/chat/session.rb +68 -0
- data/lib/roast/dsl/cogs/chat.rb +59 -56
- data/lib/roast/dsl/cogs/cmd.rb +251 -61
- data/lib/roast/dsl/cogs/ruby.rb +171 -0
- data/lib/roast/dsl/command_runner.rb +191 -0
- data/lib/roast/dsl/config_manager.rb +58 -11
- data/lib/roast/dsl/control_flow.rb +41 -0
- data/lib/roast/dsl/execution_manager.rb +162 -32
- data/lib/roast/dsl/nil_assertions.rb +23 -0
- data/lib/roast/dsl/system_cog/params.rb +32 -0
- data/lib/roast/dsl/system_cog.rb +36 -0
- data/lib/roast/dsl/system_cogs/call.rb +163 -0
- data/lib/roast/dsl/system_cogs/map.rb +454 -0
- data/lib/roast/dsl/system_cogs/repeat.rb +242 -0
- data/lib/roast/dsl/workflow.rb +26 -16
- data/lib/roast/dsl/workflow_context.rb +20 -0
- data/lib/roast/dsl/workflow_params.rb +24 -0
- data/lib/roast/helpers/minitest_coverage_runner.rb +1 -1
- data/lib/roast/sorbet_runtime_stub.rb +154 -0
- data/lib/roast/tools/apply_diff.rb +1 -3
- data/lib/roast/tools/cmd.rb +4 -3
- data/lib/roast/tools/read_file.rb +1 -1
- data/lib/roast/tools/update_files.rb +1 -1
- data/lib/roast/tools/write_file.rb +1 -1
- data/lib/roast/version.rb +1 -1
- data/lib/roast/workflow/base_workflow.rb +4 -0
- data/lib/roast/workflow/step_loader.rb +14 -2
- data/lib/roast-ai.rb +4 -0
- data/lib/roast.rb +58 -21
- data/{roast.gemspec → roast-ai.gemspec} +9 -13
- data/sorbet/rbi/gems/async@2.34.0.rbi +1577 -0
- data/sorbet/rbi/gems/cli-kit@5.2.0.rbi +2063 -0
- data/sorbet/rbi/gems/{cli-ui@2.3.0.rbi → cli-ui@2.7.0-6bdefd1d06305e5d6ae312ac76f9c88f88658dda.rbi} +1418 -1013
- data/sorbet/rbi/gems/console@1.34.2.rbi +1193 -0
- data/sorbet/rbi/gems/fiber-annotation@0.2.0.rbi +50 -0
- data/sorbet/rbi/gems/fiber-local@1.1.0.rbi +35 -0
- data/sorbet/rbi/gems/fiber-storage@1.0.1.rbi +41 -0
- data/sorbet/rbi/gems/io-event@1.14.0.rbi +724 -0
- data/sorbet/rbi/gems/metrics@0.15.0.rbi +9 -0
- data/sorbet/rbi/gems/traces@0.18.2.rbi +9 -0
- data/sorbet/rbi/shims/lib/roast/dsl/cog_input_context.rbi +1185 -5
- data/sorbet/rbi/shims/lib/roast/dsl/config_context.rbi +311 -5
- data/sorbet/rbi/shims/lib/roast/dsl/execution_context.rbi +486 -5
- data/sorbet/tapioca/config.yml +6 -0
- data/sorbet/tapioca/require.rb +2 -0
- metadata +157 -30
- data/dsl/less_simple.rb +0 -112
- data/dsl/scoped_executors.rb +0 -28
- data/dsl/simple.rb +0 -8
- data/lib/roast/dsl/cogs/execute.rb +0 -46
- data/lib/roast/dsl/cogs/graph.rb +0 -53
- data/sorbet/rbi/gems/cgi@0.5.0.rbi +0 -2961
- data/sorbet/rbi/gems/claude_swarm@0.1.19.rbi +0 -568
- data/sorbet/rbi/gems/cli-kit@5.0.1.rbi +0 -1991
- data/sorbet/rbi/gems/dry-configurable@1.3.0.rbi +0 -672
- data/sorbet/rbi/gems/dry-core@1.1.0.rbi +0 -1894
- data/sorbet/rbi/gems/dry-inflector@1.2.0.rbi +0 -659
- data/sorbet/rbi/gems/dry-initializer@3.2.0.rbi +0 -781
- data/sorbet/rbi/gems/dry-logic@1.6.0.rbi +0 -1127
- data/sorbet/rbi/gems/dry-schema@1.14.1.rbi +0 -3727
- data/sorbet/rbi/gems/dry-types@1.8.3.rbi +0 -3969
- data/sorbet/rbi/gems/fast-mcp-annotations@1.5.3.rbi +0 -1588
- data/sorbet/rbi/gems/mime-types-data@3.2025.0617.rbi +0 -136
- data/sorbet/rbi/gems/mime-types@3.7.0.rbi +0 -1342
- data/sorbet/rbi/gems/rack@2.2.19.rbi +0 -5676
- data/sorbet/rbi/gems/yard-sorbet@0.9.0.rbi +0 -435
- data/sorbet/rbi/gems/yard@0.9.37.rbi +0 -18492
data/lib/roast.rb
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
# Standard library requires
|
|
5
|
+
require "benchmark"
|
|
5
6
|
require "digest"
|
|
6
7
|
require "English"
|
|
7
8
|
require "erb"
|
|
@@ -11,6 +12,7 @@ require "logger"
|
|
|
11
12
|
require "net/http"
|
|
12
13
|
require "open3"
|
|
13
14
|
require "pathname"
|
|
15
|
+
require "pp"
|
|
14
16
|
require "securerandom"
|
|
15
17
|
require "shellwords"
|
|
16
18
|
require "tempfile"
|
|
@@ -28,6 +30,8 @@ require "active_support/core_ext/string"
|
|
|
28
30
|
require "active_support/core_ext/string/inflections"
|
|
29
31
|
require "active_support/isolated_execution_state"
|
|
30
32
|
require "active_support/notifications"
|
|
33
|
+
require "async"
|
|
34
|
+
require "async/semaphore"
|
|
31
35
|
require "cli/kit"
|
|
32
36
|
require "cli/ui"
|
|
33
37
|
require "diff/lcs"
|
|
@@ -40,12 +44,23 @@ require "ruby_llm"
|
|
|
40
44
|
require "thor"
|
|
41
45
|
require "timeout"
|
|
42
46
|
|
|
47
|
+
unless defined?(T)
|
|
48
|
+
# NOTE: stubs for sorbet-runtime were being imported from cli-kit. They were removed in cli-kit v5.2
|
|
49
|
+
# Ideally we will not need them at all in the future, but for now I have brought them into the project
|
|
50
|
+
# because a large quantity of legacy code is using sorbet runtime assertions.
|
|
51
|
+
require("roast/sorbet_runtime_stub")
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Require project components that will not get automatically loaded
|
|
55
|
+
require "roast/dsl/nil_assertions"
|
|
56
|
+
|
|
43
57
|
# Autoloading setup
|
|
44
58
|
require "zeitwerk"
|
|
45
59
|
|
|
46
60
|
# Set up Zeitwerk autoloader
|
|
47
61
|
loader = Zeitwerk::Loader.for_gem
|
|
48
62
|
loader.inflector.inflect("dsl" => "DSL")
|
|
63
|
+
loader.ignore("#{__dir__}/roast-ai.rb")
|
|
49
64
|
loader.setup
|
|
50
65
|
|
|
51
66
|
module Roast
|
|
@@ -60,7 +75,7 @@ module Roast
|
|
|
60
75
|
option :replay, type: :string, aliases: "-r", desc: "Resume workflow from a specific step. Format: step_name or session_timestamp:step_name"
|
|
61
76
|
option :pause, type: :string, aliases: "-p", desc: "Pause workflow after a specific step. Format: step_name"
|
|
62
77
|
option :file_storage, type: :boolean, aliases: "-f", desc: "Use filesystem storage for sessions instead of SQLite"
|
|
63
|
-
option :executor, type: :string, default: "default", desc: "Set workflow executor
|
|
78
|
+
option :executor, type: :string, default: "default", desc: "Set workflow executor (use 'dsl' for Roast 1.0 Feature Preview)"
|
|
64
79
|
|
|
65
80
|
def execute(*paths)
|
|
66
81
|
raise Thor::Error, "Workflow configuration file is required" if paths.empty?
|
|
@@ -68,8 +83,13 @@ module Roast
|
|
|
68
83
|
workflow_path, *files = paths
|
|
69
84
|
|
|
70
85
|
if options[:executor] == "dsl"
|
|
71
|
-
puts "⚠️ WARNING:
|
|
72
|
-
|
|
86
|
+
$stderr.puts "⚠️ WARNING: You are using Roast 1.0 feature preview. This syntax has not yet been officially released and should not be considered fully stable." if $stderr.tty?
|
|
87
|
+
targets, workflow_args, workflow_kwargs = parse_custom_workflow_args(files, ARGV)
|
|
88
|
+
targets.unshift(options[:target]) if options[:target]
|
|
89
|
+
workflow_params = Roast::DSL::WorkflowParams.new(targets, workflow_args, workflow_kwargs)
|
|
90
|
+
Dir.chdir(ENV["ROAST_WORKING_DIRECTORY"] || Dir.pwd) do
|
|
91
|
+
Roast::DSL::Workflow.from_file(workflow_path, workflow_params)
|
|
92
|
+
end
|
|
73
93
|
else
|
|
74
94
|
expanded_workflow_path = if workflow_path.include?("workflow.yml")
|
|
75
95
|
File.expand_path(workflow_path)
|
|
@@ -287,6 +307,24 @@ module Roast
|
|
|
287
307
|
|
|
288
308
|
private
|
|
289
309
|
|
|
310
|
+
#: (Array[String], Array[String]) -> [Array[String], Array[Symbol], Hash[Symbol, String]]
|
|
311
|
+
def parse_custom_workflow_args(parsed_args, raw_args)
|
|
312
|
+
separator_index = raw_args.index("--")
|
|
313
|
+
extra_args = (separator_index ? raw_args[(separator_index + 1)..] : []) || []
|
|
314
|
+
targets = parsed_args.shift(parsed_args.length - extra_args.length)
|
|
315
|
+
args = []
|
|
316
|
+
kwargs = {}
|
|
317
|
+
parsed_args.each do |arg|
|
|
318
|
+
if arg.include?("=")
|
|
319
|
+
key, value = arg.split("=", 2)
|
|
320
|
+
kwargs[key.to_sym] = value if key
|
|
321
|
+
else
|
|
322
|
+
args << arg.to_sym
|
|
323
|
+
end
|
|
324
|
+
end
|
|
325
|
+
[targets, args, kwargs]
|
|
326
|
+
end
|
|
327
|
+
|
|
290
328
|
def show_example_picker
|
|
291
329
|
examples = available_examples
|
|
292
330
|
|
|
@@ -296,7 +334,7 @@ module Roast
|
|
|
296
334
|
end
|
|
297
335
|
|
|
298
336
|
puts "Select an option:"
|
|
299
|
-
choices = ["Pick from examples", "New from prompt (
|
|
337
|
+
choices = ["Pick from examples", "New from prompt (coming soon)"]
|
|
300
338
|
|
|
301
339
|
selected = run_picker(choices, "Select initialization method:")
|
|
302
340
|
|
|
@@ -304,8 +342,8 @@ module Roast
|
|
|
304
342
|
when "Pick from examples"
|
|
305
343
|
example_choice = run_picker(examples, "Select an example:")
|
|
306
344
|
copy_example(example_choice) if example_choice
|
|
307
|
-
when "New from prompt (
|
|
308
|
-
|
|
345
|
+
when "New from prompt (coming soon)"
|
|
346
|
+
show_coming_soon_message
|
|
309
347
|
end
|
|
310
348
|
end
|
|
311
349
|
|
|
@@ -349,22 +387,21 @@ module Roast
|
|
|
349
387
|
puts "Successfully copied example '#{example_name}' to current directory."
|
|
350
388
|
end
|
|
351
389
|
|
|
352
|
-
def
|
|
353
|
-
puts
|
|
390
|
+
def show_coming_soon_message
|
|
391
|
+
puts
|
|
392
|
+
puts ::CLI::UI.fmt("{{bold:Workflow Generator - Coming Soon}}")
|
|
393
|
+
puts
|
|
394
|
+
puts "The 'New from prompt' workflow generator is being rebuilt to ensure"
|
|
395
|
+
puts "generated workflows are reliable and properly validated."
|
|
396
|
+
puts
|
|
397
|
+
puts "This feature will return with:"
|
|
398
|
+
puts " • Better AI-generated workflow quality"
|
|
399
|
+
puts " • Validation to ensure generated workflows actually work"
|
|
400
|
+
puts " • Integration with Roast's upcoming DSL features"
|
|
401
|
+
puts
|
|
402
|
+
puts "For now, please use 'Pick from examples' to get started."
|
|
403
|
+
puts "You can then customize the example workflow for your needs."
|
|
354
404
|
puts
|
|
355
|
-
|
|
356
|
-
# Execute the workflow generator
|
|
357
|
-
generator_path = File.join(Roast::ROOT, "examples", "workflow_generator", "workflow.yml")
|
|
358
|
-
|
|
359
|
-
begin
|
|
360
|
-
# Execute the workflow generator (it will handle user input)
|
|
361
|
-
Roast::Workflow::WorkflowRunner.new(generator_path, [], {}).begin!
|
|
362
|
-
|
|
363
|
-
puts
|
|
364
|
-
puts("Workflow generation complete!")
|
|
365
|
-
rescue => e
|
|
366
|
-
puts("Error generating workflow: #{e.message}")
|
|
367
|
-
end
|
|
368
405
|
end
|
|
369
406
|
|
|
370
407
|
class << self
|
|
@@ -15,17 +15,10 @@ Gem::Specification.new do |spec|
|
|
|
15
15
|
spec.homepage = "https://github.com/Shopify/roast"
|
|
16
16
|
spec.license = "MIT"
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
spec.metadata["homepage_uri"] = spec.homepage
|
|
23
|
-
spec.metadata["source_code_uri"] = "https://github.com/Shopify/roast"
|
|
24
|
-
spec.metadata["changelog_uri"] = "https://github.com/Shopify/roast/blob/main/CHANGELOG.md"
|
|
25
|
-
else
|
|
26
|
-
raise "RubyGems 2.0 or newer is required to protect against " \
|
|
27
|
-
"public gem pushes."
|
|
28
|
-
end
|
|
18
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
|
19
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
|
20
|
+
spec.metadata["source_code_uri"] = "https://github.com/Shopify/roast"
|
|
21
|
+
spec.metadata["changelog_uri"] = "https://github.com/Shopify/roast/blob/main/CHANGELOG.md"
|
|
29
22
|
|
|
30
23
|
# Specify which files should be added to the gem when it is released.
|
|
31
24
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
@@ -37,12 +30,15 @@ Gem::Specification.new do |spec|
|
|
|
37
30
|
spec.require_paths = ["lib"]
|
|
38
31
|
|
|
39
32
|
spec.add_dependency("activesupport", ">= 7.0")
|
|
40
|
-
spec.add_dependency("
|
|
41
|
-
spec.add_dependency("
|
|
33
|
+
spec.add_dependency("async", "~> 2.34")
|
|
34
|
+
spec.add_dependency("benchmark", "~> 0.4.1")
|
|
35
|
+
spec.add_dependency("cli-kit", "~> 5.2")
|
|
36
|
+
spec.add_dependency("cli-ui", "~> 2.7")
|
|
42
37
|
spec.add_dependency("diff-lcs", "~> 1.5")
|
|
43
38
|
spec.add_dependency("json-schema")
|
|
44
39
|
spec.add_dependency("open_router", "~> 0.3")
|
|
45
40
|
spec.add_dependency("raix", "~> 1.0.2")
|
|
41
|
+
spec.add_dependency("rake", "~> 13.3.0") # NOTE: required by Thor
|
|
46
42
|
spec.add_dependency("ruby-graphviz", "~> 1.2")
|
|
47
43
|
spec.add_dependency("ruby_llm")
|
|
48
44
|
spec.add_dependency("sqlite3", "~> 2.6")
|