mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-01-31 06:42:03 +00:00
Merge branch 'v0.9.0rc' into feat/subagents-skills
This commit is contained in:
100
libs/types/src/codex-models.ts
Normal file
100
libs/types/src/codex-models.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
* Codex CLI Model IDs
|
||||
* Based on OpenAI Codex CLI official models
|
||||
* Reference: https://developers.openai.com/codex/models/
|
||||
*/
|
||||
export type CodexModelId =
|
||||
| 'gpt-5.2-codex' // Most advanced agentic coding model for complex software engineering
|
||||
| 'gpt-5-codex' // Purpose-built for Codex CLI with versatile tool use
|
||||
| 'gpt-5-codex-mini' // Faster workflows optimized for low-latency code Q&A and editing
|
||||
| 'codex-1' // Version of o3 optimized for software engineering
|
||||
| 'codex-mini-latest' // Version of o4-mini for Codex, optimized for faster workflows
|
||||
| 'gpt-5'; // GPT-5 base flagship model
|
||||
|
||||
/**
|
||||
* Codex model metadata
|
||||
*/
|
||||
export interface CodexModelConfig {
|
||||
id: CodexModelId;
|
||||
label: string;
|
||||
description: string;
|
||||
hasThinking: boolean;
|
||||
/** Whether the model supports vision/image inputs */
|
||||
supportsVision: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Complete model map for Codex CLI
|
||||
*/
|
||||
export const CODEX_MODEL_CONFIG_MAP: Record<CodexModelId, CodexModelConfig> = {
|
||||
'gpt-5.2-codex': {
|
||||
id: 'gpt-5.2-codex',
|
||||
label: 'GPT-5.2-Codex',
|
||||
description: 'Most advanced agentic coding model for complex software engineering',
|
||||
hasThinking: true,
|
||||
supportsVision: true, // GPT-5 supports vision
|
||||
},
|
||||
'gpt-5-codex': {
|
||||
id: 'gpt-5-codex',
|
||||
label: 'GPT-5-Codex',
|
||||
description: 'Purpose-built for Codex CLI with versatile tool use',
|
||||
hasThinking: true,
|
||||
supportsVision: true,
|
||||
},
|
||||
'gpt-5-codex-mini': {
|
||||
id: 'gpt-5-codex-mini',
|
||||
label: 'GPT-5-Codex-Mini',
|
||||
description: 'Faster workflows optimized for low-latency code Q&A and editing',
|
||||
hasThinking: false,
|
||||
supportsVision: true,
|
||||
},
|
||||
'codex-1': {
|
||||
id: 'codex-1',
|
||||
label: 'Codex-1',
|
||||
description: 'Version of o3 optimized for software engineering',
|
||||
hasThinking: true,
|
||||
supportsVision: true,
|
||||
},
|
||||
'codex-mini-latest': {
|
||||
id: 'codex-mini-latest',
|
||||
label: 'Codex-Mini-Latest',
|
||||
description: 'Version of o4-mini for Codex, optimized for faster workflows',
|
||||
hasThinking: false,
|
||||
supportsVision: true,
|
||||
},
|
||||
'gpt-5': {
|
||||
id: 'gpt-5',
|
||||
label: 'GPT-5',
|
||||
description: 'GPT-5 base flagship model',
|
||||
hasThinking: true,
|
||||
supportsVision: true,
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper: Check if model has thinking capability
|
||||
*/
|
||||
export function codexModelHasThinking(modelId: CodexModelId): boolean {
|
||||
return CODEX_MODEL_CONFIG_MAP[modelId]?.hasThinking ?? false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper: Get display name for model
|
||||
*/
|
||||
export function getCodexModelLabel(modelId: CodexModelId): string {
|
||||
return CODEX_MODEL_CONFIG_MAP[modelId]?.label ?? modelId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper: Get all Codex model IDs
|
||||
*/
|
||||
export function getAllCodexModelIds(): CodexModelId[] {
|
||||
return Object.keys(CODEX_MODEL_CONFIG_MAP) as CodexModelId[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper: Check if Codex model supports vision
|
||||
*/
|
||||
export function codexModelSupportsVision(modelId: CodexModelId): boolean {
|
||||
return CODEX_MODEL_CONFIG_MAP[modelId]?.supportsVision ?? true;
|
||||
}
|
||||
52
libs/types/src/codex.ts
Normal file
52
libs/types/src/codex.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
/** Sandbox modes for Codex CLI command execution */
|
||||
export type CodexSandboxMode = 'read-only' | 'workspace-write' | 'danger-full-access';
|
||||
|
||||
/** Approval policies for Codex CLI tool execution */
|
||||
export type CodexApprovalPolicy = 'untrusted' | 'on-failure' | 'on-request' | 'never';
|
||||
|
||||
/** Codex event types emitted by CLI */
|
||||
export type CodexEventType =
|
||||
| 'thread.started'
|
||||
| 'turn.started'
|
||||
| 'turn.completed'
|
||||
| 'turn.failed'
|
||||
| 'item.completed'
|
||||
| 'error';
|
||||
|
||||
/** Codex item types in CLI events */
|
||||
export type CodexItemType =
|
||||
| 'agent_message'
|
||||
| 'reasoning'
|
||||
| 'command_execution'
|
||||
| 'file_change'
|
||||
| 'mcp_tool_call'
|
||||
| 'web_search'
|
||||
| 'plan_update';
|
||||
|
||||
/** Codex CLI event structure */
|
||||
export interface CodexEvent {
|
||||
type: CodexEventType;
|
||||
thread_id?: string;
|
||||
item?: {
|
||||
type: CodexItemType;
|
||||
content?: string;
|
||||
[key: string]: unknown;
|
||||
};
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
/** Codex CLI configuration (stored in .automaker/codex-config.json) */
|
||||
export interface CodexCliConfig {
|
||||
/** Default model to use when not specified */
|
||||
defaultModel?: string;
|
||||
/** List of enabled models */
|
||||
models?: string[];
|
||||
}
|
||||
|
||||
/** Codex authentication status */
|
||||
export interface CodexAuthStatus {
|
||||
authenticated: boolean;
|
||||
method: 'oauth' | 'api_key' | 'none';
|
||||
hasCredentialsFile?: boolean;
|
||||
error?: string;
|
||||
}
|
||||
@@ -217,6 +217,7 @@ export interface CursorAuthStatus {
|
||||
authenticated: boolean;
|
||||
method: 'login' | 'api_key' | 'none';
|
||||
hasCredentialsFile?: boolean;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,6 +4,16 @@
|
||||
|
||||
import type { PlanningMode, ThinkingLevel } from './settings.js';
|
||||
|
||||
/**
|
||||
* A single entry in the description history
|
||||
*/
|
||||
export interface DescriptionHistoryEntry {
|
||||
description: string;
|
||||
timestamp: string; // ISO date string
|
||||
source: 'initial' | 'enhance' | 'edit'; // What triggered this version
|
||||
enhancementMode?: 'improve' | 'technical' | 'simplify' | 'acceptance'; // Only for 'enhance' source
|
||||
}
|
||||
|
||||
export interface FeatureImagePath {
|
||||
id: string;
|
||||
path: string;
|
||||
@@ -54,6 +64,7 @@ export interface Feature {
|
||||
error?: string;
|
||||
summary?: string;
|
||||
startedAt?: string;
|
||||
descriptionHistory?: DescriptionHistoryEntry[]; // History of description changes
|
||||
[key: string]: unknown; // Keep catch-all for extensibility
|
||||
}
|
||||
|
||||
|
||||
@@ -18,10 +18,26 @@ export type {
|
||||
McpSSEServerConfig,
|
||||
McpHttpServerConfig,
|
||||
AgentDefinition,
|
||||
ReasoningEffort,
|
||||
} from './provider.js';
|
||||
|
||||
// Codex CLI types
|
||||
export type {
|
||||
CodexSandboxMode,
|
||||
CodexApprovalPolicy,
|
||||
CodexCliConfig,
|
||||
CodexAuthStatus,
|
||||
} from './codex.js';
|
||||
export * from './codex-models.js';
|
||||
|
||||
// Feature types
|
||||
export type { Feature, FeatureImagePath, FeatureTextFilePath, FeatureStatus } from './feature.js';
|
||||
export type {
|
||||
Feature,
|
||||
FeatureImagePath,
|
||||
FeatureTextFilePath,
|
||||
FeatureStatus,
|
||||
DescriptionHistoryEntry,
|
||||
} from './feature.js';
|
||||
|
||||
// Session types
|
||||
export type {
|
||||
@@ -38,7 +54,18 @@ export type { ErrorType, ErrorInfo } from './error.js';
|
||||
export type { ImageData, ImageContentBlock } from './image.js';
|
||||
|
||||
// Model types and constants
|
||||
export { CLAUDE_MODEL_MAP, DEFAULT_MODELS, type ModelAlias } from './model.js';
|
||||
export {
|
||||
CLAUDE_MODEL_MAP,
|
||||
CODEX_MODEL_MAP,
|
||||
CODEX_MODEL_IDS,
|
||||
REASONING_CAPABLE_MODELS,
|
||||
supportsReasoningEffort,
|
||||
getAllCodexModelIds,
|
||||
DEFAULT_MODELS,
|
||||
type ModelAlias,
|
||||
type CodexModelId,
|
||||
type AgentModel,
|
||||
} from './model.js';
|
||||
|
||||
// Event types
|
||||
export type { EventType, EventCallback } from './event.js';
|
||||
@@ -104,11 +131,13 @@ export {
|
||||
} from './settings.js';
|
||||
|
||||
// Model display constants
|
||||
export type { ModelOption, ThinkingLevelOption } from './model-display.js';
|
||||
export type { ModelOption, ThinkingLevelOption, ReasoningEffortOption } from './model-display.js';
|
||||
export {
|
||||
CLAUDE_MODELS,
|
||||
THINKING_LEVELS,
|
||||
THINKING_LEVEL_LABELS,
|
||||
REASONING_EFFORT_LEVELS,
|
||||
REASONING_EFFORT_LABELS,
|
||||
getModelDisplayName,
|
||||
} from './model-display.js';
|
||||
|
||||
@@ -151,6 +180,7 @@ export {
|
||||
PROVIDER_PREFIXES,
|
||||
isCursorModel,
|
||||
isClaudeModel,
|
||||
isCodexModel,
|
||||
getModelProvider,
|
||||
stripProviderPrefix,
|
||||
addProviderPrefix,
|
||||
|
||||
@@ -6,7 +6,10 @@
|
||||
*/
|
||||
|
||||
import type { ModelAlias, ThinkingLevel, ModelProvider } from './settings.js';
|
||||
import type { ReasoningEffort } from './provider.js';
|
||||
import type { CursorModelId } from './cursor-models.js';
|
||||
import type { AgentModel, CodexModelId } from './model.js';
|
||||
import { CODEX_MODEL_MAP } from './model.js';
|
||||
|
||||
/**
|
||||
* ModelOption - Display metadata for a model option in the UI
|
||||
@@ -63,6 +66,61 @@ export const CLAUDE_MODELS: ModelOption[] = [
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* Codex model options with full metadata for UI display
|
||||
* Official models from https://developers.openai.com/codex/models/
|
||||
*/
|
||||
export const CODEX_MODELS: (ModelOption & { hasReasoning?: boolean })[] = [
|
||||
{
|
||||
id: CODEX_MODEL_MAP.gpt52Codex,
|
||||
label: 'GPT-5.2-Codex',
|
||||
description: 'Most advanced agentic coding model (default for ChatGPT users).',
|
||||
badge: 'Premium',
|
||||
provider: 'codex',
|
||||
hasReasoning: true,
|
||||
},
|
||||
{
|
||||
id: CODEX_MODEL_MAP.gpt5Codex,
|
||||
label: 'GPT-5-Codex',
|
||||
description: 'Purpose-built for Codex CLI (default for CLI users).',
|
||||
badge: 'Balanced',
|
||||
provider: 'codex',
|
||||
hasReasoning: true,
|
||||
},
|
||||
{
|
||||
id: CODEX_MODEL_MAP.gpt5CodexMini,
|
||||
label: 'GPT-5-Codex-Mini',
|
||||
description: 'Faster workflows for code Q&A and editing.',
|
||||
badge: 'Speed',
|
||||
provider: 'codex',
|
||||
hasReasoning: false,
|
||||
},
|
||||
{
|
||||
id: CODEX_MODEL_MAP.codex1,
|
||||
label: 'Codex-1',
|
||||
description: 'o3-based model optimized for software engineering.',
|
||||
badge: 'Premium',
|
||||
provider: 'codex',
|
||||
hasReasoning: true,
|
||||
},
|
||||
{
|
||||
id: CODEX_MODEL_MAP.codexMiniLatest,
|
||||
label: 'Codex-Mini-Latest',
|
||||
description: 'o4-mini-based model for faster workflows.',
|
||||
badge: 'Balanced',
|
||||
provider: 'codex',
|
||||
hasReasoning: false,
|
||||
},
|
||||
{
|
||||
id: CODEX_MODEL_MAP.gpt5,
|
||||
label: 'GPT-5',
|
||||
description: 'GPT-5 base flagship model.',
|
||||
badge: 'Balanced',
|
||||
provider: 'codex',
|
||||
hasReasoning: true,
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* Thinking level options with display labels
|
||||
*
|
||||
@@ -89,6 +147,43 @@ export const THINKING_LEVEL_LABELS: Record<ThinkingLevel, string> = {
|
||||
ultrathink: 'Ultra',
|
||||
};
|
||||
|
||||
/**
|
||||
* ReasoningEffortOption - Display metadata for reasoning effort selection (Codex/OpenAI)
|
||||
*/
|
||||
export interface ReasoningEffortOption {
|
||||
/** Reasoning effort identifier */
|
||||
id: ReasoningEffort;
|
||||
/** Display label */
|
||||
label: string;
|
||||
/** Description of what this level does */
|
||||
description: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reasoning effort options for Codex/OpenAI models
|
||||
* All models support reasoning effort levels
|
||||
*/
|
||||
export const REASONING_EFFORT_LEVELS: ReasoningEffortOption[] = [
|
||||
{ id: 'none', label: 'None', description: 'No reasoning tokens (GPT-5.1 models only)' },
|
||||
{ id: 'minimal', label: 'Minimal', description: 'Very quick reasoning' },
|
||||
{ id: 'low', label: 'Low', description: 'Quick responses for simpler queries' },
|
||||
{ id: 'medium', label: 'Medium', description: 'Balance between depth and speed (default)' },
|
||||
{ id: 'high', label: 'High', description: 'Maximizes reasoning depth for critical tasks' },
|
||||
{ id: 'xhigh', label: 'XHigh', description: 'Highest level for gpt-5.1-codex-max and newer' },
|
||||
];
|
||||
|
||||
/**
|
||||
* Map of reasoning effort levels to short display labels
|
||||
*/
|
||||
export const REASONING_EFFORT_LABELS: Record<ReasoningEffort, string> = {
|
||||
none: 'None',
|
||||
minimal: 'Min',
|
||||
low: 'Low',
|
||||
medium: 'Med',
|
||||
high: 'High',
|
||||
xhigh: 'XHigh',
|
||||
};
|
||||
|
||||
/**
|
||||
* Get display name for a model
|
||||
*
|
||||
@@ -107,6 +202,12 @@ export function getModelDisplayName(model: ModelAlias | string): string {
|
||||
haiku: 'Claude Haiku',
|
||||
sonnet: 'Claude Sonnet',
|
||||
opus: 'Claude Opus',
|
||||
[CODEX_MODEL_MAP.gpt52Codex]: 'GPT-5.2-Codex',
|
||||
[CODEX_MODEL_MAP.gpt5Codex]: 'GPT-5-Codex',
|
||||
[CODEX_MODEL_MAP.gpt5CodexMini]: 'GPT-5-Codex-Mini',
|
||||
[CODEX_MODEL_MAP.codex1]: 'Codex-1',
|
||||
[CODEX_MODEL_MAP.codexMiniLatest]: 'Codex-Mini-Latest',
|
||||
[CODEX_MODEL_MAP.gpt5]: 'GPT-5',
|
||||
};
|
||||
return displayNames[model] || model;
|
||||
}
|
||||
|
||||
@@ -7,12 +7,70 @@ export const CLAUDE_MODEL_MAP: Record<string, string> = {
|
||||
opus: 'claude-opus-4-5-20251101',
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* Codex/OpenAI model identifiers
|
||||
* Based on OpenAI Codex CLI official models
|
||||
* See: https://developers.openai.com/codex/models/
|
||||
*/
|
||||
export const CODEX_MODEL_MAP = {
|
||||
// Codex-specific models
|
||||
/** Most advanced agentic coding model for complex software engineering (default for ChatGPT users) */
|
||||
gpt52Codex: 'gpt-5.2-codex',
|
||||
/** Purpose-built for Codex CLI with versatile tool use (default for CLI users) */
|
||||
gpt5Codex: 'gpt-5-codex',
|
||||
/** Faster workflows optimized for low-latency code Q&A and editing */
|
||||
gpt5CodexMini: 'gpt-5-codex-mini',
|
||||
/** Version of o3 optimized for software engineering */
|
||||
codex1: 'codex-1',
|
||||
/** Version of o4-mini for Codex, optimized for faster workflows */
|
||||
codexMiniLatest: 'codex-mini-latest',
|
||||
|
||||
// Base GPT-5 model (also available in Codex)
|
||||
/** GPT-5 base flagship model */
|
||||
gpt5: 'gpt-5',
|
||||
} as const;
|
||||
|
||||
export const CODEX_MODEL_IDS = Object.values(CODEX_MODEL_MAP);
|
||||
|
||||
/**
|
||||
* Models that support reasoning effort configuration
|
||||
* These models can use reasoning.effort parameter
|
||||
*/
|
||||
export const REASONING_CAPABLE_MODELS = new Set([
|
||||
CODEX_MODEL_MAP.gpt52Codex,
|
||||
CODEX_MODEL_MAP.gpt5Codex,
|
||||
CODEX_MODEL_MAP.gpt5,
|
||||
CODEX_MODEL_MAP.codex1, // o3-based model
|
||||
]);
|
||||
|
||||
/**
|
||||
* Check if a model supports reasoning effort configuration
|
||||
*/
|
||||
export function supportsReasoningEffort(modelId: string): boolean {
|
||||
return REASONING_CAPABLE_MODELS.has(modelId as any);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all Codex model IDs as an array
|
||||
*/
|
||||
export function getAllCodexModelIds(): CodexModelId[] {
|
||||
return CODEX_MODEL_IDS as CodexModelId[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Default models per provider
|
||||
*/
|
||||
export const DEFAULT_MODELS = {
|
||||
claude: 'claude-opus-4-5-20251101',
|
||||
cursor: 'auto', // Cursor's recommended default
|
||||
codex: CODEX_MODEL_MAP.gpt52Codex, // GPT-5.2-Codex is the most advanced agentic coding model
|
||||
} as const;
|
||||
|
||||
export type ModelAlias = keyof typeof CLAUDE_MODEL_MAP;
|
||||
export type CodexModelId = (typeof CODEX_MODEL_MAP)[keyof typeof CODEX_MODEL_MAP];
|
||||
|
||||
/**
|
||||
* AgentModel - Alias for ModelAlias for backward compatibility
|
||||
* Represents available models across providers
|
||||
*/
|
||||
export type AgentModel = ModelAlias | CodexModelId;
|
||||
|
||||
@@ -8,11 +8,12 @@
|
||||
|
||||
import type { ModelProvider } from './settings.js';
|
||||
import { CURSOR_MODEL_MAP, type CursorModelId } from './cursor-models.js';
|
||||
import { CLAUDE_MODEL_MAP } from './model.js';
|
||||
import { CLAUDE_MODEL_MAP, CODEX_MODEL_MAP, type CodexModelId } from './model.js';
|
||||
|
||||
/** Provider prefix constants */
|
||||
export const PROVIDER_PREFIXES = {
|
||||
cursor: 'cursor-',
|
||||
codex: 'codex-',
|
||||
// Add new provider prefixes here
|
||||
} as const;
|
||||
|
||||
@@ -52,6 +53,35 @@ export function isClaudeModel(model: string | undefined | null): boolean {
|
||||
return model.includes('claude-');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a model string represents a Codex/OpenAI model
|
||||
*
|
||||
* @param model - Model string to check (e.g., "gpt-5.2", "o1", "codex-gpt-5.2")
|
||||
* @returns true if the model is a Codex model
|
||||
*/
|
||||
export function isCodexModel(model: string | undefined | null): boolean {
|
||||
if (!model || typeof model !== 'string') return false;
|
||||
|
||||
// Check for explicit codex- prefix
|
||||
if (model.startsWith(PROVIDER_PREFIXES.codex)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if it's a gpt- model
|
||||
if (model.startsWith('gpt-')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if it's an o-series model (o1, o3, etc.)
|
||||
if (/^o\d/.test(model)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if it's in the CODEX_MODEL_MAP
|
||||
const modelValues = Object.values(CODEX_MODEL_MAP);
|
||||
return modelValues.includes(model as CodexModelId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the provider for a model string
|
||||
*
|
||||
@@ -59,6 +89,11 @@ export function isClaudeModel(model: string | undefined | null): boolean {
|
||||
* @returns The provider type, defaults to 'claude' for unknown models
|
||||
*/
|
||||
export function getModelProvider(model: string | undefined | null): ModelProvider {
|
||||
// Check Codex first before Cursor, since Cursor also supports gpt models
|
||||
// but bare gpt-* should route to Codex
|
||||
if (isCodexModel(model)) {
|
||||
return 'codex';
|
||||
}
|
||||
if (isCursorModel(model)) {
|
||||
return 'cursor';
|
||||
}
|
||||
@@ -96,6 +131,7 @@ export function stripProviderPrefix(model: string): string {
|
||||
* @example
|
||||
* addProviderPrefix('composer-1', 'cursor') // 'cursor-composer-1'
|
||||
* addProviderPrefix('cursor-composer-1', 'cursor') // 'cursor-composer-1' (no change)
|
||||
* addProviderPrefix('gpt-5.2', 'codex') // 'codex-gpt-5.2'
|
||||
* addProviderPrefix('sonnet', 'claude') // 'sonnet' (Claude doesn't use prefix)
|
||||
*/
|
||||
export function addProviderPrefix(model: string, provider: ModelProvider): string {
|
||||
@@ -105,6 +141,10 @@ export function addProviderPrefix(model: string, provider: ModelProvider): strin
|
||||
if (!model.startsWith(PROVIDER_PREFIXES.cursor)) {
|
||||
return `${PROVIDER_PREFIXES.cursor}${model}`;
|
||||
}
|
||||
} else if (provider === 'codex') {
|
||||
if (!model.startsWith(PROVIDER_PREFIXES.codex)) {
|
||||
return `${PROVIDER_PREFIXES.codex}${model}`;
|
||||
}
|
||||
}
|
||||
// Claude models don't use prefixes
|
||||
return model;
|
||||
@@ -123,6 +163,7 @@ export function getBareModelId(model: string): string {
|
||||
/**
|
||||
* Normalize a model string to its canonical form
|
||||
* - For Cursor: adds cursor- prefix if missing
|
||||
* - For Codex: can add codex- prefix (but bare gpt-* is also valid)
|
||||
* - For Claude: returns as-is
|
||||
*
|
||||
* @param model - Model string to normalize
|
||||
@@ -136,5 +177,19 @@ export function normalizeModelString(model: string | undefined | null): string {
|
||||
return `${PROVIDER_PREFIXES.cursor}${model}`;
|
||||
}
|
||||
|
||||
// For Codex, bare gpt-* and o-series models are valid canonical forms
|
||||
// Only add prefix if it's in CODEX_MODEL_MAP but doesn't have gpt-/o prefix
|
||||
const codexModelValues = Object.values(CODEX_MODEL_MAP);
|
||||
if (codexModelValues.includes(model as CodexModelId)) {
|
||||
// If it already starts with gpt- or o, it's canonical
|
||||
if (model.startsWith('gpt-') || /^o\d/.test(model)) {
|
||||
return model;
|
||||
}
|
||||
// Otherwise, it might need a prefix (though this is unlikely)
|
||||
if (!model.startsWith(PROVIDER_PREFIXES.codex)) {
|
||||
return `${PROVIDER_PREFIXES.codex}${model}`;
|
||||
}
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,20 @@
|
||||
*/
|
||||
|
||||
import type { ThinkingLevel } from './settings.js';
|
||||
import type { CodexSandboxMode, CodexApprovalPolicy } from './codex.js';
|
||||
|
||||
/**
|
||||
* Reasoning effort levels for Codex/OpenAI models
|
||||
* Controls the computational intensity and reasoning tokens used.
|
||||
* Based on OpenAI API documentation:
|
||||
* - 'none': No reasoning (GPT-5.1 models only)
|
||||
* - 'minimal': Very quick reasoning
|
||||
* - 'low': Quick responses for simpler queries
|
||||
* - 'medium': Balance between depth and speed (default)
|
||||
* - 'high': Maximizes reasoning depth for critical tasks
|
||||
* - 'xhigh': Highest level, supported by gpt-5.1-codex-max and newer
|
||||
*/
|
||||
export type ReasoningEffort = 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh';
|
||||
|
||||
/**
|
||||
* Configuration for a provider instance
|
||||
@@ -87,11 +101,14 @@ export interface ExecuteOptions {
|
||||
maxTurns?: number;
|
||||
allowedTools?: string[];
|
||||
mcpServers?: Record<string, McpServerConfig>;
|
||||
/** If true, allows all MCP tools unrestricted (no approval needed). Default: false */
|
||||
mcpUnrestrictedTools?: boolean;
|
||||
/** If true, automatically approves all MCP tool calls. Default: undefined (uses approval policy) */
|
||||
mcpAutoApproveTools?: boolean;
|
||||
abortController?: AbortController;
|
||||
conversationHistory?: ConversationMessage[]; // Previous messages for context
|
||||
sdkSessionId?: string; // Claude SDK session ID for resuming conversations
|
||||
settingSources?: Array<'user' | 'project' | 'local'>; // Sources for CLAUDE.md loading
|
||||
sandbox?: { enabled: boolean; autoAllowBashIfSandboxed?: boolean }; // Sandbox configuration
|
||||
/**
|
||||
* If true, the provider should run in read-only mode (no file modifications).
|
||||
* For Cursor CLI, this omits the --force flag, making it suggest-only.
|
||||
@@ -109,6 +126,31 @@ export interface ExecuteOptions {
|
||||
* Key: agent name, Value: agent definition
|
||||
*/
|
||||
agents?: Record<string, AgentDefinition>;
|
||||
/**
|
||||
* Reasoning effort for Codex/OpenAI models with reasoning capabilities.
|
||||
* Controls how many reasoning tokens the model generates before responding.
|
||||
* Supported values: 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh'
|
||||
* - none: No reasoning tokens (fastest)
|
||||
* - minimal/low: Quick reasoning for simple tasks
|
||||
* - medium: Balanced reasoning (default)
|
||||
* - high: Extended reasoning for complex tasks
|
||||
* - xhigh: Maximum reasoning for quality-critical tasks
|
||||
* Only applies to models that support reasoning (gpt-5.1-codex-max+, o3-mini, o4-mini)
|
||||
*/
|
||||
reasoningEffort?: ReasoningEffort;
|
||||
codexSettings?: {
|
||||
autoLoadAgents?: boolean;
|
||||
sandboxMode?: CodexSandboxMode;
|
||||
approvalPolicy?: CodexApprovalPolicy;
|
||||
enableWebSearch?: boolean;
|
||||
enableImages?: boolean;
|
||||
additionalDirs?: string[];
|
||||
threadId?: string;
|
||||
};
|
||||
outputFormat?: {
|
||||
type: 'json_schema';
|
||||
schema: Record<string, unknown>;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -185,4 +227,5 @@ export interface ModelDefinition {
|
||||
supportsTools?: boolean;
|
||||
tier?: 'basic' | 'standard' | 'premium';
|
||||
default?: boolean;
|
||||
hasReasoning?: boolean;
|
||||
}
|
||||
|
||||
@@ -6,10 +6,11 @@
|
||||
* (for file I/O via SettingsService) and the UI (for state management and sync).
|
||||
*/
|
||||
|
||||
import type { ModelAlias } from './model.js';
|
||||
import type { ModelAlias, AgentModel, CodexModelId } from './model.js';
|
||||
import type { CursorModelId } from './cursor-models.js';
|
||||
import { CURSOR_MODEL_MAP, getAllCursorModelIds } from './cursor-models.js';
|
||||
import type { PromptCustomization } from './prompts.js';
|
||||
import type { CodexSandboxMode, CodexApprovalPolicy } from './codex.js';
|
||||
|
||||
// Re-export ModelAlias for convenience
|
||||
export type { ModelAlias };
|
||||
@@ -95,7 +96,14 @@ export function getThinkingTokenBudget(level: ThinkingLevel | undefined): number
|
||||
}
|
||||
|
||||
/** ModelProvider - AI model provider for credentials and API key management */
|
||||
export type ModelProvider = 'claude' | 'cursor';
|
||||
export type ModelProvider = 'claude' | 'cursor' | 'codex';
|
||||
|
||||
const DEFAULT_CODEX_AUTO_LOAD_AGENTS = false;
|
||||
const DEFAULT_CODEX_SANDBOX_MODE: CodexSandboxMode = 'workspace-write';
|
||||
const DEFAULT_CODEX_APPROVAL_POLICY: CodexApprovalPolicy = 'on-request';
|
||||
const DEFAULT_CODEX_ENABLE_WEB_SEARCH = false;
|
||||
const DEFAULT_CODEX_ENABLE_IMAGES = true;
|
||||
const DEFAULT_CODEX_ADDITIONAL_DIRS: string[] = [];
|
||||
|
||||
/**
|
||||
* PhaseModelEntry - Configuration for a single phase model
|
||||
@@ -227,7 +235,7 @@ export interface AIProfile {
|
||||
name: string;
|
||||
/** User-friendly description */
|
||||
description: string;
|
||||
/** Provider selection: 'claude' or 'cursor' */
|
||||
/** Provider selection: 'claude', 'cursor', or 'codex' */
|
||||
provider: ModelProvider;
|
||||
/** Whether this is a built-in default profile */
|
||||
isBuiltIn: boolean;
|
||||
@@ -245,6 +253,10 @@ export interface AIProfile {
|
||||
* Note: For Cursor, thinking is embedded in the model ID (e.g., 'claude-sonnet-4-thinking')
|
||||
*/
|
||||
cursorModel?: CursorModelId;
|
||||
|
||||
// Codex-specific settings
|
||||
/** Which Codex/GPT model to use - only for Codex provider */
|
||||
codexModel?: CodexModelId;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -262,6 +274,12 @@ export function profileHasThinking(profile: AIProfile): boolean {
|
||||
return modelConfig?.hasThinking ?? false;
|
||||
}
|
||||
|
||||
if (profile.provider === 'codex') {
|
||||
// Codex models handle thinking internally (o-series models)
|
||||
const model = profile.codexModel || 'gpt-5.2';
|
||||
return model.startsWith('o');
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -273,6 +291,10 @@ export function getProfileModelString(profile: AIProfile): string {
|
||||
return `cursor:${profile.cursorModel || 'auto'}`;
|
||||
}
|
||||
|
||||
if (profile.provider === 'codex') {
|
||||
return `codex:${profile.codexModel || 'gpt-5.2'}`;
|
||||
}
|
||||
|
||||
// Claude
|
||||
return profile.model || 'sonnet';
|
||||
}
|
||||
@@ -387,6 +409,18 @@ export interface GlobalSettings {
|
||||
/** Version number for schema migration */
|
||||
version: number;
|
||||
|
||||
// Migration Tracking
|
||||
/** Whether localStorage settings have been migrated to API storage (prevents re-migration) */
|
||||
localStorageMigrated?: boolean;
|
||||
|
||||
// Onboarding / Setup Wizard
|
||||
/** Whether the initial setup wizard has been completed */
|
||||
setupComplete: boolean;
|
||||
/** Whether this is the first run experience (used by UI onboarding) */
|
||||
isFirstRun: boolean;
|
||||
/** Whether Claude setup was skipped during onboarding */
|
||||
skipClaudeSetup: boolean;
|
||||
|
||||
// Theme Configuration
|
||||
/** Currently selected theme */
|
||||
theme: ThemeMode;
|
||||
@@ -406,6 +440,8 @@ export interface GlobalSettings {
|
||||
defaultSkipTests: boolean;
|
||||
/** Default: enable dependency blocking */
|
||||
enableDependencyBlocking: boolean;
|
||||
/** Skip verification requirement in auto-mode (treat 'completed' same as 'verified') */
|
||||
skipVerificationInAutoMode: boolean;
|
||||
/** Default: use git worktrees for feature branches */
|
||||
useWorktrees: boolean;
|
||||
/** Default: only show AI profiles (hide other settings) */
|
||||
@@ -450,6 +486,8 @@ export interface GlobalSettings {
|
||||
projects: ProjectRef[];
|
||||
/** Projects in trash/recycle bin */
|
||||
trashedProjects: TrashedProjectRef[];
|
||||
/** ID of the currently open project (null if none) */
|
||||
currentProjectId: string | null;
|
||||
/** History of recently opened project IDs */
|
||||
projectHistory: string[];
|
||||
/** Current position in project history for navigation */
|
||||
@@ -474,11 +512,25 @@ export interface GlobalSettings {
|
||||
// Claude Agent SDK Settings
|
||||
/** Auto-load CLAUDE.md files using SDK's settingSources option */
|
||||
autoLoadClaudeMd?: boolean;
|
||||
/** Enable sandbox mode for bash commands (default: false, enable for additional security) */
|
||||
enableSandboxMode?: boolean;
|
||||
/** Skip showing the sandbox risk warning dialog */
|
||||
/** Skip the sandbox environment warning dialog on startup */
|
||||
skipSandboxWarning?: boolean;
|
||||
|
||||
// Codex CLI Settings
|
||||
/** Auto-load .codex/AGENTS.md instructions into Codex prompts */
|
||||
codexAutoLoadAgents?: boolean;
|
||||
/** Sandbox mode for Codex CLI command execution */
|
||||
codexSandboxMode?: CodexSandboxMode;
|
||||
/** Approval policy for Codex CLI tool execution */
|
||||
codexApprovalPolicy?: CodexApprovalPolicy;
|
||||
/** Enable web search capability for Codex CLI (--search flag) */
|
||||
codexEnableWebSearch?: boolean;
|
||||
/** Enable image attachment support for Codex CLI (-i flag) */
|
||||
codexEnableImages?: boolean;
|
||||
/** Additional directories with write access (--add-dir flags) */
|
||||
codexAdditionalDirs?: string[];
|
||||
/** Last thread ID for session resumption */
|
||||
codexThreadId?: string;
|
||||
|
||||
// MCP Server Configuration
|
||||
/** List of configured MCP servers for agent use */
|
||||
mcpServers: MCPServerConfig[];
|
||||
@@ -656,7 +708,7 @@ export const DEFAULT_PHASE_MODELS: PhaseModelConfig = {
|
||||
};
|
||||
|
||||
/** Current version of the global settings schema */
|
||||
export const SETTINGS_VERSION = 3;
|
||||
export const SETTINGS_VERSION = 4;
|
||||
/** Current version of the credentials schema */
|
||||
export const CREDENTIALS_VERSION = 1;
|
||||
/** Current version of the project settings schema */
|
||||
@@ -689,6 +741,9 @@ export const DEFAULT_KEYBOARD_SHORTCUTS: KeyboardShortcuts = {
|
||||
/** Default global settings used when no settings file exists */
|
||||
export const DEFAULT_GLOBAL_SETTINGS: GlobalSettings = {
|
||||
version: SETTINGS_VERSION,
|
||||
setupComplete: false,
|
||||
isFirstRun: true,
|
||||
skipClaudeSetup: false,
|
||||
theme: 'dark',
|
||||
sidebarOpen: true,
|
||||
chatHistoryOpen: false,
|
||||
@@ -696,6 +751,7 @@ export const DEFAULT_GLOBAL_SETTINGS: GlobalSettings = {
|
||||
maxConcurrency: 3,
|
||||
defaultSkipTests: true,
|
||||
enableDependencyBlocking: true,
|
||||
skipVerificationInAutoMode: false,
|
||||
useWorktrees: false,
|
||||
showProfilesOnly: false,
|
||||
defaultPlanningMode: 'skip',
|
||||
@@ -711,6 +767,7 @@ export const DEFAULT_GLOBAL_SETTINGS: GlobalSettings = {
|
||||
aiProfiles: [],
|
||||
projects: [],
|
||||
trashedProjects: [],
|
||||
currentProjectId: null,
|
||||
projectHistory: [],
|
||||
projectHistoryIndex: -1,
|
||||
lastProjectDir: undefined,
|
||||
@@ -718,8 +775,14 @@ export const DEFAULT_GLOBAL_SETTINGS: GlobalSettings = {
|
||||
worktreePanelCollapsed: false,
|
||||
lastSelectedSessionByProject: {},
|
||||
autoLoadClaudeMd: false,
|
||||
enableSandboxMode: false,
|
||||
skipSandboxWarning: false,
|
||||
codexAutoLoadAgents: DEFAULT_CODEX_AUTO_LOAD_AGENTS,
|
||||
codexSandboxMode: DEFAULT_CODEX_SANDBOX_MODE,
|
||||
codexApprovalPolicy: DEFAULT_CODEX_APPROVAL_POLICY,
|
||||
codexEnableWebSearch: DEFAULT_CODEX_ENABLE_WEB_SEARCH,
|
||||
codexEnableImages: DEFAULT_CODEX_ENABLE_IMAGES,
|
||||
codexAdditionalDirs: DEFAULT_CODEX_ADDITIONAL_DIRS,
|
||||
codexThreadId: undefined,
|
||||
mcpServers: [],
|
||||
enableSkills: true,
|
||||
skillsSources: ['user', 'project'],
|
||||
|
||||
Reference in New Issue
Block a user