Files
light 6ec9778d45 chore: initial commit
Laimiao agent v2 service: agent orchestration, sessions, billing,
gateway client, skills catalog, auth, config, plus tests.
2026-11-07 10:40:07 +08:00

75 lines
2.3 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { PricingError, quoteSkill, repriceForQuantity } from "../src/billing/pricing.js";
import type { SkillDefinition } from "../src/types.js";
const skill: SkillDefinition = {
key: "demo",
name: "demo",
displayName: "Demo Skill",
description: "demo",
content: "# demo",
triggerKeywords: "demo",
usesDefaults: false,
manifest: {
key: "demo",
version: "1.0.0",
industry: "test",
model: "seedream@5.0",
defaults: { size: "1024x1536", n: 1 },
price: { currency: "credits", per_image: 30, size_multipliers: { "2048x3072": 2 } },
capabilities: [],
tags: [],
max_images: 4,
enabled: true,
},
};
describe("pricing", () => {
it("quotes one image using defaults", () => {
expect(quoteSkill(skill, { size: "1024x1536", quantity: 1 }, {}, "dry_run")).toEqual({
skill_id: "demo",
skill_name: "Demo Skill",
model: "seedream@5.0",
size: "1024x1536",
quantity: 1,
unit_credits: 30,
size_multiplier: 1,
total_credits: 30,
currency: "credits",
billing_mode: "dry_run",
});
});
it("applies size multipliers and quantity", () => {
const quote = quoteSkill(
skill,
{ size: "1024x1536", quantity: 1 },
{ size: "2048x3072", quantity: 3 },
"off",
);
expect(quote.size_multiplier).toBe(2);
expect(quote.total_credits).toBe(180);
expect(quote.billing_mode).toBe("off");
});
it("rejects over-limit, non-integer, and malformed sizes", () => {
expect(() => quoteSkill(skill, { size: "1024x1536", quantity: 1 }, { quantity: 5 }, "dry_run")).toThrow(
PricingError,
);
expect(() => quoteSkill(skill, { size: "1024x1536", quantity: 1 }, { quantity: 1.5 }, "dry_run")).toThrow(
/integer/,
);
expect(() => quoteSkill(skill, { size: "1024x1536", quantity: 1 }, { size: "large" }, "dry_run")).toThrow(
/size/,
);
});
it("reprices to the actually returned image count", () => {
const quote = quoteSkill(skill, { size: "1024x1536", quantity: 1 }, { quantity: 3 }, "dry_run");
const repriced = repriceForQuantity(quote, 1);
expect(repriced.quantity).toBe(1);
expect(repriced.total_credits).toBe(30);
expect(() => repriceForQuantity(quote, -1)).toThrow(PricingError);
});
});