UNPKG

openclaw-grafana-lens

Version:

OpenClaw plugin that gives AI agents full Grafana access — 18 composable tools for PromQL/LogQL/TraceQL queries, dashboard creation, alerting, SRE investigation, security monitoring, data collection pipeline management via Grafana Alloy (29 recipes), and

100 lines (99 loc) 4.02 kB
/** * Fallback model pricing for cost estimation. * * When openclaw's `estimateUsageCost()` returns undefined (because the user * hasn't configured model pricing in openclaw.json), this module provides * well-known pricing for popular models so cost dashboard panels still work. * * Pricing: USD per 1M tokens — matches openclaw's ModelCostConfig shape. * Returns undefined for unknown models (no guessing). */ // Provider → model ID → pricing (USD per 1M tokens) const KNOWN_MODEL_PRICING = { anthropic: { "claude-opus-4-6": { input: 15, output: 75, cacheRead: 1.5, cacheWrite: 18.75 }, "claude-sonnet-4-6": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, "claude-haiku-4-5-20251001": { input: 0.8, output: 4, cacheRead: 0.08, cacheWrite: 1 }, // Older models still in use "claude-sonnet-4-5-20250514": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, "claude-3-5-sonnet-20241022": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, "claude-3-5-haiku-20241022": { input: 0.8, output: 4, cacheRead: 0.08, cacheWrite: 1 }, }, }; /** * Estimate cost when openclaw's pricing config is missing. * Formula matches openclaw's estimateUsageCost(): * (input × inputCost + output × outputCost + cacheRead × cacheReadCost + cacheWrite × cacheWriteCost) / 1_000_000 * * Returns undefined for unknown provider/model combos. */ /** * Resolve model pricing from openclaw's config — the same config that * openclaw's own `resolveModelCostConfig()` reads. This covers ALL * user-configured models, not just the 6 hardcoded Anthropic ones. * * Config path: `config.models.providers[provider].models[{id: model}].cost` * * Returns undefined if the provider/model isn't configured or has no cost entry. */ export function resolveModelCostFromConfig(config, provider, model) { if (!provider || !model) return undefined; try { const models = config.models; if (!models) return undefined; const providers = models.providers; if (!providers) return undefined; const providerEntry = providers[provider]; if (!providerEntry) return undefined; const modelList = providerEntry.models; if (!Array.isArray(modelList)) return undefined; const modelEntry = modelList.find((m) => m.id === model); if (!modelEntry) return undefined; const cost = modelEntry.cost; if (!cost) return undefined; // openclaw's ModelCostConfig uses per-million pricing const input = typeof cost.input === "number" ? cost.input : undefined; const output = typeof cost.output === "number" ? cost.output : undefined; if (input === undefined || output === undefined) return undefined; return { input, output, cacheRead: typeof cost.cacheRead === "number" ? cost.cacheRead : input * 0.1, cacheWrite: typeof cost.cacheWrite === "number" ? cost.cacheWrite : input * 1.25, }; } catch { return undefined; } } /** * Estimate cost from a resolved ModelCost and token usage. * Same formula as openclaw's estimateUsageCost(): * (input × inputCost + output × outputCost + ...) / 1_000_000 */ export function estimateUsageCost(pricing, usage) { if (!usage) return undefined; const cost = ((usage.input ?? 0) * pricing.input + (usage.output ?? 0) * pricing.output + (usage.cacheRead ?? 0) * pricing.cacheRead + (usage.cacheWrite ?? 0) * pricing.cacheWrite) / 1_000_000; return cost > 0 ? cost : undefined; } export function estimateCostFallback(provider, model, usage) { if (!provider || !model || !usage) return undefined; const pricing = KNOWN_MODEL_PRICING[provider]?.[model]; if (!pricing) return undefined; return estimateUsageCost(pricing, usage); }