Class: Insika::Evals::HttpTransport

Inherits:
Object
  • Object
show all
Defined in:
lib/insika/evals/transport.rb

Overview

Drives real turns over POST /v1/responses — the SAME surface as scripts/loadtest.rb, so --mode perf is apples-to-apples with the loadtest and closes the real-traffic gap (#6b). A conversation is keyed by user (the adapter continues an existing chat on the same id), so multi-turn goldens replay in order under one conv id.

Instance Method Summary collapse

Constructor Details

#initialize(base_url:, token:, timeout: 120) ⇒ HttpTransport

Returns a new instance of HttpTransport.



123
124
125
126
127
# File 'lib/insika/evals/transport.rb', line 123

def initialize(base_url:, token:, timeout: 120)
  @base = base_url
  @token = token
  @timeout = timeout
end

Instance Method Details

#monoObject



129
# File 'lib/insika/evals/transport.rb', line 129

def mono = Process.clock_gettime(Process::CLOCK_MONOTONIC)

#turn(agent:, conv:, message:) ⇒ Object



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/insika/evals/transport.rb', line 131

def turn(agent:, conv:, message:)
  uri = URI.join("#{@base}/", "v1/responses")
  req = Net::HTTP::Post.new(uri)
  req["Authorization"] = "Bearer #{@token}"
  req["Content-Type"] = "application/json"
  req["Accept"] = "text/event-stream"
  req.body = JSON.generate(model: "openclaw:#{agent}", user: conv, stream: true, input: message)

  t0 = mono
  ttfb = nil
  buffer = +""
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = uri.scheme == "https"
  http.read_timeout = @timeout
  http.open_timeout = 10

  status = nil
  http.start do
    http.request(req) do |res|
      status = res.code.to_i
      return failure("HTTP #{status}", t0) unless status.between?(200, 299)

      res.read_body do |chunk|
        ttfb ||= (mono - t0) * 1000.0
        buffer << chunk
      end
    end
  end

  reduced = Sse.reduce(Sse.payloads(buffer))
  TurnOutcome.new(
    result: TurnResult.new(output_text: reduced[:output_text],
                           tool_calls: reduced[:tool_calls], error: reduced[:error]),
    ttfb: ttfb, total: (mono - t0) * 1000.0, usage: reduced[:usage]
  )
rescue StandardError => e
  failure(e.class.to_s, t0)
end