providers

package
v0.15.0 Latest Latest
Warning

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

Go to latest
Published: Jul 26, 2025 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Code generated from OpenAPI schema. DO NOT EDIT.

Code generated from OpenAPI schema. DO NOT EDIT.

Code generated from OpenAPI schema. DO NOT EDIT.

Index

Constants

View Source
const (
	AuthTypeBearer  = "bearer"
	AuthTypeXheader = "xheader"
	AuthTypeQuery   = "query"
	AuthTypeNone    = "none"
)

The authentication type of the specific provider

View Source
const (
	AnthropicDefaultBaseURL  = "https://api.anthropic.com/v1"
	CloudflareDefaultBaseURL = "https://api.cloudflare.com/client/v4/accounts/{ACCOUNT_ID}/ai"
	CohereDefaultBaseURL     = "https://api.cohere.ai"
	DeepseekDefaultBaseURL   = "https://api.deepseek.com"
	GoogleDefaultBaseURL     = "https://generativelanguage.googleapis.com/v1beta/openai"
	GroqDefaultBaseURL       = "https://api.groq.com/openai/v1"
	OllamaDefaultBaseURL     = "http://ollama:8080/v1"
	OpenaiDefaultBaseURL     = "https://api.openai.com/v1"
)

The default base URLs of each provider

View Source
const (
	AnthropicModelsEndpoint  = "/models"
	AnthropicChatEndpoint    = "/chat/completions"
	CloudflareModelsEndpoint = "/finetunes/public?limit=1000"
	CloudflareChatEndpoint   = "/v1/chat/completions"
	CohereModelsEndpoint     = "/v1/models"
	CohereChatEndpoint       = "/compatibility/v1/chat/completions"
	DeepseekModelsEndpoint   = "/models"
	DeepseekChatEndpoint     = "/chat/completions"
	GoogleModelsEndpoint     = "/models"
	GoogleChatEndpoint       = "/chat/completions"
	GroqModelsEndpoint       = "/models"
	GroqChatEndpoint         = "/chat/completions"
	OllamaModelsEndpoint     = "/models"
	OllamaChatEndpoint       = "/chat/completions"
	OpenaiModelsEndpoint     = "/models"
	OpenaiChatEndpoint       = "/chat/completions"
)

The default endpoints of each provider

View Source
const (
	AnthropicDisplayName  = "Anthropic"
	CloudflareDisplayName = "Cloudflare"
	CohereDisplayName     = "Cohere"
	DeepseekDisplayName   = "Deepseek"
	GoogleDisplayName     = "Google"
	GroqDisplayName       = "Groq"
	OllamaDisplayName     = "Ollama"
	OpenaiDisplayName     = "Openai"
)

Display names for providers

Variables

View Source
var Registry = map[Provider]*Config{
	AnthropicID: {
		ID:       AnthropicID,
		Name:     AnthropicDisplayName,
		URL:      AnthropicDefaultBaseURL,
		AuthType: AuthTypeXheader,
		ExtraHeaders: map[string][]string{
			"anthropic-version": {"2023-06-01"},
		},
		Endpoints: Endpoints{
			Models: AnthropicModelsEndpoint,
			Chat:   AnthropicChatEndpoint,
		},
	},
	CloudflareID: {
		ID:       CloudflareID,
		Name:     CloudflareDisplayName,
		URL:      CloudflareDefaultBaseURL,
		AuthType: AuthTypeBearer,
		Endpoints: Endpoints{
			Models: CloudflareModelsEndpoint,
			Chat:   CloudflareChatEndpoint,
		},
	},
	CohereID: {
		ID:       CohereID,
		Name:     CohereDisplayName,
		URL:      CohereDefaultBaseURL,
		AuthType: AuthTypeBearer,
		Endpoints: Endpoints{
			Models: CohereModelsEndpoint,
			Chat:   CohereChatEndpoint,
		},
	},
	DeepseekID: {
		ID:       DeepseekID,
		Name:     DeepseekDisplayName,
		URL:      DeepseekDefaultBaseURL,
		AuthType: AuthTypeBearer,
		Endpoints: Endpoints{
			Models: DeepseekModelsEndpoint,
			Chat:   DeepseekChatEndpoint,
		},
	},
	GoogleID: {
		ID:       GoogleID,
		Name:     GoogleDisplayName,
		URL:      GoogleDefaultBaseURL,
		AuthType: AuthTypeBearer,
		Endpoints: Endpoints{
			Models: GoogleModelsEndpoint,
			Chat:   GoogleChatEndpoint,
		},
	},
	GroqID: {
		ID:       GroqID,
		Name:     GroqDisplayName,
		URL:      GroqDefaultBaseURL,
		AuthType: AuthTypeBearer,
		Endpoints: Endpoints{
			Models: GroqModelsEndpoint,
			Chat:   GroqChatEndpoint,
		},
	},
	OllamaID: {
		ID:       OllamaID,
		Name:     OllamaDisplayName,
		URL:      OllamaDefaultBaseURL,
		AuthType: AuthTypeNone,
		Endpoints: Endpoints{
			Models: OllamaModelsEndpoint,
			Chat:   OllamaChatEndpoint,
		},
	},
	OpenaiID: {
		ID:       OpenaiID,
		Name:     OpenaiDisplayName,
		URL:      OpenaiDefaultBaseURL,
		AuthType: AuthTypeBearer,
		Endpoints: Endpoints{
			Models: OpenaiModelsEndpoint,
			Chat:   OpenaiChatEndpoint,
		},
	},
}

The registry of all providers

Functions

This section is empty.

Types

type A2AAgentCard added in v0.12.0

type A2AAgentCard struct {
	Capabilities                      map[string]interface{}    `json:"capabilities"`
	Defaultinputmodes                 []string                  `json:"defaultInputModes"`
	Defaultoutputmodes                []string                  `json:"defaultOutputModes"`
	Description                       string                    `json:"description"`
	Documentationurl                  *string                   `json:"documentationUrl,omitempty"`
	Iconurl                           *string                   `json:"iconUrl,omitempty"`
	ID                                string                    `json:"id"`
	Name                              string                    `json:"name"`
	Provider                          *map[string]interface{}   `json:"provider,omitempty"`
	Security                          *[]map[string]interface{} `json:"security,omitempty"`
	Securityschemes                   *map[string]interface{}   `json:"securitySchemes,omitempty"`
	Skills                            []map[string]interface{}  `json:"skills"`
	Supportsauthenticatedextendedcard *bool                     `json:"supportsAuthenticatedExtendedCard,omitempty"`
	Url                               string                    `json:"url"`
	Version                           string                    `json:"version"`
}

A2AAgentCard represents a A2AAgentCard in the API

type AnthropicModel added in v0.1.6

type AnthropicModel struct {
	Type        string `json:"type"`
	ID          string `json:"id"`
	DisplayName string `json:"display_name"`
	CreatedAt   string `json:"created_at"`
}

type ChatCompletionChoice added in v0.2.21

type ChatCompletionChoice struct {
	FinishReason FinishReason `json:"finish_reason"`
	Index        int          `json:"index"`
	Message      Message      `json:"message"`
}

ChatCompletionChoice represents a ChatCompletionChoice in the API

type ChatCompletionMessageToolCall added in v0.2.21

type ChatCompletionMessageToolCall struct {
	Function ChatCompletionMessageToolCallFunction `json:"function"`
	ID       string                                `json:"id"`
	Type     ChatCompletionToolType                `json:"type"`
}

ChatCompletionMessageToolCall represents a ChatCompletionMessageToolCall in the API

type ChatCompletionMessageToolCallChunk added in v0.2.21

type ChatCompletionMessageToolCallChunk struct {
	Function *ChatCompletionMessageToolCallFunction `json:"function,omitempty"`
	ID       *string                                `json:"id,omitempty"`
	Index    int                                    `json:"index"`
	Type     *string                                `json:"type,omitempty"`
}

ChatCompletionMessageToolCallChunk represents a ChatCompletionMessageToolCallChunk in the API

type ChatCompletionMessageToolCallFunction added in v0.2.21

type ChatCompletionMessageToolCallFunction struct {
	Arguments string `json:"arguments"`
	Name      string `json:"name"`
}

ChatCompletionMessageToolCallFunction represents a ChatCompletionMessageToolCallFunction in the API

type ChatCompletionStreamChoice added in v0.2.21

type ChatCompletionStreamChoice struct {
	Delta        ChatCompletionStreamResponseDelta `json:"delta"`
	FinishReason FinishReason                      `json:"finish_reason"`
	Index        int                               `json:"index"`
	Logprobs     *struct{}                         `json:"logprobs,omitempty"`
}

ChatCompletionStreamChoice represents a ChatCompletionStreamChoice in the API

type ChatCompletionStreamOptions added in v0.2.21

type ChatCompletionStreamOptions struct {
	IncludeUsage bool `json:"include_usage"`
}

ChatCompletionStreamOptions represents a ChatCompletionStreamOptions in the API

type ChatCompletionStreamResponseDelta added in v0.2.21

type ChatCompletionStreamResponseDelta struct {
	Content          string                                `json:"content"`
	Reasoning        *string                               `json:"reasoning,omitempty"`
	ReasoningContent *string                               `json:"reasoning_content,omitempty"`
	Refusal          *string                               `json:"refusal,omitempty"`
	Role             MessageRole                           `json:"role"`
	ToolCalls        *[]ChatCompletionMessageToolCallChunk `json:"tool_calls,omitempty"`
}

ChatCompletionStreamResponseDelta represents a ChatCompletionStreamResponseDelta in the API

type ChatCompletionTool added in v0.2.21

type ChatCompletionTool struct {
	Function FunctionObject         `json:"function"`
	Type     ChatCompletionToolType `json:"type"`
}

ChatCompletionTool represents a ChatCompletionTool in the API

type ChatCompletionToolType added in v0.2.21

type ChatCompletionToolType string

ChatCompletionToolType represents a value type of a Tool in the API

const (
	ChatCompletionToolTypeFunction ChatCompletionToolType = "function"
)

ChatCompletionTool represents tool types in the API, currently only function supported

type Client added in v0.1.6

type Client interface {
	Do(req *http.Request) (*http.Response, error)
	Get(url string) (*http.Response, error)
	Post(url string, bodyType string, body string) (*http.Response, error)
}

func NewHTTPClient added in v0.1.10

func NewHTTPClient(cfg *ClientConfig, scheme, hostname, port string) Client

type ClientConfig added in v0.1.10

type ClientConfig struct {
	ClientTimeout               time.Duration `env:"CLIENT_TIMEOUT, default=30s" description:"Client timeout"`
	ClientMaxIdleConns          int           `env:"CLIENT_MAX_IDLE_CONNS, default=20" description:"Maximum idle connections"`
	ClientMaxIdleConnsPerHost   int           `env:"CLIENT_MAX_IDLE_CONNS_PER_HOST, default=20" description:"Maximum idle connections per host"`
	ClientIdleConnTimeout       time.Duration `env:"CLIENT_IDLE_CONN_TIMEOUT, default=30s" description:"Idle connection timeout"`
	ClientTlsMinVersion         string        `env:"CLIENT_TLS_MIN_VERSION, default=TLS12" description:"Minimum TLS version"`
	ClientDisableCompression    bool          `env:"CLIENT_DISABLE_COMPRESSION, default=true" description:"Disable compression for faster streaming"`
	ClientResponseHeaderTimeout time.Duration `env:"CLIENT_RESPONSE_HEADER_TIMEOUT, default=10s" description:"Response header timeout"`
	ClientExpectContinueTimeout time.Duration `env:"CLIENT_EXPECT_CONTINUE_TIMEOUT, default=1s" description:"Expect continue timeout"`
}

func NewClientConfig added in v0.1.10

func NewClientConfig() (*ClientConfig, error)

type ClientImpl added in v0.1.6

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

func (*ClientImpl) Do added in v0.1.6

func (c *ClientImpl) Do(req *http.Request) (*http.Response, error)

func (*ClientImpl) Get added in v0.1.6

func (c *ClientImpl) Get(url string) (*http.Response, error)

func (*ClientImpl) Post added in v0.1.6

func (c *ClientImpl) Post(url string, bodyType string, body string) (*http.Response, error)

type CompletionUsage added in v0.2.21

type CompletionUsage struct {
	CompletionTokens int64 `json:"completion_tokens"`
	PromptTokens     int64 `json:"prompt_tokens"`
	TotalTokens      int64 `json:"total_tokens"`
}

CompletionUsage represents a CompletionUsage in the API

type Config added in v0.1.6

type Config struct {
	ID           Provider
	Name         string
	URL          string
	Token        string
	AuthType     string
	ExtraHeaders map[string][]string
	Endpoints    Endpoints
}

Base provider configuration

type CreateChatCompletionRequest added in v0.2.21

type CreateChatCompletionRequest struct {
	MaxTokens       *int                         `json:"max_tokens,omitempty"`
	Messages        []Message                    `json:"messages"`
	Model           string                       `json:"model"`
	ReasoningFormat *string                      `json:"reasoning_format,omitempty"`
	Stream          *bool                        `json:"stream,omitempty"`
	StreamOptions   *ChatCompletionStreamOptions `json:"stream_options,omitempty"`
	Tools           *[]ChatCompletionTool        `json:"tools,omitempty"`
}

CreateChatCompletionRequest represents a CreateChatCompletionRequest in the API

type CreateChatCompletionResponse added in v0.2.21

type CreateChatCompletionResponse struct {
	Choices []ChatCompletionChoice `json:"choices"`
	Created int                    `json:"created"`
	ID      string                 `json:"id"`
	Model   string                 `json:"model"`
	Object  string                 `json:"object"`
	Usage   *CompletionUsage       `json:"usage,omitempty"`
}

CreateChatCompletionResponse represents a CreateChatCompletionResponse in the API

func (*CreateChatCompletionResponse) Transform added in v0.2.21

Transform converts provider-specific response to common format

type CreateChatCompletionStreamResponse added in v0.2.21

type CreateChatCompletionStreamResponse struct {
	Choices           []ChatCompletionStreamChoice `json:"choices"`
	Created           int                          `json:"created"`
	ID                string                       `json:"id"`
	Model             string                       `json:"model"`
	Object            string                       `json:"object"`
	ReasoningFormat   *string                      `json:"reasoning_format,omitempty"`
	SystemFingerprint *string                      `json:"system_fingerprint,omitempty"`
	Usage             *CompletionUsage             `json:"usage,omitempty"`
}

CreateChatCompletionStreamResponse represents a CreateChatCompletionStreamResponse in the API

type Endpoints added in v0.1.6

type Endpoints struct {
	Chat   string `json:"chat"`
	Models string `json:"models"`
}

Endpoints represents a Endpoints in the API

type Error added in v0.2.21

type Error struct {
	Error *string `json:"error,omitempty"`
}

Error represents a Error in the API

type FinishReason added in v0.2.21

type FinishReason string

FinishReason represents the reason for finishing a chat completion

const (
	FinishReasonStop          FinishReason = "stop"
	FinishReasonLength        FinishReason = "length"
	FinishReasonToolCalls     FinishReason = "tool_calls"
	FinishReasonContentFilter FinishReason = "content_filter"
)

Chat completion finish reasons

type FunctionObject added in v0.2.21

type FunctionObject struct {
	Description *string             `json:"description,omitempty"`
	Name        string              `json:"name"`
	Parameters  *FunctionParameters `json:"parameters,omitempty"`
	Strict      *bool               `json:"strict,omitempty"`
}

FunctionObject represents a FunctionObject in the API

type FunctionParameters added in v0.2.21

type FunctionParameters map[string]interface{}

FunctionParameters represents a FunctionParameters in the API

type IProvider added in v0.2.22

type IProvider interface {
	// Getters
	GetID() *Provider
	GetName() string
	GetURL() string
	GetToken() string
	GetAuthType() string
	GetExtraHeaders() map[string][]string

	// Fetchers
	ListModels(ctx context.Context) (ListModelsResponse, error)
	ChatCompletions(ctx context.Context, clientReq CreateChatCompletionRequest) (CreateChatCompletionResponse, error)
	StreamChatCompletions(ctx context.Context, clientReq CreateChatCompletionRequest) (<-chan []byte, error)
}

type ListAgentsResponse added in v0.10.0

type ListAgentsResponse struct {
	Data   []A2AAgentCard `json:"data"`
	Object string         `json:"object"`
}

ListAgentsResponse represents a ListAgentsResponse in the API

type ListModelsResponse added in v0.1.6

type ListModelsResponse struct {
	Data     []Model   `json:"data"`
	Object   string    `json:"object"`
	Provider *Provider `json:"provider,omitempty"`
}

ListModelsResponse represents a ListModelsResponse in the API

type ListModelsResponseAnthropic added in v0.1.6

type ListModelsResponseAnthropic struct {
	Data    []AnthropicModel `json:"data"`
	HasMore bool             `json:"has_more"`
	FirstID string           `json:"first_id"`
	LastID  string           `json:"last_id"`
}

func (*ListModelsResponseAnthropic) Transform added in v0.1.6

type ListModelsResponseCloudflare added in v0.1.6

type ListModelsResponseCloudflare struct {
	Success bool               `json:"success,omitempty"`
	Result  []*ModelCloudflare `json:"result,omitempty"`
}

func (*ListModelsResponseCloudflare) Transform added in v0.1.6

type ListModelsResponseCohere added in v0.1.6

type ListModelsResponseCohere struct {
	NextPageToken string         `json:"next_page_token,omitempty"`
	Models        []*ModelCohere `json:"models,omitempty"`
}

func (*ListModelsResponseCohere) Transform added in v0.1.6

type ListModelsResponseDeepseek added in v0.3.0

type ListModelsResponseDeepseek struct {
	Object string  `json:"object"`
	Data   []Model `json:"data"`
}

func (*ListModelsResponseDeepseek) Transform added in v0.3.0

type ListModelsResponseGoogle added in v0.1.6

type ListModelsResponseGoogle struct {
	Object string  `json:"object"`
	Data   []Model `json:"data"`
}

func (*ListModelsResponseGoogle) Transform added in v0.1.6

type ListModelsResponseGroq added in v0.1.6

type ListModelsResponseGroq struct {
	Object string  `json:"object"`
	Data   []Model `json:"data"`
}

func (*ListModelsResponseGroq) Transform added in v0.1.6

type ListModelsResponseOllama added in v0.1.6

type ListModelsResponseOllama struct {
	Object string  `json:"object"`
	Data   []Model `json:"data"`
}

func (*ListModelsResponseOllama) Transform added in v0.1.6

type ListModelsResponseOpenai added in v0.1.6

type ListModelsResponseOpenai struct {
	Object string  `json:"object"`
	Data   []Model `json:"data"`
}

func (*ListModelsResponseOpenai) Transform added in v0.1.6

type ListModelsTransformer added in v0.2.21

type ListModelsTransformer interface {
	Transform() ListModelsResponse
}

ListModelsTransformer interface for transforming provider-specific responses

type ListToolsResponse added in v0.7.0

type ListToolsResponse struct {
	Data   []MCPTool `json:"data"`
	Object string    `json:"object"`
}

ListToolsResponse represents a ListToolsResponse in the API

type MCPTool added in v0.7.0

type MCPTool struct {
	Description string                  `json:"description"`
	InputSchema *map[string]interface{} `json:"input_schema,omitempty"`
	Name        string                  `json:"name"`
	Server      string                  `json:"server"`
}

MCPTool represents a MCPTool in the API

type Message added in v0.1.6

type Message struct {
	Content          string                           `json:"content"`
	Reasoning        *string                          `json:"reasoning,omitempty"`
	ReasoningContent *string                          `json:"reasoning_content,omitempty"`
	Role             MessageRole                      `json:"role"`
	ToolCallId       *string                          `json:"tool_call_id,omitempty"`
	ToolCalls        *[]ChatCompletionMessageToolCall `json:"tool_calls,omitempty"`
}

Message represents a Message in the API

type MessageRole added in v0.2.21

type MessageRole string

MessageRole represents the role of a message sender

const (
	MessageRoleSystem    MessageRole = "system"
	MessageRoleUser      MessageRole = "user"
	MessageRoleAssistant MessageRole = "assistant"
	MessageRoleTool      MessageRole = "tool"
)

Message role enum values

type Model added in v0.1.6

type Model struct {
	Created  int64    `json:"created"`
	ID       string   `json:"id"`
	Object   string   `json:"object"`
	OwnedBy  string   `json:"owned_by"`
	ServedBy Provider `json:"served_by"`
}

Model represents a Model in the API

type ModelCloudflare added in v0.2.21

type ModelCloudflare struct {
	ID          string `json:"id,omitempty"`
	Name        string `json:"name,omitempty"`
	Description string `json:"description,omitempty"`
	CreatedAt   string `json:"created_at,omitempty"`
	ModifiedAt  string `json:"modified_at,omitempty"`
	Public      int8   `json:"public,omitempty"`
	Model       string `json:"model,omitempty"`
}

type ModelCohere added in v0.2.21

type ModelCohere struct {
	Name             string   `json:"name,omitempty"`
	Endpoints        []string `json:"endpoints,omitempty"`
	Finetuned        bool     `json:"finetuned,omitempty"`
	ContextLenght    int32    `json:"context_length,omitempty"`
	TokenizerURL     string   `json:"tokenizer_url,omitempty"`
	SupportsVision   bool     `json:"supports_vision,omitempty"`
	DefaultEndpoints []string `json:"default_endpoints,omitempty"`
}

type Provider added in v0.1.6

type Provider string
const (
	AnthropicID  Provider = "anthropic"
	CloudflareID Provider = "cloudflare"
	CohereID     Provider = "cohere"
	DeepseekID   Provider = "deepseek"
	GoogleID     Provider = "google"
	GroqID       Provider = "groq"
	OllamaID     Provider = "ollama"
	OpenaiID     Provider = "openai"
)

The ID's of each provider

func DetermineProviderAndModelName added in v0.7.0

func DetermineProviderAndModelName(model string) (provider *Provider, modelName string)

DetermineProviderAndModelName analyzes a model string and tries to determine the provider based on explicit naming conventions only. It returns both the detected provider and the model name (which might be modified to strip provider prefixes).

It only checks for explicit provider prefixes like "ollama/", "groq/", etc. Implicit model name-based routing (like "gpt-" -> OpenAI) is not supported.

Returns nil provider if no explicit provider prefix is found. In such cases, the provider must be specified via query parameter.

type ProviderImpl added in v0.1.6

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

func (*ProviderImpl) ChatCompletions added in v0.2.21

ChatCompletions generates chat completions from the provider

func (*ProviderImpl) EndpointChat added in v0.2.21

func (p *ProviderImpl) EndpointChat() string

func (*ProviderImpl) EndpointModels added in v0.2.21

func (p *ProviderImpl) EndpointModels() string

func (*ProviderImpl) GetAuthType added in v0.1.6

func (p *ProviderImpl) GetAuthType() string

func (*ProviderImpl) GetExtraHeaders added in v0.1.6

func (p *ProviderImpl) GetExtraHeaders() map[string][]string

func (*ProviderImpl) GetID added in v0.1.6

func (p *ProviderImpl) GetID() *Provider

func (*ProviderImpl) GetName added in v0.1.6

func (p *ProviderImpl) GetName() string

func (*ProviderImpl) GetToken added in v0.1.6

func (p *ProviderImpl) GetToken() string

func (*ProviderImpl) GetURL added in v0.1.6

func (p *ProviderImpl) GetURL() string

func (*ProviderImpl) ListModels added in v0.1.6

func (p *ProviderImpl) ListModels(ctx context.Context) (ListModelsResponse, error)

ListModels fetches the list of models available from the provider and returns them in OpenAI compatible format

func (*ProviderImpl) StreamChatCompletions added in v0.2.21

func (p *ProviderImpl) StreamChatCompletions(ctx context.Context, clientReq CreateChatCompletionRequest) (<-chan []byte, error)

StreamChatCompletions generates chat completions from the provider using streaming

type ProviderRegistry added in v0.1.11

type ProviderRegistry interface {
	GetProviders() map[Provider]*Config
	BuildProvider(providerID Provider, client Client) (IProvider, error)
}

func NewProviderRegistry added in v0.1.11

func NewProviderRegistry(cfg map[Provider]*Config, logger logger.Logger) ProviderRegistry

type ProviderRegistryImpl added in v0.1.11

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

func (*ProviderRegistryImpl) BuildProvider added in v0.1.11

func (p *ProviderRegistryImpl) BuildProvider(providerID Provider, client Client) (IProvider, error)

func (*ProviderRegistryImpl) GetProviders added in v0.1.11

func (p *ProviderRegistryImpl) GetProviders() map[Provider]*Config

Jump to

Keyboard shortcuts

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