import { n as loadCostUsageSummary } from "./session-cost-usage-CJWHHY-C.js";
import { t as estimateUsageCost } from "./usage-format-DQJz-0qd.js";

//#region src/cost/benchmark.ts
/**
* Claude reference rates and benchmark comparison.
*
* Hardcoded per-token USD rates for Claude Opus 4.7, Sonnet 4.6, and
* Haiku 4.5 (per million tokens, Anthropic public list as of 2026-Q1).
* Override via `models.gpuRates` is for GPU rates only — Claude rates can
* be overridden via the per-model `cost: { input, output }` configuration
* on the user's `anthropic` provider entry, which already exists.
*
* Display: pick a target tier via `agents.defaults.cost.benchmark`, default
* `sonnet`. Setting `"all"` shows comparisons against all three tiers.
*/
/** Per-million-token USD rates, applied via `estimateUsageCost`. */
const CLAUDE_RATES = {
	opus: {
		input: 15,
		output: 75,
		cacheRead: 1.5,
		cacheWrite: 18.75
	},
	sonnet: {
		input: 3,
		output: 15,
		cacheRead: .3,
		cacheWrite: 3.75
	},
	haiku: {
		input: .8,
		output: 4,
		cacheRead: .08,
		cacheWrite: 1
	}
};
const CLAUDE_LABEL = {
	opus: "Claude Opus 4.7",
	sonnet: "Claude Sonnet 4.6",
	haiku: "Claude Haiku 4.5"
};
function benchmarkUsage(args) {
	if (!args.usage) return [];
	const tiers = args.target === "all" ? [
		"opus",
		"sonnet",
		"haiku"
	] : [args.target];
	const results = [];
	for (const tier of tiers) {
		const cost = estimateUsageCost({
			usage: args.usage,
			cost: CLAUDE_RATES[tier]
		});
		if (cost === void 0) continue;
		results.push({
			tier,
			costUsd: cost
		});
	}
	return results;
}
function formatBenchmarkSuffix(args) {
	if (args.benchmarks.length === 0) return;
	if (args.benchmarks.length === 1) {
		const b = args.benchmarks[0];
		return formatPair(args.ourCostUsd, b);
	}
	const parts = [];
	for (const b of args.benchmarks) parts.push(`${shortLabel(b.tier)} $${formatCostShort(b.costUsd)}`);
	const cheapest = args.benchmarks.reduce((min, b) => b.costUsd < min.costUsd ? b : min);
	if (cheapest.costUsd > args.ourCostUsd && cheapest.costUsd > 0) {
		const savedPct = (cheapest.costUsd - args.ourCostUsd) / cheapest.costUsd * 100;
		if (savedPct >= 1) parts.push(`save ${savedPct.toFixed(0)}% vs ${shortLabel(cheapest.tier)}`);
	}
	return `vs ${parts.join(" / ")}`;
}
function formatPair(ourCost, b) {
	const benchPart = `${CLAUDE_LABEL[b.tier]} would be $${formatCostShort(b.costUsd)}`;
	if (b.costUsd > 0 && b.costUsd > ourCost) {
		const saved = (b.costUsd - ourCost) / b.costUsd * 100;
		if (saved >= 1) return `${benchPart} (save ${saved.toFixed(0)}%)`;
	} else if (b.costUsd > 0 && ourCost > b.costUsd) {
		const overspend = (ourCost - b.costUsd) / b.costUsd * 100;
		if (overspend >= 1) return `${benchPart} (+${overspend.toFixed(0)}%)`;
	}
	return benchPart;
}
function shortLabel(tier) {
	if (tier === "opus") return "Opus";
	if (tier === "sonnet") return "Sonnet";
	return "Haiku";
}
function formatCostShort(value) {
	if (value >= 1) return value.toFixed(2);
	return value.toFixed(4);
}
function isClaudeTier(value) {
	return value === "opus" || value === "sonnet" || value === "haiku";
}
function isBenchmarkTarget(value) {
	return isClaudeTier(value) || value === "all";
}
function resolveBenchmarkTarget(value) {
	if (typeof value === "string" && isBenchmarkTarget(value)) return value;
	return "sonnet";
}

//#endregion
//#region src/cost/summary.ts
async function loadCostBenchmarkSummary(params) {
	const summary = await loadCostUsageSummary(params);
	const daily = summary.daily.map((day) => ({
		...day,
		benchmarkUsd: computeBenchmarkPerTier(day)
	}));
	const benchmarkTotals = computeBenchmarkPerTier(summary.totals);
	const savingsTotals = {
		opus: benchmarkTotals.opus - summary.totals.totalCost,
		sonnet: benchmarkTotals.sonnet - summary.totals.totalCost,
		haiku: benchmarkTotals.haiku - summary.totals.totalCost
	};
	return {
		...summary,
		daily,
		benchmarkTotals,
		savingsTotals
	};
}
function computeBenchmarkPerTier(totals) {
	const all = benchmarkUsage({
		usage: {
			input: totals.input,
			output: totals.output,
			cacheRead: totals.cacheRead,
			cacheWrite: totals.cacheWrite
		},
		target: "all"
	});
	const map = new Map(all.map((b) => [b.tier, b.costUsd]));
	return {
		opus: map.get("opus") ?? 0,
		sonnet: map.get("sonnet") ?? 0,
		haiku: map.get("haiku") ?? 0
	};
}
function resolveWindow(window, now = Date.now()) {
	const end = now;
	switch (window) {
		case "today": {
			const d = new Date(end);
			d.setHours(0, 0, 0, 0);
			return {
				startMs: d.getTime(),
				endMs: end
			};
		}
		case "week": return {
			startMs: end - 10080 * 6e4,
			endMs: end
		};
		case "month": return {
			startMs: end - 720 * 60 * 6e4,
			endMs: end
		};
		case "all": return {
			startMs: 0,
			endMs: end
		};
	}
}
function formatSummaryReport(summary, label) {
	const t = summary.totals;
	const b = summary.benchmarkTotals;
	const lines = [];
	if (label) lines.push(`# ${label}`);
	lines.push(`Tokens:  ${formatTokens(t.totalTokens)} (${formatTokens(t.input)} in / ${formatTokens(t.output)} out)`);
	lines.push(`Spend:   $${t.totalCost.toFixed(4)}`);
	lines.push(`Claude equivalents:`);
	lines.push(`  Opus:   $${b.opus.toFixed(4)}  (saved $${(b.opus - t.totalCost).toFixed(4)})`);
	lines.push(`  Sonnet: $${b.sonnet.toFixed(4)}  (saved $${(b.sonnet - t.totalCost).toFixed(4)})`);
	lines.push(`  Haiku:  $${b.haiku.toFixed(4)}  (saved $${(b.haiku - t.totalCost).toFixed(4)})`);
	if (summary.daily.length > 0) {
		lines.push("");
		lines.push("Daily:");
		for (const d of summary.daily.slice(-7)) lines.push(`  ${d.date}: ${formatTokens(d.totalTokens).padStart(8)} tokens · $${d.totalCost.toFixed(4).padStart(8)} · vs Sonnet $${d.benchmarkUsd.sonnet.toFixed(4)}`);
	}
	return lines.join("\n");
}
function formatTokens(n) {
	if (!Number.isFinite(n) || n <= 0) return "0";
	if (n >= 1e6) return `${(n / 1e6).toFixed(1)}m`;
	if (n >= 1e3) return `${(n / 1e3).toFixed(n >= 1e4 ? 0 : 1)}k`;
	return String(Math.round(n));
}

//#endregion
//#region src/cost/rates.ts
const GPU_VRAM_GB = {
	"a100-40gb": 40,
	"a100-80gb": 80,
	"h100-pcie": 80,
	"h100-sxm": 80,
	h200: 141,
	l40: 48,
	l40s: 48,
	a40: 48,
	a6000: 48,
	a5000: 24,
	v100: 32,
	mi300x: 192,
	"rtx-4090": 24
};
const GPU_LABEL = {
	"a100-40gb": "A100-40GB",
	"a100-80gb": "A100-80GB",
	"h100-pcie": "H100-PCIe",
	"h100-sxm": "H100-SXM",
	h200: "H200",
	l40: "L40",
	l40s: "L40S",
	a40: "A40",
	a6000: "RTX-A6000",
	a5000: "RTX-A5000",
	v100: "V100",
	mi300x: "MI300X",
	"rtx-4090": "RTX-4090"
};
const DEFAULT_HOURLY_RATES_USD = {
	"a100-40gb": 2.06,
	"a100-80gb": 2.21,
	"h100-pcie": 4.25,
	"h100-sxm": 4.76,
	h200: 6.5,
	l40: 1.27,
	l40s: 1.35,
	a40: .95,
	a6000: .96,
	a5000: .61,
	v100: .8,
	mi300x: 4.89,
	"rtx-4090": .74
};
/**
* Rough decode (output) throughput defaults in tokens/sec for a 27-30B FP8
* model on a single GPU of each type. Scales roughly inversely with model
* parameter count and bytes-per-param. Used as a fallback when no live
* `vllm:generation_tokens_total` delta has been observed yet.
*
* These are conservative published-benchmark medians; treat as ballpark.
* Override via `models.gpuRates` is rate-only; throughput overrides are
* Phase 4+ (not yet wired to config).
*/
const DEFAULT_DECODE_TPS = {
	"a100-40gb": 60,
	"a100-80gb": 80,
	"h100-pcie": 120,
	"h100-sxm": 130,
	h200: 160,
	l40: 45,
	l40s: 50,
	a40: 40,
	a6000: 35,
	a5000: 25,
	v100: 25,
	mi300x: 110,
	"rtx-4090": 55
};
/**
* Prefill throughput is typically 30-60× higher than decode for a given
* setup. Use 40× as a balanced midpoint.
*/
const PREFILL_DECODE_RATIO = 40;
function resolveDefaultDecodeTps(gpuType, paramsB, bytesPerParam) {
	const baseline = DEFAULT_DECODE_TPS[gpuType];
	if (!paramsB) return baseline;
	const refBytes = 27;
	const modelBytes = paramsB * (bytesPerParam ?? 2);
	if (modelBytes <= 0) return baseline;
	const scaled = baseline * (refBytes / modelBytes);
	return Math.max(5, scaled);
}
function resolveHourlyRate(gpuType, overrides) {
	if (overrides && typeof overrides[gpuType] === "number" && overrides[gpuType] >= 0) return overrides[gpuType];
	return DEFAULT_HOURLY_RATES_USD[gpuType];
}

//#endregion
//#region src/cost/gpu-inference.ts
/**
* Heuristic GPU type + count inference for self-hosted serving endpoints.
*
* Two signals: the baseUrl hostname (often encodes "a100", "h100", etc.) and
* the model id (encodes parameter count + quantization, e.g. "qwen36-27b-fp8").
* Output is a confidence-tagged guess so downstream code (and the user) can
* decide whether to trust the inference or override it.
*
* Bytes-per-parameter table:
*   fp32        → 4
*   fp16/bf16   → 2 (default when unspecified)
*   fp8/int8/q8 → 1
*   int4/q4/fp4 → 0.5
*
* GPU count formula:
*   model_bytes = params × bytes_per_param
*   target_util = 0.6 (40% headroom for KV cache, activations, scheduler)
*   count       = max(1, ceil(model_bytes / (vram × target_util)))
*/
const URL_GPU_PATTERNS = [
	{
		re: /h200/i,
		type: "h200",
		confidence: "high"
	},
	{
		re: /h100[-_]?pcie/i,
		type: "h100-pcie",
		confidence: "high"
	},
	{
		re: /h100[-_]?sxm/i,
		type: "h100-sxm",
		confidence: "high"
	},
	{
		re: /h100/i,
		type: "h100-sxm",
		confidence: "medium"
	},
	{
		re: /a100[-_]?80/i,
		type: "a100-80gb",
		confidence: "high"
	},
	{
		re: /a100[-_]?40/i,
		type: "a100-40gb",
		confidence: "high"
	},
	{
		re: /a100/i,
		type: "a100-80gb",
		confidence: "medium"
	},
	{
		re: /l40s/i,
		type: "l40s",
		confidence: "high"
	},
	{
		re: /l40/i,
		type: "l40",
		confidence: "high"
	},
	{
		re: /mi300x/i,
		type: "mi300x",
		confidence: "high"
	},
	{
		re: /a6000/i,
		type: "a6000",
		confidence: "high"
	},
	{
		re: /a5000/i,
		type: "a5000",
		confidence: "high"
	},
	{
		re: /a40/i,
		type: "a40",
		confidence: "high"
	},
	{
		re: /v100/i,
		type: "v100",
		confidence: "high"
	},
	{
		re: /rtx[-_]?4090|gpu[-_]?4090/i,
		type: "rtx-4090",
		confidence: "high"
	}
];
function inferGpuFromUrl(baseUrl) {
	const url = baseUrl.toLowerCase();
	for (const pattern of URL_GPU_PATTERNS) {
		const match = url.match(pattern.re);
		if (match) return {
			gpuType: pattern.type,
			confidence: pattern.confidence,
			match: match[0]
		};
	}
	return { confidence: "low" };
}
function parseModelSize(modelId) {
	const id = modelId.toLowerCase();
	const sizeMatch = id.match(/(\d+(?:\.\d+)?)b(?:[-_./]|$)/);
	const paramsB = sizeMatch ? Number.parseFloat(sizeMatch[1]) : void 0;
	let bytesPerParam;
	if (/\b(fp4|q4|int4)\b/.test(id) || /[-_]q4[-_]/.test(id)) bytesPerParam = .5;
	else if (/\b(fp8|int8|q8|w8a8|w8a16)\b/.test(id) || /[-_]fp8[-_]?/.test(id)) bytesPerParam = 1;
	else if (/\b(fp16|bf16|float16|half)\b/.test(id)) bytesPerParam = 2;
	else if (/\b(fp32|float32)\b/.test(id)) bytesPerParam = 4;
	return {
		paramsB,
		bytesPerParam
	};
}
function inferGpuCount(args) {
	const util = args.targetUtilization ?? .6;
	if (!args.paramsB || !args.bytesPerParam) return 1;
	const modelBytes = args.paramsB * 1e9 * args.bytesPerParam;
	const usableVram = args.vramGb * 1e9 * util;
	return Math.max(1, Math.ceil(modelBytes / usableVram));
}
function inferGpu(args) {
	const reasoning = [];
	const overrideType = args.override?.gpuType;
	const overrideCount = args.override?.gpuCount;
	let gpuType;
	let confidence = "low";
	if (overrideType && overrideType in GPU_VRAM_GB) {
		gpuType = overrideType;
		confidence = "high";
		reasoning.push(`gpuType=${gpuType} from config override`);
	} else if (args.baseUrl) {
		const fromUrl = inferGpuFromUrl(args.baseUrl);
		if (fromUrl.gpuType) {
			gpuType = fromUrl.gpuType;
			confidence = fromUrl.confidence;
			reasoning.push(`gpuType=${gpuType} from URL pattern '${fromUrl.match}'`);
		} else reasoning.push("no GPU type pattern matched in URL");
	}
	const sized = args.modelId ? parseModelSize(args.modelId) : {};
	if (sized.paramsB) reasoning.push(`paramsB=${sized.paramsB} from model id '${args.modelId}'`);
	if (sized.bytesPerParam) reasoning.push(`bytesPerParam=${sized.bytesPerParam} from quantization marker`);
	else if (args.modelId) reasoning.push("no quantization marker — defaulting to bf16 (2 bytes)");
	let gpuCount = 1;
	if (typeof overrideCount === "number" && overrideCount > 0) {
		gpuCount = Math.floor(overrideCount);
		reasoning.push(`gpuCount=${gpuCount} from config override`);
	} else if (gpuType) {
		const bpp = sized.bytesPerParam ?? 2;
		gpuCount = inferGpuCount({
			paramsB: sized.paramsB,
			bytesPerParam: bpp,
			vramGb: GPU_VRAM_GB[gpuType]
		});
		if (sized.paramsB) reasoning.push(`gpuCount=${gpuCount} (model ${(sized.paramsB * bpp).toFixed(0)}GB / ${GPU_VRAM_GB[gpuType]}GB × 0.6 util)`);
	}
	return {
		gpuType,
		gpuCount,
		confidence,
		paramsB: sized.paramsB,
		bytesPerParam: sized.bytesPerParam,
		reasoning
	};
}

//#endregion
//#region src/cost/serving-discovery.ts
const SUCCESS_TTL_MS = 6e4;
const NULL_TTL_MS = 5 * 6e4;
const DEFAULT_TIMEOUT_MS = 4e3;
const cache = /* @__PURE__ */ new Map();
const previousSnapshots = /* @__PURE__ */ new Map();
async function probeServingEndpoint(baseUrl, opts = {}) {
	const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
	const nowFn = opts.now ?? (() => Date.now());
	const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
	const trimmed = baseUrl.trim().replace(/\/+$/, "");
	if (!trimmed) return null;
	const cached = cache.get(trimmed);
	if (cached && !opts.forceRefresh && cached.expiresAt > nowFn()) return cached.info;
	const rootUrl = trimmed.replace(/\/v\d+$/, "");
	const probeAt = nowFn();
	const fetchOpts = () => ({
		signal: AbortSignal.timeout(timeoutMs),
		headers: { Accept: "application/json, text/plain, */*" }
	});
	const [versionRes, modelsRes, metricsRes] = await Promise.allSettled([
		fetchImpl(`${rootUrl}/version`, fetchOpts()),
		fetchImpl(`${rootUrl}/v1/models`, fetchOpts()),
		fetchImpl(`${rootUrl}/metrics`, fetchOpts())
	]);
	const info = {
		engine: "unknown",
		probedAt: probeAt,
		baseUrl: trimmed,
		rootUrl
	};
	if (versionRes.status === "fulfilled" && versionRes.value.ok) try {
		const txt = await versionRes.value.text();
		try {
			const json = JSON.parse(txt);
			if (typeof json.version === "string") info.version = json.version;
		} catch {
			const stripped = txt.trim();
			if (stripped && stripped.length < 64 && /^[\w.\-+]+$/.test(stripped)) info.version = stripped;
		}
	} catch {}
	if (modelsRes.status === "fulfilled" && modelsRes.value.ok) try {
		const first = (await modelsRes.value.json()).data?.[0];
		if (first) {
			if (typeof first.id === "string") info.modelId = first.id;
			if (typeof first.max_model_len === "number") info.contextWindow = first.max_model_len;
			if (typeof first.owned_by === "string") {
				const owner = first.owned_by.toLowerCase();
				if (owner.includes("vllm")) info.engine = "vllm";
				else if (owner.includes("sglang")) info.engine = "sglang";
				else if (info.engine === "unknown") info.engine = "openai-compat";
			}
		}
	} catch {}
	let snapshot = { probedAt: probeAt };
	if (metricsRes.status === "fulfilled" && metricsRes.value.ok) try {
		const parsed = parsePrometheusMetrics(await metricsRes.value.text());
		info.kvCacheUsagePerc = parsed.kvCacheUsagePerc;
		info.queueDepth = parsed.queueDepth;
		info.numRequestsRunning = parsed.numRequestsRunning;
		info.cacheConfig = parsed.cacheConfig;
		snapshot = {
			probedAt: probeAt,
			promptTokensTotal: parsed.promptTokensTotal,
			generationTokensTotal: parsed.generationTokensTotal
		};
		if (info.engine === "unknown" && parsed.foundVllmPrefix) info.engine = "vllm";
		if (info.engine === "unknown" && parsed.foundSglangPrefix) info.engine = "sglang";
	} catch {}
	const prev = previousSnapshots.get(trimmed);
	if (prev && typeof prev.generationTokensTotal === "number" && typeof snapshot.generationTokensTotal === "number") {
		const dt = (snapshot.probedAt - prev.probedAt) / 1e3;
		const dToks = snapshot.generationTokensTotal - prev.generationTokensTotal;
		if (dt > 0 && dToks >= 0) info.observedTps = dToks / dt;
	}
	if (snapshot.generationTokensTotal !== void 0 || snapshot.promptTokensTotal !== void 0) previousSnapshots.set(trimmed, snapshot);
	if (!(info.version !== void 0 || info.modelId !== void 0 || info.cacheConfig !== void 0 || info.kvCacheUsagePerc !== void 0 || info.queueDepth !== void 0 || info.numRequestsRunning !== void 0)) {
		cache.set(trimmed, {
			info: null,
			expiresAt: nowFn() + NULL_TTL_MS
		});
		return null;
	}
	cache.set(trimmed, {
		info,
		expiresAt: nowFn() + SUCCESS_TTL_MS
	});
	return info;
}
function parsePrometheusMetrics(text) {
	const result = {
		foundVllmPrefix: false,
		foundSglangPrefix: false
	};
	const lines = text.split("\n");
	for (const raw of lines) {
		const line = raw.trim();
		if (!line || line.startsWith("#")) continue;
		if (line.startsWith("vllm:")) result.foundVllmPrefix = true;
		if (line.startsWith("sglang:")) result.foundSglangPrefix = true;
		const match = line.match(/^([^\s{]+)(\{[^}]*\})?\s+([0-9eE+\-.]+)$/);
		if (!match) continue;
		const metric = match[1];
		const labels = match[2];
		const value = Number(match[3]);
		if (!Number.isFinite(value)) continue;
		switch (metric) {
			case "vllm:prompt_tokens_total":
				result.promptTokensTotal = (result.promptTokensTotal ?? 0) + value;
				break;
			case "vllm:generation_tokens_total":
				result.generationTokensTotal = (result.generationTokensTotal ?? 0) + value;
				break;
			case "vllm:kv_cache_usage_perc":
				result.kvCacheUsagePerc = value;
				break;
			case "vllm:num_requests_waiting":
				if (!labels || !labels.includes("reason=")) result.queueDepth = value;
				break;
			case "vllm:num_requests_running":
				result.numRequestsRunning = value;
				break;
			case "vllm:cache_config_info": {
				if (!labels) break;
				const parsed = parseLabels(labels);
				const cfg = {};
				if (parsed.block_size !== void 0) cfg.blockSize = Number(parsed.block_size);
				if (parsed.num_gpu_blocks !== void 0) cfg.numGpuBlocks = Number(parsed.num_gpu_blocks);
				if (parsed.cache_dtype !== void 0) cfg.cacheDtype = parsed.cache_dtype;
				if (parsed.gpu_memory_utilization !== void 0) {
					const n = Number(parsed.gpu_memory_utilization);
					if (Number.isFinite(n)) cfg.gpuMemoryUtilization = n;
				}
				if (parsed.enable_prefix_caching !== void 0) cfg.enablePrefixCaching = parsed.enable_prefix_caching === "True";
				result.cacheConfig = cfg;
				break;
			}
		}
	}
	return result;
}
function parseLabels(rawLabels) {
	const inner = rawLabels.replace(/^\{/, "").replace(/\}$/, "");
	const out = {};
	const re = /(\w+)="([^"]*)"/g;
	let m;
	while ((m = re.exec(inner)) !== null) out[m[1]] = m[2];
	return out;
}
function formatEngineLine(info) {
	if (!info) return null;
	const parts = [];
	const engineLabel = (() => {
		if (info.engine === "vllm") return info.version ? `vLLM ${info.version}` : "vLLM";
		if (info.engine === "sglang") return info.version ? `SGLang ${info.version}` : "SGLang";
		if (info.engine === "openai-compat") return "OpenAI-compat";
		return info.version ? `engine ${info.version}` : null;
	})();
	if (engineLabel) parts.push(engineLabel);
	if (typeof info.observedTps === "number" && info.observedTps > .5) parts.push(`${Math.round(info.observedTps)} tps`);
	if (typeof info.kvCacheUsagePerc === "number") {
		const pct = Math.round(info.kvCacheUsagePerc * 100);
		if (pct > 0) parts.push(`KV ${pct}%`);
	}
	if (typeof info.queueDepth === "number" && info.queueDepth > 0) parts.push(`queue ${info.queueDepth}`);
	if (typeof info.numRequestsRunning === "number" && info.numRequestsRunning > 0) parts.push(`running ${info.numRequestsRunning}`);
	if (parts.length === 0) return null;
	return `🖥 ${parts.join(" · ")}`;
}

//#endregion
//#region src/cost/breakdown.ts
async function buildCostBreakdown(args) {
	const benchmarkTarget = args.config?.models?.benchmark === "none" ? "none" : resolveBenchmarkTarget(args.config?.models?.benchmark);
	const breakdown = {
		serving: null,
		benchmarks: [],
		benchmarkTarget
	};
	if (args.baseUrl && args.baseUrl.trim()) try {
		breakdown.serving = await probeServingEndpoint(args.baseUrl, {
			timeoutMs: args.probeTimeoutMs ?? 3e3,
			forceRefresh: Boolean(args.forceProbeRefresh)
		});
	} catch {
		breakdown.serving = null;
	}
	breakdown.engineLine = formatEngineLine(breakdown.serving) ?? void 0;
	const modelCost = resolveModelCost(args.config, args.provider, args.modelId);
	const detectedModelId = breakdown.serving?.modelId ?? args.modelId;
	breakdown.gpu = inferGpu({
		baseUrl: args.baseUrl,
		modelId: detectedModelId,
		override: {
			gpuType: modelCost?.gpuType,
			gpuCount: modelCost?.gpuCount
		}
	});
	const overrides = args.config?.models?.gpuRates;
	let rate;
	let source;
	if (typeof modelCost?.hourlyRate === "number" && modelCost.hourlyRate >= 0) {
		rate = modelCost.hourlyRate;
		source = "model-override";
	} else if (breakdown.gpu.gpuType) {
		rate = resolveHourlyRate(breakdown.gpu.gpuType, overrides);
		if (rate !== void 0) source = overrides && breakdown.gpu.gpuType in overrides ? "config-override" : "default-table";
	}
	breakdown.hourlyRate = rate;
	breakdown.hourlyRateSource = source;
	if (breakdown.gpu?.gpuType) {
		const observed = breakdown.serving?.observedTps;
		if (typeof observed === "number" && observed > .5) {
			breakdown.decodeTps = observed;
			breakdown.prefillTps = observed * PREFILL_DECODE_RATIO;
			breakdown.throughputSource = "observed";
		} else {
			const decode = resolveDefaultDecodeTps(breakdown.gpu.gpuType, breakdown.gpu.paramsB, breakdown.gpu.bytesPerParam);
			breakdown.decodeTps = decode;
			breakdown.prefillTps = decode * PREFILL_DECODE_RATIO;
			breakdown.throughputSource = "default-table";
		}
	}
	if (args.usage && breakdown.hourlyRate !== void 0 && breakdown.gpu?.gpuType && breakdown.decodeTps !== void 0 && breakdown.prefillTps !== void 0) {
		const perSecond = breakdown.hourlyRate * breakdown.gpu.gpuCount / 3600;
		const inputTokens = args.usage.input ?? 0;
		const outputTokens = args.usage.output ?? 0;
		const totalCost = ((breakdown.prefillTps > 0 ? inputTokens / breakdown.prefillTps : 0) + (breakdown.decodeTps > 0 ? outputTokens / breakdown.decodeTps : 0)) * perSecond;
		breakdown.instanceCostUsd = totalCost;
		const totalTokens = inputTokens + outputTokens;
		if (totalTokens > 0) breakdown.perTokenAvgUsd = totalCost / totalTokens;
	}
	if (args.usage) {
		const costForEstimate = modelCost ? {
			input: modelCost.input ?? 0,
			output: modelCost.output ?? 0,
			cacheRead: modelCost.cacheRead ?? 0,
			cacheWrite: modelCost.cacheWrite ?? 0
		} : void 0;
		const rawCost = estimateUsageCost({
			usage: args.usage,
			cost: costForEstimate
		});
		if (typeof rawCost === "number" && rawCost > 0) breakdown.effectiveCostUsd = rawCost;
		else if (breakdown.instanceCostUsd !== void 0) breakdown.effectiveCostUsd = breakdown.instanceCostUsd;
		if (benchmarkTarget !== "none" && breakdown.effectiveCostUsd !== void 0) {
			breakdown.benchmarks = benchmarkUsage({
				usage: args.usage,
				target: benchmarkTarget
			});
			breakdown.costLineSuffix = formatBenchmarkSuffix({
				ourCostUsd: breakdown.effectiveCostUsd,
				benchmarks: breakdown.benchmarks
			});
		}
	}
	breakdown.hardwareLine = formatHardwareLine(breakdown);
	return breakdown;
}
function resolveModelCost(config, provider, modelId) {
	if (!config || !provider || !modelId) return;
	const providers = config.models?.providers;
	if (!providers) return;
	const providerCfg = providers[provider];
	if (!providerCfg?.models) return;
	return providerCfg.models.find((m) => m.id === modelId)?.cost;
}
function formatHardwareLine(breakdown) {
	const gpu = breakdown.gpu;
	if (!gpu?.gpuType) return;
	const label = GPU_LABEL[gpu.gpuType];
	const count = gpu.gpuCount;
	const parts = [];
	parts.push(`${count}× ${label}`);
	if (typeof breakdown.hourlyRate === "number") parts.push(`≈ $${(breakdown.hourlyRate * count).toFixed(2)}/hr`);
	const tag = (() => {
		if (breakdown.hourlyRateSource === "model-override") return "model override";
		if (breakdown.hourlyRateSource === "config-override") return "config override";
		if (gpu.confidence === "high") return "inferred";
		if (gpu.confidence === "medium") return "inferred · medium-conf";
		return "inferred · low-conf";
	})();
	parts.push(`(${tag})`);
	return `🧰 ${parts.join(" · ")}`;
}

//#endregion
export { resolveWindow as i, formatSummaryReport as n, loadCostBenchmarkSummary as r, buildCostBreakdown as t };