@agent-finops/core 0.9.3 → 0.9.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/modelPricing.d.ts +1 -1
- package/dist/modelPricing.js +24 -3
- package/dist/planMath.js +14 -2
- package/package.json +1 -1
- package/dist/emailAddress.d.ts +0 -7
- package/dist/emailAddress.js +0 -16
package/dist/modelPricing.d.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* matched top-down; first match wins. Unknown models return undefined so
|
|
8
8
|
* callers can label the record "missing" instead of inventing a number.
|
|
9
9
|
*/
|
|
10
|
-
export declare const PRICING_TABLE_AS_OF = "2026-08-
|
|
10
|
+
export declare const PRICING_TABLE_AS_OF = "2026-08-25";
|
|
11
11
|
export type TokenUsage = {
|
|
12
12
|
/** Billable, uncached input tokens. */
|
|
13
13
|
inputTokens: number;
|
package/dist/modelPricing.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* matched top-down; first match wins. Unknown models return undefined so
|
|
8
8
|
* callers can label the record "missing" instead of inventing a number.
|
|
9
9
|
*/
|
|
10
|
-
export const PRICING_TABLE_AS_OF = "2026-08-
|
|
10
|
+
export const PRICING_TABLE_AS_OF = "2026-08-25";
|
|
11
11
|
const pricingRules = [
|
|
12
12
|
// Anthropic
|
|
13
13
|
{ match: /^claude-fable-5/i, inputPerM: 10, outputPerM: 50 },
|
|
@@ -93,14 +93,35 @@ const pricingRules = [
|
|
|
93
93
|
// DeepSeek (official API list prices)
|
|
94
94
|
{ match: /^deepseek-chat|^deepseek-v3/i, inputPerM: 0.27, outputPerM: 1.1 },
|
|
95
95
|
{ match: /^deepseek-reasoner|^deepseek-r1/i, inputPerM: 0.55, outputPerM: 2.19 },
|
|
96
|
-
// Moonshot / Kimi (official
|
|
97
|
-
|
|
96
|
+
// Moonshot / Kimi (official list prices, platform.kimi.ai/docs/pricing/*,
|
|
97
|
+
// fetched 2026-08-25; cache-hit input is a distinct published rate). Order
|
|
98
|
+
// matters: k2.7-code-highspeed before its k2.7-code prefix, dot families
|
|
99
|
+
// before the legacy K2 rule.
|
|
100
|
+
// ^kimi-k3 also covers the Anthropic-style "kimi-k3[1m]" context suffix.
|
|
101
|
+
{ match: /^kimi-k3/i, inputPerM: 3, outputPerM: 15, cacheReadPerM: 0.3 },
|
|
102
|
+
{ match: /^kimi-k2\.7-code-highspeed/i, inputPerM: 1.9, outputPerM: 8, cacheReadPerM: 0.38 },
|
|
103
|
+
{ match: /^kimi-k2\.7-code/i, inputPerM: 0.95, outputPerM: 4, cacheReadPerM: 0.19 },
|
|
104
|
+
{ match: /^kimi-k2\.6/i, inputPerM: 0.95, outputPerM: 4, cacheReadPerM: 0.16 },
|
|
105
|
+
// Legacy K2 (kimi-k2, kimi-k2-*) and moonshot-v1-* (sunset 2026-08-31 —
|
|
106
|
+
// still prices past transcripts). Deliberately does NOT match the dot
|
|
107
|
+
// families above: 0.9.3's `^kimi-k2` prefix silently priced kimi-k2.7-code
|
|
108
|
+
// at these old K2 rates (~$0.60/$2.50 vs the real $0.95/$4.00).
|
|
109
|
+
{ match: /^kimi-k2(?:$|-)|^moonshot/i, inputPerM: 0.6, outputPerM: 2.5 },
|
|
98
110
|
// xAI / Grok (official API list prices)
|
|
99
111
|
{ match: /^grok-4|^grok-3$/i, inputPerM: 3, outputPerM: 15 },
|
|
100
112
|
{ match: /^grok-3-mini/i, inputPerM: 0.3, outputPerM: 0.5 },
|
|
101
113
|
// Open-weight models with NO canonical price (llama, qwen, mistral, glm):
|
|
102
114
|
// hosting rates vary several-fold by provider, so we deliberately return
|
|
103
115
|
// undefined -> costConfidence "missing" instead of inventing a number.
|
|
116
|
+
//
|
|
117
|
+
// Deliberate deferrals (2026-08-25 CN-provider review), same honest path:
|
|
118
|
+
// - First-party Qwen commercial models (qwen3.x-max/plus/flash): the
|
|
119
|
+
// canonical Model Studio price list is console-gated and aggregator
|
|
120
|
+
// numbers have been wrong for this vendor family before — no rule until
|
|
121
|
+
// a canonical price is verified.
|
|
122
|
+
// - deepseek-v4-* (api-docs.deepseek.com/quick_start/pricing): published
|
|
123
|
+
// rates are time-of-day (off-peak = half price, up to 2x swing), so any
|
|
124
|
+
// flat number here would be dishonest; needs timestamp-aware pricing.
|
|
104
125
|
];
|
|
105
126
|
export function findPricingRule(model) {
|
|
106
127
|
return pricingRules.find((rule) => rule.match.test(model));
|
package/dist/planMath.js
CHANGED
|
@@ -50,7 +50,7 @@ export function computePlanChecks(records, detectedPlans = []) {
|
|
|
50
50
|
if (detectedKnown) {
|
|
51
51
|
// The label comes from local metadata or an explicit override. It is not
|
|
52
52
|
// independently verified against the provider account.
|
|
53
|
-
valueMultiple =
|
|
53
|
+
valueMultiple = roundValueMultiple(monthly / detectedKnown.monthlyUsd);
|
|
54
54
|
const savingsVsApi = roundMoney(monthly - detectedKnown.monthlyUsd);
|
|
55
55
|
effectiveSavings = savingsVsApi > 0 ? savingsVsApi : undefined;
|
|
56
56
|
headline =
|
|
@@ -81,7 +81,7 @@ export function computePlanChecks(records, detectedPlans = []) {
|
|
|
81
81
|
}
|
|
82
82
|
else {
|
|
83
83
|
const covered = suggested && typeof savings === "number" && savings > 0;
|
|
84
|
-
valueMultiple = covered ?
|
|
84
|
+
valueMultiple = covered ? roundValueMultiple(monthly / suggested.monthlyUsd) : undefined;
|
|
85
85
|
effectiveSavings = covered ? savings : undefined;
|
|
86
86
|
if (!suggested) {
|
|
87
87
|
headline = `${agent}: ~${formatUsd(monthly)}/mo at API rates (${basis}).`;
|
|
@@ -115,4 +115,16 @@ function formatUsd(value) {
|
|
|
115
115
|
return "<$0.01";
|
|
116
116
|
return `$${value.toFixed(2)}`;
|
|
117
117
|
}
|
|
118
|
+
/**
|
|
119
|
+
* Display rounding for the plan-price multiple. One decimal at >= 1x
|
|
120
|
+
* ("~24.3x" stays as-is); TWO decimals below 1x so a small-but-real
|
|
121
|
+
* multiple never renders "~0x" (founder's live case: $9.63/mo vs a
|
|
122
|
+
* $200/mo plan printed "~0x" — now "~0.05x"), floored at 0.01 for any
|
|
123
|
+
* positive ratio so the tilde always marks a nonzero approximation.
|
|
124
|
+
*/
|
|
125
|
+
function roundValueMultiple(ratio) {
|
|
126
|
+
if (ratio >= 1)
|
|
127
|
+
return Math.round(ratio * 10) / 10;
|
|
128
|
+
return Math.max(0.01, Math.round(ratio * 100) / 100);
|
|
129
|
+
}
|
|
118
130
|
//# sourceMappingURL=planMath.js.map
|
package/package.json
CHANGED
package/dist/emailAddress.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* One intentionally pragmatic normalizer for waitlist and receipt-email
|
|
3
|
-
* boundaries. It prevents header/control injection without pretending to be
|
|
4
|
-
* a mailbox-verification system; ownership still requires an explicit flow.
|
|
5
|
-
*/
|
|
6
|
-
export declare function normalizeAibillEmailAddress(value: string): string | undefined;
|
|
7
|
-
//# sourceMappingURL=emailAddress.d.ts.map
|
package/dist/emailAddress.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
const controlCharacters = /[\u0000-\u001F\u007F]/u;
|
|
2
|
-
const pragmaticEmailAddress = /^[^\s@]+@[^\s@]+\.[^\s@]+$/u;
|
|
3
|
-
/**
|
|
4
|
-
* One intentionally pragmatic normalizer for waitlist and receipt-email
|
|
5
|
-
* boundaries. It prevents header/control injection without pretending to be
|
|
6
|
-
* a mailbox-verification system; ownership still requires an explicit flow.
|
|
7
|
-
*/
|
|
8
|
-
export function normalizeAibillEmailAddress(value) {
|
|
9
|
-
const normalized = value.trim().toLowerCase();
|
|
10
|
-
if (normalized.length < 3 || normalized.length > 254)
|
|
11
|
-
return undefined;
|
|
12
|
-
if (controlCharacters.test(normalized))
|
|
13
|
-
return undefined;
|
|
14
|
-
return pragmaticEmailAddress.test(normalized) ? normalized : undefined;
|
|
15
|
-
}
|
|
16
|
-
//# sourceMappingURL=emailAddress.js.map
|