roast-ai 0.4.4 → 0.4.6
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/.github/CODEOWNERS +2 -0
- data/.github/workflows/ci.yaml +1 -0
- data/.gitignore +0 -26
- data/.rubocop.yml +13 -0
- data/.rubocop_todo.yml +21 -0
- data/CHANGELOG.md +37 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +43 -1
- data/bin/rubocop +27 -0
- data/bin/spoom +27 -0
- data/bin/srb +27 -0
- data/bin/srb-rbi +27 -0
- data/bin/tapioca +27 -0
- data/docs/INSTRUMENTATION.md +3 -3
- data/dsl/simple.rb +10 -0
- data/examples/retry/workflow.yml +23 -0
- data/lib/roast/dsl/executor.rb +26 -0
- data/lib/roast/dsl.rb +7 -0
- data/lib/roast/errors.rb +1 -0
- data/lib/roast/factories/api_provider_factory.rb +1 -0
- data/lib/roast/helpers/function_caching_interceptor.rb +3 -0
- data/lib/roast/helpers/logger.rb +6 -9
- data/lib/roast/helpers/metadata_access.rb +1 -0
- data/lib/roast/helpers/minitest_coverage_runner.rb +1 -0
- data/lib/roast/helpers/path_resolver.rb +8 -18
- data/lib/roast/helpers/prompt_loader.rb +3 -2
- data/lib/roast/helpers/timeout_handler.rb +3 -5
- data/lib/roast/initializers.rb +1 -0
- data/lib/roast/resources/api_resource.rb +4 -3
- data/lib/roast/resources/base_resource.rb +1 -0
- data/lib/roast/resources/directory_resource.rb +1 -0
- data/lib/roast/resources/file_resource.rb +1 -0
- data/lib/roast/resources/none_resource.rb +1 -0
- data/lib/roast/resources/url_resource.rb +2 -1
- data/lib/roast/resources.rb +1 -2
- data/lib/roast/services/context_threshold_checker.rb +1 -0
- data/lib/roast/services/token_counting_service.rb +1 -0
- data/lib/roast/tools/apply_diff.rb +1 -0
- data/lib/roast/tools/ask_user.rb +1 -0
- data/lib/roast/tools/bash.rb +1 -0
- data/lib/roast/tools/cmd.rb +1 -0
- data/lib/roast/tools/coding_agent.rb +1 -0
- data/lib/roast/tools/context_summarizer.rb +1 -0
- data/lib/roast/tools/grep.rb +1 -0
- data/lib/roast/tools/helpers/coding_agent_message_formatter.rb +1 -0
- data/lib/roast/tools/read_file.rb +1 -0
- data/lib/roast/tools/search_file.rb +1 -0
- data/lib/roast/tools/swarm.rb +1 -0
- data/lib/roast/tools/update_files.rb +1 -0
- data/lib/roast/tools/write_file.rb +1 -0
- data/lib/roast/tools.rb +2 -0
- data/lib/roast/value_objects/api_token.rb +1 -0
- data/lib/roast/value_objects/step_name.rb +1 -0
- data/lib/roast/value_objects/uri_base.rb +1 -0
- data/lib/roast/value_objects/workflow_path.rb +1 -0
- data/lib/roast/value_objects.rb +1 -0
- data/lib/roast/version.rb +2 -1
- data/lib/roast/workflow/agent_step.rb +1 -0
- data/lib/roast/workflow/api_configuration.rb +1 -0
- data/lib/roast/workflow/base_iteration_step.rb +1 -0
- data/lib/roast/workflow/base_step.rb +1 -0
- data/lib/roast/workflow/base_workflow.rb +1 -0
- data/lib/roast/workflow/case_executor.rb +1 -0
- data/lib/roast/workflow/case_step.rb +1 -0
- data/lib/roast/workflow/command_executor.rb +1 -0
- data/lib/roast/workflow/conditional_executor.rb +1 -0
- data/lib/roast/workflow/conditional_step.rb +1 -0
- data/lib/roast/workflow/configuration.rb +9 -0
- data/lib/roast/workflow/configuration_loader.rb +4 -1
- data/lib/roast/workflow/context_manager.rb +1 -0
- data/lib/roast/workflow/context_path_resolver.rb +1 -0
- data/lib/roast/workflow/dot_access_hash.rb +1 -0
- data/lib/roast/workflow/each_step.rb +1 -0
- data/lib/roast/workflow/error_handler.rb +39 -3
- data/lib/roast/workflow/expression_evaluator.rb +1 -0
- data/lib/roast/workflow/expression_utils.rb +1 -0
- data/lib/roast/workflow/file_state_repository.rb +2 -1
- data/lib/roast/workflow/input_executor.rb +1 -0
- data/lib/roast/workflow/input_step.rb +1 -0
- data/lib/roast/workflow/interpolator.rb +2 -1
- data/lib/roast/workflow/iteration_executor.rb +1 -0
- data/lib/roast/workflow/llm_boolean_coercer.rb +1 -0
- data/lib/roast/workflow/metadata_manager.rb +1 -0
- data/lib/roast/workflow/output_handler.rb +1 -0
- data/lib/roast/workflow/output_manager.rb +1 -0
- data/lib/roast/workflow/parallel_executor.rb +1 -0
- data/lib/roast/workflow/prompt_step.rb +1 -0
- data/lib/roast/workflow/repeat_step.rb +1 -0
- data/lib/roast/workflow/replay_handler.rb +1 -0
- data/lib/roast/workflow/resource_resolver.rb +2 -6
- data/lib/roast/workflow/session_manager.rb +1 -0
- data/lib/roast/workflow/shell_script_step.rb +1 -0
- data/lib/roast/workflow/sqlite_state_repository.rb +1 -0
- data/lib/roast/workflow/state_manager.rb +1 -0
- data/lib/roast/workflow/state_repository.rb +1 -0
- data/lib/roast/workflow/state_repository_factory.rb +4 -2
- data/lib/roast/workflow/step_completion_reporter.rb +1 -0
- data/lib/roast/workflow/step_executor_coordinator.rb +17 -6
- data/lib/roast/workflow/step_executor_factory.rb +1 -0
- data/lib/roast/workflow/step_executor_registry.rb +2 -3
- data/lib/roast/workflow/step_executor_with_reporting.rb +1 -0
- data/lib/roast/workflow/step_executors/base_step_executor.rb +1 -0
- data/lib/roast/workflow/step_executors/hash_step_executor.rb +1 -0
- data/lib/roast/workflow/step_executors/parallel_step_executor.rb +1 -0
- data/lib/roast/workflow/step_executors/string_step_executor.rb +1 -0
- data/lib/roast/workflow/step_factory.rb +1 -0
- data/lib/roast/workflow/step_finder.rb +1 -0
- data/lib/roast/workflow/step_loader.rb +1 -0
- data/lib/roast/workflow/step_name_extractor.rb +1 -0
- data/lib/roast/workflow/step_runner.rb +1 -0
- data/lib/roast/workflow/step_type_resolver.rb +1 -0
- data/lib/roast/workflow/validation_command.rb +1 -0
- data/lib/roast/workflow/validator.rb +1 -0
- data/lib/roast/workflow/validators/base_validator.rb +1 -0
- data/lib/roast/workflow/validators/dependency_validator.rb +1 -0
- data/lib/roast/workflow/validators/linting_validator.rb +1 -0
- data/lib/roast/workflow/validators/schema_validator.rb +1 -0
- data/lib/roast/workflow/validators/step_collector.rb +1 -0
- data/lib/roast/workflow/validators/validation_orchestrator.rb +1 -0
- data/lib/roast/workflow/workflow_context.rb +1 -0
- data/lib/roast/workflow/workflow_execution_context.rb +1 -0
- data/lib/roast/workflow/workflow_executor.rb +2 -1
- data/lib/roast/workflow/workflow_initializer.rb +16 -1
- data/lib/roast/workflow/workflow_runner.rb +66 -55
- data/lib/roast/workflow.rb +1 -0
- data/lib/roast/workflow_diagram_generator.rb +3 -2
- data/lib/roast.rb +23 -8
- data/sorbet/config +8 -0
- data/sorbet/rbi/dsl/.gitattributes +1 -0
- data/sorbet/rbi/dsl/active_support/callbacks.rbi +21 -0
- data/sorbet/rbi/gems/.gitattributes +1 -0
- data/sorbet/rbi/gems/activesupport@8.0.2.rbi +19107 -0
- data/sorbet/rbi/gems/addressable@2.8.7.rbi +1994 -0
- data/sorbet/rbi/gems/ast@2.4.3.rbi +585 -0
- data/sorbet/rbi/gems/base64@0.3.0.rbi +545 -0
- data/sorbet/rbi/gems/benchmark@0.4.1.rbi +619 -0
- data/sorbet/rbi/gems/bigdecimal@3.2.2.rbi +62 -0
- data/sorbet/rbi/gems/cgi@0.5.0.rbi +2961 -0
- data/sorbet/rbi/gems/claude_swarm@0.1.19.rbi +568 -0
- data/sorbet/rbi/gems/cli-kit@5.0.1.rbi +1991 -0
- data/sorbet/rbi/gems/cli-ui@2.3.0.rbi +3181 -0
- data/sorbet/rbi/gems/coderay@1.1.3.rbi +9 -0
- data/sorbet/rbi/gems/concurrent-ruby@1.3.5.rbi +11657 -0
- data/sorbet/rbi/gems/connection_pool@2.5.3.rbi +9 -0
- data/sorbet/rbi/gems/crack@1.0.0.rbi +145 -0
- data/sorbet/rbi/gems/diff-lcs@1.6.2.rbi +972 -0
- data/sorbet/rbi/gems/dotenv@3.1.8.rbi +295 -0
- data/sorbet/rbi/gems/drb@2.2.3.rbi +1661 -0
- data/sorbet/rbi/gems/dry-configurable@1.3.0.rbi +672 -0
- data/sorbet/rbi/gems/dry-core@1.1.0.rbi +1894 -0
- data/sorbet/rbi/gems/dry-inflector@1.2.0.rbi +659 -0
- data/sorbet/rbi/gems/dry-initializer@3.2.0.rbi +781 -0
- data/sorbet/rbi/gems/dry-logic@1.6.0.rbi +1127 -0
- data/sorbet/rbi/gems/dry-schema@1.14.1.rbi +3727 -0
- data/sorbet/rbi/gems/dry-types@1.8.3.rbi +3969 -0
- data/sorbet/rbi/gems/erubi@1.13.1.rbi +155 -0
- data/sorbet/rbi/gems/event_stream_parser@1.0.0.rbi +49 -0
- data/sorbet/rbi/gems/faraday-multipart@1.1.1.rbi +283 -0
- data/sorbet/rbi/gems/faraday-net_http@3.4.1.rbi +147 -0
- data/sorbet/rbi/gems/faraday-retry@2.3.2.rbi +9 -0
- data/sorbet/rbi/gems/faraday@2.13.1.rbi +2977 -0
- data/sorbet/rbi/gems/fast-mcp-annotations@1.5.3.rbi +1588 -0
- data/sorbet/rbi/gems/ffi@1.17.2.rbi +9 -0
- data/sorbet/rbi/gems/formatador@1.1.0.rbi +9 -0
- data/sorbet/rbi/gems/guard-compat@1.2.1.rbi +102 -0
- data/sorbet/rbi/gems/guard-minitest@2.4.6.rbi +402 -0
- data/sorbet/rbi/gems/guard@2.19.1.rbi +2283 -0
- data/sorbet/rbi/gems/hashdiff@1.2.0.rbi +355 -0
- data/sorbet/rbi/gems/i18n@1.14.7.rbi +2359 -0
- data/sorbet/rbi/gems/json-schema@5.1.1.rbi +1466 -0
- data/sorbet/rbi/gems/json@2.12.2.rbi +2051 -0
- data/sorbet/rbi/gems/language_server-protocol@3.17.0.5.rbi +9 -0
- data/sorbet/rbi/gems/lint_roller@1.1.0.rbi +9 -0
- data/sorbet/rbi/gems/listen@3.9.0.rbi +1206 -0
- data/sorbet/rbi/gems/logger@1.7.0.rbi +963 -0
- data/sorbet/rbi/gems/lumberjack@1.2.10.rbi +1830 -0
- data/sorbet/rbi/gems/method_source@1.1.0.rbi +9 -0
- data/sorbet/rbi/gems/mime-types-data@3.2025.0617.rbi +136 -0
- data/sorbet/rbi/gems/mime-types@3.7.0.rbi +1342 -0
- data/sorbet/rbi/gems/minitest-rg@5.3.0.rbi +160 -0
- data/sorbet/rbi/gems/minitest@5.25.5.rbi +1640 -0
- data/sorbet/rbi/gems/mocha@2.7.1.rbi +12 -0
- data/sorbet/rbi/gems/multipart-post@2.4.1.rbi +244 -0
- data/sorbet/rbi/gems/nenv@0.3.0.rbi +147 -0
- data/sorbet/rbi/gems/net-http@0.6.0.rbi +4247 -0
- data/sorbet/rbi/gems/netrc@0.11.0.rbi +159 -0
- data/sorbet/rbi/gems/notiffany@0.1.3.rbi +1079 -0
- data/sorbet/rbi/gems/open_router@0.3.3.rbi +230 -0
- data/sorbet/rbi/gems/ostruct@0.6.2.rbi +354 -0
- data/sorbet/rbi/gems/parallel@1.27.0.rbi +291 -0
- data/sorbet/rbi/gems/parser@3.3.8.0.rbi +5535 -0
- data/sorbet/rbi/gems/prism@1.4.0.rbi +41732 -0
- data/sorbet/rbi/gems/pry@0.15.2.rbi +9 -0
- data/sorbet/rbi/gems/public_suffix@6.0.2.rbi +936 -0
- data/sorbet/rbi/gems/racc@1.8.1.rbi +158 -0
- data/sorbet/rbi/gems/rack@2.2.17.rbi +5659 -0
- data/sorbet/rbi/gems/rainbow@3.1.1.rbi +9 -0
- data/sorbet/rbi/gems/raix@1.0.2.rbi +1104 -0
- data/sorbet/rbi/gems/rake@13.3.0.rbi +3036 -0
- data/sorbet/rbi/gems/rb-fsevent@0.11.2.rbi +9 -0
- data/sorbet/rbi/gems/rb-inotify@0.11.1.rbi +9 -0
- data/sorbet/rbi/gems/rbi@0.3.6.rbi +6893 -0
- data/sorbet/rbi/gems/rbs@3.9.4.rbi +6978 -0
- data/sorbet/rbi/gems/regexp_parser@2.10.0.rbi +9 -0
- data/sorbet/rbi/gems/rexml@3.4.1.rbi +5346 -0
- data/sorbet/rbi/gems/rubocop-ast@1.45.1.rbi +9 -0
- data/sorbet/rbi/gems/rubocop-shopify@2.17.1.rbi +9 -0
- data/sorbet/rbi/gems/rubocop@1.77.0.rbi +9 -0
- data/sorbet/rbi/gems/ruby-graphviz@1.2.5.rbi +1333 -0
- data/sorbet/rbi/gems/ruby-openai@8.1.0.rbi +758 -0
- data/sorbet/rbi/gems/ruby-progressbar@1.13.0.rbi +9 -0
- data/sorbet/rbi/gems/ruby2_keywords@0.0.5.rbi +9 -0
- data/sorbet/rbi/gems/securerandom@0.4.1.rbi +75 -0
- data/sorbet/rbi/gems/shellany@0.0.1.rbi +102 -0
- data/sorbet/rbi/gems/spoom@1.6.3.rbi +6985 -0
- data/sorbet/rbi/gems/sqlite3@2.7.0.rbi +1900 -0
- data/sorbet/rbi/gems/tapioca@0.16.11.rbi +3628 -0
- data/sorbet/rbi/gems/thor@1.4.0.rbi +4399 -0
- data/sorbet/rbi/gems/tzinfo@2.0.6.rbi +5918 -0
- data/sorbet/rbi/gems/unicode-display_width@3.1.4.rbi +9 -0
- data/sorbet/rbi/gems/unicode-emoji@4.0.4.rbi +9 -0
- data/sorbet/rbi/gems/uri@1.0.3.rbi +2349 -0
- data/sorbet/rbi/gems/vcr@6.3.1.rbi +3040 -0
- data/sorbet/rbi/gems/webmock@3.25.1.rbi +1792 -0
- data/sorbet/rbi/gems/yard-sorbet@0.9.0.rbi +435 -0
- data/sorbet/rbi/gems/yard@0.9.37.rbi +18492 -0
- data/sorbet/rbi/gems/zeitwerk@2.7.3.rbi +1429 -0
- data/sorbet/tapioca/config.yml +13 -0
- data/sorbet/tapioca/require.rb +36 -0
- metadata +114 -2
- data/lib/roast/workflow/configuration_parser.rb +0 -54
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1b30690bd6345f217ff752e69865abf269792917e6463bbb70745a812ec15a4b
|
4
|
+
data.tar.gz: de3732ccd3322fb8ff782d10e52168e0e4292fdb21596ff0eff7201532498c8d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ba81d35b6484ffbdb3bb5aaed1baacbbc684033e62df23131c6d0bcb7833bc0902600f84a462fb451213d56c43862e49e8db5bfd150fb4a7520b66cd1e078d85
|
7
|
+
data.tar.gz: 01b3d585d72528c5d8382a13edd379f6af249d75059564adb8eb33671b2dfb252749a09f8e2d8a551b09fad048b735960fcf8f2cf37d1c0f1d06aa758feee50d
|
data/.github/CODEOWNERS
ADDED
data/.github/workflows/ci.yaml
CHANGED
data/.gitignore
CHANGED
@@ -13,32 +13,6 @@
|
|
13
13
|
**/CLAUDE.local.md
|
14
14
|
.roast/
|
15
15
|
|
16
|
-
bin/_guard-core
|
17
|
-
bin/bundle
|
18
|
-
bin/coderay
|
19
|
-
bin/dotenv
|
20
|
-
bin/erb
|
21
|
-
bin/guard
|
22
|
-
bin/htmldiff
|
23
|
-
bin/irb
|
24
|
-
bin/ldiff
|
25
|
-
bin/listen
|
26
|
-
bin/pry
|
27
|
-
bin/racc
|
28
|
-
bin/rake
|
29
|
-
bin/rbs
|
30
|
-
bin/rdbg
|
31
|
-
bin/rdoc
|
32
|
-
bin/ri
|
33
|
-
bin/rubocop
|
34
|
-
bin/ruby-lsp
|
35
|
-
bin/ruby-lsp-check
|
36
|
-
bin/ruby-lsp-launcher
|
37
|
-
bin/ruby-lsp-test-exec
|
38
|
-
bin/ruby-parse
|
39
|
-
bin/ruby-rewrite
|
40
|
-
bin/thor
|
41
|
-
|
42
16
|
gemfiles/*.lock
|
43
17
|
bin/claude-swarm
|
44
18
|
*.gem
|
data/.rubocop.yml
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
inherit_from: .rubocop_todo.yml
|
2
|
+
|
3
|
+
plugins:
|
4
|
+
- rubocop-sorbet
|
5
|
+
|
1
6
|
inherit_gem:
|
2
7
|
rubocop-shopify: rubocop.yml
|
3
8
|
|
@@ -10,3 +15,11 @@ AllCops:
|
|
10
15
|
SuggestExtensions: false
|
11
16
|
TargetRubyVersion: 3.4
|
12
17
|
UseCache: true
|
18
|
+
|
19
|
+
Sorbet/FalseSigil:
|
20
|
+
Enabled: true
|
21
|
+
Include:
|
22
|
+
- "lib/**/*.rb"
|
23
|
+
Exclude:
|
24
|
+
- "test/**/*"
|
25
|
+
- "examples/**/*"
|
data/.rubocop_todo.yml
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2025-08-17 17:40:01 UTC using RuboCop version 1.77.0.
|
4
|
+
# The point is for the user to remove these configuration records
|
5
|
+
# one by one as the offenses are removed from the code base.
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
8
|
+
|
9
|
+
# Offense count: 4
|
10
|
+
Sorbet/ConstantsFromStrings:
|
11
|
+
Exclude:
|
12
|
+
- 'lib/roast/helpers/logger.rb'
|
13
|
+
- 'lib/roast/workflow/step_loader.rb'
|
14
|
+
- 'lib/roast/workflow/validators/dependency_validator.rb'
|
15
|
+
- 'lib/roast/workflow/workflow_initializer.rb'
|
16
|
+
|
17
|
+
# Offense count: 1
|
18
|
+
# This cop supports safe autocorrection (--autocorrect).
|
19
|
+
Sorbet/SelectByIsA:
|
20
|
+
Exclude:
|
21
|
+
- 'lib/roast/workflow/configuration_loader.rb'
|
data/CHANGELOG.md
CHANGED
@@ -5,6 +5,43 @@ 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.6]
|
9
|
+
|
10
|
+
### Added
|
11
|
+
- Step retries
|
12
|
+
|
13
|
+
### Fixed
|
14
|
+
- Tokens containing whitespace
|
15
|
+
|
16
|
+
## [0.4.5]
|
17
|
+
|
18
|
+
### Added
|
19
|
+
- **Sorbet static type checking** (#359, #360, #362)
|
20
|
+
- Initial setup of Sorbet for static type analysis
|
21
|
+
- Added `bin/srb tc` command for type checking
|
22
|
+
- Gradually adding type signatures to improve code safety and navigation
|
23
|
+
- Fixed invalid constants that were undefined and never reached
|
24
|
+
- Added to CI pipeline for continuous type checking
|
25
|
+
- **Workflow name in step event payloads** (#333, #351)
|
26
|
+
- Added `workflow_name` field to all step-related ActiveSupport::Notification events
|
27
|
+
- Enables better tracking of which workflow a step belongs to in monitoring systems
|
28
|
+
- Updated events: `roast.step.start`, `roast.step.complete`, `roast.step.error`
|
29
|
+
|
30
|
+
### Changed
|
31
|
+
- **Improved error output formatting** (#358)
|
32
|
+
- Error messages now show concise output by default (just the error message)
|
33
|
+
- Full exception details and stack traces only shown in verbose mode (`-v`)
|
34
|
+
- Makes error output cleaner and more user-friendly
|
35
|
+
- **Consolidated workflow runner architecture** (#355)
|
36
|
+
- Merged ConfigurationParser functionality into WorkflowRunner for better cohesion
|
37
|
+
- Simplified the codebase by removing redundant abstraction layers
|
38
|
+
|
39
|
+
### Fixed
|
40
|
+
- **Removed duplicated pre/post processing code** (#357)
|
41
|
+
- Extracted common pre/post processing logic from individual step executors
|
42
|
+
- Eliminated code duplication across different step types
|
43
|
+
- Improved maintainability and consistency
|
44
|
+
|
8
45
|
## [0.4.3] - 2025-07-10
|
9
46
|
|
10
47
|
### Changed
|
data/Gemfile
CHANGED
@@ -15,8 +15,12 @@ gem "guard-minitest"
|
|
15
15
|
gem "mocha"
|
16
16
|
gem "rake", require: false
|
17
17
|
gem "rubocop-shopify", require: false
|
18
|
+
gem "rubocop-sorbet", require: false
|
18
19
|
gem "vcr", require: false
|
19
20
|
gem "webmock", require: false
|
20
21
|
gem "minitest-rg"
|
21
22
|
|
23
|
+
gem "sorbet", require: false
|
24
|
+
gem "tapioca", require: false
|
25
|
+
|
22
26
|
gem "claude_swarm"
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
roast-ai (0.4.
|
4
|
+
roast-ai (0.4.6)
|
5
5
|
activesupport (>= 7.0)
|
6
6
|
cli-kit (~> 5.0)
|
7
7
|
cli-ui (= 2.3.0)
|
@@ -81,6 +81,7 @@ GEM
|
|
81
81
|
dry-inflector (~> 1.0)
|
82
82
|
dry-logic (~> 1.4)
|
83
83
|
zeitwerk (~> 2.6)
|
84
|
+
erubi (1.13.1)
|
84
85
|
event_stream_parser (1.0.0)
|
85
86
|
faraday (2.13.1)
|
86
87
|
faraday-net_http (>= 2.0, < 3.5)
|
@@ -145,6 +146,7 @@ GEM
|
|
145
146
|
nenv (0.3.0)
|
146
147
|
net-http (0.6.0)
|
147
148
|
uri
|
149
|
+
netrc (0.11.0)
|
148
150
|
notiffany (0.1.3)
|
149
151
|
nenv (~> 0.1)
|
150
152
|
shellany (~> 0.0)
|
@@ -176,6 +178,11 @@ GEM
|
|
176
178
|
rb-fsevent (0.11.2)
|
177
179
|
rb-inotify (0.11.1)
|
178
180
|
ffi (~> 1.0)
|
181
|
+
rbi (0.3.6)
|
182
|
+
prism (~> 1.0)
|
183
|
+
rbs (>= 3.4.4)
|
184
|
+
rbs (3.9.4)
|
185
|
+
logger
|
179
186
|
regexp_parser (2.10.0)
|
180
187
|
rexml (3.4.1)
|
181
188
|
rubocop (1.77.0)
|
@@ -194,6 +201,9 @@ GEM
|
|
194
201
|
prism (~> 1.4)
|
195
202
|
rubocop-shopify (2.17.1)
|
196
203
|
rubocop (~> 1.62)
|
204
|
+
rubocop-sorbet (0.10.5)
|
205
|
+
lint_roller
|
206
|
+
rubocop (>= 1.75.2)
|
197
207
|
ruby-graphviz (1.2.5)
|
198
208
|
rexml
|
199
209
|
ruby-openai (8.1.0)
|
@@ -204,8 +214,33 @@ GEM
|
|
204
214
|
ruby2_keywords (0.0.5)
|
205
215
|
securerandom (0.4.1)
|
206
216
|
shellany (0.0.1)
|
217
|
+
sorbet (0.5.12414)
|
218
|
+
sorbet-static (= 0.5.12414)
|
219
|
+
sorbet-runtime (0.5.12414)
|
220
|
+
sorbet-static (0.5.12414-universal-darwin)
|
221
|
+
sorbet-static (0.5.12414-x86_64-linux)
|
222
|
+
sorbet-static-and-runtime (0.5.12414)
|
223
|
+
sorbet (= 0.5.12414)
|
224
|
+
sorbet-runtime (= 0.5.12414)
|
225
|
+
spoom (1.6.3)
|
226
|
+
erubi (>= 1.10.0)
|
227
|
+
prism (>= 0.28.0)
|
228
|
+
rbi (>= 0.3.3)
|
229
|
+
rexml (>= 3.2.6)
|
230
|
+
sorbet-static-and-runtime (>= 0.5.10187)
|
231
|
+
thor (>= 0.19.2)
|
207
232
|
sqlite3 (2.7.0-arm64-darwin)
|
208
233
|
sqlite3 (2.7.0-x86_64-linux-gnu)
|
234
|
+
tapioca (0.16.11)
|
235
|
+
benchmark
|
236
|
+
bundler (>= 2.2.25)
|
237
|
+
netrc (>= 0.11.0)
|
238
|
+
parallel (>= 1.21.0)
|
239
|
+
rbi (~> 0.2)
|
240
|
+
sorbet-static-and-runtime (>= 0.5.11087)
|
241
|
+
spoom (>= 1.2.0)
|
242
|
+
thor (>= 1.2.0)
|
243
|
+
yard-sorbet
|
209
244
|
thor (1.4.0)
|
210
245
|
tzinfo (2.0.6)
|
211
246
|
concurrent-ruby (~> 1.0)
|
@@ -219,6 +254,10 @@ GEM
|
|
219
254
|
addressable (>= 2.8.0)
|
220
255
|
crack (>= 0.3.2)
|
221
256
|
hashdiff (>= 0.4.0, < 2.0.0)
|
257
|
+
yard (0.9.37)
|
258
|
+
yard-sorbet (0.9.0)
|
259
|
+
sorbet-runtime
|
260
|
+
yard
|
222
261
|
zeitwerk (2.7.3)
|
223
262
|
|
224
263
|
PLATFORMS
|
@@ -237,6 +276,9 @@ DEPENDENCIES
|
|
237
276
|
rake
|
238
277
|
roast-ai!
|
239
278
|
rubocop-shopify
|
279
|
+
rubocop-sorbet
|
280
|
+
sorbet
|
281
|
+
tapioca
|
240
282
|
vcr
|
241
283
|
webmock
|
242
284
|
|
data/bin/rubocop
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'rubocop' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
|
12
|
+
|
13
|
+
bundle_binstub = File.expand_path("bundle", __dir__)
|
14
|
+
|
15
|
+
if File.file?(bundle_binstub)
|
16
|
+
if File.read(bundle_binstub, 300).include?("This file was generated by Bundler")
|
17
|
+
load(bundle_binstub)
|
18
|
+
else
|
19
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
20
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
require "rubygems"
|
25
|
+
require "bundler/setup"
|
26
|
+
|
27
|
+
load Gem.bin_path("rubocop", "rubocop")
|
data/bin/spoom
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'spoom' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
|
12
|
+
|
13
|
+
bundle_binstub = File.expand_path("bundle", __dir__)
|
14
|
+
|
15
|
+
if File.file?(bundle_binstub)
|
16
|
+
if File.read(bundle_binstub, 300).include?("This file was generated by Bundler")
|
17
|
+
load(bundle_binstub)
|
18
|
+
else
|
19
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
20
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
require "rubygems"
|
25
|
+
require "bundler/setup"
|
26
|
+
|
27
|
+
load Gem.bin_path("spoom", "spoom")
|
data/bin/srb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'srb' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
|
12
|
+
|
13
|
+
bundle_binstub = File.expand_path("bundle", __dir__)
|
14
|
+
|
15
|
+
if File.file?(bundle_binstub)
|
16
|
+
if File.read(bundle_binstub, 300).include?("This file was generated by Bundler")
|
17
|
+
load(bundle_binstub)
|
18
|
+
else
|
19
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
20
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
require "rubygems"
|
25
|
+
require "bundler/setup"
|
26
|
+
|
27
|
+
load Gem.bin_path("sorbet", "srb")
|
data/bin/srb-rbi
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'srb-rbi' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
|
12
|
+
|
13
|
+
bundle_binstub = File.expand_path("bundle", __dir__)
|
14
|
+
|
15
|
+
if File.file?(bundle_binstub)
|
16
|
+
if File.read(bundle_binstub, 300).include?("This file was generated by Bundler")
|
17
|
+
load(bundle_binstub)
|
18
|
+
else
|
19
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
20
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
require "rubygems"
|
25
|
+
require "bundler/setup"
|
26
|
+
|
27
|
+
load Gem.bin_path("sorbet", "srb-rbi")
|
data/bin/tapioca
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'tapioca' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
|
12
|
+
|
13
|
+
bundle_binstub = File.expand_path("bundle", __dir__)
|
14
|
+
|
15
|
+
if File.file?(bundle_binstub)
|
16
|
+
if File.read(bundle_binstub, 300).include?("This file was generated by Bundler")
|
17
|
+
load(bundle_binstub)
|
18
|
+
else
|
19
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
20
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
require "rubygems"
|
25
|
+
require "bundler/setup"
|
26
|
+
|
27
|
+
load Gem.bin_path("tapioca", "tapioca")
|
data/docs/INSTRUMENTATION.md
CHANGED
@@ -39,13 +39,13 @@ your-project/
|
|
39
39
|
### Step Events
|
40
40
|
|
41
41
|
- `roast.step.start` - Emitted when a step begins execution
|
42
|
-
- Payload: `{ step_name: }`
|
42
|
+
- Payload: `{ step_name:, resource_type:, workflow_name: }`
|
43
43
|
|
44
44
|
- `roast.step.complete` - Emitted when a step completes successfully
|
45
|
-
- Payload: `{ step_name:, success: true, execution_time:, result_size: }`
|
45
|
+
- Payload: `{ step_name:, resource_type:, workflow_name:, success: true, execution_time:, result_size: }`
|
46
46
|
|
47
47
|
- `roast.step.error` - Emitted when a step encounters an error
|
48
|
-
- Payload: `{ step_name:, error:, message:, execution_time: }`
|
48
|
+
- Payload: `{ step_name:, resource_type:, workflow_name:, error:, message:, execution_time: }`
|
49
49
|
|
50
50
|
### AI/Chat Completion Events
|
51
51
|
|
data/dsl/simple.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
description: Demonstrate retry functionality for steps
|
2
|
+
|
3
|
+
# This example shows how to configure steps to automatically retry on failure
|
4
|
+
# The 'retries' parameter specifies how many times to retry a failing step
|
5
|
+
|
6
|
+
steps:
|
7
|
+
- check_network: "$(curl -f -s -o /dev/null -w '%{http_code}' https://httpstat.us/500)"
|
8
|
+
- process_data: "Process important data that might fail transiently"
|
9
|
+
- flaky_command: "$(./flaky_script.sh)"
|
10
|
+
|
11
|
+
# Configuration for each step
|
12
|
+
check_network:
|
13
|
+
retries: 3 # Will retry up to 3 times if it fails
|
14
|
+
exit_on_error: true # Will exit workflow if all retries fail
|
15
|
+
|
16
|
+
process_data:
|
17
|
+
model: gpt-4o-mini
|
18
|
+
retries: 2 # Will retry up to 2 times
|
19
|
+
|
20
|
+
# Command with retries but won't exit on error after all retries fail
|
21
|
+
flaky_command:
|
22
|
+
retries: 5
|
23
|
+
exit_on_error: false # Continue workflow even after all retries fail
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# typed: true
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Roast
|
5
|
+
module DSL
|
6
|
+
class Executor
|
7
|
+
class << self
|
8
|
+
def from_file(workflow_path)
|
9
|
+
execute(File.read(workflow_path))
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def execute(input)
|
15
|
+
new.instance_eval(input)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Define methods to be used in workflows below.
|
20
|
+
|
21
|
+
def shell(command_string)
|
22
|
+
puts %x(#{command_string})
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/roast/dsl.rb
ADDED
data/lib/roast/errors.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
|
+
# typed: true
|
1
2
|
# frozen_string_literal: true
|
2
3
|
|
3
4
|
module Roast
|
4
5
|
module Helpers
|
5
6
|
# Intercepts function dispatching to add caching capabilities
|
6
7
|
# This module wraps around Raix::FunctionDispatch to provide caching for tool functions
|
8
|
+
# @requires_ancestor: Kernel
|
9
|
+
# @requires_ancestor: Raix::ChatCompletion
|
7
10
|
module FunctionCachingInterceptor
|
8
11
|
def dispatch_tool_function(function_name, params)
|
9
12
|
start_time = Time.now
|
data/lib/roast/helpers/logger.rb
CHANGED
@@ -1,28 +1,25 @@
|
|
1
|
+
# typed: true
|
1
2
|
# frozen_string_literal: true
|
2
3
|
|
3
4
|
module Roast
|
4
5
|
module Helpers
|
5
6
|
# Central logger for the Roast application
|
6
7
|
class Logger
|
7
|
-
VALID_LOG_LEVELS = ["DEBUG", "INFO", "WARN", "ERROR", "FATAL"].freeze
|
8
|
+
VALID_LOG_LEVELS = ["DEBUG", "INFO", "WARN", "ERROR", "FATAL"].freeze #: Array[String]
|
8
9
|
|
9
|
-
|
10
|
+
delegate :debug, :info, :warn, :error, :fatal, to: :@logger
|
10
11
|
|
11
12
|
attr_reader :logger
|
12
13
|
|
13
14
|
class << self
|
14
|
-
|
15
|
+
delegate :debug, :info, :warn, :error, :fatal, to: :instance
|
15
16
|
|
17
|
+
#: -> Roast::Helpers::Logger
|
16
18
|
def instance
|
17
19
|
@instance ||= new
|
18
20
|
end
|
19
21
|
|
20
|
-
|
21
|
-
def warn(*args)
|
22
|
-
instance.warn(*args)
|
23
|
-
end
|
24
|
-
|
25
|
-
# For testing purposes
|
22
|
+
#: -> void
|
26
23
|
def reset
|
27
24
|
@instance = nil
|
28
25
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# typed: true
|
1
2
|
# frozen_string_literal: true
|
2
3
|
|
3
4
|
module Roast
|
@@ -38,17 +39,14 @@ module Roast
|
|
38
39
|
next if i == 0 # Skip the first segment
|
39
40
|
|
40
41
|
# Check if this segment appears earlier in the path
|
41
|
-
next unless path_parts[0...i]
|
42
|
+
next unless path_parts[0...i]&.include?(part)
|
42
43
|
|
43
44
|
# Create a new path without this segment
|
44
45
|
test_parts = path_parts.dup
|
45
46
|
test_parts.delete_at(i)
|
47
|
+
test_parts.prepend("/") if original_path.start_with?("/")
|
46
48
|
|
47
|
-
test_path =
|
48
|
-
File.join("/", *test_parts)
|
49
|
-
else
|
50
|
-
File.join(test_parts)
|
51
|
-
end
|
49
|
+
test_path = File.join(test_parts)
|
52
50
|
|
53
51
|
# If this path exists, return it
|
54
52
|
return test_path if File.exist?(test_path)
|
@@ -66,12 +64,8 @@ module Roast
|
|
66
64
|
filtered_parts = path_parts.dup
|
67
65
|
# Remove from end to beginning to keep indices valid
|
68
66
|
duplicate_indices.reverse_each { |idx| filtered_parts.delete_at(idx) }
|
69
|
-
|
70
|
-
test_path =
|
71
|
-
File.join("/", *filtered_parts)
|
72
|
-
else
|
73
|
-
File.join(filtered_parts)
|
74
|
-
end
|
67
|
+
filtered_parts.prepend("/") if original_path.start_with?("/")
|
68
|
+
test_path = File.join(filtered_parts)
|
75
69
|
|
76
70
|
return test_path if File.exist?(test_path)
|
77
71
|
end
|
@@ -93,12 +87,8 @@ module Roast
|
|
93
87
|
unique_parts = path_parts.dup
|
94
88
|
# Remove from end to beginning to keep indices valid
|
95
89
|
duplicate_indices.reverse_each { |i| unique_parts.delete_at(i) }
|
96
|
-
|
97
|
-
test_path =
|
98
|
-
File.join("/", *unique_parts)
|
99
|
-
else
|
100
|
-
File.join(unique_parts)
|
101
|
-
end
|
90
|
+
unique_parts.prepend("/") if original_path.start_with?("/")
|
91
|
+
test_path = File.join(unique_parts)
|
102
92
|
|
103
93
|
return test_path if File.exist?(test_path)
|
104
94
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# typed: true
|
1
2
|
# frozen_string_literal: true
|
2
3
|
|
3
4
|
module Roast
|
@@ -58,7 +59,7 @@ module Roast
|
|
58
59
|
glob_pattern = File.join(context_dir, "{#{base_name},prompt}.*+*.md")
|
59
60
|
Dir.glob(glob_pattern).each do |combined_path|
|
60
61
|
basename = File.basename(combined_path, ".md")
|
61
|
-
combined_exts = basename.split(".", 2)[1]
|
62
|
+
combined_exts = basename.split(".", 2)[1]&.split("+")
|
62
63
|
|
63
64
|
# Return the first matching combined format
|
64
65
|
return combined_path if extensions.intersect?(combined_exts)
|
@@ -77,7 +78,7 @@ module Roast
|
|
77
78
|
|
78
79
|
if file_basename.end_with?(".md") && file_basename.count(".") > 1
|
79
80
|
without_md = file_basename[0...-3] # Remove .md
|
80
|
-
without_md
|
81
|
+
without_md&.split(".", 2)&.[](1)&.split("+") || []
|
81
82
|
else
|
82
83
|
ext = File.extname(target_file)[1..]
|
83
84
|
ext&.empty? ? [] : [ext]
|
@@ -1,8 +1,6 @@
|
|
1
|
+
# typed: true
|
1
2
|
# frozen_string_literal: true
|
2
3
|
|
3
|
-
require "timeout"
|
4
|
-
require "open3"
|
5
|
-
|
6
4
|
module Roast
|
7
5
|
module Helpers
|
8
6
|
# Shared timeout handling logic for command-based tools
|
@@ -29,8 +27,8 @@ module Roast
|
|
29
27
|
def call(command, timeout: DEFAULT_TIMEOUT, working_directory: Dir.pwd)
|
30
28
|
timeout = validate_timeout(timeout)
|
31
29
|
output = ""
|
32
|
-
exit_status = nil
|
33
|
-
wait_thr = nil
|
30
|
+
exit_status = nil #: Integer?
|
31
|
+
wait_thr = nil #: Process::Waiter?
|
34
32
|
|
35
33
|
begin
|
36
34
|
Timeout.timeout(timeout) do
|
data/lib/roast/initializers.rb
CHANGED