103 lines
4.0 KiB
TypeScript
103 lines
4.0 KiB
TypeScript
import type { ModelCapabilityChoice } from "@/components/model-protocol-picker";
|
|
import type { ChannelModel, ChannelModelPriceTier } from "@/services/api/wallet";
|
|
|
|
export type PriceTierMatchMode = "default" | "advanced";
|
|
|
|
export type PriceTierFormValues = {
|
|
matchMode: PriceTierMatchMode;
|
|
operation: string;
|
|
quality: string;
|
|
size: string;
|
|
resolution: string;
|
|
videoSeconds: number;
|
|
imageCount: number;
|
|
providerModelKey?: string;
|
|
billingMode: ChannelModel["billingMode"];
|
|
unitPrice: number;
|
|
inputTokenPrice: number;
|
|
outputTokenPrice: number;
|
|
cachedTokenPrice: number;
|
|
priceConfigured: boolean;
|
|
enabled: boolean;
|
|
};
|
|
|
|
export function defaultPriceTier(matchMode: PriceTierMatchMode = "default"): PriceTierFormValues {
|
|
return {
|
|
matchMode,
|
|
operation: "*",
|
|
quality: "*",
|
|
size: "*",
|
|
resolution: "*",
|
|
videoSeconds: 0,
|
|
imageCount: 0,
|
|
providerModelKey: "",
|
|
billingMode: "fixed_request",
|
|
unitPrice: 0,
|
|
inputTokenPrice: 0,
|
|
outputTokenPrice: 0,
|
|
cachedTokenPrice: 0,
|
|
priceConfigured: true,
|
|
enabled: true,
|
|
};
|
|
}
|
|
|
|
export function priceTierToForm(tier: ChannelModelPriceTier): PriceTierFormValues {
|
|
const selector = tier.selector || {};
|
|
const hasSpecificMatch = Object.values(selector).some((value) => value && value !== "*") || (tier.resolution && tier.resolution !== "*") || tier.videoSeconds > 0;
|
|
return {
|
|
matchMode: hasSpecificMatch ? "advanced" : "default",
|
|
operation: selector.operation || "*",
|
|
quality: selector.quality || "*",
|
|
size: selector.size || "*",
|
|
resolution: tier.resolution || "*",
|
|
videoSeconds: tier.videoSeconds || 0,
|
|
imageCount: Number(selector.imageCount || 0),
|
|
providerModelKey: tier.providerModelKey || "",
|
|
billingMode: tier.billingMode,
|
|
unitPrice: tier.unitPriceMicrocredits / 1_000_000,
|
|
inputTokenPrice: tier.inputTokenPriceMicrocredits / 1_000_000,
|
|
outputTokenPrice: tier.outputTokenPriceMicrocredits / 1_000_000,
|
|
cachedTokenPrice: tier.cachedTokenPriceMicrocredits / 1_000_000,
|
|
priceConfigured: tier.priceConfigured,
|
|
enabled: tier.enabled,
|
|
};
|
|
}
|
|
|
|
export function legacyPriceTierToForm(item: ChannelModel): PriceTierFormValues {
|
|
return {
|
|
...defaultPriceTier(),
|
|
providerModelKey: item.providerModelKey || "",
|
|
billingMode: item.billingMode,
|
|
unitPrice: item.unitPriceMicrocredits / 1_000_000,
|
|
inputTokenPrice: item.inputTokenPriceMicrocredits / 1_000_000,
|
|
outputTokenPrice: item.outputTokenPriceMicrocredits / 1_000_000,
|
|
cachedTokenPrice: item.cachedTokenPriceMicrocredits / 1_000_000,
|
|
priceConfigured: item.priceConfigured,
|
|
enabled: item.enabled,
|
|
};
|
|
}
|
|
|
|
export function skuSelectorFromForm(capability: ModelCapabilityChoice, tier: PriceTierFormValues) {
|
|
if (tier.matchMode !== "advanced") return {};
|
|
const selector: Record<string, string> = {};
|
|
if (tier.operation && tier.operation !== "*") selector.operation = tier.operation;
|
|
if (capability === "video") {
|
|
if (tier.resolution && tier.resolution !== "*") selector.vquality = tier.resolution;
|
|
if (Number(tier.videoSeconds) > 0) selector.videoSeconds = String(Number(tier.videoSeconds));
|
|
if (Number(tier.imageCount) > 0) selector.imageCount = String(Number(tier.imageCount));
|
|
}
|
|
if (capability === "image") {
|
|
if (tier.quality && tier.quality !== "*") selector.quality = tier.quality;
|
|
if (tier.size && tier.size !== "*") selector.size = tier.size;
|
|
}
|
|
return selector;
|
|
}
|
|
|
|
export function priceTierResolutionFromForm(capability: ModelCapabilityChoice, tier: PriceTierFormValues) {
|
|
return capability === "video" && tier.matchMode === "advanced" ? tier.resolution || "*" : "*";
|
|
}
|
|
|
|
export function priceTierVideoSecondsFromForm(capability: ModelCapabilityChoice, tier: PriceTierFormValues) {
|
|
return capability === "video" && tier.matchMode === "advanced" ? Number(tier.videoSeconds || 0) : 0;
|
|
}
|