fix: guard rawBaseUrl against the literal string "undefined" from env vars (#340)
On Windows, shells can set OPENAI_BASE_URL to the literal string "undefined" when the variable is referenced without quotes while unset. The nullish-coalescing operator (??) does not catch this because "undefined" is a truthy string, causing resolveProviderRequest() to treat it as a real base URL. This broke the Codex transport check: (!rawBaseUrl && isCodexAlias(model)) evaluated as (false || true) = false so the transport was incorrectly set to chat_completions (issue #336). Fix: introduce asEnvUrl() which trims the value and rejects both empty strings and the sentinel string "undefined". Use it for all three rawBaseUrl sources (options.baseUrl, OPENAI_BASE_URL, OPENAI_API_BASE). Tests: add three new cases to the 'Codex provider config' describe block covering the empty-string, "undefined"-string, and options-override scenarios. Also add beforeEach/afterEach guards so individual tests cannot contaminate each other via env var state. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -112,7 +112,19 @@ function isPrivateIpv6Address(hostname: string): boolean {
|
||||
}
|
||||
|
||||
function asTrimmedString(value: unknown): string | undefined {
|
||||
return typeof value === 'string' && value.trim() ? value.trim() : undefined
|
||||
if (typeof value !== 'string') return undefined
|
||||
const trimmed = value.trim()
|
||||
return trimmed ? trimmed : undefined
|
||||
}
|
||||
|
||||
// Reads an env-var-style string intended as a URL or path, rejecting both
|
||||
// empty strings and the literal string "undefined" that Windows shells can
|
||||
// write when a variable is unset-then-referenced without quotes (issue #336).
|
||||
function asEnvUrl(value: string | undefined): string | undefined {
|
||||
if (!value) return undefined
|
||||
const trimmed = value.trim()
|
||||
if (!trimmed || trimmed === 'undefined') return undefined
|
||||
return trimmed
|
||||
}
|
||||
|
||||
function readNestedString(
|
||||
@@ -287,10 +299,9 @@ export function resolveProviderRequest(options?: {
|
||||
(isGithubMode ? 'github:copilot' : 'gpt-4o')
|
||||
const descriptor = parseModelDescriptor(requestedModel)
|
||||
const rawBaseUrl =
|
||||
options?.baseUrl ??
|
||||
process.env.OPENAI_BASE_URL ??
|
||||
process.env.OPENAI_API_BASE ??
|
||||
undefined
|
||||
asEnvUrl(options?.baseUrl) ??
|
||||
asEnvUrl(process.env.OPENAI_BASE_URL) ??
|
||||
asEnvUrl(process.env.OPENAI_API_BASE)
|
||||
// Use Codex transport only when:
|
||||
// - the base URL is explicitly the Codex endpoint, OR
|
||||
// - the model is a Codex alias AND no custom base URL has been set
|
||||
|
||||
Reference in New Issue
Block a user