Merge remote-tracking branch 'upstream/main' into feat/secret-friendly-names
This commit is contained in:
@@ -10,9 +10,10 @@ import type {
|
||||
Model,
|
||||
ProviderSessionState,
|
||||
ServiceTier,
|
||||
ServiceTierByFamily,
|
||||
SimpleStreamOptions,
|
||||
} from "@oh-my-pi/pi-ai";
|
||||
import { streamSimple } from "@oh-my-pi/pi-ai";
|
||||
import { resolveModelServiceTier, streamSimple } from "@oh-my-pi/pi-ai";
|
||||
import { buildModelProviderPriorityRank, type CanonicalModelVariant } from "@oh-my-pi/pi-catalog/identity";
|
||||
import { replaceTabs, truncateToWidth } from "@oh-my-pi/pi-tui";
|
||||
import { formatDuration, getProjectDir } from "@oh-my-pi/pi-utils";
|
||||
@@ -25,7 +26,7 @@ import {
|
||||
getModelMatchPreferences,
|
||||
resolveCliModel,
|
||||
} from "../config/model-resolver";
|
||||
import { resolveServiceTierSetting } from "../config/service-tier";
|
||||
import { buildServiceTierByFamily, serviceTierForAllFamilies, serviceTierSettingToTier } from "../config/service-tier";
|
||||
import { Settings } from "../config/settings";
|
||||
import benchPrompt from "../prompts/bench.md" with { type: "text" };
|
||||
import { discoverAuthStorage, loadCliExtensionProviders } from "../sdk";
|
||||
@@ -106,8 +107,8 @@ export interface BenchSummary {
|
||||
maxTokens: number;
|
||||
models: BenchModelReport[];
|
||||
failures: number;
|
||||
/** Requested service tier passed to every request; absent when none was requested. Scoped tiers (`openai-only`/`claude-only`) may be dropped per-provider downstream. */
|
||||
serviceTier?: ServiceTier;
|
||||
/** Requested per-family service tiers, resolved per model before reaching the wire. */
|
||||
serviceTierByFamily?: ServiceTierByFamily;
|
||||
}
|
||||
|
||||
type BenchStreamSimple = (
|
||||
@@ -518,12 +519,18 @@ export async function runBenchCommand(command: BenchCommandArgs, deps: BenchDepe
|
||||
const runtime = await (deps.createRuntime ?? createDefaultRuntime)();
|
||||
try {
|
||||
const targets = resolveBenchModels(command.models, runtime.modelRegistry, runtime.settings, writeStderr);
|
||||
// Explicit `--service-tier` wins; otherwise fall back to the configured
|
||||
// `serviceTier` setting (`none`/unset omits the wire field). Scope-aware
|
||||
// gating to the model's provider happens downstream in the provider layer.
|
||||
const serviceTierValue = command.flags.serviceTier ?? runtime.settings?.get("serviceTier");
|
||||
const serviceTier = serviceTierValue ? resolveServiceTierSetting(serviceTierValue, undefined) : undefined;
|
||||
if (!json && serviceTier) writeStdout(`${chalk.dim(`service tier: ${serviceTier}`)}\n`);
|
||||
// Explicit `--service-tier` (a single value broadcast across families) wins;
|
||||
// otherwise fall back to the configured per-family `tier.*` settings. Each
|
||||
// model resolves its own family's tier below before reaching the wire.
|
||||
const flagTier = command.flags.serviceTier ? serviceTierSettingToTier(command.flags.serviceTier) : undefined;
|
||||
const serviceTierByFamily = command.flags.serviceTier
|
||||
? serviceTierForAllFamilies(flagTier)
|
||||
: buildServiceTierByFamily(
|
||||
runtime.settings?.get("tier.openai") ?? "none",
|
||||
runtime.settings?.get("tier.anthropic") ?? "none",
|
||||
runtime.settings?.get("tier.google") ?? "none",
|
||||
);
|
||||
if (!json && flagTier) writeStdout(`${chalk.dim(`service tier: ${flagTier}`)}\n`);
|
||||
const reports: BenchModelReport[] = [];
|
||||
for (const { selector, model, thinking } of targets) {
|
||||
if (!json) {
|
||||
@@ -564,7 +571,7 @@ export async function runBenchCommand(command: BenchCommandArgs, deps: BenchDepe
|
||||
maxTokens,
|
||||
reasoning: toReasoningEffort(thinking),
|
||||
disableReasoning: shouldDisableReasoning(thinking) ? true : undefined,
|
||||
serviceTier,
|
||||
serviceTier: resolveModelServiceTier(serviceTierByFamily, model),
|
||||
},
|
||||
streamFn,
|
||||
now,
|
||||
@@ -606,7 +613,7 @@ export async function runBenchCommand(command: BenchCommandArgs, deps: BenchDepe
|
||||
reports.push(buildModelReport(selector, model, thinking, results));
|
||||
}
|
||||
const failures = reports.reduce((sum, report) => sum + report.results.filter(result => !result.ok).length, 0);
|
||||
const summary: BenchSummary = { runs, maxTokens, models: reports, failures, serviceTier };
|
||||
const summary: BenchSummary = { runs, maxTokens, models: reports, failures, serviceTierByFamily };
|
||||
if (json) {
|
||||
writeStdout(`${JSON.stringify(summary, null, 2)}\n`);
|
||||
} else if (reports.length > 1 || runs > 1) {
|
||||
|
||||
@@ -28,12 +28,21 @@ interface ProgressReporter {
|
||||
interface DownloadResult {
|
||||
model: TinyLocalModelKey;
|
||||
ok: boolean;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
function writeLine(text = ""): void {
|
||||
process.stdout.write(`${text}\n`);
|
||||
}
|
||||
|
||||
function downloadErrorSummary(error: string | undefined): string | undefined {
|
||||
return error
|
||||
?.split(/\r?\n/)
|
||||
.map(line => line.trim())
|
||||
.find(line => line.length > 0)
|
||||
?.replace(/^Error:\s*/, "");
|
||||
}
|
||||
|
||||
export function resolveModels(model: string | undefined): TinyLocalModelKey[] {
|
||||
if (!model) return [DEFAULT_TINY_TITLE_LOCAL_MODEL_KEY];
|
||||
// `all` is a prefetch convenience: skip models that fail before load (unsupported
|
||||
@@ -101,10 +110,15 @@ async function downloadOne(modelKey: TinyLocalModelKey, json: boolean | undefine
|
||||
const label = getTinyLocalModelSpec(modelKey)?.label ?? modelKey;
|
||||
if (!json && !process.stdout.isTTY) writeLine(`Downloading ${label} (${modelKey})...`);
|
||||
const progress = makeProgressReporter(modelKey, json);
|
||||
const ok = await tinyTitleClient.downloadModel(modelKey, { onProgress: progress.onProgress });
|
||||
progress.finish(ok);
|
||||
if (!json && !process.stdout.isTTY) writeLine(ok ? `Downloaded ${label}.` : `Failed to download ${label}.`);
|
||||
return { model: modelKey, ok };
|
||||
const result = await tinyTitleClient.downloadModel(modelKey, { onProgress: progress.onProgress });
|
||||
progress.finish(result.ok);
|
||||
const error = downloadErrorSummary(result.error);
|
||||
if (!json && !process.stdout.isTTY) {
|
||||
writeLine(result.ok ? `Downloaded ${label}.` : `Failed to download ${label}${error ? `: ${error}` : ""}.`);
|
||||
} else if (!json && !result.ok && error) {
|
||||
writeLine(`${label} failed: ${error}`);
|
||||
}
|
||||
return result.error ? { model: modelKey, ok: result.ok, error: result.error } : { model: modelKey, ok: result.ok };
|
||||
}
|
||||
|
||||
export async function runTinyModelsCommand(command: TinyModelsCommandArgs): Promise<void> {
|
||||
|
||||
Reference in New Issue
Block a user