# dsh-agent-teams-fish v0.5.1

**降级链修正 + 厂商识别细化版**：修掉一个让「厂商头像整档不可达」的链序缺陷，并按各厂商官方文档补齐一批真实模型 ID 的漏命中。

## 一、根因：厂商那一跳被岗位那一跳永久挡住

用户截图现场：成员 `code-reviewer-cn`（route `cn-f` / `cline/cline-free/step-5-preview`）的头像右下角**徽标已经是 StepFun 商标**，头像本体却是**通用岗位鲸鱼**。

这说明厂商识别本身是对的（徽标证明了它），坏的是**降级链的顺序**。原链是：

```
vendor+role  →  role  →  vendor
```

而岗位通用图（`member-<role>-v2.png`，随包的 8 张鲸鱼）对**每一个**岗位都存在，所以第 2 跳**永远**命中，第 3 跳是死代码。后果有两条，且都被当时全部门禁放过：

1. 只有厂商通用图的 **7 家**（`meta` / `mistral` / `rwkv` / `seed` / `ernie` / `stepfun` / `jev`）的厂商角色**永远不可达** —— 徽标看着是「阶跃」，人却是那条通用鲸鱼；
2. `member-<vendor>-full-v2.webp`（**17 张**厂商立绘）同样永远轮不到，点击放大只拿到 256 岗位头像。

现在链序改为 **`vendor+role → vendor → role`**：厂商身份是这套头像的主诉求（岗位通用图对任何厂商都长一样），所以厂商优先；岗位图仍留在链尾，厂商未知或厂商素材缺失时照旧兜底。

修复前后（本机真实素材探针）：

| 厂商 | 修复前落点 | 修复后落点 |
|------|-----------|-----------|
| `stepfun` × 任意岗位 | `member-qa-v2.png`（通用鲸鱼） | `member-stepfun-v2.png`（自家角色） |
| `meta` / `mistral` / `rwkv` / `seed` / `ernie` / `jev` | 同上 | 各自的 `member-<vendor>-v2.png` |
| `stepfun` 点击放大 | `member-qa-v2.png` | `member-stepfun-full-v2.webp`（厂商立绘） |
| 10 个「全套」厂商 | `member-<vendor>-<role>-v2.png`（第 1 跳，本来就是对的） | 不变 |

**为什么门禁没抓到**：当时的断言只钉了**第 1 跳**（`vendor+role` 必须命中自己那张）。对只有通用图的厂商，第 1 跳本来就该落空，第 2 跳落哪儿没人管 —— 而事故恰恰发生在第 2 跳。`scripts/verify.mjs` 新增两条断言补上这个洞：第 2 跳必须是自家 `member-<vendor>-v2.png`，且**厂商那一跳的下标必须小于岗位那一跳**（对全部 17 厂商 × 10 岗位）。`-full` 链同理加了一条。

## 二、厂商识别细化（按各厂商官方文档补漏命中）

上一版补 `step-<数字>` 时只覆盖了「step 后跟数字」，而阶跃星辰官方文档里**一大批模型 ID 是字母后缀**，全部漏命中。本次按 [阶跃模型总览](https://platform.stepfun.com/docs/zh/guides/models/overview) 等官方口径逐厂商补齐：

| 厂商 | 本次新增命中 | 依据 / 病根 |
|------|-------------|------------|
| `stepfun` | `step-<字母>`（`step-asr` / `step-tts-mini` / `step-r1-v-mini` / `step-video-t2v`）、`stepaudio-*` | 官方公开 ID；旧规则要求 step 后跟**数字**，字母家族整片漏 |
| `glm` | `charglm-*` / `codegeex-*` / `cogview-*` / `cogvideo-*`、平台名 `bigmodel` | 智谱的非 GLM 命名家族此前完全认不出 |
| `qwen` | 平台名 `dashscope` / `aliyun` | 中转站常把 provider 段写成平台名 |
| `gemini` | `palm-<数字>` / `bison-*` / `gecko-*`、平台名 `vertex` | Google 历史模型名与 Vertex AI |
| `seed` | `byteplus`、`skylark-*` | BytePlus 海外站与火山方舟早期模型名 |
| `minimax` | `speech-<数字>` | 语音模型无厂商前缀 |
| `ernie` | **收紧**：`\bern` → `\bernie` | 旧前缀把 `ernest-1` / `ernestine` 判成文心一言；真实 ID 一律以 `ernie` 开头 |

**仍然刻意不吞的**：`stepper` / `steps` / `stepstone` / `step-log`、`palmyra-x5`（Writer 的模型家族，不是 Google 的 `palm`）、`metaphor-3`、`metadata-model`、`hypothesis`、`jevons` / `jevenile` —— 全部有单测钉住。

**诚实说明两处保留的过度放宽**：`\bseed[\w.-]*` 会吞 `seeder-2`、`\bmeta\b` 会吞 `meta-analysis`，但这两条**不能收紧** —— 收紧就丢掉真实的 `seedream-3.0` 与 `meta-llama/Llama-3.3`。权衡后按现状保留，未写进负例断言。

## 三、改动文件

| 文件 | 改动 |
|------|------|
| `src/artwork-source.ts` | `artworkCandidates` 链序：`vendor` 提到 `role` 之前 |
| `src/client/artwork.ts` | `VENDOR_ART` 表补齐上述家族与平台名，`ern` 收紧为 `ernie` |
| `scripts/custom-artwork.test.mjs` | 3 条链序断言改为新契约 + 1 条「通用档第 2 跳可达」 |
| `scripts/artwork-role-match.test.mjs` | +5 组厂商用例（阶跃字母家族 / 智谱非 GLM 家族 / 平台别名 / Google 历史家族 / 防误伤负例） |
| `scripts/verify.mjs` | +3 条可达性门禁（第 2 跳、链序、`-full` 优先厂商立绘） |
| `README.md` · `README.en.md` | 修正 [0.5.0](v0.5.0.md) 里「第 2 跳命中岗位通用图」的**错误描述**（那正是缺陷本身），补链序说明表 |

## 四、验证

- `pnpm typecheck` 通过；
- `artwork-role-match.test.mjs` **41 项全绿**（改动前 5 项红）；`custom-artwork.test.mjs` **21 项全绿**（改动前 2 项红，均因断言的是旧链序）；
- `node scripts/verify.mjs` 新增 3 条门禁全 PASS，全脚本 0 FAIL；
- 真实素材探针复核：7 个通用档厂商 × 10 岗位**全部**命中自家角色（修复前 100% 落岗位鲸鱼），17 张厂商立绘**全部**经 `-full` 请求可达；
- `pnpm verify` 仅剩 `compatibility.test.mjs` 的符号链接用例失败 —— 本机未开开发者模式的 Windows 无法 `symlinkSync`（环境限制，**非本次改动**，[0.5.0](v0.5.0.md) 起即如此）。