Class: EasyAI::Command::Codex

Inherits:
AIToolBase
  • Object
show all
Defined in:
lib/easyai/command/codex.rb

Overview

v2.0 新增:替代 v1.x 的 easyai gpt 子命令,启动 OpenAI Codex CLI(codex 二进制)。

Constant Summary collapse

PROFILE_SPECS =

部分第三方端点无法只靠环境变量接入 Codex:需要在 .config.toml 写自定义 model_provider(model / wire_api 等无法用环境变量表达)。 · LongCat 用 Responses API(wire_api=responses),文档:https://longcat.chat/platform/docs/zh/Codex.html · DeepSeek:codex 已移除 wire_api="chat"(2026-02-01),只认 responses;故此处也写 responses。 注意:实测 https://api.deepseek.com/v1/responses 返回 404(DeepSeek 仅实现 /chat/completions), 该 profile 能加载但运行时可能 404,待 DeepSeek 支持 Responses API 或在前面加协议转换代理。

实现策略(凭证隔离 + 配置共享):按 base_url 标记匹配 → 给该平台分配独立的 CODEX_HOME(~/.easyai/codex-home/),把 auth.json + profile layer 作为 真实文件写进去,其余(config.toml / prompts / sessions …)软链回 ~/.codex 共享; 再注入 CODEX_HOME + --profile。这样各平台 auth.json 物理隔离——可同时开多个终端跑 不同平台互不覆盖(如 LongCat 与 ChatGPT 官方并行),而用户的全局 config.toml 仍共享。 官方 / ChatGPT Subscribe 不走此路径,继续用默认 ~/.codex。新增端点只需往本表追加一项。

[
  {
    profile: 'longcat',
    marker: 'api.longcat.chat',
    toml: <<~TOML
      model_provider = "codex"
      model = "LongCat-2.0"
      disable_response_storage = true
      web_search = "disabled"
      model_reasoning_effort = "high"
      model_supports_reasoning_summaries = true

      [model_providers.codex]
      name = "codex"
      base_url = "https://api.longcat.chat/openai/v1"
      wire_api = "responses"
      requires_openai_auth = true
    TOML
  },
  {
    profile: 'deepseek',
    marker: 'api.deepseek.com',
    toml: <<~TOML
      model_provider = "deepseek"
      model = "deepseek-v4-pro"
      disable_response_storage = true
      web_search = "disabled"
      model_reasoning_effort = "high"
      model_supports_reasoning_summaries = true

      [model_providers.deepseek]
      name = "deepseek"
      base_url = "https://api.deepseek.com/v1"
      wire_api = "responses"
      requires_openai_auth = true
    TOML
  }
].freeze
CHATGPT_SUBSCRIBE_MARKER =

ChatGPT Subscribe 虚拟平台标记(写入虚拟平台 data,runtime 据此还原官方 token)

'chatgpt_subscribe'

Constants inherited from AIToolBase

AIToolBase::PROTECTED_ENV_KEYS

Instance Method Summary collapse

Methods inherited from AIToolBase

#default_env, #initialize, options, #run, #validate!

Constructor Details

This class inherits a constructor from EasyAI::Command::AIToolBase

Instance Method Details

#exec_commandObject



35
36
37
# File 'lib/easyai/command/codex.rb', line 35

def exec_command
  'codex'
end

#extra_platformsObject

存在含官方 token 的备份时,向 codex 平台选择列表注入「ChatGPT Subscribe」虚拟项。 复用 openai_official 这个 key(PLATFORM_DISPLAY_NAMES 已映射为「ChatGPT Subscribe」), 选中后用备份里的官方 OAuth token 还原 auth.json,再原生启动 codex。



101
102
103
104
105
# File 'lib/easyai/command/codex.rb', line 101

def extra_platforms
  return {} unless Backup::Codex.new(CLAide::ARGV.new([])).backup_has_official_token?

  { 'openai_official' => { 'env' => {}, CHATGPT_SUBSCRIBE_MARKER => true } }
end

#install_hintObject



39
40
41
# File 'lib/easyai/command/codex.rb', line 39

def install_hint
  '未找到 codex CLI。请安装:npm install -g @openai/codex'
end

#pre_execObject



107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/easyai/command/codex.rb', line 107

def pre_exec
  # 方案 A:运行前兜底备份 Codex 登录信息(仅当备份缺失时触发),确保可恢复
  Backup::Codex.new(CLAide::ARGV.new([])).backup_if_absent

  # ChatGPT Subscribe:从备份还原官方 OAuth token 后原生启动,不走 provider profile
  if chatgpt_subscribe_selected?
    restore_chatgpt_subscribe
    return
  end

  # 命中自定义 provider:写独立 profile layer + 注入 --profile,不污染 config.toml
  spec = matched_profile_spec
  apply_profile(spec) if spec
end

#tool_nameObject



31
32
33
# File 'lib/easyai/command/codex.rb', line 31

def tool_name
  'codex'
end