Class: RobotLab::A2A::IoBridge

Inherits:
Object
  • Object
show all
Defined in:
lib/robot_lab/a2a/io_bridge.rb

Overview

IO-compatible wrapper for :io_bridge interactive mode.

Inject as both robot.input and robot.output before robot.run(). Output written by AskUser (the prompt text) is buffered; when AskUser calls gets(), the buffer becomes the input_required message and the call blocks until the A2A client resumes the task with an answer.

This lets existing robots that use RobotLab::AskUser work under A2A without any modification — the terminal is replaced by the HTTP protocol.

Only works with in-process storage: the robot thread must stay alive between INPUT_REQUIRED and resume.

Instance Method Summary collapse

Constructor Details

#initialize(event_queue:, answer_queue:) ⇒ IoBridge

Returns a new instance of IoBridge.



18
19
20
21
22
23
# File 'lib/robot_lab/a2a/io_bridge.rb', line 18

def initialize(event_queue:, answer_queue:)
  @event_queue   = event_queue
  @answer_queue  = answer_queue
  @output_buffer = +''
  @buffer_mutex  = Mutex.new
end

Instance Method Details

#flushObject



48
49
50
# File 'lib/robot_lab/a2a/io_bridge.rb', line 48

def flush
  self
end

#getsObject

— input side (robot.input) —



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/robot_lab/a2a/io_bridge.rb', line 58

def gets
  prompt_text = @buffer_mutex.synchronize do
    text = @output_buffer.dup.strip
    @output_buffer.clear
    text
  end

  prompt = ::A2A::Models::Message.agent(
    prompt_text.empty? ? 'Input required:' : prompt_text
  )
  @event_queue.push({ type: :ask, prompt: prompt })

  answer = @answer_queue.pop
  "#{answer}\n"
end

— output side (robot.output) —



27
28
29
30
# File 'lib/robot_lab/a2a/io_bridge.rb', line 27

def print(*args)
  @buffer_mutex.synchronize { @output_buffer << args.join }
  nil
end

#puts(*args) ⇒ Object



32
33
34
35
36
37
38
39
40
41
# File 'lib/robot_lab/a2a/io_bridge.rb', line 32

def puts(*args)
  @buffer_mutex.synchronize do
    if args.empty?
      @output_buffer << "\n"
    else
      args.each { |a| @output_buffer << a.to_s << "\n" }
    end
  end
  nil
end

#sync=Object



52
53
54
# File 'lib/robot_lab/a2a/io_bridge.rb', line 52

def sync=(*)
  # no-op — satisfy IO compatibility
end

#write(str) ⇒ Object



43
44
45
46
# File 'lib/robot_lab/a2a/io_bridge.rb', line 43

def write(str)
  @buffer_mutex.synchronize { @output_buffer << str.to_s }
  str.to_s.length
end