openrouter

package
v0.9.0 Latest Latest
Warning

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

Go to latest
Published: May 17, 2026 License: MIT Imports: 23 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FilterReasoningForLog added in v0.4.5

func FilterReasoningForLog(details interface{}) interface{}

FilterReasoningForLog filters out encrypted reasoning entries from reasoning_details. Keeps only "reasoning.text" entries which are human-readable and useful for debugging. This prevents massive base64 blobs from polluting logs.

func RecordLLMRequest added in v0.3.0

func RecordLLMRequest(userID int64, model string, durationSeconds float64, success bool, promptTokens, completionTokens int, cost *float64, jobType string)

RecordLLMRequest записывает метрики LLM запроса. jobType should be "interactive" or "background" (use jobtype.JobType constants).

func RecordLLMRetry added in v0.3.0

func RecordLLMRetry(model string)

RecordLLMRetry записывает retry-попытку.

Types

type ChatCompletionChunk added in v0.9.0

type ChatCompletionChunk struct {
	ID          string        `json:"id"`
	Object      string        `json:"object"` // "chat.completion.chunk"
	Created     int64         `json:"created"`
	Model       string        `json:"model"`
	Provider    string        `json:"provider,omitempty"`
	ServiceTier string        `json:"service_tier,omitempty"`
	Choices     []ChunkChoice `json:"choices"`
	Usage       *ChunkUsage   `json:"usage,omitempty"`
}

ChatCompletionChunk is one SSE delta from /chat/completions in stream mode. Mirrors the OpenAI-compatible shape OpenRouter emits between `data:` and `\n\n`. Most chunks carry a single Choices[0].Delta with partial content/reasoning/tool_calls; the final chunk before `data: [DONE]` additionally carries Usage.

type ChatCompletionRequest

type ChatCompletionRequest struct {
	Model          string           `json:"model"`
	Messages       []Message        `json:"messages"`
	Plugins        []Plugin         `json:"plugins,omitempty"`
	Tools          []Tool           `json:"tools,omitempty"`
	ToolChoice     any              `json:"tool_choice,omitempty"`
	ResponseFormat interface{}      `json:"response_format,omitempty"`
	Reasoning      *ReasoningConfig `json:"reasoning,omitempty"`
	// Modalities enables image-output models. Use ["image","text"] for Gemini
	// image models that return both text and images. Required for image generation;
	// see TestAllImageGenerationRequestsSetModalities.
	Modalities []string `json:"modalities,omitempty"`
	// ImageConfig is model-specific image-generation configuration
	// (aspect ratio, size). Only used when Modalities includes "image".
	ImageConfig *ImageConfig `json:"image_config,omitempty"`
	// Provider overrides OpenRouter's provider routing for this request.
	// When nil, the client-level default (if any) is applied before sending.
	Provider *ProviderRouting `json:"provider,omitempty"`
	// User is the OpenAI/OpenRouter-standard end-user id, used for abuse
	// signals on the provider side and as user.id on OR-emitted Broadcast
	// spans. Auto-populated from UserID in CreateChatCompletion when empty.
	User string `json:"user,omitempty"`
	// Trace carries OpenRouter's Broadcast metadata. Keys with special
	// meaning: trace_id, parent_span_id, trace_name, span_name,
	// generation_name. CreateChatCompletion auto-fills trace_id and
	// parent_span_id from the current span context so OR-emitted spans
	// nest under our local trace when Broadcast is configured. When
	// Broadcast is disabled on the OR side, the field is ignored.
	Trace map[string]any `json:"trace,omitempty"`

	// Stream switches the request to SSE streaming. Set internally by
	// CreateChatCompletionStream; callers leave this false and use the
	// dedicated streaming method.
	Stream bool `json:"stream,omitempty"`

	// UserID is used for metrics tracking only, not sent to API
	UserID int64 `json:"-"`
}

type ChatCompletionResponse

type ChatCompletionResponse struct {
	ID       string           `json:"id"`
	Model    string           `json:"model"`
	Provider string           `json:"provider,omitempty"` // Actual provider that served the request (e.g. "Google", "Google AI Studio")
	Choices  []ResponseChoice `json:"choices"`
	Usage    struct {
		PromptTokens     int      `json:"prompt_tokens"`
		CompletionTokens int      `json:"completion_tokens"`
		TotalTokens      int      `json:"total_tokens"`
		Cost             *float64 `json:"cost,omitempty"` // Cost in USD from OpenRouter
	} `json:"usage"`

	// DebugRequestBody contains the raw JSON request body sent to OpenRouter.
	// Not part of API response - populated by client for debugging purposes.
	DebugRequestBody string `json:"-"`

	// DebugResponseBody contains the raw JSON response body from OpenRouter.
	// Not part of API response - populated by client for debugging purposes.
	DebugResponseBody string `json:"-"`
}

type ChunkChoice added in v0.9.0

type ChunkChoice struct {
	Index              int        `json:"index"`
	Delta              ChunkDelta `json:"delta"`
	FinishReason       string     `json:"finish_reason,omitempty"`
	NativeFinishReason string     `json:"native_finish_reason,omitempty"`
}

type ChunkDelta added in v0.9.0

type ChunkDelta struct {
	Role             string          `json:"role,omitempty"`
	Content          string          `json:"content,omitempty"`
	Reasoning        string          `json:"reasoning,omitempty"`
	ReasoningDetails interface{}     `json:"reasoning_details,omitempty"`
	ToolCalls        []ChunkToolCall `json:"tool_calls,omitempty"`
}

type ChunkToolCall added in v0.9.0

type ChunkToolCall struct {
	Index    int                   `json:"index"`
	ID       string                `json:"id,omitempty"`
	Type     string                `json:"type,omitempty"`
	Function ChunkToolCallFunction `json:"function,omitempty"`
}

type ChunkToolCallFunction added in v0.9.0

type ChunkToolCallFunction struct {
	Name      string `json:"name,omitempty"`
	Arguments string `json:"arguments,omitempty"`
}

type ChunkUsage added in v0.9.0

type ChunkUsage struct {
	PromptTokens     int      `json:"prompt_tokens"`
	CompletionTokens int      `json:"completion_tokens"`
	TotalTokens      int      `json:"total_tokens"`
	Cost             *float64 `json:"cost,omitempty"`
}

type Client

type Client interface {
	CreateChatCompletion(ctx context.Context, req ChatCompletionRequest) (ChatCompletionResponse, error)
	CreateChatCompletionStream(ctx context.Context, req ChatCompletionRequest) (<-chan StreamEvent, error)
	CreateEmbeddings(ctx context.Context, req EmbeddingRequest) (EmbeddingResponse, error)
}

func NewClient

func NewClient(logger *slog.Logger, apiKey, proxyURL string, defaultProvider *ProviderRouting) (Client, error)

func NewClientWithBaseURL

func NewClientWithBaseURL(logger *slog.Logger, apiKey, proxyURL, baseURL string, defaultProvider *ProviderRouting) (Client, error)

type EmbeddingObject

type EmbeddingObject struct {
	Object    string    `json:"object"`
	Embedding []float32 `json:"embedding"`
	Index     int       `json:"index"`
}

type EmbeddingRequest

type EmbeddingRequest struct {
	Model      string                 `json:"model"`
	Input      []string               `json:"input"`
	Dimensions int                    `json:"dimensions,omitempty"`
	Provider   *ProviderRouting       `json:"provider,omitempty"`
	LogMeta    map[string]interface{} `json:"-"`
	// User mirrors the OpenAI-standard end-user id. See the identical
	// field on ChatCompletionRequest for semantics.
	User string `json:"user,omitempty"`
	// Trace carries OpenRouter Broadcast metadata. See
	// ChatCompletionRequest.Trace for semantics and auto-populated keys.
	Trace map[string]any `json:"trace,omitempty"`
}

type EmbeddingResponse

type EmbeddingResponse struct {
	Object string            `json:"object"`
	Data   []EmbeddingObject `json:"data"`
	Model  string            `json:"model"`
	Usage  struct {
		PromptTokens int      `json:"prompt_tokens"`
		TotalTokens  int      `json:"total_tokens"`
		Cost         *float64 `json:"cost,omitempty"` // Cost in USD from OpenRouter
	} `json:"usage"`
}

type File

type File struct {
	FileName string `json:"filename"`
	FileData string `json:"file_data"` // data URL format: "data:mime/type;base64,..."
}

File represents a file for multimodal content (v0.6.0: unified format).

type FilePart

type FilePart struct {
	Type string `json:"type"` // "file"
	File File   `json:"file"`
}

FilePart represents a file part in multimodal messages (v0.6.0: unified format). This is the recommended format for all file types: images, PDFs, audio, video.

type ImageConfig added in v0.8.0

type ImageConfig struct {
	// AspectRatio: "1:1","2:3","3:2","3:4","4:3","4:5","5:4","9:16","16:9","21:9"
	// Extended on nano banana: "1:4","4:1","1:8","8:1".
	AspectRatio string `json:"aspect_ratio,omitempty"`
	// ImageSize: "1K", "2K", "4K". OpenRouter's validator advertises "0.5K"
	// as a fourth value but Google rejects that upstream as INVALID_ARGUMENT;
	// the actual Gemini enum value "512" is in turn rejected by OR's validator.
	// Don't advertise either to the LLM — see docs/bugs/2026-04-30-nano-banana-*.
	ImageSize string `json:"image_size,omitempty"`
}

ImageConfig controls image generation output for models that support it (e.g. google/gemini-3.1-flash-image-preview). Only meaningful when the request sets Modalities to include "image".

type ImageOutput added in v0.8.0

type ImageOutput struct {
	Type     string        `json:"type"` // "image_url"
	ImageURL ImageURLValue `json:"image_url"`
}

ImageOutput represents an image emitted by image-generation models in the response. The URL is a base64 data URL, e.g. "data:image/png;base64,...".

type ImageURLPart added in v0.8.0

type ImageURLPart struct {
	Type     string        `json:"type"` // "image_url"
	ImageURL ImageURLValue `json:"image_url"`
}

ImageURLPart represents an image reference for MODEL INPUT, in the OpenAI-compatible shape. Use this when calling image-generation or image-editing models (e.g. google/gemini-3.1-flash-image-preview) — they reject the "file" FilePart shape with "Invalid file type: image/…". Regular multimodal text models accept either shape, but for image models this is the only format the provider accepts for input images.

type ImageURLValue added in v0.8.0

type ImageURLValue struct {
	URL string `json:"url"`
}

ImageURLValue is the inner object of an ImageOutput; kept as a named type so struct literals can be written without repeating the anonymous shape.

type JSONSchema

type JSONSchema struct {
	Name   string                 `json:"name"`
	Strict bool                   `json:"strict,omitempty"`
	Schema map[string]interface{} `json:"schema"`
}

type Message

type Message struct {
	Role             string      `json:"role"`
	Content          interface{} `json:"content"`
	ToolCalls        []ToolCall  `json:"tool_calls,omitempty"`
	ToolCallID       string      `json:"tool_call_id,omitempty"`
	ReasoningDetails interface{} `json:"reasoning_details,omitempty"`
}

type PDFConfig

type PDFConfig struct {
	Engine string `json:"engine"`
}

type Plugin

type Plugin struct {
	ID  string    `json:"id"`
	PDF PDFConfig `json:"pdf,omitempty"`
}

type ProviderRouting added in v0.9.0

type ProviderRouting struct {
	Order          []string `json:"order,omitempty"`
	AllowFallbacks *bool    `json:"allow_fallbacks,omitempty"`
}

ProviderRouting controls OpenRouter's provider selection for a request. Order lists preferred providers (tried in sequence). AllowFallbacks is a pointer so callers can distinguish "unset" (default true on OpenRouter's side) from an explicit false (strict routing — fail instead of falling back to providers outside the order list).

type ReasoningConfig added in v0.4.3

type ReasoningConfig struct {
	Effort    string `json:"effort,omitempty"`     // Gemini 3: "minimal", "low", "medium", "high"
	MaxTokens int    `json:"max_tokens,omitempty"` // Other models: token budget for reasoning
	Exclude   bool   `json:"exclude,omitempty"`    // Suppress reasoning from response
}

ReasoningConfig controls the model's internal reasoning behavior. For Gemini 3: effort levels "minimal", "low", "medium", "high". For other models: max_tokens (1024-128000) controls reasoning depth.

NOTE: response-healing plugin breaks reasoning visibility when combined with json_object format.

type ResponseChoice added in v0.8.0

type ResponseChoice struct {
	Message      ResponseMessage `json:"message"`
	FinishReason string          `json:"finish_reason,omitempty"`
	Index        int             `json:"index"`
}

ResponseChoice is one choice on a ChatCompletionResponse. Named for the same reason as ResponseMessage.

type ResponseFormat

type ResponseFormat struct {
	Type       string      `json:"type"`
	JSONSchema *JSONSchema `json:"json_schema,omitempty"`
}

type ResponseFormatJSONSchema

type ResponseFormatJSONSchema struct {
	Type       string     `json:"type"` // "json_schema"
	JSONSchema JSONSchema `json:"json_schema"`
}

type ResponseMessage added in v0.8.0

type ResponseMessage struct {
	Role             string        `json:"role"`
	Content          string        `json:"content"`
	ToolCalls        []ToolCall    `json:"tool_calls,omitempty"`
	Reasoning        string        `json:"reasoning,omitempty"`         // Gemini 3: raw reasoning text
	ReasoningDetails interface{}   `json:"reasoning_details,omitempty"` // Structured reasoning details
	Images           []ImageOutput `json:"images,omitempty"`            // Generated images (image-output models)
}

ResponseMessage is the assistant message on a ChatCompletionResponse choice. Extracted as a named type so test fixtures and helpers don't have to restate the anonymous struct shape every time a field is added.

type StreamEvent added in v0.9.0

type StreamEvent struct {
	Chunk *ChatCompletionChunk
	Err   error
}

StreamEvent carries either a decoded chunk or a terminal error. When Err != nil the channel is about to close; callers should treat this as the stream's final event and not look for further chunks. Successful streams terminate by closing the channel without an Err event.

type TextPart

type TextPart struct {
	Type string `json:"type"`
	Text string `json:"text"`
}

TextPart represents a text part in messages.

type Tool

type Tool struct {
	Type     string       `json:"type"`
	Function ToolFunction `json:"function"`
}

type ToolCall

type ToolCall struct {
	ID       string `json:"id"`
	Type     string `json:"type"`
	Function struct {
		Name      string `json:"name"`
		Arguments string `json:"arguments"`
	} `json:"function"`
	ExtraContent interface{} `json:"extra_content,omitempty"`
}

type ToolFunction

type ToolFunction struct {
	Name        string `json:"name"`
	Description string `json:"description"`
	Parameters  any    `json:"parameters"`
}

Jump to

Keyboard shortcuts

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