fix: require providers for new CLI agents

This commit is contained in:
Mohamed Boudra
2026-04-24 21:40:59 +07:00
parent 2b37276577
commit d3f9655e33
4 changed files with 66 additions and 18 deletions
-1
View File
@@ -30,7 +30,6 @@ export function addRunOptions(cmd: Command): Command {
.option( .option(
"--provider <provider>", "--provider <provider>",
"Agent provider, or provider/model (e.g. codex or codex/gpt-5.4)", "Agent provider, or provider/model (e.g. codex or codex/gpt-5.4)",
"claude",
) )
.option( .option(
"--model <model>", "--model <model>",
+17 -16
View File
@@ -86,20 +86,20 @@ export function formatDurationMs(durationMs: number): string {
function resolveScheduleTarget(args: { function resolveScheduleTarget(args: {
targetValue: string | undefined; targetValue: string | undefined;
hasExplicitProviderSelection: boolean; hasExplicitProviderSelection: boolean;
newAgentTarget: ScheduleTarget; createNewAgentTarget: () => ScheduleTarget;
}): ScheduleTarget { }): ScheduleTarget {
const { targetValue, hasExplicitProviderSelection, newAgentTarget } = args; const { targetValue, hasExplicitProviderSelection, createNewAgentTarget } = args;
const currentAgentId = process.env.PASEO_AGENT_ID?.trim(); const currentAgentId = process.env.PASEO_AGENT_ID?.trim();
if (!targetValue) { if (!targetValue) {
if (currentAgentId && !hasExplicitProviderSelection) { if (currentAgentId && !hasExplicitProviderSelection) {
return { type: "self", agentId: currentAgentId }; return { type: "self", agentId: currentAgentId };
} }
return newAgentTarget; return createNewAgentTarget();
} }
if (targetValue === "new-agent") { if (targetValue === "new-agent") {
return newAgentTarget; return createNewAgentTarget();
} }
if (hasExplicitProviderSelection) { if (hasExplicitProviderSelection) {
@@ -155,22 +155,23 @@ export function parseScheduleCreateInput(options: {
const targetValue = options.target?.trim(); const targetValue = options.target?.trim();
const hasExplicitProviderSelection = options.provider !== undefined; const hasExplicitProviderSelection = options.provider !== undefined;
const resolvedProviderModel = resolveProviderAndModel({ const createNewAgentTarget = (): ScheduleTarget => {
provider: options.provider, const resolvedProviderModel = resolveProviderAndModel({
defaultProvider: "claude", provider: options.provider,
}); });
const newAgentTarget: ScheduleTarget = { return {
type: "new-agent", type: "new-agent",
config: { config: {
provider: resolvedProviderModel.provider, provider: resolvedProviderModel.provider,
cwd: process.cwd(), cwd: process.cwd(),
...(resolvedProviderModel.model ? { model: resolvedProviderModel.model } : {}), ...(resolvedProviderModel.model ? { model: resolvedProviderModel.model } : {}),
}, },
};
}; };
const target = resolveScheduleTarget({ const target = resolveScheduleTarget({
targetValue, targetValue,
hasExplicitProviderSelection, hasExplicitProviderSelection,
newAgentTarget, createNewAgentTarget,
}); });
const maxRuns = const maxRuns =
@@ -0,0 +1,38 @@
import { describe, expect, test } from "vitest";
import { resolveProviderAndModel } from "./provider-model.js";
describe("resolveProviderAndModel", () => {
test("requires an explicit provider when no default is supplied", () => {
expect(() => resolveProviderAndModel({})).toThrow(
expect.objectContaining({
code: "MISSING_PROVIDER",
message: "Provider is required",
}),
);
});
test("uses an explicit default provider when supplied by a scoped caller", () => {
expect(resolveProviderAndModel({ defaultProvider: "claude" })).toEqual({
provider: "claude",
model: undefined,
});
});
test("parses provider/model shorthand", () => {
expect(resolveProviderAndModel({ provider: "codex/gpt-5.4" })).toEqual({
provider: "codex",
model: "gpt-5.4",
});
});
test("rejects conflicting model values", () => {
expect(() =>
resolveProviderAndModel({ provider: "codex/gpt-5.4", model: "gpt-5.4-mini" }),
).toThrow(
expect.objectContaining({
code: "CONFLICTING_MODEL_OPTIONS",
}),
);
});
});
+11 -1
View File
@@ -14,9 +14,19 @@ export interface ResolvedProviderModel {
export function resolveProviderAndModel( export function resolveProviderAndModel(
options: ResolveProviderAndModelOptions, options: ResolveProviderAndModelOptions,
): ResolvedProviderModel { ): ResolvedProviderModel {
const providerInput = options.provider?.trim() || options.defaultProvider || "claude"; const providerInput = options.provider?.trim() || options.defaultProvider;
const modelInput = options.model?.trim(); const modelInput = options.model?.trim();
if (!providerInput) {
const error: CommandError = {
code: "MISSING_PROVIDER",
message: "Provider is required",
details:
"Pass --provider <provider> or --provider <provider>/<model>. Use `paseo provider ls` to see providers and `paseo provider models <provider>` to see models.",
};
throw error;
}
if (options.model !== undefined && !modelInput) { if (options.model !== undefined && !modelInput) {
const error: CommandError = { const error: CommandError = {
code: "INVALID_MODEL", code: "INVALID_MODEL",