Class: Protege::OpenRouterProvider

Inherits:
Provider
  • Object
show all
Defined in:
app/providers/protege/open_router_provider.rb

Overview

Built-in OpenRouter provider. Hits OpenRouter's OpenAI-compatible /chat/completions endpoint. Model selection lives in the Request model field so one configured OpenRouter instance dispatches across every model OpenRouter routes to.

Plugs into Protege by subclassing Protege::Provider and registering under protege_id :openrouter, so it satisfies the Protege::Inference::Provider contract (+generate+ and generate_stream) that the harness drives. Activated when config.provider_id = :openrouter.

Auth and endpoint come from this provider's slice of config.providers:api_key and :base_url under the :openrouter key — resolved lazily on first request, so construction never touches them and the built-in is harmless when unused. The host sets both in the Protege initializer (typically defaulted to ENV vars there; the provider itself does not read ENV).

Instance Method Summary collapse

Instance Method Details

#generate(request) ⇒ Hash

Run a blocking, non-streaming completion.

Parameters:

  • request (Hash)

    the request hash (messages + tools; see the providers doc)

Returns:

  • (Hash)

    the response hash (content + tool_calls + finish_reason)

Raises:



29
30
31
32
33
34
35
36
# File 'app/providers/protege/open_router_provider.rb', line 29

def generate(request)
  response = http_client.post('chat/completions') do |req|
    req.body = build_payload(request).to_json
  end

  raise_for_status(response)
  parse_response(JSON.parse(response.body))
end

#generate_stream(request) {|chunk| ... } ⇒ Hash

Run a streaming completion over SSE.

Streams tokens as they arrive: text deltas are yielded to block as { type: :text, content: ... } hashes, tool-call deltas are accumulated, and the final assembled response hash is returned once the stream closes.

Parameters:

  • request (Hash)

    the request hash (messages + tools; see the providers doc)

Yield Parameters:

  • chunk (Hash)

    a { type: :text, content: String } token chunk

Returns:

  • (Hash)

    the response hash (content + tool_calls + finish_reason)



47
48
49
50
51
52
53
54
55
56
# File 'app/providers/protege/open_router_provider.rb', line 47

def generate_stream(request, &block)
  payload     = build_payload(request).merge(stream: true)
  accumulator = { text_parts: [], tool_calls: {}, finish_reason: nil }

  stream_chat_completion(payload) do |line|
    process_stream_line(line, accumulator, &block)
  end

  build_stream_response(accumulator)
end

#settingsHash

The sampling settings this provider applies beyond the model — the same knobs merged into the wire payload — surfaced for tracing. Overrides the mixin default so a trace records the generation settings that shaped the output.

Returns:

  • (Hash)

    the temperature/max-tokens settings in effect (nils dropped)



63
64
65
# File 'app/providers/protege/open_router_provider.rb', line 63

def settings
  { temperature:, max_tokens: max_output_tokens }.compact
end