Merge branch 'v0.9.0rc' into opencode-support

This commit is contained in:
webdevcody
2026-01-09 09:40:16 -05:00
28 changed files with 1547 additions and 20 deletions

View File

@@ -17,6 +17,7 @@ export type {
McpStdioServerConfig,
McpSSEServerConfig,
McpHttpServerConfig,
AgentDefinition,
ReasoningEffort,
} from './provider.js';
@@ -189,6 +190,7 @@ export {
addProviderPrefix,
getBareModelId,
normalizeModelString,
validateBareModelId,
} from './provider-utils.js';
// Pipeline types

View File

@@ -240,3 +240,37 @@ export function normalizeModelString(model: string | undefined | null): string {
return model;
}
/**
* Validate that a model ID does not contain a provider prefix
*
* Providers should receive bare model IDs (e.g., "gpt-5.1-codex-max", "composer-1")
* without provider prefixes (e.g., NOT "codex-gpt-5.1-codex-max", NOT "cursor-composer-1").
*
* This validation ensures the ProviderFactory properly stripped prefixes before
* passing models to providers.
*
* @param model - Model ID to validate
* @param providerName - Name of the provider for error messages
* @throws Error if model contains a provider prefix
*
* @example
* validateBareModelId("gpt-5.1-codex-max", "CodexProvider"); // ✅ OK
* validateBareModelId("codex-gpt-5.1-codex-max", "CodexProvider"); // ❌ Throws error
*/
export function validateBareModelId(model: string, providerName: string): void {
if (!model || typeof model !== 'string') {
throw new Error(`[${providerName}] Invalid model ID: expected string, got ${typeof model}`);
}
for (const [provider, prefix] of Object.entries(PROVIDER_PREFIXES)) {
if (model.startsWith(prefix)) {
throw new Error(
`[${providerName}] Model ID should not contain provider prefix '${prefix}'. ` +
`Got: '${model}'. ` +
`This is likely a bug in ProviderFactory - it should strip the '${provider}' prefix ` +
`before passing the model to the provider.`
);
}
}
}

View File

@@ -76,12 +76,29 @@ export interface McpHttpServerConfig {
headers?: Record<string, string>;
}
/**
* Subagent definition for specialized task delegation
*/
export interface AgentDefinition {
/** Natural language description of when to use this agent */
description: string;
/** System prompt defining the agent's role and behavior */
prompt: string;
/** Restricted tool list (if omitted, inherits all tools) */
tools?: string[];
/** Model override for this agent */
model?: 'sonnet' | 'opus' | 'haiku' | 'inherit';
}
/**
* Options for executing a query via a provider
*/
export interface ExecuteOptions {
prompt: string | Array<{ type: string; text?: string; source?: object }>;
/** Bare model ID without provider prefix (e.g., "gpt-5.1-codex-max", "composer-1") */
model: string;
/** Original model ID with provider prefix for logging (e.g., "codex-gpt-5.1-codex-max") */
originalModel?: string;
cwd: string;
systemPrompt?: string | SystemPromptPreset;
maxTurns?: number;
@@ -107,6 +124,11 @@ export interface ExecuteOptions {
* Only applies to Claude models; Cursor models handle thinking internally.
*/
thinkingLevel?: ThinkingLevel;
/**
* Custom subagents for specialized task delegation
* 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.

View File

@@ -564,6 +564,43 @@ export interface GlobalSettings {
// Prompt Customization
/** Custom prompts for Auto Mode, Agent Runner, Backlog Planning, and Enhancements */
promptCustomization?: PromptCustomization;
// Skills Configuration
/**
* Enable Skills functionality (loads from .claude/skills/ directories)
* @default true
*/
enableSkills?: boolean;
/**
* Which directories to load Skills from
* - 'user': ~/.claude/skills/ (personal skills)
* - 'project': .claude/skills/ (project-specific skills)
* @default ['user', 'project']
*/
skillsSources?: Array<'user' | 'project'>;
// Subagents Configuration
/**
* Enable Custom Subagents functionality (loads from .claude/agents/ directories)
* @default true
*/
enableSubagents?: boolean;
/**
* Which directories to load Subagents from
* - 'user': ~/.claude/agents/ (personal agents)
* - 'project': .claude/agents/ (project-specific agents)
* @default ['user', 'project']
*/
subagentsSources?: Array<'user' | 'project'>;
/**
* Custom subagent definitions for specialized task delegation (programmatic)
* Key: agent name (e.g., 'code-reviewer', 'test-runner')
* Value: agent configuration
*/
customSubagents?: Record<string, import('./provider.js').AgentDefinition>;
}
/**
@@ -663,6 +700,15 @@ export interface ProjectSettings {
// Claude Agent SDK Settings
/** Auto-load CLAUDE.md files using SDK's settingSources option (project override) */
autoLoadClaudeMd?: boolean;
// Subagents Configuration
/**
* Project-specific custom subagent definitions for specialized task delegation
* Merged with global customSubagents, project-level takes precedence
* Key: agent name (e.g., 'code-reviewer', 'test-runner')
* Value: agent configuration
*/
customSubagents?: Record<string, import('./provider.js').AgentDefinition>;
}
/**
@@ -766,6 +812,10 @@ export const DEFAULT_GLOBAL_SETTINGS: GlobalSettings = {
codexAdditionalDirs: DEFAULT_CODEX_ADDITIONAL_DIRS,
codexThreadId: undefined,
mcpServers: [],
enableSkills: true,
skillsSources: ['user', 'project'],
enableSubagents: true,
subagentsSources: ['user', 'project'],
};
/** Default credentials (empty strings - user must provide API keys) */