Class: LLM::Function::Fork::Task
- Defined in:
- lib/llm/function/fork/task.rb
Overview
The Task class wraps a fork-backed function call and exchanges control and result messages with the child process.
Instance Attribute Summary
Attributes inherited from Task
Instance Method Summary collapse
- #alive? ⇒ Boolean
- #group_class ⇒ Class
- #initialize(fn, options = {}) ⇒ LLM::Function::Fork::Task constructor
- #interrupt! ⇒ nil (also: #cancel!)
- #spawn ⇒ LLM::Function::Fork::Task
- #wait ⇒ LLM::Function::Return (also: #value)
Constructor Details
#initialize(fn, options = {}) ⇒ LLM::Function::Fork::Task
13 14 15 16 17 18 |
# File 'lib/llm/function/fork/task.rb', line 13 def initialize(fn, = {}) super @tracer = .fetch(:tracer, nil) @spawned = false @waited = false end |
Instance Method Details
#alive? ⇒ Boolean
54 55 56 57 58 59 60 61 62 |
# File 'lib/llm/function/fork/task.rb', line 54 def alive? return false if @waited || !@pid result = ::Process.waitpid(@pid, ::Process::WNOHANG) @waited = !result.nil? !@waited rescue Errno::ECHILD @waited = true false end |
#group_class ⇒ Class
97 98 99 |
# File 'lib/llm/function/fork/task.rb', line 97 def group_class LLM::Function::Fork::Group end |
#interrupt! ⇒ nil Also known as: cancel!
66 67 68 69 70 71 72 |
# File 'lib/llm/function/fork/task.rb', line 66 def interrupt! return nil if @waited @ch.control.write(:interrupt) nil rescue Errno::ESRCH, IOError nil end |
#spawn ⇒ LLM::Function::Fork::Task
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/llm/function/fork/task.rb', line 22 def spawn return if @guarded @span = @tracer&.on_tool_start( id: @function.id, name: @function.name, arguments: @function.arguments, model: @function.model ) @ch = LLM::Object.from( control: xchan(:marshal), result: xchan(:marshal, sock: Socket::SOCK_STREAM) ) @pid = Kernel.fork do ## # The child inherits the parent's terminal. When # the runtime runs under a curses REPL, a forked # tool reading or writing the tty would steal the # user's input or clobber the parent's display. # Point all three standard streams at null so the # child keeps off the user's terminal entirely. A # tool that genuinely needs the terminal can reopen # it via /dev/tty; the tty fd stays available to # the child. $stdin.reopen(File::NULL) $stdout.reopen(File::NULL) $stderr.reopen(File::NULL) Fork::Job.new(@function, @ch).call end @spawned = true self end |
#wait ⇒ LLM::Function::Return Also known as: value
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/llm/function/fork/task.rb', line 77 def wait return @guarded if @guarded spawn unless @spawned kind, data = @ch.result.recv raise LLM::Interrupt if kind == :interrupt raise ArgumentError, "Unknown fork message: #{kind.inspect}" unless kind == :result result = Return.new(data[:id], data[:name], data[:value]) reap @tracer&.on_tool_finish(result:, span: @span) result ensure if @guarded.nil? reap [@ch.control, @ch.result].each { _1.close unless _1.closed? } if @ch end end |