chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 13:39:12 +08:00
commit d8dcd5f6d1
8604 changed files with 2479390 additions and 0 deletions
+125
View File
@@ -0,0 +1,125 @@
import { readFileSync } from "node:fs";
import { apiFetch } from "../api.mjs";
import { emit } from "../output.mjs";
import { t } from "../i18n.mjs";
const simulateSchema = [
{ key: "order", header: "#", width: 4 },
{ key: "provider", header: "Provider", width: 20 },
{ key: "model", header: "Model", width: 35 },
{ key: "probability", header: "Probability", formatter: (v) => `${Math.round(v * 100)}%` },
{ key: "estimatedCost", header: "Est. Cost", formatter: (v) => (v ? `$${v.toFixed(4)}` : "-") },
{ key: "healthStatus", header: "Breaker", width: 10 },
{ key: "quotaAvailable", header: "Quota %", formatter: (v) => `${v}%` },
];
export function registerSimulate(program) {
program
.command("simulate [prompt]")
.description(t("simulate.description"))
.option("--file <path>", t("simulate.file"))
.option("-m, --model <id>", t("simulate.model"), "auto")
.option("--combo <name>", t("simulate.combo"))
.option("--reasoning-effort <level>", t("simulate.reasoning"))
.option("--thinking-budget <n>", t("simulate.thinking"), parseInt)
.option("--explain", t("simulate.explain"))
.action(runSimulateCommand);
}
export async function runSimulateCommand(promptArg, opts, cmd) {
const globalOpts = cmd.optsWithGlobals();
let promptTokenEstimate = 100;
if (opts.file) {
try {
const raw = readFileSync(opts.file, "utf8");
const parsed = JSON.parse(raw);
const text = JSON.stringify(parsed);
promptTokenEstimate = Math.ceil(text.length / 4);
} catch {
promptTokenEstimate = 100;
}
} else if (promptArg) {
promptTokenEstimate = Math.ceil(promptArg.length / 4);
}
const [combosRes, healthRes, quotaRes] = await Promise.allSettled([
apiFetch("/api/combos", { timeout: globalOpts.timeout }).then((r) => r.json()),
apiFetch("/api/monitoring/health", { timeout: globalOpts.timeout }).then((r) => r.json()),
apiFetch("/api/usage/quota", { timeout: globalOpts.timeout }).then((r) => r.json()),
]);
if (combosRes.status === "rejected") {
process.stderr.write(t("common.serverOffline") + "\n");
process.exit(3);
}
const combos = normalizeCombos(combosRes.value);
const health = healthRes.status === "fulfilled" ? healthRes.value : {};
const quota = quotaRes.status === "fulfilled" ? quotaRes.value : {};
const targetCombo = opts.combo
? combos.find((c) => c.id === opts.combo || c.name === opts.combo)
: combos.find((c) => c.enabled !== false);
if (!targetCombo) {
process.stderr.write(t("simulate.noCombo") + "\n");
process.exit(1);
}
const models = getComboModels(targetCombo, opts.model);
const breakers = toArray(health.circuitBreakers ?? health.breakers);
const providers = toArray(quota.providers ?? quota.data);
const simulatedPath = models.map((m, idx) => {
const cb = breakers.find((b) => String(b.provider) === m.provider);
const q = providers.find((p) => p.provider === m.provider);
const inputCost = m.inputCostPer1M ?? 0;
const estimatedCost = Math.round((promptTokenEstimate / 1_000_000) * inputCost * 10000) / 10000;
return {
order: idx + 1,
provider: m.provider,
model: m.model || opts.model,
probability: idx === 0 ? 0.85 : 0.15 / Math.max(models.length - 1, 1),
estimatedCost,
healthStatus: String(cb?.state ?? "CLOSED"),
quotaAvailable: q?.percentRemaining ?? 100,
};
});
emit(simulatedPath, globalOpts, simulateSchema);
if (opts.explain && !globalOpts.quiet) {
const primary = simulatedPath[0];
const fallbacks = simulatedPath.slice(1).map((s) => s.provider);
process.stderr.write(`\nPrimary: ${primary?.provider} / ${primary?.model}\n`);
if (fallbacks.length > 0) {
process.stderr.write(`Fallbacks: ${fallbacks.join(" → ")}\n`);
}
const costs = simulatedPath.map((s) => s.estimatedCost);
process.stderr.write(
`Est. cost range: $${Math.min(...costs).toFixed(4)} $${Math.max(...costs).toFixed(4)}\n`
);
}
}
function normalizeCombos(raw) {
if (Array.isArray(raw)) return raw;
if (raw && Array.isArray(raw.combos)) return raw.combos;
if (raw && Array.isArray(raw.data)) return raw.data;
return [];
}
function getComboModels(combo, modelFallback) {
const steps = combo.steps ?? combo.models ?? combo.targets ?? [];
return steps.map((step) => ({
provider: step.provider ?? step.providerId ?? "",
model: step.model ?? step.modelId ?? modelFallback ?? "auto",
inputCostPer1M: step.inputCostPer1M ?? step.costPer1MInput ?? 0,
}));
}
function toArray(val) {
if (Array.isArray(val)) return val;
return [];
}