mirror of
https://github.com/getpaseo/paseo.git
synced 2026-07-29 12:01:31 +00:00
Use safer automatic approval modes by default (#2213)
* feat(providers): default to safer automatic approvals * fix(providers): preserve defaults on older Codex versions * test(providers): cover Claude automatic approval default * fix(providers): preserve Claude defaults on cloud transports * fix(providers): resolve defaults from launch capabilities
This commit is contained in:
@@ -575,6 +575,25 @@ describe("resolveFormState", () => {
|
||||
expect(resolved.modeId).toBe("workspace-write");
|
||||
});
|
||||
|
||||
it("falls back when the provider cannot advertise its preferred default mode", () => {
|
||||
const providerMap = makeProviderMap({
|
||||
...TEST_CODEX_DEFINITION,
|
||||
defaultModeId: "auto-review",
|
||||
modes: TEST_CODEX_DEFINITION.modes,
|
||||
});
|
||||
|
||||
const resolved = resolveFormState(
|
||||
undefined,
|
||||
{ provider: "codex" },
|
||||
CODEX_MODELS,
|
||||
INITIAL_USER_MODIFIED,
|
||||
makeState({ provider: "codex" }).form,
|
||||
providerMap,
|
||||
);
|
||||
|
||||
expect(resolved.modeId).toBe("auto");
|
||||
});
|
||||
|
||||
it("ignores disabled ready providers when resolving selectable defaults", () => {
|
||||
const entries: ProviderSnapshotEntry[] = [
|
||||
{
|
||||
|
||||
@@ -171,7 +171,12 @@ function resolvePreferredModeId(input: {
|
||||
const preferredModeId = normalizeSelectedModeId(input.preferredModeId);
|
||||
if (preferredModeId) return preferredModeId;
|
||||
|
||||
return input.providerDef?.defaultModeId ?? input.providerDef?.modes[0]?.id ?? "";
|
||||
const defaultModeId = input.providerDef?.defaultModeId;
|
||||
const modes = input.providerDef?.modes ?? [];
|
||||
if (defaultModeId && (modes.length === 0 || modes.some((mode) => mode.id === defaultModeId))) {
|
||||
return defaultModeId;
|
||||
}
|
||||
return modes[0]?.id ?? "";
|
||||
}
|
||||
|
||||
export function mergeSelectedComposerPreferences(args: {
|
||||
|
||||
@@ -185,7 +185,7 @@ export const AGENT_PROVIDER_DEFINITIONS: AgentProviderDefinition[] = [
|
||||
id: "claude",
|
||||
label: "Claude",
|
||||
description: "Anthropic's multi-tool assistant with MCP support, streaming, and deep reasoning",
|
||||
defaultModeId: "default",
|
||||
defaultModeId: "auto",
|
||||
modes: CLAUDE_MODES,
|
||||
voice: {
|
||||
enabled: true,
|
||||
@@ -197,7 +197,7 @@ export const AGENT_PROVIDER_DEFINITIONS: AgentProviderDefinition[] = [
|
||||
id: "codex",
|
||||
label: "Codex",
|
||||
description: "OpenAI's Codex workspace agent with sandbox controls and optional network access",
|
||||
defaultModeId: "auto",
|
||||
defaultModeId: "auto-review",
|
||||
modes: CODEX_MODES,
|
||||
voice: {
|
||||
enabled: true,
|
||||
|
||||
@@ -35,6 +35,7 @@ import type {
|
||||
AgentStreamEvent,
|
||||
AgentTimelineItem,
|
||||
ImportProviderSessionInput,
|
||||
ResolveAgentDefaultModeInput,
|
||||
} from "./agent-sdk-types.js";
|
||||
import type { PaseoToolCatalog } from "./tools/types.js";
|
||||
import type { ProviderDefinition } from "./provider-registry.js";
|
||||
@@ -111,11 +112,15 @@ function expectArchivedAgentRecord(
|
||||
}
|
||||
|
||||
class TestAgentClient implements AgentClient {
|
||||
readonly provider = "codex" as const;
|
||||
readonly provider: AgentProvider;
|
||||
readonly capabilities = TEST_CAPABILITIES;
|
||||
readonly createdConfigs: AgentSessionConfig[] = [];
|
||||
readonly resumeOverrides: Array<Partial<AgentSessionConfig> | undefined> = [];
|
||||
|
||||
constructor(provider: AgentProvider = "codex") {
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
async isAvailable(): Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
@@ -129,18 +134,18 @@ class TestAgentClient implements AgentClient {
|
||||
return {
|
||||
models: [
|
||||
{
|
||||
provider: "codex",
|
||||
provider: this.provider,
|
||||
id: "gpt-5.4",
|
||||
label: "GPT-5.4",
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
provider: "codex",
|
||||
provider: this.provider,
|
||||
id: "gpt-5.4-mini",
|
||||
label: "GPT-5.4 Mini",
|
||||
},
|
||||
{
|
||||
provider: "codex",
|
||||
provider: this.provider,
|
||||
id: "gpt-5.2-codex",
|
||||
label: "GPT-5.2 Codex",
|
||||
},
|
||||
@@ -156,7 +161,7 @@ class TestAgentClient implements AgentClient {
|
||||
): Promise<AgentSession> {
|
||||
this.resumeOverrides.push(config);
|
||||
return new TestAgentSession({
|
||||
provider: "codex",
|
||||
provider: this.provider,
|
||||
cwd: config?.cwd ?? process.cwd(),
|
||||
daemonAppendSystemPrompt: config?.daemonAppendSystemPrompt,
|
||||
});
|
||||
@@ -935,9 +940,43 @@ test("normalizeConfig injects the provider default model when omitted", async ()
|
||||
);
|
||||
|
||||
expect(snapshot.config.model).toBe("gpt-5.4");
|
||||
expect(snapshot.config.modeId).toBe("auto-review");
|
||||
});
|
||||
|
||||
test("normalizeConfig injects Claude's automatic approval default when omitted", async () => {
|
||||
const workdir = mkdtempSync(join(tmpdir(), "agent-manager-claude-default-test-"));
|
||||
const manager = new AgentManager({
|
||||
clients: { claude: new TestAgentClient("claude") },
|
||||
logger,
|
||||
});
|
||||
|
||||
const snapshot = await manager.createAgent({ provider: "claude", cwd: workdir }, undefined, {
|
||||
workspaceId: undefined,
|
||||
});
|
||||
|
||||
expect(snapshot.config.modeId).toBe("auto");
|
||||
});
|
||||
|
||||
test("normalizeConfig uses a capability-aware provider mode default", async () => {
|
||||
const workdir = mkdtempSync(join(tmpdir(), "agent-manager-mode-default-test-"));
|
||||
class CapabilityAwareClient extends TestAgentClient {
|
||||
override async resolveDefaultModeId(input: ResolveAgentDefaultModeInput): Promise<string> {
|
||||
return input.env?.CLAUDE_CODE_USE_BEDROCK === "1" ? "default" : "auto";
|
||||
}
|
||||
}
|
||||
const manager = new AgentManager({
|
||||
clients: { codex: new CapabilityAwareClient() },
|
||||
logger,
|
||||
});
|
||||
|
||||
const snapshot = await manager.createAgent({ provider: "codex", cwd: workdir }, undefined, {
|
||||
workspaceId: undefined,
|
||||
env: { CLAUDE_CODE_USE_BEDROCK: "1" },
|
||||
});
|
||||
|
||||
expect(snapshot.config.modeId).toBe("default");
|
||||
});
|
||||
|
||||
test("createAgent forwards request env into the spawned provider process", async () => {
|
||||
const workdir = mkdtempSync(join(tmpdir(), "agent-manager-env-test-"));
|
||||
const client = new EnvProbeAgentClient();
|
||||
@@ -997,7 +1036,7 @@ test("normalizeConfig strips legacy 'default' model id", async () => {
|
||||
);
|
||||
|
||||
expect(snapshot.config.model).toBe("gpt-5.4");
|
||||
expect(snapshot.config.modeId).toBe("auto");
|
||||
expect(snapshot.config.modeId).toBe("auto-review");
|
||||
});
|
||||
|
||||
test("listDraftCommands returns no commands without guessing a missing model", async () => {
|
||||
@@ -1094,7 +1133,7 @@ test("listDraftCommands uses explicit model config without default model fetchin
|
||||
provider: "codex",
|
||||
cwd: workdir,
|
||||
model: "gpt-5.4",
|
||||
modeId: "auto",
|
||||
modeId: "auto-review",
|
||||
},
|
||||
]);
|
||||
});
|
||||
@@ -1194,7 +1233,7 @@ test("listDraftFeatures uses explicit model config without default model fetchin
|
||||
provider: "codex",
|
||||
cwd: workdir,
|
||||
model: "gpt-5.4",
|
||||
modeId: "auto",
|
||||
modeId: "auto-review",
|
||||
},
|
||||
]);
|
||||
});
|
||||
@@ -1651,7 +1690,7 @@ test("createAgent passes daemon launch env through the provider launch context",
|
||||
provider: "codex",
|
||||
cwd: workdir,
|
||||
model: "gpt-5.4",
|
||||
modeId: "auto",
|
||||
modeId: "auto-review",
|
||||
});
|
||||
expect(client.lastLaunchContext).toEqual({
|
||||
agentId: snapshot.id,
|
||||
@@ -2448,7 +2487,7 @@ test("resumeAgentFromPersistence keeps metadata config, applies overrides, and p
|
||||
});
|
||||
expect(client.lastResumeOverrides).toMatchObject({
|
||||
model: "gpt-5.4",
|
||||
modeId: "auto",
|
||||
modeId: "auto-review",
|
||||
systemPrompt: "new prompt",
|
||||
mcpServers: {
|
||||
paseo: {
|
||||
|
||||
@@ -117,6 +117,7 @@ interface PreparedSessionConfig {
|
||||
|
||||
interface NormalizeConfigOptions {
|
||||
resolveDefaultModel?: boolean;
|
||||
env?: Record<string, string>;
|
||||
}
|
||||
|
||||
interface TimeoutOptions {
|
||||
@@ -1034,7 +1035,11 @@ export class AgentManager {
|
||||
this.assertAcceptingAgentRegistrations();
|
||||
const resolvedAgentId = validateAgentId(agentId ?? this.idFactory(), "createAgent");
|
||||
await this.deleteAgentState(resolvedAgentId);
|
||||
const { storedConfig, launchConfig } = await this.prepareSessionConfig(config, resolvedAgentId);
|
||||
const { storedConfig, launchConfig } = await this.prepareSessionConfig(
|
||||
config,
|
||||
resolvedAgentId,
|
||||
options?.env,
|
||||
);
|
||||
this.requireEnabledProvider(storedConfig.provider);
|
||||
const client = await this.requireAvailableClient({
|
||||
provider: storedConfig.provider,
|
||||
@@ -4075,17 +4080,27 @@ export class AgentManager {
|
||||
}
|
||||
|
||||
if (!normalized.modeId) {
|
||||
try {
|
||||
normalized.modeId =
|
||||
getAgentProviderDefinition(normalized.provider).defaultModeId ?? undefined;
|
||||
} catch {
|
||||
// Unknown provider
|
||||
}
|
||||
normalized.modeId = await this.resolveDefaultModeId(normalized, options.env);
|
||||
}
|
||||
|
||||
return normalized;
|
||||
}
|
||||
|
||||
private async resolveDefaultModeId(
|
||||
config: AgentSessionConfig,
|
||||
env?: Record<string, string>,
|
||||
): Promise<string | undefined> {
|
||||
const providerDefault = await this.clients
|
||||
.get(config.provider)
|
||||
?.resolveDefaultModeId?.({ config, env });
|
||||
if (providerDefault) return providerDefault;
|
||||
try {
|
||||
return getAgentProviderDefinition(config.provider).defaultModeId ?? undefined;
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
private async resolveDefaultModelId(config: AgentSessionConfig): Promise<string | undefined> {
|
||||
const client = this.clients.get(config.provider);
|
||||
if (!client) {
|
||||
@@ -4107,8 +4122,9 @@ export class AgentManager {
|
||||
private async prepareSessionConfig(
|
||||
config: AgentSessionConfig,
|
||||
agentId: string,
|
||||
env?: Record<string, string>,
|
||||
): Promise<PreparedSessionConfig> {
|
||||
const storedConfig = await this.normalizeConfig(stripInternalPaseoMcpServer(config));
|
||||
const storedConfig = await this.normalizeConfig(stripInternalPaseoMcpServer(config), { env });
|
||||
const launchConfig = this.applyDaemonAppendSystemPrompt(
|
||||
withRuntimePaseoMcpServer({
|
||||
config: storedConfig,
|
||||
|
||||
@@ -668,6 +668,12 @@ export type FetchCatalogOptions =
|
||||
export interface ProviderCatalog {
|
||||
models: AgentModelDefinition[];
|
||||
modes: AgentMode[];
|
||||
defaultModeId?: string | null;
|
||||
}
|
||||
|
||||
export interface ResolveAgentDefaultModeInput {
|
||||
config: AgentSessionConfig;
|
||||
env?: Record<string, string>;
|
||||
}
|
||||
|
||||
export interface AgentClient {
|
||||
@@ -690,6 +696,7 @@ export interface AgentClient {
|
||||
* The registry is responsible for merging configured model overrides.
|
||||
*/
|
||||
fetchCatalog(options: FetchCatalogOptions): Promise<ProviderCatalog>;
|
||||
resolveDefaultModeId?(input: ResolveAgentDefaultModeInput): Promise<string | undefined>;
|
||||
resolveCreateConfig?(input: ResolveAgentCreateConfigInput): ResolveAgentCreateConfigResult;
|
||||
isCreateConfigUnattended?(input: AgentCreateConfigUnattendedInput): boolean;
|
||||
listCommands?(config: AgentSessionConfig): Promise<AgentSlashCommand[]>;
|
||||
|
||||
@@ -814,7 +814,7 @@ test("enabled: false keeps provider metadata in registry", () => {
|
||||
id: "claude",
|
||||
label: "Claude",
|
||||
description: "Anthropic's multi-tool assistant with MCP support, streaming, and deep reasoning",
|
||||
defaultModeId: "default",
|
||||
defaultModeId: "auto",
|
||||
enabled: false,
|
||||
});
|
||||
expect(registry.claude.modes).toEqual(
|
||||
@@ -1487,6 +1487,31 @@ describe("fetchCatalog", () => {
|
||||
expect(catalog.models.map((model) => model.id)).toEqual(["profile-model", "extra-model"]);
|
||||
});
|
||||
|
||||
test("replacement models still resolve the provider's capability-aware default mode", async () => {
|
||||
const resolveDefaultModeId = vi.fn(async () => "default");
|
||||
const injectedClient = {
|
||||
provider: "codex",
|
||||
capabilities: {},
|
||||
resolveDefaultModeId,
|
||||
isAvailable: vi.fn(async () => true),
|
||||
} satisfies Partial<AgentClient> as AgentClient;
|
||||
const registry = buildProviderRegistry(logger, {
|
||||
providerOverrides: {
|
||||
codex: { models: [{ id: "profile-model", label: "Profile Model" }] },
|
||||
},
|
||||
});
|
||||
|
||||
const catalog = await registry.codex.fetchCatalog(
|
||||
{ scope: "workspace", cwd: "/tmp/catalog", force: false },
|
||||
injectedClient,
|
||||
);
|
||||
|
||||
expect(catalog.defaultModeId).toBe("default");
|
||||
expect(resolveDefaultModeId).toHaveBeenCalledWith({
|
||||
config: { provider: "codex", cwd: "/tmp/catalog" },
|
||||
});
|
||||
});
|
||||
|
||||
test("additionalModels can override replacement model fields", async () => {
|
||||
const registry = buildProviderRegistry(logger, {
|
||||
providerOverrides: {
|
||||
|
||||
@@ -14,6 +14,7 @@ import type {
|
||||
ProviderCatalog,
|
||||
ResolveAgentCreateConfigInput,
|
||||
ResolveAgentCreateConfigResult,
|
||||
ResolveAgentDefaultModeInput,
|
||||
} from "./agent-sdk-types.js";
|
||||
import {
|
||||
isDefaultAgentCreateConfigUnattended,
|
||||
@@ -427,12 +428,20 @@ function wrapClientProvider(
|
||||
fetchCatalog: async (options) => {
|
||||
const catalog = await inner.fetchCatalog(options);
|
||||
return {
|
||||
...catalog,
|
||||
models: mergeModels(provider, profileModels, additionalModels, catalog.models, {
|
||||
profileModelsAreAdditive,
|
||||
}),
|
||||
modes: catalog.modes,
|
||||
};
|
||||
},
|
||||
resolveDefaultModeId: inner.resolveDefaultModeId
|
||||
? async ({ config, env }: ResolveAgentDefaultModeInput) =>
|
||||
await inner.resolveDefaultModeId?.({
|
||||
config: { ...config, provider: inner.provider },
|
||||
env,
|
||||
})
|
||||
: undefined,
|
||||
resolveCreateConfig: inner.resolveCreateConfig?.bind(inner),
|
||||
isCreateConfigUnattended: inner.isCreateConfigUnattended?.bind(inner),
|
||||
listFeatures: listFeatures
|
||||
@@ -516,17 +525,25 @@ function createRegistryEntry(
|
||||
// the single catalog API; otherwise use static/empty modes with no runtime.
|
||||
const models = mergeModelAdditions(provider, replacementModels, resolved.additionalModels);
|
||||
if (hasStaticModes) {
|
||||
const defaultModeId = await catalogClient.resolveDefaultModeId?.({
|
||||
config: {
|
||||
provider,
|
||||
cwd: options.scope === "workspace" ? options.cwd : process.cwd(),
|
||||
},
|
||||
});
|
||||
return {
|
||||
models,
|
||||
modes: decorateModes(resolved.definition.modes),
|
||||
defaultModeId,
|
||||
};
|
||||
}
|
||||
const catalog = await catalogClient.fetchCatalog(options);
|
||||
return { models, modes: decorateModes(catalog.modes) };
|
||||
return { ...catalog, models, modes: decorateModes(catalog.modes) };
|
||||
}
|
||||
|
||||
const catalog = await catalogClient.fetchCatalog(options);
|
||||
return {
|
||||
...catalog,
|
||||
models: mergeModels(
|
||||
provider,
|
||||
resolved.profileModels,
|
||||
|
||||
@@ -117,9 +117,11 @@ describe("ProviderSnapshotManager public surface", () => {
|
||||
try {
|
||||
const snapshot = manager.getSnapshot("/tmp/project");
|
||||
const claude = snapshot.find((entry) => entry.provider === "claude");
|
||||
const codex = snapshot.find((entry) => entry.provider === "codex");
|
||||
expect(claude?.status).toBe("loading");
|
||||
expect(claude?.label).toBe("Claude");
|
||||
expect(claude?.defaultModeId).toBe("default");
|
||||
expect(claude?.defaultModeId).toBe("auto");
|
||||
expect(codex?.defaultModeId).toBe("auto-review");
|
||||
} finally {
|
||||
manager.destroy();
|
||||
}
|
||||
@@ -220,6 +222,34 @@ describe("ProviderSnapshotManager public surface", () => {
|
||||
}
|
||||
});
|
||||
|
||||
test("ready snapshots publish the catalog's capability-aware default mode", async () => {
|
||||
const manager = new ProviderSnapshotManager({
|
||||
logger: createTestLogger(),
|
||||
extraClients: {
|
||||
codex: createExtraClient("codex", {
|
||||
isAvailable: async () => true,
|
||||
fetchCatalog: async () => ({
|
||||
models: [],
|
||||
modes: [{ id: "default", label: "Default", description: "Ask before running tools" }],
|
||||
defaultModeId: "default",
|
||||
}),
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
try {
|
||||
const entry = await manager.getProvider({
|
||||
cwd: "/tmp/project",
|
||||
provider: "codex",
|
||||
wait: true,
|
||||
});
|
||||
|
||||
expect(entry).toMatchObject({ status: "ready", defaultModeId: "default" });
|
||||
} finally {
|
||||
manager.destroy();
|
||||
}
|
||||
});
|
||||
|
||||
test("explicit refresh re-probes only the requested warm provider", async () => {
|
||||
const cwd = "/tmp/project";
|
||||
const isAvailableCodex = vi.fn(async () => true);
|
||||
|
||||
@@ -799,6 +799,8 @@ export class ProviderSnapshotManager {
|
||||
|
||||
setEntry({
|
||||
...base,
|
||||
defaultModeId:
|
||||
catalog.defaultModeId === undefined ? definition.defaultModeId : catalog.defaultModeId,
|
||||
status: "ready",
|
||||
enabled: true,
|
||||
models: catalog.models,
|
||||
|
||||
@@ -218,6 +218,37 @@ test("rejects auto mode when Claude Code uses Bedrock", async () => {
|
||||
}
|
||||
});
|
||||
|
||||
test.each([
|
||||
{ env: {}, expected: "auto" },
|
||||
{ env: { CLAUDE_CODE_USE_BEDROCK: "1" }, expected: "default" },
|
||||
{ env: { CLAUDE_CODE_USE_VERTEX: "true" }, expected: "default" },
|
||||
])("defaults to $expected for transport environment $env", async ({ env, expected }) => {
|
||||
const client = new ClaudeAgentClient({
|
||||
logger: createTestLogger(),
|
||||
runtimeSettings: { env },
|
||||
});
|
||||
|
||||
await expect(
|
||||
client.resolveDefaultModeId({
|
||||
config: { provider: "claude", cwd: process.cwd() },
|
||||
}),
|
||||
).resolves.toBe(expected);
|
||||
});
|
||||
|
||||
test("launch environment participates in the Claude default mode", async () => {
|
||||
const client = new ClaudeAgentClient({
|
||||
logger: createTestLogger(),
|
||||
runtimeSettings: { env: {} },
|
||||
});
|
||||
|
||||
await expect(
|
||||
client.resolveDefaultModeId({
|
||||
config: { provider: "claude", cwd: process.cwd() },
|
||||
env: { CLAUDE_CODE_USE_BEDROCK: "1" },
|
||||
}),
|
||||
).resolves.toBe("default");
|
||||
});
|
||||
|
||||
test("allows launch env to disable inherited Bedrock transport for auto mode", async () => {
|
||||
const previousBedrock = process.env.CLAUDE_CODE_USE_BEDROCK;
|
||||
process.env.CLAUDE_CODE_USE_BEDROCK = "1";
|
||||
|
||||
@@ -91,6 +91,7 @@ import {
|
||||
type ListImportableSessionsOptions,
|
||||
type McpServerConfig,
|
||||
type ProviderCatalog,
|
||||
type ResolveAgentDefaultModeInput,
|
||||
} from "../../agent-sdk-types.js";
|
||||
import { importSessionFromPersistence } from "../../provider-session-import.js";
|
||||
import {
|
||||
@@ -1472,7 +1473,28 @@ export class ClaudeAgentClient implements AgentClient {
|
||||
async fetchCatalog(_options: FetchCatalogOptions): Promise<ProviderCatalog> {
|
||||
// Claude exposes a global catalog here; cwd/force are intentionally irrelevant.
|
||||
const models = await getClaudeModelsWithSettings(this.logger, this.configDir);
|
||||
return { models, modes: DEFAULT_MODES };
|
||||
const modes = detectIneligibleAutoModeTransport(
|
||||
createProviderEnv({ baseEnv: process.env, runtimeSettings: this.runtimeSettings }),
|
||||
)
|
||||
? DEFAULT_MODES.filter((mode) => mode.id !== "auto")
|
||||
: DEFAULT_MODES;
|
||||
return {
|
||||
models,
|
||||
modes,
|
||||
defaultModeId: modes.some((mode) => mode.id === "auto") ? "auto" : "default",
|
||||
};
|
||||
}
|
||||
|
||||
async resolveDefaultModeId({
|
||||
config,
|
||||
env: launchEnv,
|
||||
}: ResolveAgentDefaultModeInput): Promise<string> {
|
||||
const env = createProviderEnv({
|
||||
baseEnv: process.env,
|
||||
runtimeSettings: this.runtimeSettings,
|
||||
overlays: [config.extra?.claude?.env, launchEnv],
|
||||
});
|
||||
return detectIneligibleAutoModeTransport(env) ? "default" : "auto";
|
||||
}
|
||||
|
||||
async listFeatures(config: AgentSessionConfig): Promise<AgentFeature[]> {
|
||||
|
||||
@@ -6379,8 +6379,21 @@ export class CodexAppServerAgentClient implements AgentClient {
|
||||
}
|
||||
|
||||
async fetchCatalog(_options: FetchCatalogOptions): Promise<ProviderCatalog> {
|
||||
const models = await this.fetchModelsFromAppServer();
|
||||
return { models, modes: CODEX_MODES };
|
||||
const [models, autoReviewEnabled] = await Promise.all([
|
||||
this.fetchModelsFromAppServer(),
|
||||
this.resolveAutoReviewEnabled(),
|
||||
]);
|
||||
return {
|
||||
models,
|
||||
defaultModeId: autoReviewEnabled ? "auto-review" : DEFAULT_CODEX_MODE_ID,
|
||||
modes: autoReviewEnabled
|
||||
? CODEX_MODES
|
||||
: CODEX_MODES.filter((mode) => mode.id !== "auto-review"),
|
||||
};
|
||||
}
|
||||
|
||||
async resolveDefaultModeId(): Promise<string> {
|
||||
return (await this.resolveAutoReviewEnabled()) ? "auto-review" : DEFAULT_CODEX_MODE_ID;
|
||||
}
|
||||
|
||||
private async fetchModelsFromAppServer(): Promise<AgentModelDefinition[]> {
|
||||
|
||||
Reference in New Issue
Block a user