roast-ai 0.4.10 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.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/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 +40 -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 +248 -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 +162 -0
- data/lib/roast/dsl/system_cogs/map.rb +448 -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/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,31 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Roast
|
|
5
|
+
module DSL
|
|
6
|
+
module Cogs
|
|
7
|
+
class Agent < Cog
|
|
8
|
+
module Providers
|
|
9
|
+
class Claude < Provider
|
|
10
|
+
class Output < Agent::Output
|
|
11
|
+
delegate :response, :session, :stats, to: :@invocation_result
|
|
12
|
+
|
|
13
|
+
#: (ClaudeInvocation::Result) -> void
|
|
14
|
+
def initialize(invocation_result)
|
|
15
|
+
super()
|
|
16
|
+
@invocation_result = invocation_result
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
#: (Agent::Input) -> Agent::Output
|
|
21
|
+
def invoke(input)
|
|
22
|
+
invocation = ClaudeInvocation.new(@config, input)
|
|
23
|
+
invocation.run!
|
|
24
|
+
Output.new(invocation.result)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Roast
|
|
5
|
+
module DSL
|
|
6
|
+
module Cogs
|
|
7
|
+
class Agent < Cog
|
|
8
|
+
# Statistics about agent execution
|
|
9
|
+
#
|
|
10
|
+
# Contains metrics tracking the performance and resource usage of an agent execution,
|
|
11
|
+
# including duration, conversation turns, token usage, and cost. Statistics are broken
|
|
12
|
+
# down by model when multiple models are used during execution.
|
|
13
|
+
class Stats
|
|
14
|
+
include ActiveSupport::NumberHelper
|
|
15
|
+
|
|
16
|
+
NO_VALUE = "---"
|
|
17
|
+
|
|
18
|
+
# The total execution duration in milliseconds
|
|
19
|
+
#
|
|
20
|
+
# Measures the wall-clock time from when the agent started executing until it completed.
|
|
21
|
+
# This includes all time spent on API calls, processing, and waiting.
|
|
22
|
+
#
|
|
23
|
+
#: Integer?
|
|
24
|
+
attr_accessor :duration_ms
|
|
25
|
+
|
|
26
|
+
# The number of conversation turns in the agent execution
|
|
27
|
+
#
|
|
28
|
+
# A turn represents one complete back-and-forth exchange between the user (or system)
|
|
29
|
+
# and the agent. For example, if the user sends a prompt and the agent responds, that
|
|
30
|
+
# is one turn. If the agent then uses a tool and responds again, that is another turn.
|
|
31
|
+
#
|
|
32
|
+
#: Integer?
|
|
33
|
+
attr_accessor :num_turns
|
|
34
|
+
|
|
35
|
+
# Aggregate token usage and cost across all models
|
|
36
|
+
#
|
|
37
|
+
# Provides the total input tokens, output tokens, and cost in USD for the entire
|
|
38
|
+
# agent execution, regardless of which models were used.
|
|
39
|
+
#
|
|
40
|
+
# #### See Also
|
|
41
|
+
# - `model_usage` - for per-model usage breakdown
|
|
42
|
+
# - `Agent::Usage`
|
|
43
|
+
#
|
|
44
|
+
#: Usage
|
|
45
|
+
attr_accessor :usage
|
|
46
|
+
|
|
47
|
+
# Token usage and cost broken down by model
|
|
48
|
+
#
|
|
49
|
+
# A hash mapping model names (as strings) to their individual usage statistics.
|
|
50
|
+
# This allows tracking how much each model contributed to the overall resource usage
|
|
51
|
+
# when multiple models were used during execution.
|
|
52
|
+
#
|
|
53
|
+
# #### See Also
|
|
54
|
+
# - `usage` - for aggregate usage across all models
|
|
55
|
+
# - `Agent::Usage`
|
|
56
|
+
#
|
|
57
|
+
#: Hash[String, Usage]
|
|
58
|
+
attr_accessor :model_usage
|
|
59
|
+
|
|
60
|
+
def initialize
|
|
61
|
+
@usage = Usage.new
|
|
62
|
+
@model_usage = {}
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Get a human-readable string representation of the statistics
|
|
66
|
+
#
|
|
67
|
+
# Formats the statistics into a multi-line string with the following information:
|
|
68
|
+
# - Number of turns
|
|
69
|
+
# - Total duration (formatted as a human-readable duration)
|
|
70
|
+
# - Total cost in USD (formatted with 6 decimal places)
|
|
71
|
+
# - Per-model token usage (input and output tokens)
|
|
72
|
+
#
|
|
73
|
+
# Values that are not available are shown as "---".
|
|
74
|
+
#
|
|
75
|
+
#: () -> String
|
|
76
|
+
def to_s
|
|
77
|
+
lines = []
|
|
78
|
+
lines << "Turns: #{num_turns.nil? ? NO_VALUE : number_to_human(num_turns)}"
|
|
79
|
+
lines << "Duration: #{duration_ms.nil? ? NO_VALUE : ActiveSupport::Duration.build((duration_ms || 0) / 1000).inspect}"
|
|
80
|
+
lines << "Cost (USD): $#{usage.cost_usd.nil? ? NO_VALUE : number_to_human(usage.cost_usd, precision: 6, significant: false)}"
|
|
81
|
+
model_usage.each do |m, u|
|
|
82
|
+
input_tokens = u.input_tokens.nil? ? NO_VALUE : number_to_human(u.input_tokens)
|
|
83
|
+
output_tokens = u.output_tokens.nil? ? NO_VALUE : number_to_human(u.output_tokens)
|
|
84
|
+
lines << "Tokens (#{m}): #{input_tokens} in, #{output_tokens} out"
|
|
85
|
+
end
|
|
86
|
+
lines.join("\n")
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Roast
|
|
5
|
+
module DSL
|
|
6
|
+
module Cogs
|
|
7
|
+
class Agent < Cog
|
|
8
|
+
# Token usage and cost information for agent execution
|
|
9
|
+
#
|
|
10
|
+
# Tracks the number of input and output tokens consumed during agent execution,
|
|
11
|
+
# along with the associated cost in USD. This information is used to monitor
|
|
12
|
+
# resource consumption and estimate execution costs.
|
|
13
|
+
#
|
|
14
|
+
# Usage data can represent either aggregate usage across all models or usage
|
|
15
|
+
# for a specific model when tracked in the per-model breakdown.
|
|
16
|
+
#
|
|
17
|
+
# #### See Also
|
|
18
|
+
# - `Agent::Stats` - contains aggregate and per-model usage information
|
|
19
|
+
class Usage
|
|
20
|
+
# The number of input tokens consumed
|
|
21
|
+
#
|
|
22
|
+
# Input tokens represent the text sent to the agent, including the user prompt,
|
|
23
|
+
# system instructions, conversation history, and any other context provided to
|
|
24
|
+
# the model. This metric is used to calculate the cost of providing input to the agent.
|
|
25
|
+
#
|
|
26
|
+
# #### See Also
|
|
27
|
+
# - `output_tokens`
|
|
28
|
+
# - `cost_usd`
|
|
29
|
+
#
|
|
30
|
+
#: Integer?
|
|
31
|
+
attr_accessor :input_tokens
|
|
32
|
+
|
|
33
|
+
# The number of output tokens generated
|
|
34
|
+
#
|
|
35
|
+
# Output tokens represent the text generated by the agent in response to the input.
|
|
36
|
+
# This includes the agent's responses, reasoning, and any other text produced during
|
|
37
|
+
# execution. This metric is used to calculate the cost of the agent's output.
|
|
38
|
+
#
|
|
39
|
+
# #### See Also
|
|
40
|
+
# - `input_tokens`
|
|
41
|
+
# - `cost_usd`
|
|
42
|
+
#
|
|
43
|
+
#: Integer?
|
|
44
|
+
attr_accessor :output_tokens
|
|
45
|
+
|
|
46
|
+
# The total cost in United States Dollars (USD)
|
|
47
|
+
#
|
|
48
|
+
# Represents the monetary cost of the agent execution based on the provider's pricing
|
|
49
|
+
# model. This typically accounts for both input and output token usage, though pricing
|
|
50
|
+
# models may vary by provider and model.
|
|
51
|
+
#
|
|
52
|
+
# #### See Also
|
|
53
|
+
# - `input_tokens`
|
|
54
|
+
# - `output_tokens`
|
|
55
|
+
#
|
|
56
|
+
#: Float?
|
|
57
|
+
attr_accessor :cost_usd
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Roast
|
|
5
|
+
module DSL
|
|
6
|
+
module Cogs
|
|
7
|
+
# Agent cog for running coding agents on the local machine
|
|
8
|
+
#
|
|
9
|
+
# The agent cog runs a coding agent on the local machine with access to local files,
|
|
10
|
+
# tools, and MCP servers. It is designed for coding tasks and any work requiring local
|
|
11
|
+
# filesystem access.
|
|
12
|
+
#
|
|
13
|
+
# Key capabilities:
|
|
14
|
+
# - Access to local filesystem (read and write files)
|
|
15
|
+
# - Can run local tools and commands
|
|
16
|
+
# - Access to locally-configured MCP servers
|
|
17
|
+
# - Maintain session state across multiple invocations
|
|
18
|
+
# - Resume previous conversations using session identifiers
|
|
19
|
+
# - Track detailed execution statistics including token usage and cost
|
|
20
|
+
#
|
|
21
|
+
# For pure LLM interaction without local system access, use the `chat` cog instead.
|
|
22
|
+
class Agent < Cog
|
|
23
|
+
# Parent class for all agent cog errors
|
|
24
|
+
class AgentCogError < Roast::Error; end
|
|
25
|
+
|
|
26
|
+
# Raised when an unknown or unsupported provider is specified
|
|
27
|
+
class UnknownProviderError < AgentCogError; end
|
|
28
|
+
|
|
29
|
+
# Raised when a required provider is not configured
|
|
30
|
+
class MissingProviderError < AgentCogError; end
|
|
31
|
+
|
|
32
|
+
# Raised when a required prompt is not provided
|
|
33
|
+
class MissingPromptError < AgentCogError; end
|
|
34
|
+
|
|
35
|
+
# The configuration object for this agent cog instance
|
|
36
|
+
#
|
|
37
|
+
#: Agent::Config
|
|
38
|
+
attr_reader :config
|
|
39
|
+
|
|
40
|
+
# Execute the agent with the given input and return the output
|
|
41
|
+
#
|
|
42
|
+
# Invokes the configured agent provider with the input prompt and any session context.
|
|
43
|
+
# Optionally displays the user prompt, agent response, and execution statistics to the
|
|
44
|
+
# console based on the cog's configuration.
|
|
45
|
+
#
|
|
46
|
+
# The agent may make multiple turns (back-and-forth exchanges) during execution,
|
|
47
|
+
# especially when using tools. Each turn is counted in the execution statistics.
|
|
48
|
+
#
|
|
49
|
+
#: (Input) -> Output
|
|
50
|
+
def execute(input)
|
|
51
|
+
puts "[USER PROMPT] #{input.valid_prompt!}" if config.show_prompt?
|
|
52
|
+
output = provider.invoke(input)
|
|
53
|
+
# NOTE: If progress is displayed, the agent's response will always be the last progress message,
|
|
54
|
+
# so showing it again is duplicative.
|
|
55
|
+
puts "[AGENT RESPONSE] #{output.response}" if config.show_response? && !config.show_progress?
|
|
56
|
+
puts "[AGENT STATS] #{output.stats}" if config.show_stats?
|
|
57
|
+
puts "Session ID: #{output.session}" if config.show_stats?
|
|
58
|
+
output
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
private
|
|
62
|
+
|
|
63
|
+
#: () -> Provider
|
|
64
|
+
def provider
|
|
65
|
+
@provider ||= case config.valid_provider!
|
|
66
|
+
when :claude
|
|
67
|
+
Providers::Claude.new(config)
|
|
68
|
+
else
|
|
69
|
+
raise UnknownProviderError, "Unknown provider: #{config.valid_provider!}"
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|