Documentation
¶
Index ¶
- Constants
- Variables
- func NewPriceNotFoundError(provider, modelID string) error
- func NewPriceOverrideNotFoundError(id string) error
- func NormalizeModelID(provider string, modelID string) (canonicalProvider string, canonicalModelID string)
- func NormalizeProvider(provider string) string
- type Adapter
- type CreateOverrideInput
- type DeleteOverrideInput
- type GetPriceInput
- type ListOverridesInput
- type ListPricesInput
- type ModelPricing
- type Price
- type PriceSource
- type Provider
- type ResolvePriceInput
- type Service
- type SourcePrice
- type SourcePriceData
- type SourcePricesMap
Constants ¶
const ErrCodeEffectiveFromAfterTo models.ErrorCode = "llm_cost_effective_from_after_to"
const ErrCodeInvalidPriceSource models.ErrorCode = "llm_cost_invalid_source"
const ErrCodeModelIDEmpty models.ErrorCode = "llm_cost_model_id_empty"
const ErrCodeNamespaceEmpty models.ErrorCode = "llm_cost_namespace_empty"
const ErrCodePriceIDEmpty models.ErrorCode = "llm_cost_price_id_empty"
const ErrCodePriceMustBeNonNegative models.ErrorCode = "llm_cost_price_non_negative"
const ErrCodeProviderEmpty models.ErrorCode = "llm_cost_provider_empty"
Variables ¶
var ErrEffectiveFromAfterTo = models.NewValidationIssue( ErrCodeEffectiveFromAfterTo, "effective_from must not be after effective_to", models.WithFieldString("effective_from"), models.WithCriticalSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrInvalidPriceSource = models.NewValidationIssue( ErrCodeInvalidPriceSource, "invalid price source", models.WithFieldString("source"), models.WithCriticalSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrModelIDEmpty = models.NewValidationIssue( ErrCodeModelIDEmpty, "model_id must not be empty", models.WithFieldString("model_id"), models.WithCriticalSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrNamespaceEmpty = models.NewValidationIssue( ErrCodeNamespaceEmpty, "namespace must not be empty", models.WithFieldString("namespace"), models.WithCriticalSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrPriceIDEmpty = models.NewValidationIssue( ErrCodePriceIDEmpty, "price id must not be empty", models.WithFieldString("id"), models.WithCriticalSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrPriceMustBeNonNegative = models.NewValidationIssue( ErrCodePriceMustBeNonNegative, "price must be non-negative", models.WithFieldString("pricing"), models.WithCriticalSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
var ErrProviderEmpty = models.NewValidationIssue( ErrCodeProviderEmpty, "provider must not be empty", models.WithFieldString("provider"), models.WithCriticalSeverity(), commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), )
Functions ¶
func NewPriceNotFoundError ¶
func NormalizeModelID ¶
func NormalizeModelID(provider string, modelID string) (canonicalProvider string, canonicalModelID string)
NormalizeModelID maps a raw model ID and provider to their canonical forms. It lowercases, trims whitespace, strips date version suffixes, and normalizes provider aliases (e.g. "azure_ai" → "azure", "gemini" → "google").
func NormalizeProvider ¶
NormalizeProvider maps alternative provider names to their canonical form. It lowercases and trims whitespace before matching.
Types ¶
type Adapter ¶
type Adapter interface {
entutils.TxCreator
// Canonical prices (global + overrides)
ListPrices(ctx context.Context, input ListPricesInput) (pagination.Result[Price], error)
GetPrice(ctx context.Context, input GetPriceInput) (Price, error)
ResolvePrice(ctx context.Context, input ResolvePriceInput) (Price, error)
// Per-namespace overrides
CreateOverride(ctx context.Context, input CreateOverrideInput) (Price, error)
DeleteOverride(ctx context.Context, input DeleteOverrideInput) error
ListOverrides(ctx context.Context, input ListOverridesInput) (pagination.Result[Price], error)
// Reconciled global prices
UpsertGlobalPrice(ctx context.Context, price Price) error
}
Adapter provides persistence for LLM cost prices.
type CreateOverrideInput ¶
type CreateOverrideInput struct {
Namespace string
Provider Provider
ModelID string
ModelName string
Pricing ModelPricing
Currency string
EffectiveFrom time.Time
EffectiveTo *time.Time
}
CreateOverrideInput creates a per-namespace price override.
func (CreateOverrideInput) Validate ¶
func (i CreateOverrideInput) Validate() error
type DeleteOverrideInput ¶
DeleteOverrideInput identifies a per-namespace override to delete.
func (DeleteOverrideInput) Validate ¶
func (i DeleteOverrideInput) Validate() error
type GetPriceInput ¶
type GetPriceInput struct {
ID string
// Namespace is used to overlay namespace overrides.
// When set and the fetched price is global, if a matching override exists
// for the same provider/model in this namespace, it will be returned instead.
Namespace string
}
GetPriceInput identifies a price by ID.
func (GetPriceInput) Validate ¶
func (i GetPriceInput) Validate() error
type ListOverridesInput ¶
type ListOverridesInput struct {
Namespace string
pagination.Page
Provider *filter.FilterString `json:"provider,omitempty"`
ModelID *filter.FilterString `json:"model_id,omitempty"`
ModelName *filter.FilterString `json:"model_name,omitempty"`
Currency *filter.FilterString `json:"currency,omitempty"`
}
ListOverridesInput filters for listing per-namespace overrides.
func (ListOverridesInput) Validate ¶
func (i ListOverridesInput) Validate() error
type ListPricesInput ¶
type ListPricesInput struct {
pagination.Page
// Namespace is used to overlay namespace overrides on top of global prices.
// When set, any global price that has a matching override in this namespace
// will be replaced by the override in the result.
Namespace string `json:"namespace,omitempty"`
// OrderBy is the field to sort by (e.g., "id", "provider.id", "model.id", "effective_from", "effective_to").
OrderBy string `json:"order_by,omitempty"`
// Order is the sort direction (ASC or DESC).
Order sortx.Order `json:"order,omitempty"`
// Provider filters by LLM vendor.
Provider *filter.FilterString `json:"provider,omitempty"`
// ModelID filters by model identifier.
ModelID *filter.FilterString `json:"model_id,omitempty"`
// ModelName filters by model display name.
ModelName *filter.FilterString `json:"model_name,omitempty"`
// Currency filters by currency code.
Currency *filter.FilterString `json:"currency,omitempty"`
// Source filters by price source (e.g., "manual", "system").
Source *filter.FilterString `json:"source,omitempty"`
}
ListPricesInput filters for listing global prices.
func (ListPricesInput) Validate ¶
func (i ListPricesInput) Validate() error
type ModelPricing ¶
type ModelPricing struct {
// InputPerToken is the cost per input token in USD.
InputPerToken alpacadecimal.Decimal `json:"input_per_token"`
// OutputPerToken is the cost per output token in USD.
OutputPerToken alpacadecimal.Decimal `json:"output_per_token"`
// CacheReadPerToken is the cost per cache read token in USD.
CacheReadPerToken *alpacadecimal.Decimal `json:"cache_read_per_token,omitempty"`
// CacheWritePerToken is the cost per cache write token in USD.
CacheWritePerToken *alpacadecimal.Decimal `json:"cache_write_per_token,omitempty"`
// ReasoningPerToken is the cost per reasoning/thinking token in USD.
ReasoningPerToken *alpacadecimal.Decimal `json:"reasoning_per_token,omitempty"`
}
ModelPricing holds the cost per token for each dimension.
func (ModelPricing) Validate ¶
func (p ModelPricing) Validate() error
type Price ¶
type Price struct {
models.ManagedModel
// ID is the unique identifier for this price record.
ID string `json:"id"`
// Namespace is nil for global prices, set for per-namespace overrides.
Namespace *string `json:"namespace,omitempty"`
// Provider is the LLM vendor (e.g., "openai", "anthropic").
Provider Provider `json:"provider"`
// ModelID is the canonical model identifier (e.g., "gpt-4", "claude-3-5-sonnet").
ModelID string `json:"model_id"`
// ModelName is the human-readable model name.
ModelName string `json:"model_name"`
// Pricing contains the cost per token for each dimension.
Pricing ModelPricing `json:"pricing"`
// Currency is the currency code (always "USD" for now).
Currency string `json:"currency"`
// Source indicates where this price came from.
Source PriceSource `json:"source"`
// SourcePrices stores the per-source pricing data that contributed to a system price.
// Only populated for system prices, nil for manual overrides.
SourcePrices SourcePricesMap `json:"source_prices,omitempty"`
// EffectiveFrom is the time from which this price is active.
EffectiveFrom time.Time `json:"effective_from"`
// EffectiveTo is the time at which this price expires. Nil means current.
EffectiveTo *time.Time `json:"effective_to,omitempty"`
// Metadata is arbitrary key-value data.
Metadata models.Metadata `json:"metadata,omitempty"`
}
Price represents a versioned price record for an LLM model.
type PriceSource ¶
type PriceSource string
PriceSource identifies where a price came from.
const ( // PriceSourceManual is used for per-namespace price overrides created by users. PriceSourceManual PriceSource = "manual" // PriceSourceSystem is used for reconciled global prices produced by the sync job. PriceSourceSystem PriceSource = "system" )
func (PriceSource) Validate ¶
func (s PriceSource) Validate() error
type ResolvePriceInput ¶
type ResolvePriceInput struct {
Namespace string
Provider Provider
ModelID string
At *time.Time // defaults to now if nil
}
ResolvePriceInput resolves the effective price for a model in a namespace.
func (ResolvePriceInput) Validate ¶
func (i ResolvePriceInput) Validate() error
type Service ¶
type Service interface {
// ListPrices returns global (synced) prices with optional filtering.
ListPrices(ctx context.Context, input ListPricesInput) (pagination.Result[Price], error)
// GetPrice returns a specific price by ID.
GetPrice(ctx context.Context, input GetPriceInput) (Price, error)
// ResolvePrice returns the effective price for a model in a namespace,
// preferring namespace overrides over global prices.
ResolvePrice(ctx context.Context, input ResolvePriceInput) (Price, error)
// CreateOverride creates a per-namespace price override.
CreateOverride(ctx context.Context, input CreateOverrideInput) (Price, error)
// DeleteOverride soft-deletes a per-namespace price override.
DeleteOverride(ctx context.Context, input DeleteOverrideInput) error
// ListOverrides returns per-namespace price overrides.
ListOverrides(ctx context.Context, input ListOverridesInput) (pagination.Result[Price], error)
}
Service provides read-only access to LLM cost prices and management of per-namespace overrides.
type SourcePrice ¶
type SourcePrice struct {
Source PriceSource `json:"source"`
Provider Provider `json:"provider"`
ModelID string `json:"model_id"`
ModelName string `json:"model_name"`
Pricing ModelPricing `json:"pricing"`
FetchedAt time.Time `json:"fetched_at"`
}
SourcePrice is a price fetched from a single external source, used in-memory during sync.
type SourcePriceData ¶
type SourcePriceData struct {
Pricing ModelPricing `json:"pricing"`
FetchedAt time.Time `json:"fetched_at"`
}
SourcePriceData is the per-source pricing stored as part of the JSON blob on a Price row.
type SourcePricesMap ¶
type SourcePricesMap map[PriceSource]SourcePriceData
SourcePricesMap maps source name to its pricing data.