Class: WritersRoom::Room
- Inherits:
-
Object
- Object
- WritersRoom::Room
- Defined in:
- lib/writers_room/room.rb
Overview
Scene container that holds the bus, shared memory, and actor roster.
Modeled on RobotLab example 16's Room pattern: actors communicate through a shared bus channel, use shared memory for persistence, and the Room coordinates completion detection.
Instance Attribute Summary collapse
-
#actors ⇒ Object
readonly
Returns the value of attribute actors.
-
#bus ⇒ Object
readonly
Returns the value of attribute bus.
-
#config ⇒ Object
readonly
Returns the value of attribute config.
-
#display ⇒ Object
readonly
Returns the value of attribute display.
-
#memory ⇒ Object
readonly
Returns the value of attribute memory.
-
#scene_info ⇒ Object
readonly
Returns the value of attribute scene_info.
Instance Method Summary collapse
-
#add_actor(name, character_info:) ⇒ Actor
Add an actor to the room.
-
#assemble_transcript ⇒ Array<Hash>
Assemble the transcript from shared memory.
-
#initialize(display:, config:, scene_info:) ⇒ Room
constructor
A new instance of Room.
-
#seed(opening_prompt) ⇒ Object
Seed the scene by publishing the opening prompt from the "director".
-
#shutdown ⇒ Object
Disconnect all actors and close the bus.
-
#wait_for_completion(timeout: 300, max_lines: 50, poll_interval: 2, heartbeat_interval: 30) ⇒ Boolean
Wait for the scene to complete.
Constructor Details
#initialize(display:, config:, scene_info:) ⇒ Room
Returns a new instance of Room.
16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/writers_room/room.rb', line 16 def initialize(display:, config:, scene_info:) @bus = TypedBus::MessageBus.new @memory = RobotLab::Memory.new(enable_cache: false) @display = display @config = config @scene_info = scene_info @actors = {} # Shared broadcast channel for the scene @bus.add_channel(:scene) end |
Instance Attribute Details
#actors ⇒ Object (readonly)
Returns the value of attribute actors.
11 12 13 |
# File 'lib/writers_room/room.rb', line 11 def actors @actors end |
#bus ⇒ Object (readonly)
Returns the value of attribute bus.
11 12 13 |
# File 'lib/writers_room/room.rb', line 11 def bus @bus end |
#config ⇒ Object (readonly)
Returns the value of attribute config.
11 12 13 |
# File 'lib/writers_room/room.rb', line 11 def config @config end |
#display ⇒ Object (readonly)
Returns the value of attribute display.
11 12 13 |
# File 'lib/writers_room/room.rb', line 11 def display @display end |
#memory ⇒ Object (readonly)
Returns the value of attribute memory.
11 12 13 |
# File 'lib/writers_room/room.rb', line 11 def memory @memory end |
#scene_info ⇒ Object (readonly)
Returns the value of attribute scene_info.
11 12 13 |
# File 'lib/writers_room/room.rb', line 11 def scene_info @scene_info end |
Instance Method Details
#add_actor(name, character_info:) ⇒ Actor
Add an actor to the room.
33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/writers_room/room.rb', line 33 def add_actor(name, character_info:) actor = Actor.new( character_info: character_info, scene_info: @scene_info, bus: @bus, shared_memory: @memory, display: @display, room: self, config: @config ) @actors[name] = actor actor end |
#assemble_transcript ⇒ Array<Hash>
Assemble the transcript from shared memory.
114 115 116 |
# File 'lib/writers_room/room.rb', line 114 def assemble_transcript @memory.get(:dialog_history) || [] end |
#seed(opening_prompt) ⇒ Object
Seed the scene by publishing the opening prompt from the "director". Uses a director identity so actors don't filter it as their own message.
51 52 53 54 55 56 57 58 59 60 |
# File 'lib/writers_room/room.rb', line 51 def seed(opening_prompt) return if @actors.empty? = RobotLab::RobotMessage.build( id: 0, from: "director", content: opening_prompt ) Async { @bus.publish(:scene, ) } end |
#shutdown ⇒ Object
Disconnect all actors and close the bus.
119 120 121 122 123 124 125 126 127 |
# File 'lib/writers_room/room.rb', line 119 def shutdown @actors.each_value do |actor| actor.disconnect @display.info(" - #{actor.name} has left the stage") end @bus.close_all @actors.clear @display.close end |
#wait_for_completion(timeout: 300, max_lines: 50, poll_interval: 2, heartbeat_interval: 30) ⇒ Boolean
Wait for the scene to complete.
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/writers_room/room.rb', line 69 def wait_for_completion(timeout: 300, max_lines: 50, poll_interval: 2, heartbeat_interval: 30) deadline = Time.now + timeout last_heartbeat = Time.now @last_line_count = 0 loop do # Check if scene was marked complete by an actor if @memory.key?(:scene_complete) @display.director_note("Scene complete!") return true end # Check line count safety net history = @memory.get(:dialog_history) || [] if history.length >= max_lines @display.director_note("Maximum lines reached (#{max_lines})") @memory.set(:scene_complete, true) return true end # Check timeout if Time.now > deadline @display.director_note("Scene timeout reached (#{timeout}s)") return false end # Heartbeat: display status and nudge actors if dialog has stalled if Time.now - last_heartbeat >= heartbeat_interval send_heartbeat(history.length, max_lines) if history.length == @last_line_count send_director_nudge(history) end @last_line_count = history.length last_heartbeat = Time.now end sleep poll_interval end end |