Class: Agent::SessionContext::LoopView
- Inherits:
-
Object
- Object
- Agent::SessionContext::LoopView
- Defined in:
- lib/agent/session_context/loop_view.rb
Overview
Renders one Loop for a human (#ascii, #markdown) or a machine (#to_h).
Every rendering prints SIZES, never BODIES. A transcript can hold a credential or a customer's data anywhere — even a shell command line can carry a token — and this gem has no redaction before milestone 0.5, so a truncated preview is not a safer middle ground; it is the same leak with extra steps. A byte count and a tool name carry enough signal to see what a loop did without carrying what it said.
Every timestamp goes through #utc: two renderings of the same file must be byte-identical no matter which machine or time zone reads it, and a local time would make that false for a fact (the recorded instant) that has not actually changed.
The ending is always printed as inferred, because Loop#ending is always a deduction — no on-disk transcript records WHY a session stopped, since that fact lives in a non-interactive run's streamed output, never in the file itself. Printing it as a plain fact would claim information the file does not hold.
Constant Summary collapse
- YOU_LANE =
2- HARNESS_LANE =
15- MODEL_LANE =
50- LABEL_SHAPE =
A label is a record TYPE name (hook_success, turn_duration), never prose — but the field carrying it is a free String, so this shape check is what actually keeps R9 (no bodies) true the day a format starts putting a sentence there instead of a type name.
/\A[A-Za-z0-9_.:-]{1,64}\z/
Instance Method Summary collapse
- #ascii ⇒ Object
-
#initialize(loop_model) ⇒ LoopView
constructor
A new instance of LoopView.
- #markdown ⇒ Object
- #to_h ⇒ Object
Constructor Details
#initialize(loop_model) ⇒ LoopView
Returns a new instance of LoopView.
35 36 37 |
# File 'lib/agent/session_context/loop_view.rb', line 35 def initialize(loop_model) @loop = loop_model end |
Instance Method Details
#ascii ⇒ Object
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/agent/session_context/loop_view.rb', line 39 def ascii lines = [ "session #{@loop.session.uid}", "round trips: #{@loop.round_trips.size} (grouping: #{grouping})", "tool calls: #{@loop.tool_calls.size} (#{unanswered_count} unanswered)", "", ascii_header ] @loop.round_trips.each { |trip| lines.concat(ascii_round_trip(trip)) } lines << "" << "ending: #{@loop.ending} (inferred) — #{@loop.ending_detail}" if @loop.warnings.any? lines << "" << "warnings:" @loop.warnings.each { |warning| lines << " - #{warning}" } end "#{lines.join("\n")}\n" end |
#markdown ⇒ Object
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/agent/session_context/loop_view.rb', line 56 def markdown lines = ["# session #{@loop.session.uid}", "", "- round trips: #{@loop.round_trips.size} (grouping: #{grouping})", "- tool calls: #{@loop.tool_calls.size} (#{unanswered_count} unanswered)", "", "## Round trips", ""] @loop.round_trips.each { |trip| lines << markdown_round_trip(trip) } lines << "" << "## Tool calls" << "" lines.concat(markdown_tool_calls_table) lines << "" << "## Ending" << "" << "#{@loop.ending} (inferred) — #{@loop.ending_detail}" if @loop.warnings.any? lines << "" << "## Warnings" << "" @loop.warnings.each { |warning| lines << "- #{warning}" } end "#{lines.join("\n")}\n" end |
#to_h ⇒ Object
72 73 74 75 76 77 78 79 80 81 |
# File 'lib/agent/session_context/loop_view.rb', line 72 def to_h { session: { agent: @loop.session.agent, id: @loop.session.id, uid: @loop.session.uid }, round_trips: @loop.round_trips.map { |trip| round_trip_h(trip) }, tool_calls: @loop.tool_calls.map { |call| tool_call_h(call) }, ending: { name: @loop.ending, detail: @loop.ending_detail, inferred: true }, recorded: @loop.recorded, warnings: @loop.warnings } end |