Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 20 additions & 7 deletions packages/mcp-server/src/internal/agents/openai-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,34 +21,47 @@ export function setOpenAIBaseUrl(baseUrl: string | undefined): void {
configuredBaseUrl = baseUrl;
}

/**
* Check if a model supports reasoning effort parameter (o1 series only)
*/
function supportsReasoningEffort(modelName: string): boolean {
return modelName.startsWith("o1-") || modelName.startsWith("o3-");
}

/**
* Retrieve an OpenAI language model configured from environment variables and explicit config.
*
* Configuration:
* - OPENAI_MODEL: Model to use (default: "gpt-5") - env var OK
* - OPENAI_REASONING_EFFORT: Reasoning effort for o1 models: "low", "medium", "high", or "" to disable (default: "low") - env var OK
* - OPENAI_REASONING_EFFORT: Reasoning effort for o1 models: "low", "medium", "high", or "" to disable (default: "low" for o1 models) - env var OK
* - Base URL: Must be set via setOpenAIBaseUrl() - NOT from env vars (security risk)
*/
export function getOpenAIModel(model?: string): LanguageModelV1 {
const defaultModel = process.env.OPENAI_MODEL || DEFAULT_OPENAI_MODEL;
const selectedModel = model ?? defaultModel;

// Handle reasoning effort: empty string explicitly disables it, undefined uses default
const envReasoningEffort = process.env.OPENAI_REASONING_EFFORT;
let reasoningEffort: ReasoningEffort | undefined;

// Validate reasoning effort if it's set (regardless of model)
if (envReasoningEffort === "") {
// Empty string explicitly disables reasoning effort
reasoningEffort = undefined;
} else if (envReasoningEffort === undefined) {
// Not set - use default
reasoningEffort = DEFAULT_REASONING_EFFORT;
// Not set - use default only for o1 models
if (supportsReasoningEffort(selectedModel)) {
reasoningEffort = DEFAULT_REASONING_EFFORT;
}
} else if (
VALID_REASONING_EFFORTS.includes(envReasoningEffort as ReasoningEffort)
) {
// Valid value
reasoningEffort = envReasoningEffort as ReasoningEffort;
// Valid value - only use it for o1 models
if (supportsReasoningEffort(selectedModel)) {
reasoningEffort = envReasoningEffort as ReasoningEffort;
}
} else {
// Invalid value - provide helpful error with all valid options
// Invalid value - always throw error to help users catch configuration mistakes
const validValues = VALID_REASONING_EFFORTS.map((v) => `"${v}"`).join(", ");
throw new Error(
`Invalid OPENAI_REASONING_EFFORT value: "${envReasoningEffort}". Must be one of: ${validValues}, or "" (empty string to disable). Default is "${DEFAULT_REASONING_EFFORT}".`,
Expand All @@ -62,7 +75,7 @@ export function getOpenAIModel(model?: string): LanguageModelV1 {
},
});

return factory(model ?? defaultModel, {
return factory(selectedModel, {
...(reasoningEffort && { reasoningEffort }),
});
}
Loading