# 前端模型后缀提示实现计划

> **面向 AI 代理的工作者：** 必需子技能：使用 superpowers:subagent-driven-development（推荐）或 superpowers:executing-plans 逐任务实现此计划。步骤使用复选框（`- [ ]`）语法来跟踪进度。

**目标：** 在 `codex-plus-manager` 的“配置模型”和“模型列表”输入框中添加后缀语法提示（placeholder + hint），让用户知道可以写 `deepseek-v4-pro[1M]` 这类带窗口后缀的模型名。

**架构：** 纯前端文案改动，复用现有 `.field-hint` 样式类，不引入新依赖、不增加校验/解析逻辑。修改集中在 `apps/codex-plus-manager/src/App.tsx` 的两处模型相关字段。

**技术栈：** React + TypeScript + Tailwind CSS（项目已有），Tauri（仅用于桌面端手工测试）。

---

## 文件结构

- **修改：** `apps/codex-plus-manager/src/App.tsx`
  - 职责：React 主界面，包含 Relay Profile 编辑器表单。
  - 改动：更新“配置模型”和“模型列表”的 placeholder，并在各自 `<Field>` 内新增 `<p className="field-hint">`。
- **无需修改：** `apps/codex-plus-manager/src/styles.css`
  - 已有 `.field-hint` 类（第 2100 行），直接使用。
- **测试：**
  - `cargo test -p codex-plus-core --test model_suffix`
  - `cargo test -p codex-plus-core --test relay_config`
  - `cargo test -p codex-plus-manager`
  - `cargo build -p codex-plus-manager`
  - 手工测试：`npm run dev` 启动桌面端。

---

## 任务 1：更新“配置模型”placeholder 与 hint

**文件：**
- 修改：`apps/codex-plus-manager/src/App.tsx`（约第 3788 行附近）

- [ ] **步骤 1：定位代码**

  在 `apps/codex-plus-manager/src/App.tsx` 中找到如下代码：

  ```tsx
  <Field className="relay-field-config-model" label="配置模型">
    <Input
      value={profile.model}
      onChange={(event) => updateDraft({ model: event.currentTarget.value })}
      placeholder="留空使用默认值"
    />
  </Field>
  ```

- [ ] **步骤 2：修改代码**

  将其改为：

  ```tsx
  <Field className="relay-field-config-model" label="配置模型">
    <Input
      value={profile.model}
      onChange={(event) => updateDraft({ model: event.currentTarget.value })}
      placeholder="例如 deepseek-v4-pro 或 deepseek-v4-pro[1M]"
    />
    <p className="field-hint">
      支持在模型名后加 <code>[1M]</code>、<code>[200K]</code> 或 <code>[1000000]</code> 指定上下文窗口；不写则使用 Codex 默认长度。
    </p>
  </Field>
  ```

- [ ] **步骤 3：编译检查**

  运行：

  ```bash
  cd /Users/jarvis/Documents/codexplusplus
  npm run vite:build --prefix apps/codex-plus-manager
  ```

  预期：前端构建成功，无新增 TypeScript/CSS 错误。

- [ ] **步骤 4：Commit**

  ```bash
  git add apps/codex-plus-manager/src/App.tsx
  git commit -m "feat(manager): 配置模型字段添加后缀语法提示"
  ```

---

## 任务 2：更新“模型列表”placeholder 与 hint

**文件：**
- 修改：`apps/codex-plus-manager/src/App.tsx`（约第 3898 行附近）

- [ ] **步骤 1：定位代码**

  在 `apps/codex-plus-manager/src/App.tsx` 中找到如下代码：

  ```tsx
  <Field className="relay-field-model-list" label="模型列表">
    <div className="relay-model-list-tools">
      <Textarea
        value={profile.modelList}
        onChange={(event) => updateDraft({ modelList: event.currentTarget.value })}
        placeholder="每行一个模型，例如 qwen3-coder"
      />
      <Button
        onClick={async () => {
          const models = await actions.fetchRelayProfileModels(profile);
          if (models?.length) updateDraft({ modelList: models.join("\n") });
        }}
        size="sm"
        type="button"
        variant="secondary"
      >
        <Download className="h-4 w-4" />
        从上游获取
      </Button>
    </div>
  </Field>
  ```

- [ ] **步骤 2：修改代码**

  仅修改 `placeholder` 并在 `</Field>` 之前新增 hint 段落：

  ```tsx
  <Field className="relay-field-model-list" label="模型列表">
    <div className="relay-model-list-tools">
      <Textarea
        value={profile.modelList}
        onChange={(event) => updateDraft({ modelList: event.currentTarget.value })}
        placeholder="每行一个模型，例如 qwen3-coder 或 deepseek-v4-pro[1M]"
      />
      <Button
        onClick={async () => {
          const models = await actions.fetchRelayProfileModels(profile);
          if (models?.length) updateDraft({ modelList: models.join("\n") });
        }}
        size="sm"
        type="button"
        variant="secondary"
      >
        <Download className="h-4 w-4" />
        从上游获取
      </Button>
    </div>
    <p className="field-hint">
      每行一个模型，支持在模型名后加 <code>[1M]</code>、<code>[200K]</code> 或 <code>[1000000]</code>；不写后缀的模型使用 Codex 默认长度。
    </p>
  </Field>
  ```

- [ ] **步骤 3：编译检查**

  运行：

  ```bash
  cd /Users/jarvis/Documents/codexplusplus/apps/codex-plus-manager
  npm run vite:build
  ```

  预期：前端构建成功。

- [ ] **步骤 4：Commit**

  ```bash
  git add apps/codex-plus-manager/src/App.tsx
  git commit -m "feat(manager): 模型列表字段添加后缀语法提示"
  ```

---

## 任务 3：回归测试

**文件：** 无新增文件，仅运行测试命令。

- [ ] **步骤 1：运行 codex-plus-core 单元/集成测试**

  ```bash
  cd /Users/jarvis/Documents/codexplusplus
  cargo test -p codex-plus-core --test model_suffix
  cargo test -p codex-plus-core --test relay_config
  ```

  预期：
  - `model_suffix`：9 passed; 0 failed
  - `relay_config`：83 passed; 0 failed

- [ ] **步骤 2：运行 manager 相关构建与测试**

  ```bash
  cd /Users/jarvis/Documents/codexplusplus/apps/codex-plus-manager
  npm run vite:build
  cd /Users/jarvis/Documents/codexplusplus
  cargo test -p codex-plus-manager
  cargo build -p codex-plus-manager
  ```

  预期：
  - `vite:build`：成功
  - `cargo test -p codex-plus-manager`：12 passed; 0 failed
  - `cargo build -p codex-plus-manager`：成功

- [ ] **步骤 3：Commit（如测试全部通过）**

  若测试全部通过，此任务无需单独 commit；如发现问题，修复后再 commit。

---

## 任务 4：桌面端手工测试

**文件：** 无代码修改，仅验证 UI 与后端产物。

- [ ] **步骤 1：启动开发模式**

  ```bash
  cd /Users/jarvis/Documents/codexplusplus/apps/codex-plus-manager
  npm run dev
  ```

  预期：弹出桌面窗口。

- [ ] **步骤 2：输入带后缀模型并保存**

  1. 打开或新建一个 Relay Profile。
  2. “配置模型”输入：`deepseek/deepseek-v4-flash[1M]`。
  3. “模型列表”输入：
     ```
     deepseek/deepseek-v4-flash[1M]
     qwen/qwen3-next-80b-a3b-instruct:free[256k]
     z-ai/glm-4.7-flash
     ```
  4. 保存并应用 profile。

- [ ] **步骤 3：检查后端产物**

  检查 `~/.codex/config.toml` 是否包含：

  ```toml
  model_catalog_json = "model-catalogs/<profile-id>.json"
  ```

  检查 `~/.codex/model-catalogs/<profile-id>.json` 中：
  - `deepseek/deepseek-v4-flash` 的 `context_window` 为 `1000000`
  - `qwen/qwen3-next-80b-a3b-instruct:free` 的 `context_window` 为 `256000`
  - `z-ai/glm-4.7-flash` 的 `context_window` 为 Codex 默认值或顶层 fallback

- [ ] **步骤 4：运行 codex debug models**

  ```bash
  codex debug models \
    -c model="deepseek/deepseek-v4-flash" \
    -c model_catalog_json="$HOME/.codex/model-catalogs/<profile-id>.json"
  ```

  预期：`deepseek/deepseek-v4-flash` 的 `context_window` 为 `1000000`。

- [ ] **步骤 5：记录验证结论**

  将手工测试结果补充到 `docs/specs/2026-06-24-前端模型后缀提示-design.md` 的“测试计划”或单独记录。可选 commit：

  ```bash
  git add docs/specs/2026-06-24-前端模型后缀提示-design.md
  git commit -m "docs(specs): 记录前端后缀提示手工验证结论"
  ```

---

## 任务 5：大上下文窗口验证（100 万）

**目标：** 验证 catalog 声明的 100 万上下文被 codex 接受，并在实际调用上游模型时不会触发上下文超限。

**文件：** 无代码修改，仅执行测试命令并记录结论。

- [ ] **步骤 1：方法 1 — codex debug models 查看声明值**

  使用任务 4 生成的 catalog，运行：

  ```bash
  codex debug models \
    -c model="deepseek/deepseek-v4-flash" \
    -c model_catalog_json="$HOME/.codex/model-catalogs/<profile-id>.json"
  ```

  确认输出中 `context_window` 为 `1000000`。

- [ ] **步骤 2：方法 2 — 构造 10 万 token 级别输入验证压缩/发送**

  1. 下载或生成约 10 万 token 的公开长文本测试数据（例如维基百科长条目、公开书籍/法律文档、Hugging Face 长文本评测集）。
  2. 配置 profile 使用 OpenRouter 自定义 provider，模型指向 `deepseek/deepseek-v4-flash`。
  3. 在 codex 中请求：“请总结上文前 10 万 token 的内容。”
  4. 观察：
     - 请求是否成功发出；
     - 是否触发 `auto_compact` 压缩；
     - 上游是否返回上下文超限错误；
     - token usage 中 prompt token 数是否接近预期。

  > OpenRouter API key 通过环境变量或 CodexPlusPlus auth 内容注入，**不可硬编码**。

- [ ] **步骤 3：方法 3 — codex debug/verbose 日志查看实际 token 使用**

  在调用 codex 时开启 debug/verbose 模式（具体参数视 codex CLI 版本而定），检查日志中：
  - 模型看到的 `context_window`；
  - 实际发送的 prompt token 数。

- [ ] **步骤 4：方法 4 — 直接调用 OpenRouter API 验证上限**

  ```bash
  export OPENROUTER_API_KEY="$OPENROUTER_API_KEY"  # 从环境变量读取
  curl https://openrouter.ai/api/v1/chat/completions \
    -H "Authorization: Bearer $OPENROUTER_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "deepseek/deepseek-v4-flash",
      "messages": [{"role": "user", "content": "<10万token文本>"}]
    }'
  ```

  确认上游接受接近声明值的上下文。

- [ ] **步骤 5：记录结论**

  将 4 种方法的执行结果写入 `docs/research/01-调研结果.md` 或 `docs/specs/2026-06-24-前端模型后缀提示-design.md`，包含：
  - 使用的模型 slug；
  - catalog 声明值；
  - codex 实际报告值；
  - 上游 API 实际响应（是否成功、token 数、错误信息）。

  然后 commit：

  ```bash
  git add docs/research/01-调研结果.md docs/specs/2026-06-24-前端模型后缀提示-design.md
  git commit -m "docs(research/specs): 记录大上下文窗口 4 法验证结论"
  ```

---

## 验收标准

- [ ] `apps/codex-plus-manager/src/App.tsx` 中“配置模型”placeholder 更新为包含后缀示例。
- [ ] “配置模型”字段下方新增 `.field-hint` 文案，说明后缀语法及不写后缀的行为。
- [ ] “模型列表”placeholder 更新为包含后缀示例。
- [ ] “模型列表”字段下方新增 `.field-hint` 文案，说明后缀语法及不写后缀的行为。
- [ ] 未引入新的依赖。
- [ ] `cargo test -p codex-plus-core --test model_suffix` 通过（9 passed）。
- [ ] `cargo test -p codex-plus-core --test relay_config` 通过（83 passed）。
- [ ] `cargo test -p codex-plus-manager` 通过（12 passed）。
- [ ] `cargo build -p codex-plus-manager` 成功。
- [ ] `npm run vite:build` 成功。
- [ ] 桌面端 `npm run dev` 手工测试：输入带后缀模型并应用后，`~/.codex/model-catalogs/<id>.json` 与 `~/.codex/config.toml` 正确生成。
- [ ] `codex debug models` 报告正确窗口。
- [ ] 大上下文验证：4 种方法至少各执行一次并记录结论。

---

## 自检

- **规格覆盖度：** 设计文档中的 placeholder 更新、hint 文案、样式复用、测试计划、验收标准均已对应到任务。
- **占位符扫描：** 无“待定”、“TODO”或模糊描述；所有代码片段为实际可运行的 TSX；所有命令为实际可执行命令。
- **类型一致性：** 未引入新类型或函数签名，仅修改字符串 placeholder 与新增静态 JSX。
