Files
llm-intelligence/scripts/minimax_subscription_lib.go

189 lines
7.2 KiB
Go
Raw Normal View History

//go:build llm_script
package main
import (
"fmt"
"regexp"
"strings"
)
const defaultMinimaxTokenPlanURL = "https://platform.minimax.io/docs/guides/pricing-token-plan"
type minimaxPlanSpec struct {
billingCycle string
priceUnit string
blockPattern string
modelScope []string
tiers []string
planCodes []string
planNames []string
quotaUnit string
}
func parseMinimaxTokenPlans(raw string) ([]subscriptionImportRecord, error) {
publishedAt, known := publishedAtFromText(raw)
normalized := normalizeMinimaxTokenPlanText(raw)
specs := []minimaxPlanSpec{
{
billingCycle: "monthly",
priceUnit: "USD/month",
blockPattern: `Monthly.*?Starter\s+Plus\s+Max\s+Price\s+\$([\d,]+)\s*/month\s+\$([\d,]+)\s*/month\s+\$([\d,]+)\s*/month\s+M2\.7\s+([\d,]+)\s+requests/5hrs\s+([\d,]+)\s+requests/5hrs\s+([\d,]+)\s+requests/5hrs`,
modelScope: []string{"MiniMax-M2.7"},
tiers: []string{"Starter", "Plus", "Max"},
planCodes: []string{"minimax-token-plan-starter", "minimax-token-plan-plus", "minimax-token-plan-max"},
planNames: []string{"MiniMax Token Plan Starter", "MiniMax Token Plan Plus", "MiniMax Token Plan Max"},
quotaUnit: "requests/5hrs",
},
{
billingCycle: "monthly",
priceUnit: "USD/month",
blockPattern: `Monthly.*?Highspeed Plans\s+Plus-Highspeed\s+Max-Highspeed\s+Ultra-Highspeed\s+Price\s+\$([\d,]+)\s*/month\s+\$([\d,]+)\s*/month\s+\$([\d,]+)\s*/month\s+M2\.7-highspeed\s+([\d,]+)\s+requests/5hrs\s+([\d,]+)\s+requests/5hrs\s+([\d,]+)\s+requests/5hrs`,
modelScope: []string{"MiniMax-M2.7-Highspeed"},
tiers: []string{"Plus-Highspeed", "Max-Highspeed", "Ultra-Highspeed"},
planCodes: []string{"minimax-token-plan-plus-highspeed", "minimax-token-plan-max-highspeed", "minimax-token-plan-ultra-highspeed"},
planNames: []string{"MiniMax Token Plan Plus-Highspeed", "MiniMax Token Plan Max-Highspeed", "MiniMax Token Plan Ultra-Highspeed"},
quotaUnit: "requests/5hrs",
},
{
billingCycle: "yearly",
priceUnit: "USD/year",
blockPattern: `Yearly.*?Starter\s+Plus\s+Max\s+Price\s+\$([\d,]+)\s*/year\s+\$([\d,]+)\s*/year\s+\$([\d,]+)\s*/year\s+M2\.7\s+([\d,]+)\s+requests/5hrs\s+([\d,]+)\s+requests/5hrs\s+([\d,]+)\s+requests/5hrs`,
modelScope: []string{"MiniMax-M2.7"},
tiers: []string{"Starter-Yearly", "Plus-Yearly", "Max-Yearly"},
planCodes: []string{"minimax-token-plan-starter-yearly", "minimax-token-plan-plus-yearly", "minimax-token-plan-max-yearly"},
planNames: []string{"MiniMax Token Plan Starter Yearly", "MiniMax Token Plan Plus Yearly", "MiniMax Token Plan Max Yearly"},
quotaUnit: "requests/5hrs",
},
{
billingCycle: "yearly",
priceUnit: "USD/year",
blockPattern: `Yearly.*?Highspeed Plans\s+Plus-Highspeed\s+Max-Highspeed\s+Ultra-Highspeed\s+Price\s+\$([\d,]+)\s*/year\s+\$([\d,]+)\s*/year\s+\$([\d,]+)\s*/year\s+M2\.7-highspeed\s+([\d,]+)\s+requests/5hrs\s+([\d,]+)\s+requests/5hrs\s+([\d,]+)\s+requests/5hrs`,
modelScope: []string{"MiniMax-M2.7-Highspeed"},
tiers: []string{"Plus-Highspeed-Yearly", "Max-Highspeed-Yearly", "Ultra-Highspeed-Yearly"},
planCodes: []string{"minimax-token-plan-plus-highspeed-yearly", "minimax-token-plan-max-highspeed-yearly", "minimax-token-plan-ultra-highspeed-yearly"},
planNames: []string{"MiniMax Token Plan Plus-Highspeed Yearly", "MiniMax Token Plan Max-Highspeed Yearly", "MiniMax Token Plan Ultra-Highspeed Yearly"},
quotaUnit: "requests/5hrs",
},
}
var records []subscriptionImportRecord
for _, spec := range specs {
parsed, err := parseMinimaxPlanBlock(normalized, spec, publishedAt)
if err != nil {
return nil, err
}
records = append(records, parsed...)
}
standardNotes := extractMinimaxNotes(normalized, []string{
"Speech 2.8",
"image-01",
"Hailuo-2.3-Fast",
"Hailuo-2.3",
"Music-2.6",
})
for i := range records {
records[i].PublishedAtKnown = known
if strings.Contains(records[i].PlanCode, "highspeed") {
records[i].Notes = joinNonEmptyNotes(records[i].Notes, "高速版覆盖 MiniMax-M2.7-Highspeed。")
continue
}
records[i].Notes = joinNonEmptyNotes(records[i].Notes, standardNotes)
}
return records, nil
}
func parseMinimaxPlanBlock(raw string, spec minimaxPlanSpec, publishedAt string) ([]subscriptionImportRecord, error) {
match := regexp.MustCompile(spec.blockPattern).FindStringSubmatch(raw)
if len(match) != 7 {
return nil, fmt.Errorf("unexpected minimax %s block", spec.billingCycle)
}
records := make([]subscriptionImportRecord, 0, 3)
for i := range spec.tiers {
records = append(records, subscriptionImportRecord{
ProviderName: "MiniMax",
ProviderNameCn: "MiniMax",
ProviderCountry: "CN",
ProviderWebsite: "https://platform.minimax.io",
OperatorName: "MiniMax",
OperatorNameCn: "MiniMax",
OperatorCountry: "CN",
OperatorWebsite: "https://platform.minimax.io/docs/guides/pricing-overview",
OperatorType: "official",
PlanFamily: "token_plan",
PlanCode: spec.planCodes[i],
PlanName: spec.planNames[i],
Tier: spec.tiers[i],
BillingCycle: spec.billingCycle,
Currency: "USD",
ListPrice: mustParseSubscriptionPrice(match[i+1]),
PriceUnit: spec.priceUnit,
QuotaValue: mustParseSubscriptionInt64(match[i+4]),
QuotaUnit: spec.quotaUnit,
PlanScope: "Token Plan",
ModelScope: append([]string(nil), spec.modelScope...),
SourceURL: defaultMinimaxTokenPlanURL,
PublishedAt: publishedAt,
EffectiveDate: effectiveDateFromPublishedAt(publishedAt),
PublishedAtKnown: true,
})
}
return records, nil
}
func normalizeMinimaxTokenPlanText(raw string) string {
replacer := strings.NewReplacer(
"High-Speed", "Highspeed",
"High Speed", "Highspeed",
"Max-High-Speed", "Max-Highspeed",
"Ultra-High-Speed", "Ultra-Highspeed",
"Plus `Cost-Effective`", "Plus",
"Max `Extra Large`", "Max",
"Starter `Save $20`", "Starter",
"Plus `Save $40`", "Plus",
"Max `Save $100`", "Max",
"Plus-Highspeed `Save $80`", "Plus-Highspeed",
"Max-Highspeed `Save $160`", "Max-Highspeed",
"Ultra-Highspeed `Save $300`", "Ultra-Highspeed",
"Subscribe Now Standard Plans:", "",
"Subscribe Now", "",
"Standard Plans:", "",
"Highspeed Plans:", "Highspeed Plans",
)
normalized := replacer.Replace(raw)
normalized = strings.ReplaceAll(normalized, "\r\n", "\n")
normalized = strings.ReplaceAll(normalized, "\r", "\n")
normalized = strings.ReplaceAll(normalized, "|", " ")
normalized = strings.ReplaceAll(normalized, "---", " ")
normalized = regexp.MustCompile(`\s+`).ReplaceAllString(normalized, " ")
return strings.TrimSpace(normalized)
}
func extractMinimaxNotes(raw string, markers []string) string {
var hits []string
for _, marker := range markers {
if strings.Contains(raw, marker) {
hits = append(hits, marker)
}
}
if len(hits) == 0 {
return ""
}
return "附带配额包含 " + strings.Join(hits, " / ") + "。"
}
func joinNonEmptyNotes(parts ...string) string {
filtered := make([]string, 0, len(parts))
for _, part := range parts {
part = strings.TrimSpace(part)
if part == "" {
continue
}
filtered = append(filtered, part)
}
return strings.Join(filtered, " ")
}