Help us shape the future of Go! Take the 2026 Go Developer Survey

openrouter

package
v0.0.51 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 26, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

Documentation

Overview

Package openrouter is a stdlib-only LEAF adapter that fetches the LIVE OpenRouter model catalog from the public, UNAUTHENTICATED models endpoint and maps it into a neutral, package-own result type. It carries no behaviour beyond the HTTP GET + JSON→neutral mapping; nothing here knows about the agent, providers, ports, the composition layer, or any other adapter.

Provenance and wire shape

The endpoint is:

GET https://openrouter.ai/api/v1/models

It is UNAUTHENTICATED — no API key is read or sent (CWE-200: the key lives only in the resilience-wrapped port.LLMProvider, never in this lister). The response envelope is {"data":[ {id, name, context_length, architecture:{input_modalities}, supported_parameters:[...]}, ... ]}. Mapping:

id                                       → ID
name                                     → DisplayName
context_length                           → ContextLimit
top_provider.max_completion_tokens       → OutputLimit (the output ceiling)
architecture.input_modalities ∋ "image"  → InputModalities (carries "image")
supported_parameters ∋ "reasoning"       → Reasoning
supported_parameters ∋ "tools"           → ToolCall

Wire shape verified against a live capture pinned 2026-07-13 (345 models). A trimmed sample lives in testdata/ for the offline tests; the live endpoint is NEVER contacted in a test.

Layering

LEAF adapter: net/http + encoding/json + stdlib ONLY. It imports NO domain (session/prompt/tool/governance), NO port, NO internal/app, NO providercatalog, and NO other adapter. Its Model type is package-own and must never leak into the domain or port — only the composition layer (internal/app) reads it and maps it to its own neutral liveModel type (so there is no import cycle: the adapter does not import internal/app).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Lister

type Lister struct {
	// contains filtered or unexported fields
}

Lister fetches the OpenRouter live model catalog over an INJECTED *http.Client (tests pass a mock transport; production gets a default client with a sane timeout). It is KEYLESS — it sends no Authorization header and never sees the OpenRouter API key.

func NewLister

func NewLister(client *http.Client) *Lister

NewLister constructs a Lister over the given client. A nil client yields a default client with defaultTimeout (so production wiring may pass nil and tests inject a mock transport).

func (*Lister) ListModels

func (l *Lister) ListModels(ctx context.Context) ([]Model, error)

ListModels GETs the live OpenRouter catalog and maps it to []Model. It is read-only and fail-safe to the caller: any transport, status, size, or parse error returns a non-nil error (the composition layer then falls back to the embedded catalog). It NEVER panics.

type Model

type Model struct {
	ID           string
	DisplayName  string
	ContextLimit int
	// OutputLimit is top_provider.max_completion_tokens (the output ceiling; 0 =
	// unknown). It is CAPTURED for the meta store but is currently OFF the request
	// path for OpenRouter: OpenRouter rides the openai Responses adapter, which takes
	// NO per-model max_tokens resolver today (unlike the native anthropic adapter). So
	// this value reaches the resolvers' store but no OpenRouter request consumes it
	// yet. If a future change wires a max_tokens resolver for the openai/OpenRouter
	// adapter, the composition UPPER clamp (internal/app/livemeta.go clampLive) MUST
	// already gate this live value before it can flow into max_tokens — do not wire
	// the consumer ahead of the clamp.
	OutputLimit     int
	InputModalities []string
	Reasoning       bool
	ToolCall        bool
}

Model is the adapter's OWN neutral result type. The composition layer maps it to its composition-local modelEntry; it never leaves this package's caller as-is and carries nothing provider-private (no key, no URL).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL