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 }