






















@@ -6,6 +6,10 @@ import { formatCliCommand } from "../../cli/command-format.js";
66import { withProgressTotals } from "../../cli/progress.js";
77import { logConfigUpdated } from "../../config/logging.js";
88import { toAgentModelListLike } from "../../config/model-input.js";
9+import {
10+parseStrictFiniteNumber,
11+parseStrictPositiveInteger,
12+} from "../../infra/parse-finite-number.js";
913import { type RuntimeEnv, writeRuntimeJson } from "../../runtime.js";
1014import {
1115stylePromptHint,
@@ -153,6 +157,39 @@ function printScanTable(results: ModelScanResult[], runtime: RuntimeEnv) {
153157}
154158}
155159160+function parseOptionalNonNegativeFiniteOption(raw: unknown, label: string): number | undefined {
161+if (raw === undefined || raw === null || raw === "") {
162+return undefined;
163+}
164+const parsed = parseStrictFiniteNumber(raw);
165+if (parsed === undefined || parsed < 0) {
166+throw new Error(`${label} must be >= 0`);
167+}
168+return parsed;
169+}
170+171+function parseOptionalPositiveFiniteOption(raw: unknown, label: string): number | undefined {
172+if (raw === undefined || raw === null || raw === "") {
173+return undefined;
174+}
175+const parsed = parseStrictFiniteNumber(raw);
176+if (parsed === undefined || parsed <= 0) {
177+throw new Error(`${label} must be > 0`);
178+}
179+return parsed;
180+}
181+182+function parsePositiveIntegerOption(raw: unknown, label: string, fallback: number): number {
183+if (raw === undefined || raw === null || raw === "") {
184+return fallback;
185+}
186+const parsed = parseStrictPositiveInteger(raw);
187+if (parsed === undefined) {
188+throw new Error(`${label} must be a positive integer`);
189+}
190+return parsed;
191+}
192+156193export async function modelsScanCommand(
157194opts: {
158195minParams?: string;
@@ -170,26 +207,14 @@ export async function modelsScanCommand(
170207},
171208runtime: RuntimeEnv,
172209) {
173-const minParams = opts.minParams ? Number(opts.minParams) : undefined;
174-if (minParams !== undefined && (!Number.isFinite(minParams) || minParams < 0)) {
175-throw new Error("--min-params must be >= 0");
176-}
177-const maxAgeDays = opts.maxAgeDays ? Number(opts.maxAgeDays) : undefined;
178-if (maxAgeDays !== undefined && (!Number.isFinite(maxAgeDays) || maxAgeDays < 0)) {
179-throw new Error("--max-age-days must be >= 0");
180-}
181-const maxCandidates = opts.maxCandidates ? Number(opts.maxCandidates) : 6;
182-if (!Number.isFinite(maxCandidates) || maxCandidates <= 0) {
183-throw new Error("--max-candidates must be > 0");
184-}
185-const timeout = opts.timeout ? Number(opts.timeout) : undefined;
186-if (timeout !== undefined && (!Number.isFinite(timeout) || timeout <= 0)) {
187-throw new Error("--timeout must be > 0");
188-}
189-const concurrency = opts.concurrency ? Number(opts.concurrency) : undefined;
190-if (concurrency !== undefined && (!Number.isFinite(concurrency) || concurrency <= 0)) {
191-throw new Error("--concurrency must be > 0");
192-}
210+const minParams = parseOptionalNonNegativeFiniteOption(opts.minParams, "--min-params");
211+const maxAgeDays = parseOptionalNonNegativeFiniteOption(opts.maxAgeDays, "--max-age-days");
212+const maxCandidates = parsePositiveIntegerOption(opts.maxCandidates, "--max-candidates", 6);
213+const timeout = parseOptionalPositiveFiniteOption(opts.timeout, "--timeout");
214+const concurrency =
215+opts.concurrency === undefined
216+ ? undefined
217+ : parsePositiveIntegerOption(opts.concurrency, "--concurrency", 1);
193218194219const requestedProbe = opts.probe ?? true;
195220if (!requestedProbe && (opts.setDefault || opts.setImage)) {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。