# @yqt5421/vision-router

> 让任何模型都能“看图” —— pi 视觉通道自动维护 + 智能路由扩展

`@yqt5421/vision-router` 是 [pi](https://pi.dev) 的扩展。它自动扫描你当前可用的全部模型，**实测**每个模型是否真的支持图片输入，维护一份“可用视觉通道”清单；当主模型无法读取图片时，自动把图片交给清单里的视觉模型识别，并支持外部免费通道兜底。

## 特性

- **自动维护视觉通道**：扫描模型注册表，对每个候选模型发送 1×1 测试图，实测其视觉能力（不信任网关元数据，防止模型被错误标记）
- **零后台开销**：懒加载扫描 + 30 分钟后台静默刷新，状态缓存 24 小时，不阻塞会话
- **智能路由**：主模型读图失败时自动兜底，按「同 provider 优先 → 其他视觉模型 → 外部免费 GLM/Agnes」的顺序尝试，首批 3 通道竞速，谁快用谁
- **三个内置命令**：`/vision-status`（查看通道）、`/vision-scan`（手动扫描）、`/vision-test`（手动测试图片）
- **`vision_analyze` 工具**：模型可直接调用识别图片，失败信息透传给模型
- **健壮性**：每个请求超时控制、状态文件原子写入、扫描互斥（单飞）、错误分类（不支持视觉 vs 通道故障）、15MB 图片上限

## 安装

### 方式一：npm（推荐，国内访问稳定）

```bash
pi install npm:@yqt5421/vision-router
```

### 方式二：本地路径

```bash
pi install /path/to/@yqt5421/vision-router
```

安装后重启 pi（或 `/reload`），会话启动时会看到类似提示：

```
[vision-router] 已加载 12 个模型通道（2 个支持视觉）
```

## 快速上手

1. 安装后输入 `/vision-scan` 手动触发一次扫描（首次启动 5 秒后也会自动后台扫描）。
2. 输入 `/vision-status` 查看哪些模型实测支持视觉：

```
视觉通道（2/12 可用）：
✓ provider-a/minimax-m3
✓ provider-b/gemini-3.5-flash
✗ provider-a/deepseek-v4-pro（不支持视觉）
? provider-c/pool-xxx（通道异常: timeout）
```

3. 现在用 `read` 读图片，如果当前模型不支持视觉，扩展会自动调用视觉通道识别并把结果注入对话。
4. 也可以直接用 `/vision-test <图片路径>` 测试，或让模型调用 `vision_analyze` 工具。

## 外部免费兜底（可选）

路由列表全部失败时，会尝试以下免费通道，需要设置对应的环境变量：

| 通道 | 环境变量 | 默认模型 |
|------|----------|----------|
| GLM 免费视觉 | `GLM_API_KEY` | `glm-4v-flash` |
| Agnes 免费视觉 | `AGNES_API_KEY`（可选 `AGNES_BASE_URL` 自定义网关） | `agnes-2.5-flash` |

```bash
# ~/.bashrc 或 shell 配置
export GLM_API_KEY="你的 key"
export AGNES_API_KEY="你的 key"
```

不设置也不影响主功能——只是少一层免费兜底。

## 工作原理

```
                     ┌──────────────────────────────┐
                     │  session_start（懒加载扫描）    │
                     │  30min 后台定时刷新（静默）     │
                     └──────────────┬───────────────┘
                                    ▼
                    ┌──────────────────────────────┐
                    │  对每个模型实测视觉能力          │
                    │  （1×1 测试图 + 关键词判定）     │
                    └──────────────┬───────────────┘
                                    ▼
                    ┌──────────────────────────────┐
                    │  维护 ~/.pi/agent/            │
                    │  vision-channels.json（原子写）│
                    └──────────────┬───────────────┘
                                    ▼
   read 图片 ──► 主模型能看图？ ──是──► 正常返回
                    │
                    否
                    ▼
        ┌───────────────────────────┐
        │ 按优先级路由：              │
        │ 1. 同 provider 的视觉模型   │
        │ 2. 其他视觉模型（3 路竞速）  │
        │ 3. 外部免费 GLM/Agnes      │
        └───────────────────────────┘
```

### 路由细节

- **同 provider 优先**：与当前模型同网关的视觉模型延迟更低、凭证通用，优先尝试
- **竞速模式**：每批最多 3 个通道并发请求，任一成功即返回（每通道 30s 超时）
- **判定标准**：请求失败时解析错误体，用关键词正则区分「不支持视觉」（400/415 + image 相关错误）与「通道故障」（网络/认证/超时），避免误杀
- **embedding 模型自动跳过**：不浪费时间实测

## 命令

| 命令 | 说明 |
|------|------|
| `/vision-status` | 查看通道维护状态（✓ 可用 / ✗ 不支持 / ? 通道异常） |
| `/vision-scan` | 立即扫描并实测所有模型的视觉能力 |
| `/vision-test <图片路径>` | 用当前视觉通道测试一张图片，结果写入编辑器 |

## 状态文件

通道缓存存放在 `~/.pi/agent/vision-channels.json`（原子写入，安全断电）。格式：

```json
{
  "channels": [
    {
      "provider": "my-gateway",
      "model": "minimax-m3",
      "baseUrl": "https://...",
      "api": "openai-completions",
      "vision": true,
      "lastTested": 1722900000000
    }
  ],
  "updatedAt": 1722900000000
}
```

- `vision: true` — 实测支持视觉
- `visionUnsupported: true` — 实测不支持
- `channelError: true` — 通道故障（网络/认证/超时），`lastError` 记录原因

缓存 24 小时有效，之后自动重新实测；60 秒内的重复扫描请求会被去重。

## 开发

```bash
cd @yqt5421/vision-router
npm install        # 安装 typebox 等（可选，pi 会自带核心包）
```

本地测试：

```bash
pi -e ./extensions/vision-router.ts
```

## 发布到 npm

```bash
npm login          # 账号：yqt5420
npm publish
```

## 许可证

MIT © 2026

## 免责声明

扩展以完整权限运行在你的系统上，且会向你配置的模型网关发送测试请求。仅从你信任的源安装。使用第三方免费通道时，图片会发送给对应服务商，请注意隐私。
