Skip to content
dsh.fish
Bundle

dsh-openrouter-providers

OpenRouter Provider List — 在「插件 → 插件配置」填写 OpenRouter 请求使用的提供商列表与量化位数限制,作为 provider.only / provider.order / provider.quantizations 注入;设置通过 settings 服务持久化到 DSH 设置文档。

Source
MoRanYue
stars
2 stars
License
MIT
Updated
Updated 8 hours ago

Readme

# dsh-openrouter-providers

DeepSeek Harness 插件:在**「插件」→「插件配置」**中填写 OpenRouter 请求使用的**提供商列表**与**量化位数限制**,并把它们作为 `provider.only` / `provider.order` / `provider.quantizations` 路由参数注入到所有 OpenRouter 模型请求中。设置通过 **DSH settings 服务**持久化到设置文档(`~/.dsh/settings.yaml`),与其它插件一致,重启后自动恢复。

**适配版本**:DeepSeek Harness `0.1.5-rc.1` —— `peerDependencies` 声明 `@deepseek-ai/dsh-settings@^0.1.5-rc.1`(DSH 0.1.5-rc.1 的 lockstep 版本),插件市场据此判定并在插件卡片上显示「适配当前 DSH 0.1.5-rc.1」。更早的 DSH 版本不在本插件的适配声明范围内。

## 功能

- **插件配置卡**(插件 → 插件配置 → OpenRouter 提供商列表):以**折叠卡片**形式展示(与内置插件卡一致的外观 —— 点击头部展开/收起、有未保存标记与保存/撤销按钮),填写提供商 slug 列表(每行一个)、选择路由模式、选择量化位数限制:
  - **仅允许这些提供商** → 请求体注入 `provider: { only: [...], allow_fallbacks: false }`
  - **按顺序优先尝试** → 注入 `provider: { order: [...], allow_fallbacks: true }`
  - **量化位数限制** → 注入 `provider: { quantizations: ['int4' | 'int8' | ...] }`(可选,默认不限制;合法值见 [OpenRouter Quantization](https://openrouter.ai/docs/guides/routing/provider-selection#quantization))
  - 可整体开关;保存后写入 DSH 设置文档(`openrouter-providers` 命名空间,`~/.dsh/settings.yaml`)
- **请求注入**:监听 `llm/stream` waterfall——当请求的 provider 路由为 `openrouter`(已启用且列表非空或设置了量化限制)时,把请求重路由到插件自研的 chat-completions adapter,由它构造请求体注入 `provider` 字段;`reasoning.effort`(off/low/medium/high/max,均为 OpenRouter 合法值)按契约透传。会话日志与 UI 仍显示 `openrouter`。
- **凭据**:复用现有 `OPENROUTER_API_KEY`(通过 `credentials` 服务解析,与 `llm-pi-ai` 的 `apiKeyEnv` 一致)。
- **应用归属(App Attribution)**:请求携带 `HTTP-Referer: https://github.com/deepseek-ai/deepseek-harness`、`X-OpenRouter-Title: DeepSeek Harness OpenRouter` 与 `X-OpenRouter-Categories: cli-agent` 头,使 OpenRouter 界面/排行榜中显示为 `DeepSeek Harness OpenRouter` 而非 Unknown([OpenRouter App Attribution 文档](https://openrouter.ai/docs/app-attribution))。

## 安装(bundle 挂载)

插件以 **bundle 包**形式挂载,与其他插件(dshmarket、dsh-recall-plugin 等)一致,通过 `cordis.patch.yml` 的 insert 行自动合并进 profile composition。

### 方式 A:从 npm 安装(推荐)

在 profile 目录(如 `~/.dsh/profiles/web/`)执行:

```bash
pnpm add dsh-openrouter-providers@latest
```

然后把包加入 profile 的 `package.json` 的 `dsh.profile.bundles` 列表:

```json
"dsh": { "profile": { "bundles": [ ..., "dsh-openrouter-providers" ] } }
```

再重启 `dsh web`。bundle 协调器自动合并包内的 `cordis.patch.yml`(insert 行:`id: openrouter-providers`)。

### 方式 B:从 GitHub 安装

```bash
pnpm add dsh-openrouter-providers@github:MoRanYue/dsh-openrouter-providers
```

其余步骤与方式 A 相同(加入 `dsh.profile.bundles` 并重启)。

### 方式 C:本地路径

```bash
pnpm add dsh-openrouter-providers@file:D:\\path\\to\\dsh-openrouter-providers
# 然后同样把包名加入 dsh.profile.bundles 并重启
```

### 手动方式(不依赖 bundle)

在 `~/.dsh/profiles/web/cordis.patch.yml` 中追加:

```yaml
- insert:
    - id: openrouter-providers
      name: 'dsh-openrouter-providers'
```

并在 profile 的 `package.json` 中把包加入 `dependencies` 与 `dsh.profile.bundles`,然后 `pnpm install` 并重启。

## 使用

1. 确保模型的 provider 路由为 `openrouter`(模型选择器中选中 OpenRouter 下的模型)。
2. 打开 插件 → 插件配置 → OpenRouter 提供商列表,填写提供商 slug(如 `DeepInfra`、`Together`),选择路由模式与量化位数限制,保存。
3. 之后的 OpenRouter 请求都会携带注入的 provider 路由参数。

> 提供商 slug 格式参见 [OpenRouter Provider Routing 文档](https://openrouter.ai/docs/guides/routing/provider-selection)(`order`/`only` 字段)。

## 工作原理(简要)

- **传输层**:动态插件环境没有 `fetch` 内置,adapter 通过 `subprocess` 服务派生 `node -e` 子进程执行 HTTP + SSE 流式解析(文本/推理/工具调用增量、usage、`[DONE]`、错误分类 AUTH/RATE_LIMIT/INVALID_REQUEST/SERVER 等)。
- **状态持久化**:`settings` 服务注册 `openrouter-providers` 命名空间,设置写入 DSH 设置文档(默认 `~/.dsh/settings.yaml`),与其他插件一致;首次启动会自动把旧版工作区状态文件(`<workspaceRoot>/.dsh-plugins/openrouter-providers.json`,v1.0.4 及以前)迁移进设置文档。
- **Client 通信**:插件配置卡通过 HTTP API `GET/POST /api/openrouter-providers/state` 读写状态(Host 端经 `webServer` 注册)。

## 限制

- 图像输入不支持(模型请求含图片时返回 `UNSUPPORTED_CONTENT`)。
- `only` 模式下 `allow_fallbacks=false`:列表中的提供商全部不可用时请求失败(OpenRouter 行为)。

## License

MIT

Install

dsh plugin --profile web add github:MoRanYue/dsh-openrouter-providers

Profile: web

  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source