Ctrl K
ComunidadGuías…

codersdk/aimodelprices.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package codersdk

import (
	"context"
	"net/http"
	"time"
)

// AIModelPrice is a per-model token price used by AI Gateway to compute the
// cost of an interception.
//
// Prices are integer micro-units per million tokens, so 1000000 is $1.00 per
// million tokens. A nil price means the price is not known, which the cost
// calculation treats the same as zero. Distinguish that from an explicit 0,
// which declares the model free of charge.
type AIModelPrice struct {
	Provider        string             `json:"provider"`
	Model           string             `json:"model"`
	InputPrice      *int64             `json:"input_price"`
	OutputPrice     *int64             `json:"output_price"`
	CacheReadPrice  *int64             `json:"cache_read_price"`
	CacheWritePrice *int64             `json:"cache_write_price"`
	Source          AIModelPriceSource `json:"source"`
	CreatedAt       time.Time          `json:"created_at" format:"date-time"`
	UpdatedAt       time.Time          `json:"updated_at" format:"date-time"`
}

// AIModelPriceSource is where a model price came from.
type AIModelPriceSource string

const (
	// AIModelPriceSourceDefault is a price from the embedded price book.
	AIModelPriceSourceDefault AIModelPriceSource = "default"
	// AIModelPriceSourceCustom is a price set through the API.
	AIModelPriceSourceCustom AIModelPriceSource = "custom"
)

// AIModelPriceSourceFilter selects which prices a listing reports. It is
// distinct from AIModelPriceSource because no stored price is "all".
//
// @typescript-ignore AIModelPriceSourceFilter
type AIModelPriceSourceFilter string

const (
	AIModelPriceSourceFilterDefault = AIModelPriceSourceFilter(AIModelPriceSourceDefault)
	AIModelPriceSourceFilterCustom  = AIModelPriceSourceFilter(AIModelPriceSourceCustom)
	// AIModelPriceSourceFilterAll reports every price a model holds, so a model
	// carrying both appears twice.
	AIModelPriceSourceFilterAll AIModelPriceSourceFilter = "all"
)

// MaxAIModelPricesBytes bounds an upsert request body.
const MaxAIModelPricesBytes = 1 << 20 // 1 MiB

// UpsertAIModelPricesRequest sets prices for the listed models. Models absent
// from the request are left untouched.
type UpsertAIModelPricesRequest struct {
	Prices []AIModelPriceUpsert `json:"prices"`
}

// AIModelPriceUpsert is one model's prices in an upsert request. It carries
// only the writable fields of AIModelPrice.
type AIModelPriceUpsert struct {
	Provider        string `json:"provider"`
	Model           string `json:"model"`
	InputPrice      *int64 `json:"input_price"`
	OutputPrice     *int64 `json:"output_price"`
	CacheReadPrice  *int64 `json:"cache_read_price"`
	CacheWritePrice *int64 `json:"cache_write_price"`
}

// AIModelPricesFilter narrows the listed model prices. An empty field does not
// filter on that attribute.
//
// @typescript-ignore AIModelPricesFilter
type AIModelPricesFilter struct {
	Provider string `json:"provider,omitempty"`
	Model    string `json:"model,omitempty"`
	// Source narrows to prices from one source. A model with both reports only
	// its custom price unless this is set.
	Source AIModelPriceSourceFilter `json:"source,omitempty"`
}

func (f AIModelPricesFilter) asRequestOption() RequestOption {
	return func(r *http.Request) {
		query := r.URL.Query()
		if f.Provider != "" {
			query.Set("provider", f.Provider)
		}
		if f.Model != "" {
			query.Set("model", f.Model)
		}
		if f.Source != "" {
			query.Set("source", string(f.Source))
		}
		r.URL.RawQuery = query.Encode()
	}
}

// ListAIModelPrices returns the AI model prices matching the filter.
func (c *ExperimentalClient) ListAIModelPrices(ctx context.Context, filter AIModelPricesFilter) ([]AIModelPrice, error) {
	res, err := c.Request(ctx, http.MethodGet, "/api/experimental/ai/model-prices", nil, filter.asRequestOption())
	if err != nil {
		return nil, err
	}
	defer res.Body.Close()
	if res.StatusCode != http.StatusOK {
		return nil, ReadBodyAsError(res)
	}

	var prices []AIModelPrice
	return prices, ReadBodyAsJSON(res, &prices)
}

// UpsertAIModelPrices sets prices for the models in req. The request is
// rejected in full if any model fails validation.
func (c *ExperimentalClient) UpsertAIModelPrices(ctx context.Context, req UpsertAIModelPricesRequest) error {
	res, err := c.Request(ctx, http.MethodPost, "/api/experimental/ai/model-prices", req)
	if err != nil {
		return err
	}
	defer res.Body.Close()
	if res.StatusCode != http.StatusNoContent {
		return ReadBodyAsError(res)
	}
	return nil
}