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
|
@@ -0,0 +1,465 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Roast
|
|
5
|
+
module DSL
|
|
6
|
+
module Cogs
|
|
7
|
+
class Agent < Cog
|
|
8
|
+
class Config < Cog::Config
|
|
9
|
+
VALID_PROVIDERS = [:claude].freeze #: Array[Symbol]
|
|
10
|
+
|
|
11
|
+
# Configure the cog to use a specified provider when invoking an agent
|
|
12
|
+
#
|
|
13
|
+
# The provider is the source of the agent tool itself.
|
|
14
|
+
# If no provider is specified, Anthropic Claude Code (`:claude`) will be used as the default provider.
|
|
15
|
+
#
|
|
16
|
+
# A provider must be properly installed on your system in order for Roast to be able to use it.
|
|
17
|
+
#
|
|
18
|
+
# #### See Also
|
|
19
|
+
# - `use_default_provider!`
|
|
20
|
+
#
|
|
21
|
+
#: (Symbol) -> void
|
|
22
|
+
def provider(provider)
|
|
23
|
+
@values[:provider] = provider
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Configure the cog to use the default provider when invoking an agent
|
|
27
|
+
#
|
|
28
|
+
# The default provider used by Roast is Anthropic Claude Code (`:claude`).
|
|
29
|
+
#
|
|
30
|
+
# The provider must be properly installed on your system in order for Roast to be able to use it.
|
|
31
|
+
#
|
|
32
|
+
# #### See Also
|
|
33
|
+
# - `provider`
|
|
34
|
+
#
|
|
35
|
+
#: () -> void
|
|
36
|
+
def use_default_provider!
|
|
37
|
+
@values[:provider] = nil
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Get the validated provider name that the cog is configured to use when invoking an agent
|
|
41
|
+
#
|
|
42
|
+
# Note: this method will return the name of a valid provider or raise an `InvalidConfigError`.
|
|
43
|
+
# It will __not__, however, validate that the agent is properly installed on your system.
|
|
44
|
+
# If the agent is not properly installed, you will likely experience a failure when Roast attempts to
|
|
45
|
+
# run your workflow.
|
|
46
|
+
#
|
|
47
|
+
# #### See Also
|
|
48
|
+
# - `provider`
|
|
49
|
+
# - `use_default_provider!`
|
|
50
|
+
#
|
|
51
|
+
#: () -> Symbol
|
|
52
|
+
def valid_provider!
|
|
53
|
+
provider = @values[:provider] || VALID_PROVIDERS.first
|
|
54
|
+
unless VALID_PROVIDERS.include?(provider)
|
|
55
|
+
raise ArgumentError, "'#{provider}' is not a valid provider. Available providers include: #{VALID_PROVIDERS.join(", ")}"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
provider
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Configure the cog to use a specific base command when invoking the agent
|
|
62
|
+
#
|
|
63
|
+
# The command format is provider-specific.
|
|
64
|
+
#
|
|
65
|
+
# #### See Also
|
|
66
|
+
# - `use_default_command!`
|
|
67
|
+
#
|
|
68
|
+
#: (String | Array[String]) -> void
|
|
69
|
+
def command(command)
|
|
70
|
+
@values[:command] = command
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Configure the cog to use the provider's default command when invoking the agent
|
|
74
|
+
#
|
|
75
|
+
# Note: the default command will be different for different providers.
|
|
76
|
+
#
|
|
77
|
+
# #### See Also
|
|
78
|
+
# - `command`
|
|
79
|
+
#
|
|
80
|
+
#: () -> void
|
|
81
|
+
def use_default_command!
|
|
82
|
+
@values[:command] = nil
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Get the validated, configured value of the command the cog is configured to use when running the agent
|
|
86
|
+
#
|
|
87
|
+
# Returns `nil` if the provider should use its own default command, however that is configured.
|
|
88
|
+
#
|
|
89
|
+
# #### See Also
|
|
90
|
+
# - `command`
|
|
91
|
+
# - `use_default_command!`
|
|
92
|
+
#
|
|
93
|
+
#: () -> (String | Array[String])?
|
|
94
|
+
def valid_command
|
|
95
|
+
@values[:command].presence
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Configure the cog to use a specific model when invoking the agent
|
|
99
|
+
#
|
|
100
|
+
# The model name format is provider-specific.
|
|
101
|
+
#
|
|
102
|
+
# #### See Also
|
|
103
|
+
# - `use_default_model!`
|
|
104
|
+
#
|
|
105
|
+
#: (String) -> void
|
|
106
|
+
def model(model)
|
|
107
|
+
@values[:model] = model
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Configure the cog to use the provider's default model when invoking the agent
|
|
111
|
+
#
|
|
112
|
+
# Note: the default model will be different for different providers.
|
|
113
|
+
#
|
|
114
|
+
# #### See Also
|
|
115
|
+
# - `model`
|
|
116
|
+
#
|
|
117
|
+
#: () -> void
|
|
118
|
+
def use_default_model!
|
|
119
|
+
@values[:model] = nil
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Get the validated, configured value of the model the cog is configured to use when running the agent
|
|
123
|
+
#
|
|
124
|
+
# Returns `nil` if the provider should use its own default model, however that is configured.
|
|
125
|
+
#
|
|
126
|
+
# #### See Also
|
|
127
|
+
# - `model`
|
|
128
|
+
# - `use_default_model!`
|
|
129
|
+
#
|
|
130
|
+
#: () -> String?
|
|
131
|
+
def valid_model
|
|
132
|
+
@values[:model].presence
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# Configure the cog with an initial prompt component that will be appended to the agent's system prompt
|
|
136
|
+
# every time the agent is invoked
|
|
137
|
+
#
|
|
138
|
+
# #### See Also
|
|
139
|
+
# - `no_initial_prompt!`
|
|
140
|
+
#
|
|
141
|
+
#: (String) -> void
|
|
142
|
+
def initial_prompt(prompt)
|
|
143
|
+
@values[:initial_prompt] = prompt
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# Configure the cog __not__ to append an initial prompt to the agent's system prompt when the agent is invoked
|
|
147
|
+
#
|
|
148
|
+
# #### See Also
|
|
149
|
+
# - `initial_prompt`
|
|
150
|
+
#
|
|
151
|
+
#: () -> void
|
|
152
|
+
def no_initial_prompt!
|
|
153
|
+
@values[:initial_prompt] = ""
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# Get the validated, configured initial prompt that will be appended to the agent's system prompt when
|
|
157
|
+
# the agent is invoked
|
|
158
|
+
#
|
|
159
|
+
# Returns `nil` if __no__ prompt should be appended.
|
|
160
|
+
#
|
|
161
|
+
# #### See Also
|
|
162
|
+
# - `initial_prompt`
|
|
163
|
+
# - `no_initial_prompt!`
|
|
164
|
+
#
|
|
165
|
+
#: () -> String?
|
|
166
|
+
def valid_initial_prompt
|
|
167
|
+
@values[:initial_prompt].presence
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# Configure the cog to apply the default set of system and user permissions when running the agent
|
|
171
|
+
#
|
|
172
|
+
# How these permissions are defined and configured is specific to the agent provider being used.
|
|
173
|
+
#
|
|
174
|
+
# The cog's default behaviour is to run with __no__ permissions.
|
|
175
|
+
#
|
|
176
|
+
# #### Alias Methods
|
|
177
|
+
# - `apply_permissions!`
|
|
178
|
+
# - `no_skip_permissions!`
|
|
179
|
+
#
|
|
180
|
+
# #### Inverse Methods
|
|
181
|
+
# - `no_apply_permissions!`
|
|
182
|
+
# - `skip_permissions!`
|
|
183
|
+
#
|
|
184
|
+
#: () -> void
|
|
185
|
+
def apply_permissions!
|
|
186
|
+
@values[:apply_permissions] = true
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
# Configure the cog to run the agent with __no__ permissions applied
|
|
190
|
+
#
|
|
191
|
+
# The cog's default behaviour is to run with __no__ permissions.
|
|
192
|
+
#
|
|
193
|
+
# #### Alias Methods
|
|
194
|
+
# - `no_apply_permissions!`
|
|
195
|
+
# - `skip_permissions!`
|
|
196
|
+
#
|
|
197
|
+
# #### Inverse Methods
|
|
198
|
+
# - `apply_permissions!`
|
|
199
|
+
# - `no_skip_permissions!`
|
|
200
|
+
#
|
|
201
|
+
#: () -> void
|
|
202
|
+
def no_apply_permissions!
|
|
203
|
+
@values[:apply_permissions] = false
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
# Check if the cog is configured to apply permissions when running the agent
|
|
207
|
+
#
|
|
208
|
+
# #### See Also
|
|
209
|
+
# - `apply_permissions!`
|
|
210
|
+
# - `no_apply_permissions!`
|
|
211
|
+
# - `skip_permissions!`
|
|
212
|
+
# - `no_skip_permissions!`
|
|
213
|
+
#
|
|
214
|
+
#: () -> bool
|
|
215
|
+
def apply_permissions?
|
|
216
|
+
!!@values[:apply_permissions]
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
# Configure the cog to display the prompt when running the agent
|
|
220
|
+
#
|
|
221
|
+
# Disabled by default.
|
|
222
|
+
#
|
|
223
|
+
# #### See Also
|
|
224
|
+
# - `no_show_prompt!`
|
|
225
|
+
# - `show_prompt?`
|
|
226
|
+
# - `display!`
|
|
227
|
+
#
|
|
228
|
+
#: () -> void
|
|
229
|
+
def show_prompt!
|
|
230
|
+
@values[:show_prompt] = true
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
# Configure the cog __not__ to display the prompt when running the agent
|
|
234
|
+
#
|
|
235
|
+
# This is the default behaviour.
|
|
236
|
+
#
|
|
237
|
+
# #### See Also
|
|
238
|
+
# - `show_prompt!`
|
|
239
|
+
# - `show_prompt?`
|
|
240
|
+
# - `no_display!`
|
|
241
|
+
# - `quiet!`
|
|
242
|
+
#
|
|
243
|
+
#: () -> void
|
|
244
|
+
def no_show_prompt!
|
|
245
|
+
@values[:show_prompt] = false
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
# Check if the cog is configured to display the prompt when running the agent
|
|
249
|
+
#
|
|
250
|
+
# #### See Also
|
|
251
|
+
# - `show_prompt!`
|
|
252
|
+
# - `no_show_prompt!`
|
|
253
|
+
#
|
|
254
|
+
#: () -> bool
|
|
255
|
+
def show_prompt?
|
|
256
|
+
@values.fetch(:show_prompt, false)
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
# Configure the cog to display the agent's in-progress messages when running
|
|
260
|
+
#
|
|
261
|
+
# This includes thinking blocks and other intermediate output from the agent.
|
|
262
|
+
# Enabled by default.
|
|
263
|
+
#
|
|
264
|
+
# #### See Also
|
|
265
|
+
# - `no_show_progress!`
|
|
266
|
+
# - `show_progress?`
|
|
267
|
+
# - `display!`
|
|
268
|
+
#
|
|
269
|
+
#: () -> void
|
|
270
|
+
def show_progress!
|
|
271
|
+
@values[:show_progress] = true
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
# Configure the cog __not__ to display the agent's in-progress messages when running
|
|
275
|
+
#
|
|
276
|
+
# This will hide thinking blocks and other intermediate output from the agent.
|
|
277
|
+
#
|
|
278
|
+
# #### See Also
|
|
279
|
+
# - `show_progress!`
|
|
280
|
+
# - `show_progress?`
|
|
281
|
+
# - `no_display!`
|
|
282
|
+
# - `quiet!`
|
|
283
|
+
#
|
|
284
|
+
#: () -> void
|
|
285
|
+
def no_show_progress!
|
|
286
|
+
@values[:show_progress] = false
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
# Check if the cog is configured to display the agent's in-progress messages when running
|
|
290
|
+
#
|
|
291
|
+
# #### See Also
|
|
292
|
+
# - `show_progress!`
|
|
293
|
+
# - `no_show_progress!`
|
|
294
|
+
#
|
|
295
|
+
#: () -> bool
|
|
296
|
+
def show_progress?
|
|
297
|
+
@values.fetch(:show_progress, true)
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
# Configure the cog to display the agent's final response
|
|
301
|
+
#
|
|
302
|
+
# Enabled by default.
|
|
303
|
+
#
|
|
304
|
+
# #### See Also
|
|
305
|
+
# - `no_show_response!`
|
|
306
|
+
# - `show_response?`
|
|
307
|
+
# - `display!`
|
|
308
|
+
#
|
|
309
|
+
#: () -> void
|
|
310
|
+
def show_response!
|
|
311
|
+
@values[:show_response] = true
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
# Configure the cog __not__ to display the agent's final response
|
|
315
|
+
#
|
|
316
|
+
# #### See Also
|
|
317
|
+
# - `show_response!`
|
|
318
|
+
# - `show_response?`
|
|
319
|
+
# - `no_display!`
|
|
320
|
+
# - `quiet!`
|
|
321
|
+
#
|
|
322
|
+
#: () -> void
|
|
323
|
+
def no_show_response!
|
|
324
|
+
@values[:show_response] = false
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
# Check if the cog is configured to display the agent's final response
|
|
328
|
+
#
|
|
329
|
+
# #### See Also
|
|
330
|
+
# - `show_response!`
|
|
331
|
+
# - `no_show_response!`
|
|
332
|
+
#
|
|
333
|
+
#: () -> bool
|
|
334
|
+
def show_response?
|
|
335
|
+
@values.fetch(:show_response, true)
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
# Configure the cog to display statistics about the agent's operation
|
|
339
|
+
#
|
|
340
|
+
# Enabled by default.
|
|
341
|
+
#
|
|
342
|
+
# #### See Also
|
|
343
|
+
# - `no_show_stats!`
|
|
344
|
+
# - `show_stats?`
|
|
345
|
+
# - `display!`
|
|
346
|
+
#
|
|
347
|
+
#: () -> void
|
|
348
|
+
def show_stats!
|
|
349
|
+
@values[:show_stats] = true
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
# Configure the cog __not__ to display statistics about the agent's operation
|
|
353
|
+
#
|
|
354
|
+
# #### See Also
|
|
355
|
+
# - `show_stats!`
|
|
356
|
+
# - `show_stats?`
|
|
357
|
+
# - `no_display!`
|
|
358
|
+
# - `quiet!`
|
|
359
|
+
#
|
|
360
|
+
#: () -> void
|
|
361
|
+
def no_show_stats!
|
|
362
|
+
@values[:show_stats] = false
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
# Check if the cog is configured to display statistics about the agent's operation
|
|
366
|
+
#
|
|
367
|
+
# #### See Also
|
|
368
|
+
# - `show_stats!`
|
|
369
|
+
# - `no_show_stats!`
|
|
370
|
+
#
|
|
371
|
+
#: () -> bool
|
|
372
|
+
def show_stats?
|
|
373
|
+
@values.fetch(:show_stats, true)
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
# Configure the cog to display all agent output
|
|
377
|
+
#
|
|
378
|
+
# This enables `show_prompt!`, `show_progress!`, `show_response!`, and `show_stats!`.
|
|
379
|
+
#
|
|
380
|
+
# #### See Also
|
|
381
|
+
# - `no_display!`
|
|
382
|
+
# - `quiet!`
|
|
383
|
+
# - `show_prompt!`
|
|
384
|
+
# - `show_progress!`
|
|
385
|
+
# - `show_response!`
|
|
386
|
+
# - `show_stats!`
|
|
387
|
+
#
|
|
388
|
+
#: () -> void
|
|
389
|
+
def display!
|
|
390
|
+
show_prompt!
|
|
391
|
+
show_progress!
|
|
392
|
+
show_response!
|
|
393
|
+
show_stats!
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
# Configure the cog to __hide__ all agent output
|
|
397
|
+
#
|
|
398
|
+
# This enables `no_show_prompt!`, `no_show_progress!`, `no_show_response!`, `no_show_stats!`.
|
|
399
|
+
#
|
|
400
|
+
# #### Alias Methods
|
|
401
|
+
# - `no_display!`
|
|
402
|
+
# - `quiet!`
|
|
403
|
+
#
|
|
404
|
+
# #### See Also
|
|
405
|
+
# - `display!`
|
|
406
|
+
# - `quiet!`
|
|
407
|
+
# - `no_show_prompt!`
|
|
408
|
+
# - `no_show_progress!`
|
|
409
|
+
# - `no_show_response!`
|
|
410
|
+
# - `no_show_stats!`
|
|
411
|
+
#
|
|
412
|
+
#: () -> void
|
|
413
|
+
def no_display!
|
|
414
|
+
no_show_prompt!
|
|
415
|
+
no_show_progress!
|
|
416
|
+
no_show_response!
|
|
417
|
+
no_show_stats!
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
# Check if the cog is configured to display any output while running
|
|
421
|
+
#
|
|
422
|
+
# #### See Also
|
|
423
|
+
# - `show_prompt?`
|
|
424
|
+
# - `show_progress?`
|
|
425
|
+
# - `show_response?`
|
|
426
|
+
# - `show_stats?`
|
|
427
|
+
#
|
|
428
|
+
#: () -> bool
|
|
429
|
+
def display?
|
|
430
|
+
show_prompt? || show_progress? || show_response? || show_stats?
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
# Configure the cog to dump raw messages received from the agent process to a file
|
|
434
|
+
#
|
|
435
|
+
# This is intended for development and debugging purposes to inspect the raw message stream
|
|
436
|
+
# from the agent provider.
|
|
437
|
+
#
|
|
438
|
+
#: (String) -> void
|
|
439
|
+
def dump_raw_agent_messages_to(filename)
|
|
440
|
+
@values[:dump_raw_agent_messages_to] = filename
|
|
441
|
+
end
|
|
442
|
+
|
|
443
|
+
# Get the validated, configured path to which raw agent messages should be dumped
|
|
444
|
+
#
|
|
445
|
+
# Returns `nil` if no path has been configured.
|
|
446
|
+
#
|
|
447
|
+
# This is intended for development and debugging purposes to inspect the raw message stream
|
|
448
|
+
# from the agent provider.
|
|
449
|
+
#
|
|
450
|
+
# #### See Also
|
|
451
|
+
# - `dump_raw_agent_messages_to`
|
|
452
|
+
#
|
|
453
|
+
#: () -> Pathname?
|
|
454
|
+
def valid_dump_raw_agent_messages_to_path
|
|
455
|
+
Pathname.new(@values[:dump_raw_agent_messages_to]) if @values[:dump_raw_agent_messages_to]
|
|
456
|
+
end
|
|
457
|
+
|
|
458
|
+
alias_method(:skip_permissions!, :no_apply_permissions!)
|
|
459
|
+
alias_method(:no_skip_permissions!, :apply_permissions!)
|
|
460
|
+
alias_method(:quiet!, :no_display!)
|
|
461
|
+
end
|
|
462
|
+
end
|
|
463
|
+
end
|
|
464
|
+
end
|
|
465
|
+
end
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Roast
|
|
5
|
+
module DSL
|
|
6
|
+
module Cogs
|
|
7
|
+
class Agent < Cog
|
|
8
|
+
# Input specification for the agent cog
|
|
9
|
+
#
|
|
10
|
+
# The agent cog requires a prompt that will be sent to the agent for processing.
|
|
11
|
+
# Optionally, a session identifier can be provided to maintain context across multiple invocations.
|
|
12
|
+
class Input < Cog::Input
|
|
13
|
+
# The prompt to send to the agent for processing
|
|
14
|
+
#
|
|
15
|
+
#: String?
|
|
16
|
+
attr_accessor :prompt
|
|
17
|
+
|
|
18
|
+
# Optional session identifier for maintaining conversation context
|
|
19
|
+
#
|
|
20
|
+
# When provided, the agent will use this session to maintain context across
|
|
21
|
+
# multiple invocations, allowing for conversational interactions.
|
|
22
|
+
#
|
|
23
|
+
# The agent will fork a new session from this point, so multiple agents can resume from the
|
|
24
|
+
# same session state.
|
|
25
|
+
#
|
|
26
|
+
#: String?
|
|
27
|
+
attr_accessor :session
|
|
28
|
+
|
|
29
|
+
#: () -> void
|
|
30
|
+
def initialize
|
|
31
|
+
super
|
|
32
|
+
@prompt = nil #: String?
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Validate that the input has all required parameters
|
|
36
|
+
#
|
|
37
|
+
# This method ensures that a prompt has been provided before the agent executes.
|
|
38
|
+
#
|
|
39
|
+
# #### See Also
|
|
40
|
+
# - `coerce`
|
|
41
|
+
# - `valid_prompt!`
|
|
42
|
+
#
|
|
43
|
+
#: () -> void
|
|
44
|
+
def validate!
|
|
45
|
+
valid_prompt!
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Coerce the input from the return value of the input block
|
|
49
|
+
#
|
|
50
|
+
# If the input block returns a String, it will be used as the prompt value.
|
|
51
|
+
#
|
|
52
|
+
# #### See Also
|
|
53
|
+
# - `validate!`
|
|
54
|
+
#
|
|
55
|
+
#: (untyped) -> void
|
|
56
|
+
def coerce(input_return_value)
|
|
57
|
+
if input_return_value.is_a?(String)
|
|
58
|
+
self.prompt ||= input_return_value
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Get the validated prompt value
|
|
63
|
+
#
|
|
64
|
+
# Returns the prompt if it is present, otherwise raises an `InvalidInputError`.
|
|
65
|
+
#
|
|
66
|
+
# #### See Also
|
|
67
|
+
# - `prompt`
|
|
68
|
+
# - `validate!`
|
|
69
|
+
#
|
|
70
|
+
#: () -> String
|
|
71
|
+
def valid_prompt!
|
|
72
|
+
valid_prompt = @prompt
|
|
73
|
+
raise Cog::Input::InvalidInputError, "'prompt' is required" unless valid_prompt.present?
|
|
74
|
+
|
|
75
|
+
valid_prompt
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Roast
|
|
5
|
+
module DSL
|
|
6
|
+
module Cogs
|
|
7
|
+
class Agent < Cog
|
|
8
|
+
# Output from running the agent cog
|
|
9
|
+
#
|
|
10
|
+
# Contains the agent's final response text, session identifier for conversation continuity,
|
|
11
|
+
# and statistics about the agent execution.
|
|
12
|
+
class Output < Cog::Output
|
|
13
|
+
include Cog::Output::WithJson
|
|
14
|
+
include Cog::Output::WithNumber
|
|
15
|
+
include Cog::Output::WithText
|
|
16
|
+
|
|
17
|
+
# The agent's final response text
|
|
18
|
+
#
|
|
19
|
+
# This is the text content of the agent's last message in the conversation.
|
|
20
|
+
# For multi-turn conversations, this represents only the final response, not the
|
|
21
|
+
# entire conversation history.
|
|
22
|
+
#
|
|
23
|
+
# #### See Also
|
|
24
|
+
# - `text` (from WithText module)
|
|
25
|
+
# - `lines` (from WithText module)
|
|
26
|
+
#
|
|
27
|
+
#: String
|
|
28
|
+
attr_reader :response
|
|
29
|
+
|
|
30
|
+
# The session identifier for this agent conversation
|
|
31
|
+
#
|
|
32
|
+
# This identifier can be used to resume the conversation in subsequent agent invocations.
|
|
33
|
+
# When provided to a new agent cog's input, the agent will have access to the full
|
|
34
|
+
# conversation history from this session.
|
|
35
|
+
#
|
|
36
|
+
# An agent resuming from this session will fork the session, so multiple agents can
|
|
37
|
+
# independently resume from the same initial session and each see the same state.
|
|
38
|
+
#
|
|
39
|
+
#: String
|
|
40
|
+
attr_reader :session
|
|
41
|
+
|
|
42
|
+
# Statistics about the agent execution
|
|
43
|
+
#
|
|
44
|
+
# Contains metrics such as execution duration, number of turns (back-and-forth exchanges
|
|
45
|
+
# with the agent), token usage, and per-model usage breakdown.
|
|
46
|
+
#
|
|
47
|
+
#: Stats
|
|
48
|
+
attr_reader :stats
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
def raw_text
|
|
53
|
+
response
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Roast
|
|
5
|
+
module DSL
|
|
6
|
+
module Cogs
|
|
7
|
+
class Agent < Cog
|
|
8
|
+
# Abstract base class for agent provider implementations
|
|
9
|
+
#
|
|
10
|
+
# Providers are responsible for interfacing with specific agent backends (e.g., Claude)
|
|
11
|
+
# to execute agent requests. Each provider must implement the `invoke` method to handle
|
|
12
|
+
# agent execution according to their specific API requirements.
|
|
13
|
+
#
|
|
14
|
+
# Subclasses should override `invoke` to provide concrete implementations that communicate
|
|
15
|
+
# with their respective agent services.
|
|
16
|
+
class Provider
|
|
17
|
+
# Initialize a new provider with the given configuration
|
|
18
|
+
#
|
|
19
|
+
# Stores the agent configuration for use during invocation. The configuration contains
|
|
20
|
+
# all settings needed to communicate with the agent service, such as API keys, model
|
|
21
|
+
# names, and execution parameters.
|
|
22
|
+
#
|
|
23
|
+
# #### See Also
|
|
24
|
+
# - `invoke`
|
|
25
|
+
#
|
|
26
|
+
#: (Config) -> void
|
|
27
|
+
def initialize(config)
|
|
28
|
+
super()
|
|
29
|
+
@config = config
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Execute an agent request and return the result
|
|
33
|
+
#
|
|
34
|
+
# This method must be implemented by subclasses to handle the actual agent execution.
|
|
35
|
+
# Implementations should use the stored configuration to set up the request, send the
|
|
36
|
+
# input to the agent service, and return a properly formatted output.
|
|
37
|
+
#
|
|
38
|
+
# Raises `NotImplementedError` if called on the base Provider class.
|
|
39
|
+
#
|
|
40
|
+
# #### See Also
|
|
41
|
+
# - `initialize`
|
|
42
|
+
#
|
|
43
|
+
#: (Input) -> Output
|
|
44
|
+
def invoke(input)
|
|
45
|
+
raise NotImplementedError, "Subclasses must implement #invoke"
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|