Class: LittleGhost::CodeMode::Javascript::Client::Program

Inherits:
Object
  • Object
show all
Defined in:
lib/little_ghost/code_mode/javascript/client.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(id:, owner:, dispatcher:, generation: nil) ⇒ Program

Returns a new instance of Program.



41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/little_ghost/code_mode/javascript/client.rb', line 41

def initialize(id:, owner:, dispatcher:, generation: nil)
  @id = id
  @owner = owner
  @dispatcher = dispatcher
  @generation = generation
  @outputs = []
  @output_bytes = 0
  @returned_output = false
  @terminal = nil
  @termination_error = nil
  @client_termination_requested = false
  @mutex = Mutex.new
  @condition = ConditionVariable.new
end

Instance Attribute Details

#dispatcherObject (readonly)

Returns the value of attribute dispatcher.



39
40
41
# File 'lib/little_ghost/code_mode/javascript/client.rb', line 39

def dispatcher
  @dispatcher
end

#generationObject (readonly)

Returns the value of attribute generation.



39
40
41
# File 'lib/little_ghost/code_mode/javascript/client.rb', line 39

def generation
  @generation
end

#idObject (readonly)

Returns the value of attribute id.



39
40
41
# File 'lib/little_ghost/code_mode/javascript/client.rb', line 39

def id
  @id
end

#ownerObject (readonly)

Returns the value of attribute owner.



39
40
41
# File 'lib/little_ghost/code_mode/javascript/client.rb', line 39

def owner
  @owner
end

Instance Method Details

#claim_client_failure(error) ⇒ Object



103
104
105
106
107
108
109
110
111
# File 'lib/little_ghost/code_mode/javascript/client.rb', line 103

def claim_client_failure(error)
  @mutex.synchronize do
    return false if @terminal

    @client_termination_requested = true
    @termination_error = error
    true
  end
end

#client_termination_requested?Boolean

Returns:

  • (Boolean)


113
114
115
# File 'lib/little_ghost/code_mode/javascript/client.rb', line 113

def client_termination_requested?
  @mutex.synchronize { @client_termination_requested }
end

#complete(status:, error: nil) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/little_ghost/code_mode/javascript/client.rb', line 73

def complete(status:, error: nil)
  @mutex.synchronize do
    return if @terminal

    if status == "completed" && @termination_error
      status = "failed"
      error = @termination_error
    end
    @terminal = {status:, error:}.compact
    @condition.broadcast
  end
end

#observe(timeout:, max_tokens:, context: nil) ⇒ Object



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/little_ghost/code_mode/javascript/client.rb', line 117

def observe(timeout:, max_tokens:, context: nil)
  deadline = monotonic + timeout
  @mutex.synchronize do
    loop do
      context&.check!
      break if @terminal || monotonic >= deadline

      @condition.wait(@mutex, [deadline - monotonic, 0.05].min)
    end
    output = drain_output
    output = LittleGhost::Support::OutputTruncation
      .truncate_middle_with_token_budget(output, max_tokens).first
    (@terminal || {status: "still_working"}).merge(program_id: id, output:)
  end
end

#output(value) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/little_ghost/code_mode/javascript/client.rb', line 56

def output(value)
  text = String(value)
  @mutex.synchronize do
    return if @terminal || @termination_error

    if @output_bytes + text.bytesize > MAX_BUFFERED_OUTPUT_BYTES
      @termination_error = "Code-mode output exceeded the buffer limit"
      overflow = true
    else
      @outputs << text
      @output_bytes += text.bytesize
    end
    @condition.broadcast
    overflow
  end
end

#request_client_termination(error) ⇒ Object



93
94
95
96
97
98
99
100
101
# File 'lib/little_ghost/code_mode/javascript/client.rb', line 93

def request_client_termination(error)
  @mutex.synchronize do
    return false if @terminal || @client_termination_requested

    @client_termination_requested = true
    @termination_error = error
    true
  end
end

#terminal?Boolean

Returns:

  • (Boolean)


148
149
150
# File 'lib/little_ghost/code_mode/javascript/client.rb', line 148

def terminal?
  @mutex.synchronize { !@terminal.nil? }
end

#terminatedObject



86
87
88
89
90
91
# File 'lib/little_ghost/code_mode/javascript/client.rb', line 86

def terminated
  complete(
    status: @termination_error ? "failed" : "terminated",
    error: @termination_error
  )
end

#wait_until_terminal(timeout: nil) ⇒ Object



133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/little_ghost/code_mode/javascript/client.rb', line 133

def wait_until_terminal(timeout: nil)
  deadline = Process.clock_gettime(Process::CLOCK_MONOTONIC) + Float(timeout) if timeout
  @mutex.synchronize do
    until @terminal
      remaining = deadline && deadline - Process.clock_gettime(Process::CLOCK_MONOTONIC)
      if remaining && !remaining.positive?
        raise LittleGhost::CleanupError, "Code-mode program cleanup timed out"
      end

      @condition.wait(@mutex, remaining)
    end
    @terminal.merge(program_id: id, output: drain_output)
  end
end