Class: RubynCode::Teams::Mailbox
- Inherits:
-
Object
- Object
- RubynCode::Teams::Mailbox
- Defined in:
- lib/rubyn_code/teams/mailbox.rb
Overview
JSONL-based mailbox for inter-agent messaging backed by SQLite.
Messages are stored in the ‘mailbox_messages` table with structured JSON content. Each message tracks read/unread state per recipient.
Instance Method Summary collapse
-
#broadcast(from:, content:, all_names:) ⇒ Array<String>
Broadcasts a message from one agent to all other agents.
-
#initialize(db) ⇒ Mailbox
constructor
A new instance of Mailbox.
-
#pending_for(name) ⇒ Array<Hash>
Returns unread messages for the given agent WITHOUT marking them as read.
-
#read_inbox(name) ⇒ Array<Hash>
Reads all unread messages for the given agent and marks them as read.
-
#send(from:, to:, content:, message_type: 'message') ⇒ String
Sends a message from one agent to another.
-
#unread_count(name) ⇒ Integer
Returns the count of unread messages for the given agent.
Constructor Details
#initialize(db) ⇒ Mailbox
Returns a new instance of Mailbox.
14 15 16 17 |
# File 'lib/rubyn_code/teams/mailbox.rb', line 14 def initialize(db) @db = db ensure_table! end |
Instance Method Details
#broadcast(from:, content:, all_names:) ⇒ Array<String>
Broadcasts a message from one agent to all other agents.
85 86 87 88 89 90 91 |
# File 'lib/rubyn_code/teams/mailbox.rb', line 85 def broadcast(from:, content:, all_names:) recipients = all_names.reject { |n| n == from } recipients.map do |recipient| send(from: from, to: recipient, content: content, message_type: 'broadcast') end end |
#pending_for(name) ⇒ Array<Hash>
Returns unread messages for the given agent WITHOUT marking them as read. Used by IdlePoller to check for pending work without consuming messages.
98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/rubyn_code/teams/mailbox.rb', line 98 def pending_for(name) rows = @db.query( <<~SQL, SELECT payload FROM mailbox_messages WHERE recipient = ? AND read = 0 ORDER BY created_at ASC SQL [name] ).to_a rows.map { |r| JSON.parse(r['payload'], symbolize_names: true) } end |
#read_inbox(name) ⇒ Array<Hash>
Reads all unread messages for the given agent and marks them as read.
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/rubyn_code/teams/mailbox.rb', line 54 def read_inbox(name) rows = @db.query( <<~SQL, SELECT id, payload FROM mailbox_messages WHERE recipient = ? AND read = 0 ORDER BY created_at ASC SQL [name] ).to_a return [] if rows.empty? ids = rows.map { |r| r['id'] } = rows.map { |r| JSON.parse(r['payload'], symbolize_names: true) } # Mark all fetched messages as read in a single statement placeholders = ids.map { '?' }.join(', ') @db.execute( "UPDATE mailbox_messages SET read = 1 WHERE id IN (#{placeholders})", ids ) end |
#send(from:, to:, content:, message_type: 'message') ⇒ String
Sends a message from one agent to another.
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/rubyn_code/teams/mailbox.rb', line 26 def send(from:, to:, content:, message_type: 'message') id = SecureRandom.uuid now = Time.now.utc.iso8601 payload = JSON.generate({ id: id, from: from, to: to, content: content, message_type: , timestamp: now }) @db.execute( <<~SQL, INSERT INTO mailbox_messages (id, sender, recipient, message_type, payload, read, created_at) VALUES (?, ?, ?, ?, ?, 0, ?) SQL [id, from, to, , payload, now] ) id end |
#unread_count(name) ⇒ Integer
Returns the count of unread messages for the given agent.
115 116 117 118 119 120 121 |
# File 'lib/rubyn_code/teams/mailbox.rb', line 115 def unread_count(name) rows = @db.query( 'SELECT COUNT(*) AS cnt FROM mailbox_messages WHERE recipient = ? AND read = 0', [name] ).to_a rows.first&.fetch('cnt', 0) || 0 end |