brute 4.3.2 → 5.0.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/lib/brute/completion/async_faraday.rb +38 -0
- data/lib/brute/completion/lang_chain.rb +185 -0
- data/lib/brute/completion/llmrb.rb +182 -0
- data/lib/brute/completion/open_router.rb +54 -42
- data/lib/brute/completion/ruby_llm.rb +198 -0
- data/lib/brute/contrib/otel.rb +208 -0
- data/lib/brute/hooks.rb +149 -31
- data/lib/brute/message_transport/lang_chain.rb +36 -0
- data/lib/brute/message_transport/llm.rb +6 -0
- data/lib/brute/message_transport/open_router.rb +6 -0
- data/lib/brute/message_transport/ruby_llm.rb +6 -0
- data/lib/brute/message_transport.rb +8 -0
- data/lib/brute/middleware/000_base.rb +61 -0
- data/lib/brute/middleware/002_session_log.rb +1 -1
- data/lib/brute/middleware/004_summarize.rb +1 -1
- data/lib/brute/middleware/005_tracing.rb +1 -1
- data/lib/brute/middleware/006_loop.rb +1 -1
- data/lib/brute/middleware/008_checkpoint.rb +1 -1
- data/lib/brute/middleware/010_max_iterations.rb +1 -1
- data/lib/brute/middleware/020_system_prompt.rb +1 -1
- data/lib/brute/middleware/025_skills.rb +1 -1
- data/lib/brute/middleware/040_compaction_check.rb +1 -1
- data/lib/brute/middleware/060_questions.rb +1 -1
- data/lib/brute/middleware/070_tool_pipeline.rb +60 -47
- data/lib/brute/middleware/event_handler.rb +1 -1
- data/lib/brute/middleware/user_queue.rb +1 -1
- data/lib/brute/turn/agent_pipeline.rb +3 -4
- data/lib/brute/turn/pipeline.rb +151 -2
- data/lib/brute/usage_detection/lang_chain.rb +44 -0
- data/lib/brute/usage_detection/llmrb.rb +53 -0
- data/lib/brute/usage_detection/open_router.rb +62 -0
- data/lib/brute/usage_detection/ruby_llm.rb +55 -0
- data/lib/brute/usage_detection/usage.rb +51 -0
- data/lib/brute/version.rb +1 -1
- data/lib/brute.rb +95 -3
- metadata +83 -8
- data/lib/brute/changelog.rb +0 -322
- data/lib/brute/deprecate.rb +0 -132
- data/lib/brute/middleware/001_otel_span.rb +0 -79
- data/lib/brute/middleware/015_otel_token_usage.rb +0 -44
- data/lib/brute/middleware/073_otel_tool_call.rb +0 -51
- data/lib/brute/middleware/075_otel_tool_results.rb +0 -48
- data/lib/brute/middleware/open_router.rb +0 -56
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bundler/setup"
|
|
4
|
+
require "brute"
|
|
5
|
+
require "brute/usage_detection/usage"
|
|
6
|
+
|
|
7
|
+
module Brute
|
|
8
|
+
module UsageDetection
|
|
9
|
+
# llm.rb models usage as its own LLM::Usage value object. Note it answers
|
|
10
|
+
# 0, not nil, for anything the provider left out — that is llm.rb's
|
|
11
|
+
# reading of the response and it is reported as given.
|
|
12
|
+
module LLMrb
|
|
13
|
+
def self.detect(response)
|
|
14
|
+
return nil unless response.respond_to?(:usage)
|
|
15
|
+
|
|
16
|
+
usage = response.usage
|
|
17
|
+
return nil if usage.nil?
|
|
18
|
+
|
|
19
|
+
Usage.new(
|
|
20
|
+
input: read(usage, :input_tokens),
|
|
21
|
+
output: read(usage, :output_tokens),
|
|
22
|
+
total: read(usage, :total_tokens),
|
|
23
|
+
reasoning: read(usage, :reasoning_tokens),
|
|
24
|
+
cache_read: read(usage, :cache_read_tokens),
|
|
25
|
+
cache_write: read(usage, :cache_write_tokens),
|
|
26
|
+
raw: usage,
|
|
27
|
+
)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.read(usage, name) = usage.respond_to?(name) ? usage.public_send(name) : nil
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
__END__
|
|
36
|
+
|
|
37
|
+
describe "brute/usage_detection/llmrb" do
|
|
38
|
+
LLMrbUsage = Struct.new(:input_tokens, :output_tokens, :total_tokens, :reasoning_tokens,
|
|
39
|
+
:cache_read_tokens, :cache_write_tokens) unless defined?(LLMrbUsage)
|
|
40
|
+
LLMrbResponse = Struct.new(:usage) unless defined?(LLMrbResponse)
|
|
41
|
+
|
|
42
|
+
it "reports LLM::Usage as given, and answers nil when there is no usage to read" do
|
|
43
|
+
usage = Brute::UsageDetection::LLMrb.detect(LLMrbResponse.new(LLMrbUsage.new(10, 5, 15, 0, 0, 0)))
|
|
44
|
+
|
|
45
|
+
usage.input.should == 10
|
|
46
|
+
usage.output.should == 5
|
|
47
|
+
usage.total.should == 15
|
|
48
|
+
usage.reasoning.should == 0 # llm.rb's own zero, reported as given
|
|
49
|
+
|
|
50
|
+
Brute::UsageDetection::LLMrb.detect(LLMrbResponse.new(nil)).should.be.nil
|
|
51
|
+
Brute::UsageDetection::LLMrb.detect(Object.new).should.be.nil
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bundler/setup"
|
|
4
|
+
require "brute"
|
|
5
|
+
require "brute/usage_detection/usage"
|
|
6
|
+
|
|
7
|
+
module Brute
|
|
8
|
+
module UsageDetection
|
|
9
|
+
# OpenRouter reports usage as the provider's raw hash on the response,
|
|
10
|
+
# in OpenAI's wire shape. Reasoning tokens, when the model reports them,
|
|
11
|
+
# arrive nested under completion_tokens_details.
|
|
12
|
+
module OpenRouter
|
|
13
|
+
def self.detect(response)
|
|
14
|
+
return nil unless response.respond_to?(:usage)
|
|
15
|
+
|
|
16
|
+
usage = response.usage
|
|
17
|
+
return nil if usage.nil?
|
|
18
|
+
|
|
19
|
+
usage = usage.to_h
|
|
20
|
+
details = (usage["completion_tokens_details"] || usage[:completion_tokens_details] || {}).to_h
|
|
21
|
+
|
|
22
|
+
Usage.new(
|
|
23
|
+
input: field(usage, "prompt_tokens"),
|
|
24
|
+
output: field(usage, "completion_tokens"),
|
|
25
|
+
total: field(usage, "total_tokens"),
|
|
26
|
+
reasoning: field(details, "reasoning_tokens"),
|
|
27
|
+
cache_read: field(usage, "cached_tokens"),
|
|
28
|
+
cost: field(usage, "cost"),
|
|
29
|
+
raw: usage,
|
|
30
|
+
)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# OpenRouter hands back string keys; a hand-built response may not.
|
|
34
|
+
def self.field(hash, key) = hash[key] || hash[key.to_sym]
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
__END__
|
|
40
|
+
|
|
41
|
+
describe "brute/usage_detection/open_router" do
|
|
42
|
+
Response = Struct.new(:usage) unless defined?(Response)
|
|
43
|
+
|
|
44
|
+
it "reads the OpenAI-shaped hash, string or symbol keys, and answers nil for no usage" do
|
|
45
|
+
usage = Brute::UsageDetection::OpenRouter.detect(Response.new({
|
|
46
|
+
"prompt_tokens" => 10, "completion_tokens" => 5, "total_tokens" => 15,
|
|
47
|
+
"completion_tokens_details" => { "reasoning_tokens" => 4 },
|
|
48
|
+
}))
|
|
49
|
+
usage.input.should == 10
|
|
50
|
+
usage.output.should == 5
|
|
51
|
+
usage.total.should == 15
|
|
52
|
+
usage.reasoning.should == 4
|
|
53
|
+
|
|
54
|
+
symbols = Brute::UsageDetection::OpenRouter.detect(Response.new({ prompt_tokens: 1, completion_tokens: 2 }))
|
|
55
|
+
symbols.input.should == 1
|
|
56
|
+
symbols.output.should == 2
|
|
57
|
+
symbols.total.should.be.nil
|
|
58
|
+
|
|
59
|
+
Brute::UsageDetection::OpenRouter.detect(Response.new(nil)).should.be.nil
|
|
60
|
+
Brute::UsageDetection::OpenRouter.detect(Object.new).should.be.nil
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bundler/setup"
|
|
4
|
+
require "brute"
|
|
5
|
+
require "brute/usage_detection/usage"
|
|
6
|
+
|
|
7
|
+
module Brute
|
|
8
|
+
module UsageDetection
|
|
9
|
+
# ruby_llm hangs usage off the *message*, not the response: a Tokens
|
|
10
|
+
# object with input/output/cache_read/cache_write/thinking, plus the
|
|
11
|
+
# provider's own reported_cost when it gives one.
|
|
12
|
+
module RubyLLM
|
|
13
|
+
def self.detect(message)
|
|
14
|
+
return nil unless message.respond_to?(:tokens)
|
|
15
|
+
|
|
16
|
+
tokens = message.tokens
|
|
17
|
+
return nil if tokens.nil?
|
|
18
|
+
|
|
19
|
+
Usage.new(
|
|
20
|
+
input: read(tokens, :input),
|
|
21
|
+
output: read(tokens, :output),
|
|
22
|
+
reasoning: read(tokens, :thinking),
|
|
23
|
+
cache_read: read(tokens, :cache_read),
|
|
24
|
+
cache_write: read(tokens, :cache_write),
|
|
25
|
+
cost: read(tokens, :reported_cost),
|
|
26
|
+
raw: tokens,
|
|
27
|
+
)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.read(tokens, name) = tokens.respond_to?(name) ? tokens.public_send(name) : nil
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
__END__
|
|
36
|
+
|
|
37
|
+
describe "brute/usage_detection/ruby_llm" do
|
|
38
|
+
FakeTokens = Struct.new(:input, :output, :cache_read, :cache_write, :thinking, :reported_cost) unless defined?(FakeTokens)
|
|
39
|
+
FakeMessage = Struct.new(:tokens) unless defined?(FakeMessage)
|
|
40
|
+
|
|
41
|
+
it "reads Tokens off the message, maps thinking to reasoning, and answers nil for no usage" do
|
|
42
|
+
usage = Brute::UsageDetection::RubyLLM.detect(FakeMessage.new(FakeTokens.new(10, 5, 2, 1, 4, 0.002)))
|
|
43
|
+
|
|
44
|
+
usage.input.should == 10
|
|
45
|
+
usage.output.should == 5
|
|
46
|
+
usage.total.should.be.nil # ruby_llm reports parts, not a total
|
|
47
|
+
usage.reasoning.should == 4
|
|
48
|
+
usage.cache_read.should == 2
|
|
49
|
+
usage.cache_write.should == 1
|
|
50
|
+
usage.cost.should == 0.002
|
|
51
|
+
|
|
52
|
+
Brute::UsageDetection::RubyLLM.detect(FakeMessage.new(nil)).should.be.nil
|
|
53
|
+
Brute::UsageDetection::RubyLLM.detect(Object.new).should.be.nil
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bundler/setup"
|
|
4
|
+
require "brute"
|
|
5
|
+
|
|
6
|
+
module Brute
|
|
7
|
+
# What the provider reported, normalised. Every library reports usage
|
|
8
|
+
# differently —
|
|
9
|
+
# OpenRouter as a raw hash on the response, ruby_llm as a Tokens object on
|
|
10
|
+
# the *message*, llm.rb as an LLM::Usage, langchainrb as per-provider
|
|
11
|
+
# methods digging their own raw shape — so each strategy here reads one of
|
|
12
|
+
# them and answers the same Usage.
|
|
13
|
+
#
|
|
14
|
+
# Brute::UsageDetection::OpenRouter.detect(response)
|
|
15
|
+
# # => #<data Brute::UsageDetection::Usage input=10, output=5, total=15, ...>
|
|
16
|
+
#
|
|
17
|
+
# A strategy reads one response and answers what that provider said —
|
|
18
|
+
# nothing more. It does not derive, sum or accumulate: running totals for a
|
|
19
|
+
# turn are the env's business, not the reader's. A strategy answers nil when
|
|
20
|
+
# the provider reported nothing at all.
|
|
21
|
+
module UsageDetection
|
|
22
|
+
Usage = Data.define(:input, :output, :total, :reasoning, :cache_read, :cache_write, :cost, :raw) do
|
|
23
|
+
def initialize(input: nil, output: nil, total: nil, reasoning: nil,
|
|
24
|
+
cache_read: nil, cache_write: nil, cost: nil, raw: nil)
|
|
25
|
+
super
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# What a provider did not report stays out, so a reader sees the counts
|
|
29
|
+
# that are real rather than a row of nils.
|
|
30
|
+
def to_h = super.compact
|
|
31
|
+
|
|
32
|
+
def empty? = [input, output, total].all?(&:nil?)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
__END__
|
|
38
|
+
|
|
39
|
+
describe "brute/usage_detection/usage" do
|
|
40
|
+
it "reports only what it was given, and drops what was never reported" do
|
|
41
|
+
# No derivation: a provider that reports parts and no total has no total.
|
|
42
|
+
usage = Brute::UsageDetection::Usage.new(input: 10, output: 5)
|
|
43
|
+
usage.total.should.be.nil
|
|
44
|
+
usage.to_h.should == { input: 10, output: 5 }
|
|
45
|
+
|
|
46
|
+
Brute::UsageDetection::Usage.new(input: 10, output: 5, total: 99).total.should == 99
|
|
47
|
+
|
|
48
|
+
Brute::UsageDetection::Usage.new.empty?.should.be.true
|
|
49
|
+
Brute::UsageDetection::Usage.new(total: 3).empty?.should.be.false
|
|
50
|
+
end
|
|
51
|
+
end
|
data/lib/brute/version.rb
CHANGED
data/lib/brute.rb
CHANGED
|
@@ -87,8 +87,100 @@ module Brute
|
|
|
87
87
|
end
|
|
88
88
|
end
|
|
89
89
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
90
|
+
# Explicit, in dependency order: Hooks and Middleware::Base are included and
|
|
91
|
+
# inherited at load time, so they cannot be left to a sorted glob that happens
|
|
92
|
+
# to reach completion/ before hooks.
|
|
93
|
+
require_relative "brute/version"
|
|
94
|
+
require_relative "brute/hooks"
|
|
95
|
+
require_relative "brute/messages"
|
|
96
|
+
require_relative "brute/middleware/000_base"
|
|
97
|
+
require_relative "brute/completion/async_faraday"
|
|
98
|
+
require_relative "brute/completion/open_router"
|
|
99
|
+
require_relative "brute/completion/lang_chain"
|
|
100
|
+
require_relative "brute/completion/llmrb"
|
|
101
|
+
require_relative "brute/completion/ruby_llm"
|
|
102
|
+
require_relative "brute/usage_detection/usage"
|
|
103
|
+
require_relative "brute/usage_detection/open_router"
|
|
104
|
+
require_relative "brute/usage_detection/ruby_llm"
|
|
105
|
+
require_relative "brute/usage_detection/llmrb"
|
|
106
|
+
require_relative "brute/usage_detection/lang_chain"
|
|
107
|
+
require_relative "brute/contrib/log_file"
|
|
108
|
+
require_relative "brute/contrib/otel"
|
|
109
|
+
require_relative "brute/events/handler"
|
|
110
|
+
require_relative "brute/events/prefixed_terminal_output"
|
|
111
|
+
require_relative "brute/events/terminal_output_handler"
|
|
112
|
+
require_relative "brute/message_transport"
|
|
113
|
+
require_relative "brute/message_transport/anthropic"
|
|
114
|
+
require_relative "brute/message_transport/llm"
|
|
115
|
+
require_relative "brute/message_transport/open_router"
|
|
116
|
+
require_relative "brute/message_transport/openai"
|
|
117
|
+
require_relative "brute/message_transport/ruby_llm"
|
|
118
|
+
require_relative "brute/message_transport/ruby_open_ai"
|
|
119
|
+
require_relative "brute/message_transport/lang_chain"
|
|
120
|
+
require_relative "brute/middleware/002_session_log"
|
|
121
|
+
require_relative "brute/middleware/004_summarize"
|
|
122
|
+
require_relative "brute/middleware/005_tracing"
|
|
123
|
+
require_relative "brute/middleware/006_loop"
|
|
124
|
+
require_relative "brute/middleware/008_checkpoint"
|
|
125
|
+
require_relative "brute/middleware/010_max_iterations"
|
|
126
|
+
require_relative "brute/middleware/020_system_prompt"
|
|
127
|
+
require_relative "brute/middleware/025_skills"
|
|
128
|
+
require_relative "brute/middleware/040_compaction_check"
|
|
129
|
+
require_relative "brute/middleware/060_questions"
|
|
130
|
+
require_relative "brute/middleware/070_tool_pipeline"
|
|
131
|
+
require_relative "brute/middleware/event_handler"
|
|
132
|
+
require_relative "brute/middleware/user_queue"
|
|
133
|
+
require_relative "brute/prompt_template"
|
|
134
|
+
require_relative "brute/prompts"
|
|
135
|
+
require_relative "brute/prompts/autonomy"
|
|
136
|
+
require_relative "brute/prompts/base"
|
|
137
|
+
require_relative "brute/prompts/build_switch"
|
|
138
|
+
require_relative "brute/prompts/code_references"
|
|
139
|
+
require_relative "brute/prompts/code_style"
|
|
140
|
+
require_relative "brute/prompts/conventions"
|
|
141
|
+
require_relative "brute/prompts/doing_tasks"
|
|
142
|
+
require_relative "brute/prompts/editing_approach"
|
|
143
|
+
require_relative "brute/prompts/editing_constraints"
|
|
144
|
+
require_relative "brute/prompts/environment"
|
|
145
|
+
require_relative "brute/prompts/frontend_tasks"
|
|
146
|
+
require_relative "brute/prompts/git_safety"
|
|
147
|
+
require_relative "brute/prompts/identity"
|
|
148
|
+
require_relative "brute/prompts/instructions"
|
|
149
|
+
require_relative "brute/prompts/max_steps"
|
|
150
|
+
require_relative "brute/prompts/objectivity"
|
|
151
|
+
require_relative "brute/prompts/plan_reminder"
|
|
152
|
+
require_relative "brute/prompts/proactiveness"
|
|
153
|
+
require_relative "brute/prompts/security_and_safety"
|
|
154
|
+
require_relative "brute/prompts/skills"
|
|
155
|
+
require_relative "brute/prompts/task_management"
|
|
156
|
+
require_relative "brute/prompts/tone_and_style"
|
|
157
|
+
require_relative "brute/prompts/tool_usage"
|
|
158
|
+
require_relative "brute/rack/adapter"
|
|
159
|
+
require_relative "brute/skill"
|
|
160
|
+
require_relative "brute/system_prompt"
|
|
161
|
+
require_relative "brute/tool"
|
|
162
|
+
require_relative "brute/tools"
|
|
163
|
+
require_relative "brute/tools/adapter"
|
|
164
|
+
require_relative "brute/tools/fs/file_mutation_queue"
|
|
165
|
+
require_relative "brute/tools/fs/snapshot_store"
|
|
166
|
+
require_relative "brute/tools/fs_patch"
|
|
167
|
+
require_relative "brute/tools/fs_read"
|
|
168
|
+
require_relative "brute/tools/fs_remove"
|
|
169
|
+
require_relative "brute/tools/fs_search"
|
|
170
|
+
require_relative "brute/tools/fs_undo"
|
|
171
|
+
require_relative "brute/tools/fs_write"
|
|
172
|
+
require_relative "brute/tools/net_fetch"
|
|
173
|
+
require_relative "brute/tools/question"
|
|
174
|
+
require_relative "brute/tools/shell"
|
|
175
|
+
require_relative "brute/tools/skill_load"
|
|
176
|
+
require_relative "brute/tools/sub_agent"
|
|
177
|
+
require_relative "brute/tools/todo_list/store"
|
|
178
|
+
require_relative "brute/tools/todo_read"
|
|
179
|
+
require_relative "brute/tools/todo_write"
|
|
180
|
+
require_relative "brute/truncation"
|
|
181
|
+
require_relative "brute/turn/agent_pipeline"
|
|
182
|
+
require_relative "brute/turn/pipeline"
|
|
183
|
+
require_relative "brute/turn/tool_pipeline"
|
|
184
|
+
require_relative "brute/utils/diff"
|
|
93
185
|
|
|
94
186
|
# gangsta g-dogg bruh...
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: brute
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 5.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Brute Contributors
|
|
@@ -107,6 +107,20 @@ dependencies:
|
|
|
107
107
|
- - ">="
|
|
108
108
|
- !ruby/object:Gem::Version
|
|
109
109
|
version: '0'
|
|
110
|
+
- !ruby/object:Gem::Dependency
|
|
111
|
+
name: async-http-faraday
|
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
|
113
|
+
requirements:
|
|
114
|
+
- - ">="
|
|
115
|
+
- !ruby/object:Gem::Version
|
|
116
|
+
version: '0'
|
|
117
|
+
type: :runtime
|
|
118
|
+
prerelease: false
|
|
119
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
120
|
+
requirements:
|
|
121
|
+
- - ">="
|
|
122
|
+
- !ruby/object:Gem::Version
|
|
123
|
+
version: '0'
|
|
110
124
|
- !ruby/object:Gem::Dependency
|
|
111
125
|
name: json_schemer
|
|
112
126
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -149,6 +163,62 @@ dependencies:
|
|
|
149
163
|
- - "~>"
|
|
150
164
|
- !ruby/object:Gem::Version
|
|
151
165
|
version: '0.2'
|
|
166
|
+
- !ruby/object:Gem::Dependency
|
|
167
|
+
name: ruby_llm
|
|
168
|
+
requirement: !ruby/object:Gem::Requirement
|
|
169
|
+
requirements:
|
|
170
|
+
- - ">="
|
|
171
|
+
- !ruby/object:Gem::Version
|
|
172
|
+
version: '0'
|
|
173
|
+
type: :development
|
|
174
|
+
prerelease: false
|
|
175
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
176
|
+
requirements:
|
|
177
|
+
- - ">="
|
|
178
|
+
- !ruby/object:Gem::Version
|
|
179
|
+
version: '0'
|
|
180
|
+
- !ruby/object:Gem::Dependency
|
|
181
|
+
name: open_router_enhanced
|
|
182
|
+
requirement: !ruby/object:Gem::Requirement
|
|
183
|
+
requirements:
|
|
184
|
+
- - ">="
|
|
185
|
+
- !ruby/object:Gem::Version
|
|
186
|
+
version: '0'
|
|
187
|
+
type: :development
|
|
188
|
+
prerelease: false
|
|
189
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
190
|
+
requirements:
|
|
191
|
+
- - ">="
|
|
192
|
+
- !ruby/object:Gem::Version
|
|
193
|
+
version: '0'
|
|
194
|
+
- !ruby/object:Gem::Dependency
|
|
195
|
+
name: llm.rb
|
|
196
|
+
requirement: !ruby/object:Gem::Requirement
|
|
197
|
+
requirements:
|
|
198
|
+
- - ">="
|
|
199
|
+
- !ruby/object:Gem::Version
|
|
200
|
+
version: '0'
|
|
201
|
+
type: :development
|
|
202
|
+
prerelease: false
|
|
203
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
204
|
+
requirements:
|
|
205
|
+
- - ">="
|
|
206
|
+
- !ruby/object:Gem::Version
|
|
207
|
+
version: '0'
|
|
208
|
+
- !ruby/object:Gem::Dependency
|
|
209
|
+
name: langchainrb
|
|
210
|
+
requirement: !ruby/object:Gem::Requirement
|
|
211
|
+
requirements:
|
|
212
|
+
- - ">="
|
|
213
|
+
- !ruby/object:Gem::Version
|
|
214
|
+
version: '0'
|
|
215
|
+
type: :development
|
|
216
|
+
prerelease: false
|
|
217
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
218
|
+
requirements:
|
|
219
|
+
- - ">="
|
|
220
|
+
- !ruby/object:Gem::Version
|
|
221
|
+
version: '0'
|
|
152
222
|
- !ruby/object:Gem::Dependency
|
|
153
223
|
name: rake
|
|
154
224
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -212,39 +282,39 @@ extensions: []
|
|
|
212
282
|
extra_rdoc_files: []
|
|
213
283
|
files:
|
|
214
284
|
- lib/brute.rb
|
|
215
|
-
- lib/brute/
|
|
285
|
+
- lib/brute/completion/async_faraday.rb
|
|
286
|
+
- lib/brute/completion/lang_chain.rb
|
|
287
|
+
- lib/brute/completion/llmrb.rb
|
|
216
288
|
- lib/brute/completion/open_router.rb
|
|
289
|
+
- lib/brute/completion/ruby_llm.rb
|
|
217
290
|
- lib/brute/contrib/log_file.rb
|
|
218
|
-
- lib/brute/
|
|
291
|
+
- lib/brute/contrib/otel.rb
|
|
219
292
|
- lib/brute/events/handler.rb
|
|
220
293
|
- lib/brute/events/prefixed_terminal_output.rb
|
|
221
294
|
- lib/brute/events/terminal_output_handler.rb
|
|
222
295
|
- lib/brute/hooks.rb
|
|
223
296
|
- lib/brute/message_transport.rb
|
|
224
297
|
- lib/brute/message_transport/anthropic.rb
|
|
298
|
+
- lib/brute/message_transport/lang_chain.rb
|
|
225
299
|
- lib/brute/message_transport/llm.rb
|
|
226
300
|
- lib/brute/message_transport/open_router.rb
|
|
227
301
|
- lib/brute/message_transport/openai.rb
|
|
228
302
|
- lib/brute/message_transport/ruby_llm.rb
|
|
229
303
|
- lib/brute/message_transport/ruby_open_ai.rb
|
|
230
304
|
- lib/brute/messages.rb
|
|
231
|
-
- lib/brute/middleware/
|
|
305
|
+
- lib/brute/middleware/000_base.rb
|
|
232
306
|
- lib/brute/middleware/002_session_log.rb
|
|
233
307
|
- lib/brute/middleware/004_summarize.rb
|
|
234
308
|
- lib/brute/middleware/005_tracing.rb
|
|
235
309
|
- lib/brute/middleware/006_loop.rb
|
|
236
310
|
- lib/brute/middleware/008_checkpoint.rb
|
|
237
311
|
- lib/brute/middleware/010_max_iterations.rb
|
|
238
|
-
- lib/brute/middleware/015_otel_token_usage.rb
|
|
239
312
|
- lib/brute/middleware/020_system_prompt.rb
|
|
240
313
|
- lib/brute/middleware/025_skills.rb
|
|
241
314
|
- lib/brute/middleware/040_compaction_check.rb
|
|
242
315
|
- lib/brute/middleware/060_questions.rb
|
|
243
316
|
- lib/brute/middleware/070_tool_pipeline.rb
|
|
244
|
-
- lib/brute/middleware/073_otel_tool_call.rb
|
|
245
|
-
- lib/brute/middleware/075_otel_tool_results.rb
|
|
246
317
|
- lib/brute/middleware/event_handler.rb
|
|
247
|
-
- lib/brute/middleware/open_router.rb
|
|
248
318
|
- lib/brute/middleware/user_queue.rb
|
|
249
319
|
- lib/brute/prompt_template.rb
|
|
250
320
|
- lib/brute/prompts.rb
|
|
@@ -316,6 +386,11 @@ files:
|
|
|
316
386
|
- lib/brute/turn/agent_pipeline.rb
|
|
317
387
|
- lib/brute/turn/pipeline.rb
|
|
318
388
|
- lib/brute/turn/tool_pipeline.rb
|
|
389
|
+
- lib/brute/usage_detection/lang_chain.rb
|
|
390
|
+
- lib/brute/usage_detection/llmrb.rb
|
|
391
|
+
- lib/brute/usage_detection/open_router.rb
|
|
392
|
+
- lib/brute/usage_detection/ruby_llm.rb
|
|
393
|
+
- lib/brute/usage_detection/usage.rb
|
|
319
394
|
- lib/brute/utils/diff.rb
|
|
320
395
|
- lib/brute/version.rb
|
|
321
396
|
- lib/brute/version.rb.erb
|