CLOSEAI的codex左右脑互博设定之requires_openai_auth

在codex模型出的那天,我也尝试去试了一下/model,然后就没有然后了

模型切换里根本就没有这个模型,然后就看到了这篇帖子

加上了requires_openai_auth = truevscode插件配好了能选择模型了,然后去配置cli,把auth.json的key设置成null,cli也能选择模型了,这个时候应该皆大欢喜去爽爽测试新模型了。

但我选择重开了一下vscode,因为我记得之前配置vscode插件就是要设置auth.json的key的,无论设置什么字符串都得设置,不然插件不会走apikey模式,于是理所当然的vscode插件开始提示我登录了。

所以我当时选择还是把key加回来,使插件能正常使用,然后在config.toml新增profile配置

[profiles.codex]
model = "gpt-5-codex"

在cli需要新模型的时候使用-p codex启动。

但这cli和插件的配合也太左右脑互搏了

  • 插件认为:requires_openai_auth = true + 有API Key = 显示模型选择
  • CLI认为:requires_openai_auth = true + 没有API Key = 显示模型选择

于是我选择去掏源码,看看这个requires_openai_auth到底做了什么

/// Does this provider require an OpenAI API Key or ChatGPT login token? If true,
/// user is presented with login screen on first run, and login preference and token/key
/// are stored in auth.json. If false (which is the default), login screen is skipped,
/// and API key (if needed) comes from the "env_key" environment variable.
/// 该提供者是否需要 OpenAI API 密钥或 ChatGPT 登录令牌?如果为 true,
/// 用户首次运行时将看到登录界面,登录偏好和令牌/密钥将存储在 auth.json 文件中。
/// 如果为 false(默认值),则跳过登录界面,
/// 所需的 API 密钥将从环境变量 "env_key" 中获取。
#[serde(default)]
pub requires_openai_auth: bool,

也就是说预期行为是开了这个,就应该有key,会被视为openai登录,就会有模型选择,但是cli的行为明显不是这样。

相关代码

需要设置了requires_openai_auth 并且需要auth.json有认证无论是apikey还是chagpt token 才会返回已登录

fn get_login_status(config: &Config) -> LoginStatus {
    if config.model_provider.requires_openai_auth {
        // Reading the OpenAI API key is an async operation because it may need
        // to refresh the token. Block on it.
        let codex_home = config.codex_home.clone();
        match CodexAuth::from_codex_home(&codex_home) {
            Ok(Some(auth)) => LoginStatus::AuthMode(auth.mode),
            Ok(None) => LoginStatus::NotAuthenticated,
            Err(err) => {
                error!("Failed to read auth.json: {err}");
                LoginStatus::NotAuthenticated
            }
        }
    } else {
        LoginStatus::NotAuthenticated
    }
}

如果设置了requires_openai_auth 并且没有登录才需要显示登录界面

fn should_show_login_screen(login_status: LoginStatus, config: &Config) -> bool {
    // Only show the login screen for providers that actually require OpenAI auth
    // (OpenAI or equivalents). For OSS/other providers, skip login entirely.
    if !config.model_provider.requires_openai_auth {
        return false;
    }

    login_status == LoginStatus::NotAuthenticated
}

所以问题应该就出在这里了 他需要设置了requires_openai_auth 还需要登录状态必须是chatgpt模式

fn should_show_model_rollout_prompt(
    cli: &Cli,
    config: &Config,
    active_profile: Option<&str>,
    gpt_5_codex_model_prompt_seen: bool,
) -> bool {
    let login_status = get_login_status(config);

    active_profile.is_none()
        && cli.model.is_none()
        && !gpt_5_codex_model_prompt_seen
        && config.model_provider.requires_openai_auth
        && matches!(login_status, LoginStatus::AuthMode(AuthMode::ChatGPT))
        && !cli.oss
}

更奇怪了???看起来cli才是对的?

由于插件也是基于cli的mcp模式写的,所以我们可以去看看mcp处理那边怎么说

如果没有requires_openai_auth直接就是一个大失败 否则返回登录信息

async fn get_auth_status(
        &self,
        request_id: RequestId,
        params: codex_protocol::mcp_protocol::GetAuthStatusParams,
    ) {
        let include_token = params.include_token.unwrap_or(false);
        let do_refresh = params.refresh_token.unwrap_or(false);

        if do_refresh && let Err(err) = self.auth_manager.refresh_token().await {
            tracing::warn!("failed to refresh token while getting auth status: {err}");
        }

        // Determine whether auth is required based on the active model provider.
        // If a custom provider is configured with `requires_openai_auth == false`,
        // then no auth step is required; otherwise, default to requiring auth.
        // 根据当前使用的模型提供者判断是否需要认证。
        // 如果自定义提供者配置了 `requires_openai_auth == false`,
        // 则跳过认证步骤;否则默认需要认证。
        let requires_openai_auth = self.config.model_provider.requires_openai_auth;

        let response = if !requires_openai_auth {
            codex_protocol::mcp_protocol::GetAuthStatusResponse {
                auth_method: None,
                auth_token: None,
                requires_openai_auth: Some(false),
            }
        } else {
            match self.auth_manager.auth() {
                Some(auth) => {
                    let auth_mode = auth.mode;
                    let (reported_auth_method, token_opt) = match auth.get_token().await {
                        Ok(token) if !token.is_empty() => {
                            let tok = if include_token { Some(token) } else { None };
                            (Some(auth_mode), tok)
                        }
                        Ok(_) => (None, None),
                        Err(err) => {
                            tracing::warn!("failed to get token for auth status: {err}");
                            (None, None)
                        }
                    };
                    codex_protocol::mcp_protocol::GetAuthStatusResponse {
                        auth_method: reported_auth_method,
                        auth_token: token_opt,
                        requires_openai_auth: Some(true),
                    }
                }
                None => codex_protocol::mcp_protocol::GetAuthStatusResponse {
                    auth_method: None,
                    auth_token: None,
                    requires_openai_auth: Some(true),
                },
            }
        };

        self.outgoing.send_response(request_id, response).await;
    }

那很可能就是插件那边没有判断登录类型,只要有登录信息并且有requires_openai_auth就可以。

但最后的最后,我的建议是现在没必要用codex模型,因为针对这个模型有完全不一样的提示词,而且该提示词完全属于半成品级别,至少在使用中转的模式下不建议使用,其他登录模式我还没进行测试,如果有空我可能会再出一帖,唠唠这个新模型。

完结

6 个赞

大佬厉害

原来是这样

太强了,大佬

哈哈 有点喝多了,反正就一句话
1:cli认为OPENAI_API_KEY=null然后requires_openai_auth = true就可以显示codex,

2:但是vscode如果设置了requires_openai_auth就必须要OPENAI_API_KEY,不然UI让你强制输入KEY

我也只是大概测试了下,本来想用env的方法强制覆盖cli的OPENAI_API_KEY让它以为是null也是失败了的,后面有个profile的方式我就没尝试了,哪个每次启动codex都要带个参数