brute 5.0.0 → 5.0.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/lib/brute/version.rb +1 -1
- data/lib/brute.rb +0 -1
- metadata +1 -2
- data/lib/brute/middleware/005_tracing.rb +0 -94
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2e01ccfbca88337e90f041dc548bb2ced64a83bcffc1f76e302bd8fa4825b902
|
|
4
|
+
data.tar.gz: 6bd8054dacdf68ac5d3f773d53fd6a4093be59985350ba51cc78c10227fe38ef
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4eae8566ab16b8f48ab62db551efe0878569727a4a5a5069e8a7c8de533858a84707538dd6015f4651f2ef276b9c17fc9b6ef615535e76301a425039fbf8deb0
|
|
7
|
+
data.tar.gz: fb6bf08902d2917ec98089403a64f1424216ac8f2d81374a426b372ff24e2a90e32adf4c52571d24cce166ddcbd2f1f13c34180c1fee01302f9cc69753c38c87
|
data/lib/brute/version.rb
CHANGED
data/lib/brute.rb
CHANGED
|
@@ -119,7 +119,6 @@ require_relative "brute/message_transport/ruby_open_ai"
|
|
|
119
119
|
require_relative "brute/message_transport/lang_chain"
|
|
120
120
|
require_relative "brute/middleware/002_session_log"
|
|
121
121
|
require_relative "brute/middleware/004_summarize"
|
|
122
|
-
require_relative "brute/middleware/005_tracing"
|
|
123
122
|
require_relative "brute/middleware/006_loop"
|
|
124
123
|
require_relative "brute/middleware/008_checkpoint"
|
|
125
124
|
require_relative "brute/middleware/010_max_iterations"
|
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: 5.0.
|
|
4
|
+
version: 5.0.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Brute Contributors
|
|
@@ -305,7 +305,6 @@ files:
|
|
|
305
305
|
- lib/brute/middleware/000_base.rb
|
|
306
306
|
- lib/brute/middleware/002_session_log.rb
|
|
307
307
|
- lib/brute/middleware/004_summarize.rb
|
|
308
|
-
- lib/brute/middleware/005_tracing.rb
|
|
309
308
|
- lib/brute/middleware/006_loop.rb
|
|
310
309
|
- lib/brute/middleware/008_checkpoint.rb
|
|
311
310
|
- lib/brute/middleware/010_max_iterations.rb
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "bundler/setup"
|
|
4
|
-
require "brute"
|
|
5
|
-
|
|
6
|
-
module Brute
|
|
7
|
-
module Middleware
|
|
8
|
-
# Logs timing and token usage for every LLM call, and tracks cumulative
|
|
9
|
-
# timing data in env[:metadata][:timing].
|
|
10
|
-
#
|
|
11
|
-
# As the outermost middleware, it sees the full pipeline elapsed time per
|
|
12
|
-
# call. It also tracks total wall-clock time across all calls in a turn
|
|
13
|
-
# (including tool execution gaps between LLM calls).
|
|
14
|
-
#
|
|
15
|
-
# A new turn is detected when env[:current_iteration] == 1 (the agent
|
|
16
|
-
# loop resets this at the start of each turn).
|
|
17
|
-
#
|
|
18
|
-
# Stores in env[:metadata][:timing]:
|
|
19
|
-
# total_elapsed: wall-clock since the turn began (includes tool gaps)
|
|
20
|
-
# total_llm_elapsed: cumulative time spent inside LLM calls only
|
|
21
|
-
# llm_call_count: number of LLM calls so far
|
|
22
|
-
# last_call_elapsed: duration of the most recent LLM call
|
|
23
|
-
#
|
|
24
|
-
class Tracing < Brute::Middleware::Base
|
|
25
|
-
def initialize(app, logger:)
|
|
26
|
-
@app = app
|
|
27
|
-
|
|
28
|
-
@logger = logger
|
|
29
|
-
@call_count = 0
|
|
30
|
-
@total_llm_elapsed = 0.0
|
|
31
|
-
@turn_start = nil
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def call(env)
|
|
35
|
-
@call_count += 1
|
|
36
|
-
|
|
37
|
-
# Detect new turn via iteration counter
|
|
38
|
-
if env[:current_iteration] <= 1
|
|
39
|
-
@turn_start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
40
|
-
@total_llm_elapsed = 0.0
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
messages = env[:messages]
|
|
44
|
-
provider_name = env[:provider]&.respond_to?(:name) ? env[:provider].name : env[:provider].class.name
|
|
45
|
-
model_name = env[:model] || (env[:provider].default_model rescue "unknown")
|
|
46
|
-
@logger.debug("[brute] LLM call ##{@call_count} [#{provider_name}/#{model_name}] (#{messages.size} messages in context)")
|
|
47
|
-
|
|
48
|
-
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
49
|
-
response = @app.call(env)
|
|
50
|
-
now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
51
|
-
elapsed = now - start
|
|
52
|
-
|
|
53
|
-
@total_llm_elapsed += elapsed
|
|
54
|
-
|
|
55
|
-
tokens = if response.respond_to?(:usage) && (usage = response.usage)
|
|
56
|
-
read_token(usage, :total_tokens)
|
|
57
|
-
else
|
|
58
|
-
'?'
|
|
59
|
-
end
|
|
60
|
-
@logger.debug("[brute] LLM response ##{@call_count} [#{provider_name}/#{model_name}]: #{tokens} tokens, #{elapsed.round(2)}s")
|
|
61
|
-
env[:events] << { type: :log, data: "LLM response ##{@call_count}: #{tokens} tokens, #{elapsed.round(2)}s" } if response
|
|
62
|
-
|
|
63
|
-
env[:metadata][:timing] = {
|
|
64
|
-
total_elapsed: now - (@turn_start || start),
|
|
65
|
-
total_llm_elapsed: @total_llm_elapsed,
|
|
66
|
-
llm_call_count: @call_count,
|
|
67
|
-
last_call_elapsed: elapsed
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
if response.respond_to?(:usage) && (u = response.usage)
|
|
71
|
-
env[:metadata][:tokens] = {
|
|
72
|
-
total: read_token(u, :total_tokens),
|
|
73
|
-
total_input: read_token(u, :input_tokens),
|
|
74
|
-
total_output: read_token(u, :output_tokens),
|
|
75
|
-
}
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
response
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
private
|
|
82
|
-
|
|
83
|
-
def read_token(usage, method)
|
|
84
|
-
if usage.respond_to?(method)
|
|
85
|
-
usage.send(method).to_i
|
|
86
|
-
elsif usage.respond_to?(:[])
|
|
87
|
-
(usage[method] || usage[method.to_s]).to_i
|
|
88
|
-
else
|
|
89
|
-
0
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
end
|