Module: Terret::OpenRouter::Translate

Defined in:
lib/terret/openrouter/translate.rb

Overview

Pure translation between the provider-neutral vocabulary and OpenRouter's OpenAI-compatible wire format. No I/O.

Class Method Summary collapse

Class Method Details

.request_body(request) ⇒ Object



12
13
14
15
16
17
# File 'lib/terret/openrouter/translate.rb', line 12

def request_body(request)
  body = { model: request.model, messages: wire_messages(request), stream: true }
  tools = Array(request.tools)
  body[:tools] = tools.map { |s| { type: "function", function: s } } unless tools.empty?
  body
end

.wire_message(message) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/terret/openrouter/translate.rb', line 27

def wire_message(message)
  case message.role
  when :user
    [{ role: "user", content: message.text }]
  when :assistant
    msg = { role: "assistant", content: message.text.empty? ? nil : message.text }
    calls = message.tool_calls
    unless calls.empty?
      msg[:tool_calls] = calls.map do |tc|
        { id: tc.id, type: "function",
          function: { name: tc.name, arguments: JSON.generate(tc.args) } }
      end
    end
    [msg]
  when :tool
    message.parts.grep(LLM::ToolResult).map do |tr|
      content = tr.error ? "Error: #{tr.error}" : tr.content.to_s
      { role: "tool", tool_call_id: tr.id, content: content }
    end
  else
    raise ArgumentError, "cannot translate message role #{message.role.inspect}"
  end
end

.wire_messages(request) ⇒ Object



19
20
21
22
23
24
25
# File 'lib/terret/openrouter/translate.rb', line 19

def wire_messages(request)
  out = []
  system = request.system.to_s
  out << { role: "system", content: system } unless system.empty?
  request.messages.each { |m| out.concat(wire_message(m)) }
  out
end