active_harness 0.2.21 → 0.2.23
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/active_harness/agent/hooks.rb +5 -12
- data/lib/active_harness/agent.rb +29 -30
- data/lib/active_harness/core/hooks.rb +26 -0
- data/lib/active_harness/pipeline/hooks.rb +6 -6
- data/lib/active_harness/pipeline.rb +76 -13
- data/lib/active_harness/tribunal/hooks.rb +8 -14
- data/lib/active_harness/tribunal.rb +24 -9
- data/lib/active_harness.rb +2 -1
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0bf8ac57d79582b07a2d82b29be4541fcaf10b3ee8492d362d6ac10f2843537d
|
|
4
|
+
data.tar.gz: cabffcc74dd594c5222a8e0233aa9d5f7276d65cfa06848d3e2684e19efe393e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '018677f5498399d22c2a1b497649e4676023eae7b2578b8b0c13962b1c443970f20e2af5e7ca15051f75d2903287ed9f12012407cf9a671ad1d5d688d8def153'
|
|
7
|
+
data.tar.gz: 5219e6c2a208ff1a2215a71d924c24ade46b6abebc94e9a21c7a36d931d9e32919e7ddc5b054ff7bb616b46057761138aa1a01ce21e66ef6978bb5802304cabe
|
|
@@ -32,7 +32,7 @@ module ActiveHarness
|
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
agent_config[:hooks] ||= {}
|
|
35
|
-
agent_config[:hooks][event]
|
|
35
|
+
(agent_config[:hooks][event] ||= []) << block
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
# Rails-style aliases for +on+:
|
|
@@ -59,27 +59,20 @@ module ActiveHarness
|
|
|
59
59
|
end
|
|
60
60
|
end
|
|
61
61
|
|
|
62
|
+
include Core::HookRunner
|
|
63
|
+
|
|
62
64
|
private
|
|
63
65
|
|
|
64
66
|
def run_hook(event, *args)
|
|
65
|
-
|
|
66
|
-
return unless hooks[event]
|
|
67
|
-
|
|
68
|
-
if args.any?
|
|
69
|
-
instance_exec(*args, &hooks[event])
|
|
70
|
-
else
|
|
71
|
-
instance_eval(&hooks[event])
|
|
72
|
-
end
|
|
67
|
+
run_hooks(@config[:hooks] || {}, event, *args)
|
|
73
68
|
end
|
|
74
69
|
|
|
75
70
|
# Unified internal method: fires the DSL hook AND the external event_stream lambda.
|
|
76
71
|
# Consistent with Tribunal#fire and Pipeline#fire.
|
|
77
72
|
def fire(event, *args)
|
|
78
|
-
|
|
73
|
+
run_hook(event, *args)
|
|
79
74
|
@event_stream&.call(event, *args)
|
|
80
|
-
result
|
|
81
75
|
rescue IOError, ActionController::Live::ClientDisconnected
|
|
82
|
-
result
|
|
83
76
|
end
|
|
84
77
|
end
|
|
85
78
|
end
|
data/lib/active_harness/agent.rb
CHANGED
|
@@ -10,9 +10,20 @@ module ActiveHarness
|
|
|
10
10
|
#
|
|
11
11
|
# SupportAgent.call(input: "Hi")
|
|
12
12
|
# SupportAgent.call(input: "Hi", context: { user_id: 42 })
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
def call(
|
|
14
|
+
input: nil,
|
|
15
|
+
context: {},
|
|
16
|
+
params: {},
|
|
17
|
+
models: nil,
|
|
18
|
+
streams: {}
|
|
19
|
+
)
|
|
20
|
+
new(
|
|
21
|
+
input: input,
|
|
22
|
+
context: context,
|
|
23
|
+
params: params,
|
|
24
|
+
models: models,
|
|
25
|
+
streams: streams
|
|
26
|
+
).call
|
|
16
27
|
end
|
|
17
28
|
|
|
18
29
|
# Each subclass gets its own isolated config hash.
|
|
@@ -36,28 +47,33 @@ module ActiveHarness
|
|
|
36
47
|
# -------------------------------------------------------------------------
|
|
37
48
|
# Instance API
|
|
38
49
|
# -------------------------------------------------------------------------
|
|
39
|
-
attr_accessor :input,
|
|
40
|
-
|
|
50
|
+
attr_accessor :input,
|
|
51
|
+
:context,
|
|
52
|
+
:params
|
|
53
|
+
attr_reader :result,
|
|
54
|
+
:token_stream,
|
|
55
|
+
:event_stream
|
|
41
56
|
|
|
42
57
|
def models=(list)
|
|
43
58
|
@models_override = Array(list)
|
|
44
59
|
@model_list_proxy = nil
|
|
45
60
|
end
|
|
46
61
|
|
|
47
|
-
def
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
62
|
+
def initialize(
|
|
63
|
+
input: nil,
|
|
64
|
+
context: {},
|
|
65
|
+
params: {},
|
|
66
|
+
models: nil,
|
|
67
|
+
streams: {}
|
|
68
|
+
)
|
|
52
69
|
@input = input
|
|
53
70
|
@config = self.class.agent_config
|
|
54
71
|
normalize_input!
|
|
55
72
|
@context = context
|
|
73
|
+
@params = params
|
|
56
74
|
@models_override = Array(models) if models
|
|
57
75
|
@token_stream = streams[:token]
|
|
58
76
|
@event_stream = streams[:agent]
|
|
59
|
-
# memory: can be passed directly or via context[:memory]
|
|
60
|
-
@memory = memory || @context[:memory]
|
|
61
77
|
fire(:setup)
|
|
62
78
|
end
|
|
63
79
|
|
|
@@ -76,9 +92,8 @@ module ActiveHarness
|
|
|
76
92
|
@token_stream = streams[:token] if streams.key?(:token)
|
|
77
93
|
@event_stream = streams[:agent] if streams.key?(:agent)
|
|
78
94
|
end
|
|
79
|
-
@memory&.load
|
|
80
|
-
@system_prompt = resolve_system_prompt
|
|
81
95
|
fire(:before_call)
|
|
96
|
+
@system_prompt = resolve_system_prompt
|
|
82
97
|
attempts = []
|
|
83
98
|
|
|
84
99
|
cfg = ActiveHarness.config
|
|
@@ -92,7 +107,6 @@ module ActiveHarness
|
|
|
92
107
|
response = retry_policy.run { attempt_model(entry, @system_prompt) }
|
|
93
108
|
elapsed = (Process.clock_gettime(Process::CLOCK_MONOTONIC) - t0).round(3)
|
|
94
109
|
result = build_result(response, entry, attempts, elapsed)
|
|
95
|
-
save_to_memory(result)
|
|
96
110
|
fire(:after_call, result)
|
|
97
111
|
@result = result
|
|
98
112
|
return self
|
|
@@ -145,21 +159,6 @@ module ActiveHarness
|
|
|
145
159
|
)
|
|
146
160
|
end
|
|
147
161
|
|
|
148
|
-
# Auto-save to memory if no manual record was done in after_call hook.
|
|
149
|
-
# Hooks fire after this method — if a hook calls memory.record manually,
|
|
150
|
-
# the automatic save here is still the first save (hook overrides are additive).
|
|
151
|
-
# To suppress auto-save, set @memory_auto_saved in the hook.
|
|
152
|
-
def save_to_memory(result)
|
|
153
|
-
return unless @memory
|
|
154
|
-
|
|
155
|
-
@memory.record(
|
|
156
|
-
request: @input,
|
|
157
|
-
response: result.output,
|
|
158
|
-
agent: self.class.name,
|
|
159
|
-
model: result.model
|
|
160
|
-
)
|
|
161
|
-
end
|
|
162
|
-
|
|
163
162
|
def normalize_input!
|
|
164
163
|
return if @config.fetch(:normalize_input, true) == false
|
|
165
164
|
@input = @input&.strip&.gsub(/\s+/, " ")
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module ActiveHarness
|
|
2
|
+
module Core
|
|
3
|
+
# Shared hook execution logic included by Agent, Tribunal, and Pipeline.
|
|
4
|
+
#
|
|
5
|
+
# Hooks are stored in arrays so multiple +on+/+before+/+after+/+callback+
|
|
6
|
+
# calls with the same event name accumulate — later registrations append
|
|
7
|
+
# rather than overwrite. This lets modules register default hooks without
|
|
8
|
+
# blocking user-defined hooks on the same event.
|
|
9
|
+
#
|
|
10
|
+
# class MyAgent < ActiveHarness::Agent
|
|
11
|
+
# include SomeTracingConcern # registers before(:call) internally
|
|
12
|
+
# before(:call) { ... } # appends — both hooks run in order
|
|
13
|
+
# end
|
|
14
|
+
module HookRunner
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
# Execute every block registered for +event+, passing +args+ to each.
|
|
18
|
+
# Blocks run in the receiver's instance context (instance_exec / instance_eval).
|
|
19
|
+
def run_hooks(hooks_hash, event, *args)
|
|
20
|
+
Array(hooks_hash[event]).each do |blk|
|
|
21
|
+
args.any? ? instance_exec(*args, &blk) : instance_eval(&blk)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -22,13 +22,13 @@ module ActiveHarness
|
|
|
22
22
|
"Per-step hooks support: #{VALID_STEP_HOOKS.join(", ")}. Got :#{event}"
|
|
23
23
|
end
|
|
24
24
|
pipeline_config[:step_hooks][step_name] ||= {}
|
|
25
|
-
pipeline_config[:step_hooks][step_name][event]
|
|
25
|
+
(pipeline_config[:step_hooks][step_name][event] ||= []) << block
|
|
26
26
|
else
|
|
27
27
|
unless VALID_HOOKS.include?(event)
|
|
28
28
|
raise ArgumentError,
|
|
29
29
|
"Unknown Pipeline hook :#{event}. Valid: #{VALID_HOOKS.join(", ")}"
|
|
30
30
|
end
|
|
31
|
-
pipeline_config[:hooks][event]
|
|
31
|
+
(pipeline_config[:hooks][event] ||= []) << block
|
|
32
32
|
end
|
|
33
33
|
end
|
|
34
34
|
|
|
@@ -56,12 +56,13 @@ module ActiveHarness
|
|
|
56
56
|
end
|
|
57
57
|
end
|
|
58
58
|
|
|
59
|
+
include Core::HookRunner
|
|
60
|
+
|
|
59
61
|
private
|
|
60
62
|
|
|
61
63
|
# Fires global hook AND pipeline_event_stream. Consistent with Agent#fire and Tribunal#fire.
|
|
62
64
|
def fire(event, step_name, data, config)
|
|
63
|
-
|
|
64
|
-
instance_exec(step_name, data, &blk) if blk
|
|
65
|
+
run_hooks(config[:hooks], event, step_name, data)
|
|
65
66
|
@pipeline_event_stream&.call(event, step_name, data)
|
|
66
67
|
rescue IOError, ActionController::Live::ClientDisconnected
|
|
67
68
|
nil
|
|
@@ -70,8 +71,7 @@ module ActiveHarness
|
|
|
70
71
|
# Per-step hook: receives (data) only — not forwarded to pipeline_event_stream
|
|
71
72
|
# (global fire already covers the step event with step_name context).
|
|
72
73
|
def fire_step(event, step_name, data, config)
|
|
73
|
-
|
|
74
|
-
instance_exec(data, &blk) if blk
|
|
74
|
+
run_hooks(config[:step_hooks][step_name] || {}, event, data)
|
|
75
75
|
end
|
|
76
76
|
end
|
|
77
77
|
end
|
|
@@ -51,39 +51,83 @@ module ActiveHarness
|
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
def pipeline_config
|
|
54
|
-
@pipeline_config ||= { steps: [], hooks: {}, step_hooks: {} }
|
|
54
|
+
@pipeline_config ||= { steps: [], hooks: {}, step_hooks: {}, streams: {} }
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
# Each subclass gets its own isolated config.
|
|
58
58
|
def inherited(subclass)
|
|
59
59
|
subclass.instance_variable_set(
|
|
60
60
|
:@pipeline_config,
|
|
61
|
-
{ steps: [], hooks: {}, step_hooks: {} }
|
|
61
|
+
{ steps: [], hooks: {}, step_hooks: {}, streams: {} }
|
|
62
62
|
)
|
|
63
63
|
end
|
|
64
|
+
|
|
65
|
+
# Class-level event stream handlers — fired for every matching event from
|
|
66
|
+
# any agent or tribunal executed within this pipeline (including agents
|
|
67
|
+
# running inside tribunals). Multiple blocks can be registered; all fire.
|
|
68
|
+
#
|
|
69
|
+
# The handler receives the same (event, *args) signature that the runtime
|
|
70
|
+
# streams: { agent: lambda } would receive.
|
|
71
|
+
#
|
|
72
|
+
# on_agent_event do |event, result|
|
|
73
|
+
# Rails.logger.info "[Agent #{event}] #{result.model}" if event == :after_call
|
|
74
|
+
# end
|
|
75
|
+
#
|
|
76
|
+
# on_tribunal_event do |event, verdict|
|
|
77
|
+
# Rails.logger.info "[Tribunal #{event}] verdict=#{verdict}" if event == :after_verdict
|
|
78
|
+
# end
|
|
79
|
+
#
|
|
80
|
+
# on_pipeline_event do |event, step_name, _data|
|
|
81
|
+
# Rails.logger.info "[Pipeline #{event}] step=#{step_name}"
|
|
82
|
+
# end
|
|
83
|
+
def on_agent_event(&block)
|
|
84
|
+
(pipeline_config[:streams][:agent] ||= []) << block
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def on_tribunal_event(&block)
|
|
88
|
+
(pipeline_config[:streams][:tribunal] ||= []) << block
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def on_pipeline_event(&block)
|
|
92
|
+
(pipeline_config[:streams][:pipeline] ||= []) << block
|
|
93
|
+
end
|
|
64
94
|
end
|
|
65
95
|
|
|
66
96
|
# -------------------------------------------------------------------------
|
|
67
97
|
# Instance API
|
|
68
98
|
# -------------------------------------------------------------------------
|
|
69
|
-
attr_reader
|
|
70
|
-
|
|
71
|
-
|
|
99
|
+
attr_reader :original_input,
|
|
100
|
+
:output,
|
|
101
|
+
:stopped_at,
|
|
102
|
+
:stop_reason,
|
|
103
|
+
:execution_time,
|
|
104
|
+
:step_results,
|
|
105
|
+
:context
|
|
106
|
+
attr_writer :context
|
|
107
|
+
attr_accessor :params
|
|
72
108
|
|
|
73
109
|
def input=(value)
|
|
74
110
|
@original_input = value
|
|
75
111
|
@payload = value
|
|
76
112
|
end
|
|
77
113
|
|
|
78
|
-
def initialize(
|
|
114
|
+
def initialize(
|
|
115
|
+
input:,
|
|
116
|
+
context: {},
|
|
117
|
+
params: {},
|
|
118
|
+
memory: nil,
|
|
119
|
+
streams: {}
|
|
120
|
+
)
|
|
79
121
|
@original_input = input
|
|
80
122
|
@payload = input
|
|
81
123
|
@context = context.dup
|
|
124
|
+
@params = params
|
|
82
125
|
@memory = memory
|
|
83
126
|
@token_stream = streams[:token]
|
|
84
|
-
|
|
85
|
-
@
|
|
86
|
-
@
|
|
127
|
+
class_streams = self.class.pipeline_config[:streams] || {}
|
|
128
|
+
@agent_event_stream = merge_stream(streams[:agent], class_streams[:agent])
|
|
129
|
+
@tribunal_event_stream = merge_stream(streams[:tribunal], class_streams[:tribunal])
|
|
130
|
+
@pipeline_event_stream = merge_stream(streams[:pipeline], class_streams[:pipeline])
|
|
87
131
|
@step_results = {}
|
|
88
132
|
@stopped = false
|
|
89
133
|
@stopped_at = nil
|
|
@@ -120,8 +164,7 @@ module ActiveHarness
|
|
|
120
164
|
@stopped = true
|
|
121
165
|
@stopped_at = step.name
|
|
122
166
|
@stop_reason = result
|
|
123
|
-
|
|
124
|
-
instance_exec(step.name, result, &blk) if blk
|
|
167
|
+
run_hooks(config[:hooks], :stopped, step.name, result)
|
|
125
168
|
@pipeline_event_stream&.call(:stopped, step.name, result)
|
|
126
169
|
break
|
|
127
170
|
end
|
|
@@ -138,8 +181,7 @@ module ActiveHarness
|
|
|
138
181
|
)
|
|
139
182
|
|
|
140
183
|
last_result = @step_results[@step_results.keys.last]
|
|
141
|
-
|
|
142
|
-
instance_exec(last_result, &blk) if blk
|
|
184
|
+
run_hooks(config[:hooks], :complete, last_result)
|
|
143
185
|
@pipeline_event_stream&.call(:complete, last_result)
|
|
144
186
|
end
|
|
145
187
|
|
|
@@ -148,12 +190,32 @@ module ActiveHarness
|
|
|
148
190
|
|
|
149
191
|
private
|
|
150
192
|
|
|
193
|
+
# Combines a runtime-passed stream lambda with zero or more class-level handler
|
|
194
|
+
# blocks registered via on_agent_event / on_tribunal_event / on_pipeline_event.
|
|
195
|
+
# Returns nil when there are no handlers at all, preserving the existing
|
|
196
|
+
# "no stream" fast path in agents and tribunals.
|
|
197
|
+
#
|
|
198
|
+
# Each class-level handler is evaluated via instance_exec so that blocks
|
|
199
|
+
# written in the pipeline class body can access pipeline instance variables
|
|
200
|
+
# (e.g. @otel_pipeline_span, @params) and call pipeline instance methods.
|
|
201
|
+
def merge_stream(passed_in, class_handlers)
|
|
202
|
+
class_handlers = Array(class_handlers).compact
|
|
203
|
+
return passed_in if class_handlers.empty?
|
|
204
|
+
|
|
205
|
+
pipeline_instance = self
|
|
206
|
+
->(event, *args) {
|
|
207
|
+
class_handlers.each { |h| pipeline_instance.instance_exec(event, *args, &h) }
|
|
208
|
+
passed_in&.call(event, *args)
|
|
209
|
+
}
|
|
210
|
+
end
|
|
211
|
+
|
|
151
212
|
def execute_step(step)
|
|
152
213
|
if step.tribunal?
|
|
153
214
|
agent_streams = { token: @token_stream, agent: @agent_event_stream, tribunal: @tribunal_event_stream }.compact
|
|
154
215
|
step.agent_class.new(
|
|
155
216
|
input: @payload,
|
|
156
217
|
context: @context.dup,
|
|
218
|
+
params: @params,
|
|
157
219
|
streams: agent_streams
|
|
158
220
|
).call
|
|
159
221
|
else
|
|
@@ -161,6 +223,7 @@ module ActiveHarness
|
|
|
161
223
|
step.agent_class.new(
|
|
162
224
|
input: @payload,
|
|
163
225
|
context: @context.dup,
|
|
226
|
+
params: @params,
|
|
164
227
|
streams: agent_streams
|
|
165
228
|
).call.result
|
|
166
229
|
end
|
|
@@ -26,7 +26,7 @@ module ActiveHarness
|
|
|
26
26
|
"Unknown Tribunal hook :#{event}. Valid hooks: #{VALID_HOOKS.map { |h| ":#{h}" }.join(", ")}"
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
tribunal_config[:hooks][event]
|
|
29
|
+
(tribunal_config[:hooks][event] ||= []) << block
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
# Rails-style aliases for +on+:
|
|
@@ -51,7 +51,7 @@ module ActiveHarness
|
|
|
51
51
|
end
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
-
# Instance-level hook registration —
|
|
54
|
+
# Instance-level hook registration — appends to class-level hooks for this event.
|
|
55
55
|
# :before_verdict is a transform hook: its return value replaces the results array
|
|
56
56
|
# passed to the process block.
|
|
57
57
|
def on(event, &block)
|
|
@@ -60,20 +60,16 @@ module ActiveHarness
|
|
|
60
60
|
"Unknown Tribunal hook :#{event}. Valid hooks: #{VALID_HOOKS.map { |h| ":#{h}" }.join(", ")}"
|
|
61
61
|
end
|
|
62
62
|
|
|
63
|
-
@hooks[event]
|
|
63
|
+
(@hooks[event] ||= []) << block
|
|
64
64
|
self
|
|
65
65
|
end
|
|
66
66
|
|
|
67
|
+
include Core::HookRunner
|
|
68
|
+
|
|
67
69
|
private
|
|
68
70
|
|
|
69
71
|
def run_hook(event, *args)
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
if args.any?
|
|
73
|
-
instance_exec(*args, &@hooks[event])
|
|
74
|
-
else
|
|
75
|
-
instance_eval(&@hooks[event])
|
|
76
|
-
end
|
|
72
|
+
run_hooks(@hooks, event, *args)
|
|
77
73
|
end
|
|
78
74
|
|
|
79
75
|
# Fire the DSL-registered hook AND the external tribunal_event_stream lambda (if set).
|
|
@@ -84,12 +80,10 @@ module ActiveHarness
|
|
|
84
80
|
nil
|
|
85
81
|
end
|
|
86
82
|
|
|
87
|
-
# Like run_hook but
|
|
83
|
+
# Like run_hook but chains all blocks, passing each return value to the next.
|
|
88
84
|
# Used by :before_verdict to allow results transformation before verdict computation.
|
|
89
85
|
def transform_hook(event, value)
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
instance_exec(value, &@hooks[event])
|
|
86
|
+
Array(@hooks[event]).reduce(value) { |val, blk| instance_exec(val, &blk) }
|
|
93
87
|
end
|
|
94
88
|
end
|
|
95
89
|
end
|
|
@@ -46,24 +46,39 @@ module ActiveHarness
|
|
|
46
46
|
# -------------------------------------------------------------------------
|
|
47
47
|
# Instance API
|
|
48
48
|
# -------------------------------------------------------------------------
|
|
49
|
-
attr_accessor :input,
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
49
|
+
attr_accessor :input,
|
|
50
|
+
:context,
|
|
51
|
+
:params
|
|
52
|
+
attr_reader :results,
|
|
53
|
+
:errors,
|
|
54
|
+
:verdict,
|
|
55
|
+
:execution_time,
|
|
56
|
+
:agent_execution_times,
|
|
57
|
+
:token_stream,
|
|
58
|
+
:agent_event_stream,
|
|
59
|
+
:tribunal_event_stream
|
|
60
|
+
|
|
61
|
+
def initialize(
|
|
62
|
+
input: nil,
|
|
63
|
+
context: {},
|
|
64
|
+
params: {},
|
|
65
|
+
agents: nil,
|
|
66
|
+
timeout: 7,
|
|
67
|
+
streams: {},
|
|
68
|
+
may_fail: :_unset
|
|
69
|
+
)
|
|
56
70
|
config = self.class.tribunal_config
|
|
57
71
|
|
|
58
72
|
@input = input
|
|
59
73
|
@context = context
|
|
74
|
+
@params = params
|
|
60
75
|
@agents = agents || config[:agents]
|
|
61
76
|
@timeout = timeout
|
|
62
77
|
@process_block = config[:process]
|
|
63
78
|
@strategy = config[:strategy]
|
|
64
79
|
@evaluate_block = config[:evaluate_block]
|
|
65
80
|
@may_fail = may_fail == :_unset ? config[:may_fail] : may_fail
|
|
66
|
-
@hooks = config[:hooks].dup
|
|
81
|
+
@hooks = config[:hooks].transform_values { |v| Array(v).dup }
|
|
67
82
|
@token_stream = streams[:token]
|
|
68
83
|
@agent_event_stream = streams[:agent]
|
|
69
84
|
@tribunal_event_stream = streams[:tribunal]
|
|
@@ -155,7 +170,7 @@ module ActiveHarness
|
|
|
155
170
|
agent_streams = { token: @token_stream, agent: @agent_event_stream }.compact
|
|
156
171
|
@agents.map do |agent|
|
|
157
172
|
if agent.is_a?(Class)
|
|
158
|
-
agent.new(input: @input, context: @context.dup, streams: agent_streams)
|
|
173
|
+
agent.new(input: @input, context: @context.dup, params: @params, streams: agent_streams)
|
|
159
174
|
else
|
|
160
175
|
agent.input = @input if @input
|
|
161
176
|
agent.instance_variable_set(:@token_stream, @token_stream) if @token_stream
|
data/lib/active_harness.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require_relative "active_harness/configuration"
|
|
2
2
|
require_relative "active_harness/core/errors"
|
|
3
|
+
require_relative "active_harness/core/hooks"
|
|
3
4
|
require_relative "active_harness/result"
|
|
4
5
|
require_relative "active_harness/http/client"
|
|
5
6
|
require_relative "active_harness/http/streaming_client"
|
|
@@ -29,7 +30,7 @@ require_relative "active_harness/pipeline"
|
|
|
29
30
|
require_relative "active_harness/railtie" if defined?(Rails::Railtie)
|
|
30
31
|
|
|
31
32
|
module ActiveHarness
|
|
32
|
-
VERSION = "0.2.
|
|
33
|
+
VERSION = "0.2.23"
|
|
33
34
|
|
|
34
35
|
class << self
|
|
35
36
|
# Configure ActiveHarness.
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: active_harness
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.23
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- the-teacher
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-06-09 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: concurrent-ruby
|
|
@@ -42,6 +42,7 @@ files:
|
|
|
42
42
|
- lib/active_harness/agent/providers.rb
|
|
43
43
|
- lib/active_harness/configuration.rb
|
|
44
44
|
- lib/active_harness/core/errors.rb
|
|
45
|
+
- lib/active_harness/core/hooks.rb
|
|
45
46
|
- lib/active_harness/costs.rb
|
|
46
47
|
- lib/active_harness/data/models.json
|
|
47
48
|
- lib/active_harness/http/client.rb
|