roast-ai 0.4.9 → 0.4.10

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 (54) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +6 -7
  3. data/Gemfile.lock +14 -2
  4. data/dsl/demo/Gemfile +4 -0
  5. data/dsl/demo/Gemfile.lock +120 -0
  6. data/dsl/demo/cogs/local.rb +15 -0
  7. data/dsl/demo/simple_external_cog.rb +17 -0
  8. data/dsl/plugin-gem-example/.gitignore +8 -0
  9. data/dsl/plugin-gem-example/Gemfile +13 -0
  10. data/dsl/plugin-gem-example/Gemfile.lock +178 -0
  11. data/dsl/plugin-gem-example/lib/other.rb +17 -0
  12. data/dsl/plugin-gem-example/lib/plugin_gem_example.rb +5 -0
  13. data/dsl/plugin-gem-example/lib/simple.rb +15 -0
  14. data/dsl/plugin-gem-example/lib/version.rb +10 -0
  15. data/dsl/plugin-gem-example/plugin-gem-example.gemspec +28 -0
  16. data/dsl/prototype.rb +11 -3
  17. data/dsl/scoped_executors.rb +28 -0
  18. data/dsl/simple_chat.rb +12 -0
  19. data/dsl/step_communication.rb +10 -4
  20. data/lib/roast/dsl/cog/config.rb +6 -1
  21. data/lib/roast/dsl/cog/input.rb +30 -0
  22. data/lib/roast/dsl/cog/output.rb +24 -0
  23. data/lib/roast/dsl/cog/registry.rb +39 -0
  24. data/lib/roast/dsl/cog/stack.rb +2 -1
  25. data/lib/roast/dsl/cog/store.rb +8 -5
  26. data/lib/roast/dsl/cog.rb +49 -28
  27. data/lib/roast/dsl/cog_input_context.rb +9 -0
  28. data/lib/roast/dsl/cog_input_manager.rb +47 -0
  29. data/lib/roast/dsl/cogs/chat.rb +78 -0
  30. data/lib/roast/dsl/cogs/cmd.rb +97 -20
  31. data/lib/roast/dsl/cogs/execute.rb +46 -0
  32. data/lib/roast/dsl/cogs/graph.rb +3 -3
  33. data/lib/roast/dsl/config_context.rb +2 -47
  34. data/lib/roast/dsl/config_manager.rb +96 -0
  35. data/lib/roast/dsl/execution_context.rb +9 -0
  36. data/lib/roast/dsl/execution_manager.rb +137 -0
  37. data/lib/roast/dsl/workflow.rb +113 -0
  38. data/lib/roast/version.rb +1 -1
  39. data/lib/roast.rb +3 -2
  40. data/roast.gemspec +1 -0
  41. data/sorbet/config +1 -0
  42. data/sorbet/rbi/gems/marcel@1.1.0.rbi +239 -0
  43. data/sorbet/rbi/gems/{rack@2.2.18.rbi → rack@2.2.19.rbi} +55 -38
  44. data/sorbet/rbi/gems/ruby_llm@1.8.2.rbi +5703 -0
  45. data/sorbet/rbi/shims/lib/roast/dsl/cog_input_context.rbi +17 -0
  46. data/sorbet/rbi/shims/lib/roast/dsl/config_context.rbi +6 -0
  47. data/sorbet/rbi/shims/lib/roast/dsl/execution_context.rbi +17 -0
  48. metadata +45 -8
  49. data/lib/roast/dsl/cog_execution_context.rb +0 -29
  50. data/lib/roast/dsl/cogs.rb +0 -65
  51. data/lib/roast/dsl/executor.rb +0 -82
  52. data/lib/roast/dsl/workflow_execution_context.rb +0 -47
  53. data/sorbet/rbi/gems/rbs-inline@0.12.0.rbi +0 -2170
  54. data/sorbet/rbi/shims/lib/roast/dsl/workflow_execution_context.rbi +0 -11
@@ -0,0 +1,17 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module Roast
5
+ module DSL
6
+ class CogInputContext
7
+ #: (Symbol) -> Roast::DSL::Cogs::Cmd::Output
8
+ def cmd(name); end
9
+
10
+ #: (Symbol) -> Roast::DSL::Cogs::Chat::Output
11
+ def chat(name); end
12
+
13
+ #: (Symbol) -> Roast::DSL::Cog::Output
14
+ def execute(name); end
15
+ end
16
+ end
17
+ end
@@ -6,6 +6,12 @@ module Roast
6
6
  class ConfigContext
7
7
  #: (?Symbol?) {() [self: Roast::DSL::Cogs::Cmd::Config] -> void} -> void
8
8
  def cmd(name = nil, &block); end
9
+
10
+ #: (?Symbol?) {() [self: Roast::DSL::Cogs::Chat::Config] -> void} -> void
11
+ def chat(name = nil, &block); end
12
+
13
+ #: (?Symbol?) {() [self: Roast::DSL::Cog::Config] -> void} -> void
14
+ def execute(name = nil, &block); end
9
15
  end
10
16
  end
11
17
  end
@@ -0,0 +1,17 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module Roast
5
+ module DSL
6
+ class ExecutionContext
7
+ #: (?Symbol?) {(Roast::DSL::Cogs::Cmd::Input) [self: Roast::DSL::CogInputContext] -> (String | Array[String] | nil)} -> void
8
+ def cmd(name = nil, &block); end
9
+
10
+ #: (?Symbol?) {(Roast::DSL::Cogs::Chat::Input) [self: Roast::DSL::CogInputContext] -> String?} -> void
11
+ def chat(name = nil, &block); end
12
+
13
+ #: (?Symbol?) {(Roast::DSL::Cogs::Execute::Input) [self: Roast::DSL::CogInputContext] -> (Symbol | nil)} -> void
14
+ def execute(name = nil, &block); end
15
+ end
16
+ end
17
+ 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.4.9
4
+ version: 0.4.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify
@@ -121,6 +121,20 @@ dependencies:
121
121
  - - "~>"
122
122
  - !ruby/object:Gem::Version
123
123
  version: '1.2'
124
+ - !ruby/object:Gem::Dependency
125
+ name: ruby_llm
126
+ requirement: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ type: :runtime
132
+ prerelease: false
133
+ version_requirements: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
124
138
  - !ruby/object:Gem::Dependency
125
139
  name: sqlite3
126
140
  requirement: !ruby/object:Gem::Requirement
@@ -201,9 +215,23 @@ files:
201
215
  - docs/INSTRUMENTATION.md
202
216
  - docs/ITERATION_SYNTAX.md
203
217
  - docs/VALIDATION.md
218
+ - dsl/demo/Gemfile
219
+ - dsl/demo/Gemfile.lock
220
+ - dsl/demo/cogs/local.rb
221
+ - dsl/demo/simple_external_cog.rb
204
222
  - dsl/less_simple.rb
223
+ - dsl/plugin-gem-example/.gitignore
224
+ - dsl/plugin-gem-example/Gemfile
225
+ - dsl/plugin-gem-example/Gemfile.lock
226
+ - dsl/plugin-gem-example/lib/other.rb
227
+ - dsl/plugin-gem-example/lib/plugin_gem_example.rb
228
+ - dsl/plugin-gem-example/lib/simple.rb
229
+ - dsl/plugin-gem-example/lib/version.rb
230
+ - dsl/plugin-gem-example/plugin-gem-example.gemspec
205
231
  - dsl/prototype.rb
232
+ - dsl/scoped_executors.rb
206
233
  - dsl/simple.rb
234
+ - dsl/simple_chat.rb
207
235
  - dsl/step_communication.rb
208
236
  - examples/README.md
209
237
  - examples/available_tools_demo/README.md
@@ -232,15 +260,22 @@ files:
232
260
  - lib/roast/dsl.rb
233
261
  - lib/roast/dsl/cog.rb
234
262
  - lib/roast/dsl/cog/config.rb
263
+ - lib/roast/dsl/cog/input.rb
264
+ - lib/roast/dsl/cog/output.rb
265
+ - lib/roast/dsl/cog/registry.rb
235
266
  - lib/roast/dsl/cog/stack.rb
236
267
  - lib/roast/dsl/cog/store.rb
237
- - lib/roast/dsl/cog_execution_context.rb
238
- - lib/roast/dsl/cogs.rb
268
+ - lib/roast/dsl/cog_input_context.rb
269
+ - lib/roast/dsl/cog_input_manager.rb
270
+ - lib/roast/dsl/cogs/chat.rb
239
271
  - lib/roast/dsl/cogs/cmd.rb
272
+ - lib/roast/dsl/cogs/execute.rb
240
273
  - lib/roast/dsl/cogs/graph.rb
241
274
  - lib/roast/dsl/config_context.rb
242
- - lib/roast/dsl/executor.rb
243
- - lib/roast/dsl/workflow_execution_context.rb
275
+ - lib/roast/dsl/config_manager.rb
276
+ - lib/roast/dsl/execution_context.rb
277
+ - lib/roast/dsl/execution_manager.rb
278
+ - lib/roast/dsl/workflow.rb
244
279
  - lib/roast/error.rb
245
280
  - lib/roast/errors.rb
246
281
  - lib/roast/factories/api_provider_factory.rb
@@ -417,6 +452,7 @@ files:
417
452
  - sorbet/rbi/gems/listen@3.9.0.rbi
418
453
  - sorbet/rbi/gems/logger@1.7.0.rbi
419
454
  - sorbet/rbi/gems/lumberjack@1.2.10.rbi
455
+ - sorbet/rbi/gems/marcel@1.1.0.rbi
420
456
  - sorbet/rbi/gems/method_source@1.1.0.rbi
421
457
  - sorbet/rbi/gems/mime-types-data@3.2025.0617.rbi
422
458
  - sorbet/rbi/gems/mime-types@3.7.0.rbi
@@ -436,14 +472,13 @@ files:
436
472
  - sorbet/rbi/gems/pry@0.15.2.rbi
437
473
  - sorbet/rbi/gems/public_suffix@6.0.2.rbi
438
474
  - sorbet/rbi/gems/racc@1.8.1.rbi
439
- - sorbet/rbi/gems/rack@2.2.18.rbi
475
+ - sorbet/rbi/gems/rack@2.2.19.rbi
440
476
  - sorbet/rbi/gems/rainbow@3.1.1.rbi
441
477
  - sorbet/rbi/gems/raix@1.0.2.rbi
442
478
  - sorbet/rbi/gems/rake@13.3.0.rbi
443
479
  - sorbet/rbi/gems/rb-fsevent@0.11.2.rbi
444
480
  - sorbet/rbi/gems/rb-inotify@0.11.1.rbi
445
481
  - sorbet/rbi/gems/rbi@0.3.6.rbi
446
- - sorbet/rbi/gems/rbs-inline@0.12.0.rbi
447
482
  - sorbet/rbi/gems/rbs@3.9.4.rbi
448
483
  - sorbet/rbi/gems/regexp_parser@2.10.0.rbi
449
484
  - sorbet/rbi/gems/rexml@3.4.2.rbi
@@ -455,6 +490,7 @@ files:
455
490
  - sorbet/rbi/gems/ruby-openai@8.1.0.rbi
456
491
  - sorbet/rbi/gems/ruby-progressbar@1.13.0.rbi
457
492
  - sorbet/rbi/gems/ruby2_keywords@0.0.5.rbi
493
+ - sorbet/rbi/gems/ruby_llm@1.8.2.rbi
458
494
  - sorbet/rbi/gems/securerandom@0.4.1.rbi
459
495
  - sorbet/rbi/gems/shellany@0.0.1.rbi
460
496
  - sorbet/rbi/gems/simplecov-html@0.13.2.rbi
@@ -473,8 +509,9 @@ files:
473
509
  - sorbet/rbi/gems/yard-sorbet@0.9.0.rbi
474
510
  - sorbet/rbi/gems/yard@0.9.37.rbi
475
511
  - sorbet/rbi/gems/zeitwerk@2.7.3.rbi
512
+ - sorbet/rbi/shims/lib/roast/dsl/cog_input_context.rbi
476
513
  - sorbet/rbi/shims/lib/roast/dsl/config_context.rbi
477
- - sorbet/rbi/shims/lib/roast/dsl/workflow_execution_context.rbi
514
+ - sorbet/rbi/shims/lib/roast/dsl/execution_context.rbi
478
515
  - sorbet/rbi/todo.rbi
479
516
  - sorbet/tapioca/config.yml
480
517
  - sorbet/tapioca/require.rb
@@ -1,29 +0,0 @@
1
- # typed: true
2
- # frozen_string_literal: true
3
-
4
- module Roast
5
- module DSL
6
- # Contains the cogs already executed in this run.
7
- class CogExecutionContext
8
- # Raises if you access a cog in an execution block that hasn't already been run.
9
- class IncompleteCogExecutionAccessError < StandardError; end
10
-
11
- def initialize(cogs, bound_names)
12
- @cogs = cogs
13
- bind_cog_methods(bound_names)
14
- end
15
-
16
- private
17
-
18
- def bind_cog_methods(bound_names)
19
- bound_names.map do |name|
20
- define_singleton_method(name.to_sym, ->(name) do
21
- @cogs[name].tap do |cog|
22
- raise IncompleteCogExecutionAccessError unless cog.ran?
23
- end.output
24
- end)
25
- end
26
- end
27
- end
28
- end
29
- end
@@ -1,65 +0,0 @@
1
- # typed: false
2
- # frozen_string_literal: true
3
-
4
- module Roast
5
- module DSL
6
- module Cogs
7
- class << self
8
- #: (String) -> void
9
- def load_all_for(rube_rb_fpath)
10
- rube_rb_fpath = File.expand_path(rube_rb_fpath)
11
- all_cog_files(rube_rb_fpath).each do |cog_fpath|
12
- require cog_fpath
13
- end
14
- bind_all_cog_invokers
15
- end
16
-
17
- #: () -> Array[Class]
18
- def all_cog_classes
19
- # rubocop:disable Sorbet/ConstantsFromStrings
20
- Roast::DSL::Cogs.constants.map do |cog_class_name|
21
- Roast::DSL::Cogs.const_get(cog_class_name)
22
- end
23
- # rubocop:enable Sorbet/ConstantsFromStrings
24
- end
25
-
26
- private
27
-
28
- #: () -> void
29
- def bind_all_cog_invokers
30
- all_cog_classes.each do |cog_class|
31
- # At some point we may want to tuck this all into a Roast::DSL::Binding/Scope/Context to avoid polluting toplevel.
32
- TOPLEVEL_BINDING.eval(binding_string_for(cog_class))
33
- end
34
- end
35
-
36
- #: (Class) -> String
37
- def binding_string_for(cog_class)
38
- <<~RUBY
39
- def #{cog_class.method_name}(*args, **kwargs, &block)
40
- #{cog_class.name}.invoke(*args, **kwargs, &block)
41
- end
42
- RUBY
43
- end
44
-
45
- #: (String) -> Array[String]
46
- def all_cog_files(rube_rb_fpath)
47
- dirs = [project_cogs_dir(rube_rb_fpath), internal_cogs_dir]
48
- dirs.map do |dir|
49
- Dir.glob(File.join(dir, "*.rb")) # Just toplevel .rb files
50
- end.flatten
51
- end
52
-
53
- #: (String) -> String
54
- def project_cogs_dir(rube_rb_fpath)
55
- File.join(File.dirname(rube_rb_fpath), "cogs")
56
- end
57
-
58
- #: () -> String
59
- def internal_cogs_dir
60
- File.join(File.dirname(__FILE__), "cogs")
61
- end
62
- end
63
- end
64
- end
65
- end
@@ -1,82 +0,0 @@
1
- # typed: true
2
- # frozen_string_literal: true
3
-
4
- module Roast
5
- module DSL
6
- class Executor
7
- class ExecutorError < Roast::Error; end
8
- class ExecutorAlreadyPreparedError < ExecutorError; end
9
- class ExecutorAlreadyCompletedError < ExecutorError; end
10
-
11
- class << self
12
- def from_file(workflow_path)
13
- run!(File.read(workflow_path))
14
- end
15
-
16
- private
17
-
18
- def run!(workflow_definition)
19
- executor = new
20
- executor.prepare!(workflow_definition)
21
- executor.start!
22
- end
23
- end
24
-
25
- def prepare!(input)
26
- # You can only initialize an executor once.
27
- raise ExecutorAlreadyPreparedError if @prepared
28
-
29
- extract_dsl_procs(input)
30
- @cogs = Cog::Store.new
31
- @cog_stack = Cog::Stack.new
32
-
33
- @config_context = ConfigContext.new(@cogs, @config_proc)
34
- @config_context.prepare!
35
- @execution_context = WorkflowExecutionContext.new(@cogs, @cog_stack, @execution_proc)
36
- @execution_context.prepare!
37
-
38
- @prepared = true
39
- end
40
-
41
- def start!
42
- # Now we run the cogs!
43
- # You can only do this once, executors are not reusable to avoid state pollution
44
- raise ExecutorAlreadyCompletedError if @completed
45
-
46
- @cog_stack.map do |name, cog|
47
- cog.run!(
48
- @config_context.fetch_merged_config(cog.class, name.to_sym),
49
- @execution_context.cog_execution_context,
50
- )
51
- end
52
-
53
- @completed = true
54
- end
55
-
56
- def prepared?
57
- @prepared ||= false
58
- end
59
-
60
- def completed?
61
- @completed ||= false
62
- end
63
-
64
- #: { () [self: ConfigContext] -> void} -> void
65
- def config(&block)
66
- @config_proc = block
67
- end
68
-
69
- #: { () [self: WorkflowExecutionContext] -> void} -> void
70
- def execute(&block)
71
- @execution_proc = block
72
- end
73
-
74
- # Separating the instance evals ensures that we can reuse the same cog method
75
- # names between config and execute, while have the backing objects be completely
76
- # different. This means we have an enforced separation between configuring and running.
77
- def extract_dsl_procs(input)
78
- instance_eval(input)
79
- end
80
- end
81
- end
82
- end
@@ -1,47 +0,0 @@
1
- # typed: true
2
- # frozen_string_literal: true
3
-
4
- module Roast
5
- module DSL
6
- class WorkflowExecutionContext
7
- def initialize(cogs, cog_stack, execution_proc)
8
- @cogs = cogs
9
- @cog_stack = cog_stack
10
- @execution_proc = execution_proc
11
- @bound_names = []
12
- end
13
-
14
- def prepare!
15
- bind_default_cogs
16
- instance_eval(&@execution_proc)
17
- end
18
-
19
- def cog_execution_context
20
- @cog_execution_context ||= CogExecutionContext.new(@cogs, @bound_names)
21
- end
22
-
23
- private
24
-
25
- def add_cog_instance(name, cog)
26
- @cogs.insert(name, cog)
27
- @cog_stack.push([name, cog])
28
- end
29
-
30
- def output(name)
31
- @cogs[name].output
32
- end
33
-
34
- #: () -> void
35
- def bind_default_cogs
36
- bind_cog(Cogs::Cmd, :cmd)
37
- end
38
-
39
- def bind_cog(cog_class, name)
40
- @bound_names << name
41
- instance_eval do
42
- define_singleton_method(name, &cog_class.on_create)
43
- end
44
- end
45
- end
46
- end
47
- end