61 lines
2.1 KiB
Go
61 lines
2.1 KiB
Go
package billing
|
|
|
|
import (
|
|
"errors"
|
|
"math"
|
|
"strings"
|
|
)
|
|
|
|
const Seedream50ProModel = "doubao-seedream-5-0-pro-260628"
|
|
|
|
const SeedreamLayerPixelThreshold = 2_610_000
|
|
|
|
type SeedreamLayerImage struct {
|
|
Width int
|
|
Height int
|
|
}
|
|
|
|
// CalculateSeedreamAmountFen applies Seedream's additive input-image price
|
|
// before the platform markup: the first reference image is free and every
|
|
// additional reference image costs 2 fen.
|
|
func CalculateSeedreamAmountFen(outputPriceFen int64, referenceImageCount int, markupMultiplier float64) (int64, error) {
|
|
if outputPriceFen <= 0 {
|
|
return 0, errors.New("seedream output price must be positive")
|
|
}
|
|
if referenceImageCount < 0 || referenceImageCount > 10 {
|
|
return 0, errors.New("seedream reference image count must be between 0 and 10")
|
|
}
|
|
if math.IsNaN(markupMultiplier) || math.IsInf(markupMultiplier, 0) || markupMultiplier < 1 {
|
|
return 0, errors.New("seedream markup multiplier must be at least 1")
|
|
}
|
|
extraInputPriceFen := int64(max(0, referenceImageCount-1) * 2)
|
|
return int64(math.Ceil(float64(outputPriceFen+extraInputPriceFen) * markupMultiplier)), nil
|
|
}
|
|
|
|
func IsSeedreamBillingModel(model string) bool {
|
|
return strings.TrimSpace(model) == Seedream50ProModel
|
|
}
|
|
|
|
// CalculateSeedreamLayerAmountFen charges every returned image independently:
|
|
// 15 fen up to 2.61M pixels and 30 fen above that tier, followed by markup.
|
|
func CalculateSeedreamLayerAmountFen(images []SeedreamLayerImage, markupMultiplier float64) (int64, error) {
|
|
if len(images) == 0 || len(images) > 17 {
|
|
return 0, errors.New("seedream layer output count must be between 1 and 17")
|
|
}
|
|
if math.IsNaN(markupMultiplier) || math.IsInf(markupMultiplier, 0) || markupMultiplier < 1 {
|
|
return 0, errors.New("seedream markup multiplier must be at least 1")
|
|
}
|
|
standardAmountFen := int64(0)
|
|
for _, image := range images {
|
|
if image.Width <= 0 || image.Height <= 0 {
|
|
return 0, errors.New("seedream layer output dimensions must be positive")
|
|
}
|
|
price := int64(15)
|
|
if int64(image.Width)*int64(image.Height) > SeedreamLayerPixelThreshold {
|
|
price = 30
|
|
}
|
|
standardAmountFen += price
|
|
}
|
|
return int64(math.Ceil(float64(standardAmountFen) * markupMultiplier)), nil
|
|
}
|