Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | 85x 85x 85x 528x 528x 2x 526x 1565x 22x 504x 504x 2x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | import { ModelRegistry } from "./ModelRegistry.js";
import { ModelPricing } from "./types.js";
/**
* Registry for LLM pricing information.
* Priority: Runtime Overrides > Library Default Patterns > ModelRegistry (models.ts)
*/
export class PricingRegistry {
private static pricingOverrides = new Map<string, ModelPricing>();
private static lastUpdated: Date | null = new Date();
// Library-level fallbacks for common model families
private static DEFAULT_PATTERNS: Array<{
pattern: RegExp;
provider: string;
pricing: ModelPricing;
}> = [
{
provider: "anthropic",
pattern: /claude-3-7/,
pricing: {
text_tokens: {
standard: {
input_per_million: 3.0,
output_per_million: 15.0,
reasoning_output_per_million: 37.5
},
batch: {
input_per_million: 1.5,
output_per_million: 7.5,
reasoning_output_per_million: 18.75
}
}
}
},
{
provider: "anthropic",
pattern: /claude-3/,
pricing: {
text_tokens: {
standard: { input_per_million: 3.0, output_per_million: 15.0 },
batch: { input_per_million: 1.5, output_per_million: 7.5 }
}
}
},
{
provider: "openai",
pattern: /gpt-3/,
pricing: {
text_tokens: { standard: { input_per_million: 0.5, output_per_million: 1.5 } }
}
}
];
/**
* Get pricing for a model.
*/
static getPricing(modelId: string, provider: string): ModelPricing | undefined {
// 1. Check custom overrides (Runtime/Remote)
const key = `${provider}/${modelId}`;
if (this.pricingOverrides.has(key)) {
return this.pricingOverrides.get(key);
}
// 2. Check library default patterns (Core Overrides)
for (const entry of this.DEFAULT_PATTERNS) {
if (entry.provider === provider && entry.pattern.test(modelId)) {
return entry.pricing;
}
}
// 3. Fallback to registry lookup (models.ts)
const model = ModelRegistry.find(modelId, provider);
return model?.pricing;
}
/**
* Register or override pricing at runtime.
*/
static register(provider: string, modelId: string, pricing: ModelPricing) {
this.pricingOverrides.set(`${provider}/${modelId}`, pricing);
}
/**
* Fetch updates from a remote URL.
*/
static async fetchUpdates(url: string) {
try {
const response = await fetch(url);
Iif (!response.ok) throw new Error(response.statusText);
const data = await response.json();
Eif (data.models) {
for (const [key, pricing] of Object.entries(data.models)) {
const [provider, modelId] = key.split("/");
Eif (provider && modelId) this.register(provider, modelId, pricing as ModelPricing);
}
}
this.lastUpdated = new Date();
return true;
} catch (error) {
console.error("[NodeLLM] Error fetching pricing updates:", error);
return false;
}
}
/**
* Get the timestamp of the last update.
*/
static getLastUpdated(): Date | null {
return this.lastUpdated;
}
/**
* Reset overrides.
*/
static reset() {
this.pricingOverrides.clear();
this.lastUpdated = new Date();
}
}
|