providers

package
v1.0.2 Latest Latest
Warning

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

Go to latest
Published: Nov 8, 2026 License: AGPL-3.0 Imports: 29 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrNameTaken = errors.New("provider name is already taken")

ErrNameTaken reports that another provider already has the requested name.

View Source
var ErrOAuthStateInvalid = errors.New("oauth state is unknown or expired")

ErrOAuthStateInvalid reports an OAuth callback whose state matches no pending sign-in.

View Source
var ErrOAuthUnsupported = errors.New("provider does not support oauth")

ErrOAuthUnsupported reports that the provider's client type has no OAuth sign-in, or no device authorization for the operation asked.

View Source
var ErrProviderNotFound = errors.New("provider not found")

ErrProviderNotFound reports an OAuth operation on a provider that does not exist.

View Source
var SecretConfigKeys = []string{"api_key", configOAuthClientSecretKey, "access_key", "secret_key", "app_key"}

SecretConfigKeys is the single registry of provider-config fields that hold secrets. Every read surface that masks (here and the audio speech/ transcription endpoints) and every write surface that preserves masked round-trips must draw from THIS list and mask with MaskAPIKey — the speech endpoints once masked with their own shape, and any voice-settings save then wrote the masked literal back over the real key.

Functions

func IsManagedModelCatalogClientType

func IsManagedModelCatalogClientType(clientType models.ClientType) bool

IsManagedModelCatalogClientType reports whether model rows are reconciled against an account-scoped upstream catalog instead of manually maintained.

func MaskAPIKey added in v0.20.0

func MaskAPIKey(apiKey string) string

MaskAPIKey masks an API key for security.

func ProviderConfigString

func ProviderConfigString(provider sqlc.Provider, key string) string

ProviderConfigString is a public helper for extracting a string from the config JSONB.

func PublicCatalogManaged added in v1.0.0

func PublicCatalogManaged(metadata map[string]any) bool

PublicCatalogManaged is an additional boundary for the public import path. Cloud keeps its own complete managed-provider guard and authenticated sync.

func PublicCatalogSource added in v1.0.0

func PublicCatalogSource(metadata map[string]any) string

PublicCatalogSource reads the explicit source or the identity persisted by a shipped YAML template. Gallery IDs are presentation metadata, not source IDs.

Types

type CountResponse

type CountResponse struct {
	Count int64 `json:"count"`
}

CountResponse represents the count response.

type CreateFromTemplateRequest

type CreateFromTemplateRequest struct {
	TemplateID string         `json:"template_id" validate:"required"`
	Domain     string         `json:"domain,omitempty"`
	Name       string         `json:"name,omitempty"`
	Config     map[string]any `json:"config,omitempty"`
	Metadata   map[string]any `json:"metadata,omitempty"`
}

type CreateRequest

type CreateRequest struct {
	Name       string         `json:"name" validate:"required"`
	ClientType string         `json:"client_type" validate:"required"`
	Icon       string         `json:"icon,omitempty"`
	Config     map[string]any `json:"config,omitempty"`
	Metadata   map[string]any `json:"metadata,omitempty"`
}

CreateRequest represents a request to create a new provider.

type GetResponse

type GetResponse struct {
	ID                 string         `json:"id"`
	ProviderTemplateID string         `json:"provider_template_id,omitempty"`
	Name               string         `json:"name"`
	ClientType         string         `json:"client_type"`
	Icon               string         `json:"icon,omitempty"`
	Enable             bool           `json:"enable"`
	Config             map[string]any `json:"config,omitempty"`
	Metadata           map[string]any `json:"metadata,omitempty"`
	CreatedAt          time.Time      `json:"created_at"`
	UpdatedAt          time.Time      `json:"updated_at"`
}

GetResponse represents the response for getting a provider.

type ImportCatalogModelsRequest added in v1.0.0

type ImportCatalogModelsRequest struct {
	SkipModelIDs []string `json:"skip_model_ids,omitempty"`
}

ImportCatalogModelsRequest selects the stored provider's server-side public catalog. A distinct endpoint prevents older servers treating it as discovery.

type ImportModelsRequest

type ImportModelsRequest struct {
	DefaultCompatibilities []string `json:"default_compatibilities,omitempty"`
}

ImportModelsRequest carries explicit defaults for unknown chat models listed by the provider endpoint.

type ImportModelsResponse

type ImportModelsResponse struct {
	Catalog *modelcatalog.Info `json:"catalog,omitempty"`
	Created int                `json:"created"`
	Updated int                `json:"updated"`
	Skipped int                `json:"skipped"`
	Models  []string           `json:"models"`
}

ImportModelsResponse represents the response for importing models.

type ListResponse

type ListResponse struct {
	Providers []GetResponse `json:"providers"`
	Total     int64         `json:"total"`
}

ListResponse represents the response for listing providers.

type ModelCredentials

type ModelCredentials struct {
	APIKey         string //nolint:gosec // runtime credential material used to construct SDK providers
	CodexAccountID string
}

type OAuthAccount

type OAuthAccount struct {
	Label      string `json:"label,omitempty"`
	Login      string `json:"login,omitempty"`
	Name       string `json:"name,omitempty"`
	Email      string `json:"email,omitempty"`
	AvatarURL  string `json:"avatar_url,omitempty"`
	ProfileURL string `json:"profile_url,omitempty"`
}

type OAuthAuthorizeResponse

type OAuthAuthorizeResponse struct {
	Mode    string             `json:"mode,omitempty"`
	AuthURL string             `json:"auth_url,omitempty"`
	Device  *OAuthDeviceStatus `json:"device,omitempty"`
}

type OAuthDeviceStatus

type OAuthDeviceStatus struct {
	Pending         bool       `json:"pending"`
	UserCode        string     `json:"user_code,omitempty"`
	VerificationURI string     `json:"verification_uri,omitempty"`
	ExpiresAt       *time.Time `json:"expires_at,omitempty"`
	IntervalSeconds int64      `json:"interval_seconds,omitempty"`
}

type OAuthStatus

type OAuthStatus struct {
	Configured  bool               `json:"configured"`
	Mode        string             `json:"mode,omitempty"`
	HasToken    bool               `json:"has_token"`
	Expired     bool               `json:"expired"`
	ExpiresAt   *time.Time         `json:"expires_at,omitempty"`
	CallbackURL string             `json:"callback_url"`
	Device      *OAuthDeviceStatus `json:"device,omitempty"`
	Account     *OAuthAccount      `json:"account,omitempty"`
}

OAuthStatus is returned by GET /providers/:id/oauth/status.

type OpenAICodexACPDeviceAuthorization

type OpenAICodexACPDeviceAuthorization struct {
	DeviceAuthID    string
	UserCode        string
	VerificationURL string
	IntervalSeconds int64
}

type OpenAICodexACPDevicePollResult

type OpenAICodexACPDevicePollResult struct {
	Pending           bool
	AuthorizationCode string
	CodeChallenge     string
	CodeVerifier      string
}

type OpenAICodexOAuthCredentials

type OpenAICodexOAuthCredentials struct {
	AccessToken  string //nolint:gosec // runtime credential material used to construct Codex auth.json
	IDToken      string //nolint:gosec // runtime credential material used to construct Codex auth.json
	RefreshToken string //nolint:gosec // runtime credential material used to construct Codex auth.json
	AccountID    string
	BaseURL      string
	ExpiresAt    time.Time
	LastRefresh  time.Time
}

type RemoteModel

type RemoteModel struct {
	ID               string   `json:"id"`
	Description      *string  `json:"description,omitempty"`
	Object           string   `json:"object"`
	Created          int64    `json:"created"`
	OwnedBy          string   `json:"owned_by"`
	Name             string   `json:"name,omitempty"`
	DisplayName      string   `json:"display_name,omitempty"`
	Type             string   `json:"type,omitempty"`
	Compatibilities  []string `json:"compatibilities,omitempty"`
	ReasoningEfforts []string `json:"reasoning_efforts,omitempty"`
	ThinkingMode     string   `json:"thinking_mode,omitempty"`
	// ReasoningDialect and the budget bounds must survive the import path, not
	// just live in the template: an imported Gemini 2.5 row without a dialect
	// falls back to the tier wire and every request is a 400.
	ReasoningDialect string `json:"reasoning_dialect,omitempty"`
	// ReasoningOffSupport declares how the model answers an explicit disable.
	ReasoningOffSupport string `json:"reasoning_off_support,omitempty"`
	ReasoningDefaultOn  *bool  `json:"reasoning_default_on,omitempty"`
	ThinkingBudgetMin   *int   `json:"thinking_budget_min,omitempty"`
	ThinkingBudgetMax   *int   `json:"thinking_budget_max,omitempty"`
	ContextWindow       *int   `json:"context_window,omitempty"`
	MaxOutputTokens     *int   `json:"max_output_tokens,omitempty"`
	Dimensions          *int   `json:"dimensions,omitempty"`
	CapabilitiesKnown   bool   `json:"-"`
}

RemoteModel represents a model returned by the provider's /v1/models endpoint.

type Service

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

Service handles provider operations.

func NewService

func NewService(log *slog.Logger, queries dbstore.Queries, callbackURL string) *Service

NewService creates a new provider service.

func (*Service) Count

func (s *Service) Count(ctx context.Context) (int64, error)

Count returns the total count of providers.

func (*Service) Create

func (s *Service) Create(ctx context.Context, req CreateRequest) (GetResponse, error)

Create creates a new provider.

func (*Service) CreateFromTemplate

func (s *Service) CreateFromTemplate(ctx context.Context, req CreateFromTemplateRequest) (GetResponse, error)

func (*Service) Delete

func (s *Service) Delete(ctx context.Context, id string) error

Delete deletes a provider by ID.

func (*Service) ExchangeOpenAICodexACPCode

func (s *Service) ExchangeOpenAICodexACPCode(ctx context.Context, redirectURI, code, codeVerifier string) (OpenAICodexOAuthCredentials, error)

func (*Service) ExchangeOpenAICodexACPDeviceCode

func (s *Service) ExchangeOpenAICodexACPDeviceCode(ctx context.Context, authorizationCode, codeVerifier string) (OpenAICodexOAuthCredentials, error)

func (*Service) FetchRemoteModels

func (s *Service) FetchRemoteModels(ctx context.Context, id string) ([]RemoteModel, error)

FetchRemoteModels fetches available models from the provider using the Twilight AI SDK.

func (*Service) Get

func (s *Service) Get(ctx context.Context, id string) (GetResponse, error)

Get retrieves a provider by ID.

func (*Service) GetByName

func (s *Service) GetByName(ctx context.Context, name string) (GetResponse, error)

GetByName retrieves a provider by name.

func (*Service) GetOAuthStatus

func (s *Service) GetOAuthStatus(ctx context.Context, providerID string) (*OAuthStatus, error)

func (*Service) GetValidAccessToken

func (s *Service) GetValidAccessToken(ctx context.Context, providerID string) (string, error)

func (*Service) HandleOAuthCallback

func (s *Service) HandleOAuthCallback(ctx context.Context, state, code string) (string, error)

func (*Service) List

func (s *Service) List(ctx context.Context) ([]GetResponse, error)

List retrieves all providers.

func (*Service) PollOAuthAuthorization

func (s *Service) PollOAuthAuthorization(ctx context.Context, providerID string) (*OAuthStatus, error)

func (*Service) PollOpenAICodexACPDeviceAuthorization

func (s *Service) PollOpenAICodexACPDeviceAuthorization(ctx context.Context, deviceAuthID, userCode string) (OpenAICodexACPDevicePollResult, error)

func (*Service) ResolveModelCredentials

func (s *Service) ResolveModelCredentials(ctx context.Context, provider sqlc.Provider) (ModelCredentials, error)

func (*Service) RevokeOAuthToken

func (s *Service) RevokeOAuthToken(ctx context.Context, providerID string) error

func (*Service) StartOAuthAuthorization

func (s *Service) StartOAuthAuthorization(ctx context.Context, providerID string) (*OAuthAuthorizeResponse, error)

func (*Service) StartOpenAICodexACPAuthorization

func (*Service) StartOpenAICodexACPAuthorization(_ context.Context, redirectURI, state string) (*OAuthAuthorizeResponse, string, error)

func (*Service) StartOpenAICodexACPDeviceAuthorization

func (s *Service) StartOpenAICodexACPDeviceAuthorization(ctx context.Context) (OpenAICodexACPDeviceAuthorization, error)

func (*Service) Test

func (s *Service) Test(ctx context.Context, id string) (TestResponse, error)

Test probes the provider using the Twilight AI SDK to check reachability and authentication. A successful models-list response is conclusive; no follow-up generation probe is made. An earlier fake-model probe was removed (#1042): some OpenAI-compatible gateways validate the model before auth and answer 401 for an unknown model, which the probe misclassified as "Invalid API key" even after the key had authenticated. Per-model availability is covered by models.Service.Test instead.

Outcome semantics (#1087): the models list is only a partial falsifier, so the outcome follows what sdk.Provider.Test returned:

  • nil: verified (ok), except for OpenCode Go, whose models list is public and answers without valid credentials (unverified);
  • an *sdk.APIError of kind authentication or permission_denied: auth failed (auth_error). The request carries no model parameter, so this cannot be confused with "model not found";
  • any other *sdk.APIError (404, 429, 5xx, ...): unverified, NOT a failure. The endpoint answered, but the base URL may be wrong or the provider may not implement model listing;
  • no *sdk.APIError in the chain (DNS, TCP, TLS, an ended context): error, the only hard failure kept at this layer.

Every outcome other than ok carries the SDK error as Cause.

func (*Service) Update

func (s *Service) Update(ctx context.Context, id string, req UpdateRequest) (GetResponse, error)

Update updates an existing provider.

type TestResponse

type TestResponse struct {
	Status    TestStatus `json:"status"`
	Reachable bool       `json:"reachable"`
	LatencyMs int64      `json:"latency_ms,omitempty"`
	// Code is the error catalog code for why the test did not pass. It is
	// empty on success and when no catalog code describes the failure.
	Code string `json:"code,omitempty"`
	// Cause is why the test did not pass. It never leaves the process; the
	// handler records it and derives Code from it.
	Cause error `json:"-"`
}

TestResponse is returned by POST /providers/:id/test.

type TestStatus

type TestStatus string

TestStatus represents the outcome of testing a provider.

const (
	TestStatusOK        TestStatus = "ok"
	TestStatusAuthError TestStatus = "auth_error"
	TestStatusError     TestStatus = "error"
	// TestStatusUnverified means the endpoint answered but the models list
	// could not confirm it works (e.g. the provider does not implement model
	// listing). It is deliberately not a failure: only a real generation
	// against a concrete model can settle that (see models.Service.Test).
	TestStatusUnverified TestStatus = "unverified"
)

type UpdateRequest

type UpdateRequest struct {
	Name       *string        `json:"name,omitempty"`
	ClientType *string        `json:"client_type,omitempty"`
	Icon       *string        `json:"icon,omitempty"`
	Enable     *bool          `json:"enable,omitempty"`
	Config     map[string]any `json:"config,omitempty"`
	Metadata   map[string]any `json:"metadata,omitempty"`
}

UpdateRequest represents a request to update an existing provider.

Jump to

Keyboard shortcuts

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