Class: Silas::LogSubscriber
- Inherits:
-
ActiveSupport::LogSubscriber
- Object
- ActiveSupport::LogSubscriber
- Silas::LogSubscriber
- Defined in:
- lib/silas/log_subscriber.rb
Overview
Turns the loop's notifications into log lines, at levels that match what an operator actually wants paged about: parks and rescues are INFO (a human is now in the loop, or a crash was recovered), budget breaches and nondeterminism are WARN, failed turns are ERROR, and the per-step/per-token chatter stays DEBUG.
Attach is automatic (see Silas::Engine). To silence just Silas:
Silas.logger = Logger.new(IO::NULL)
Instance Method Summary collapse
- #approval(event) ⇒ Object
- #budget(event) ⇒ Object
- #compact(event) ⇒ Object
- #nondeterminism(event) ⇒ Object
- #park(event) ⇒ Object
- #rescue(event) ⇒ Object
- #resume(event) ⇒ Object
- #step(event) ⇒ Object
- #tool(event) ⇒ Object
- #turn(event) ⇒ Object
Instance Method Details
#approval(event) ⇒ Object
41 42 43 44 |
# File 'lib/silas/log_subscriber.rb', line 41 def approval(event) info formatted_event(event, action: "Approval #{event.payload[:action]}", **event.payload.slice(:tool, :by, :turn_id).compact) end |
#budget(event) ⇒ Object
46 47 48 49 |
# File 'lib/silas/log_subscriber.rb', line 46 def budget(event) warn formatted_event(event, action: "Budget reached (#{event.payload[:reason]})", **event.payload.slice(:turn_id).compact) end |
#compact(event) ⇒ Object
51 52 53 54 |
# File 'lib/silas/log_subscriber.rb', line 51 def compact(event) info formatted_event(event, action: "Compacted through turn #{event.payload[:up_to_turn_index]}", **event.payload.slice(:session_id, :turn_id, :tokens_before, :output_tokens).compact) end |
#nondeterminism(event) ⇒ Object
56 57 58 59 |
# File 'lib/silas/log_subscriber.rb', line 56 def nondeterminism(event) error formatted_event(event, action: "Definitions changed mid-turn", **event.payload.slice(:turn_id, :was, :now).compact) end |
#park(event) ⇒ Object
30 31 32 33 |
# File 'lib/silas/log_subscriber.rb', line 30 def park(event) info formatted_event(event, action: "Turn parked (#{event.payload[:reason]})", **event.payload.slice(:turn_id, :detail).compact) end |
#rescue(event) ⇒ Object
61 62 63 64 65 66 |
# File 'lib/silas/log_subscriber.rb', line 61 def rescue(event) payload = event.payload return if payload[:rescued].to_i.zero? && payload[:stranded].to_i.zero? info formatted_event(event, action: "Rescuer", **payload.slice(:rescued, :stranded)) end |
#resume(event) ⇒ Object
35 36 37 38 39 |
# File 'lib/silas/log_subscriber.rb', line 35 def resume(event) parked_for = event.payload[:parked_for] info formatted_event(event, action: "Turn resumed after #{parked_for&.round(1)}s parked", **event.payload.slice(:turn_id).compact) end |
#step(event) ⇒ Object
19 20 21 22 |
# File 'lib/silas/log_subscriber.rb', line 19 def step(event) debug formatted_event(event, action: "Model call", **event.payload.slice(:turn_id, :index, :model).compact) end |
#tool(event) ⇒ Object
24 25 26 27 28 |
# File 'lib/silas/log_subscriber.rb', line 24 def tool(event) line = formatted_event(event, action: "Tool #{event.payload[:tool]}", **event.payload.slice(:effect_mode, :status, :approval_state, :turn_id).compact) event.payload[:status].to_s == "failed" ? warn(line) : info(line) end |
#turn(event) ⇒ Object
12 13 14 15 16 17 |
# File 'lib/silas/log_subscriber.rb', line 12 def turn(event) status = event.payload[:status] line = formatted_event(event, action: "Turn #{status}", **event.payload.slice(:turn_id, :session_id, :agent, :steps, :reason).compact) status.to_s == "failed" ? error(line) : info(line) end |