Skip to content
dsh.fish
Bundle

dsh-x-opencode-session

DSH plugin: inject dynamic/random HTTP request headers (${uuid} templates) into LLM provider requests, e.g. a run-stable x-opencode-session for the opencode-go gateway.

Source
MX1syk
License
Apache-2.0
Updated
Updated 2 hours ago

Readme

# dsh-x-opencode-session

> DSH plugin that injects dynamic/random HTTP request headers (e.g. `${uuid}` templates) into LLM provider requests — a run-stable `x-opencode-session` for the opencode-go gateway.

**dsh-x-opencode-session** is a DeepSeek Harness (DSH) plugin that injects **dynamic / random** HTTP request headers into LLM provider requests. DSH's `pi-ai` provider only accepts **static** `headers` strings — it can't express per-run dynamic values. This plugin fills that gap without touching DSH source code.

DeepSeek Harness(DSH)插件:把**动态 / 随机**的 HTTP 请求头注入 LLM provider 请求,解决 DSH 的 pi-ai provider 只能配置**静态** `headers` 字符串、无法表达“动态/随机数值”的问题。

典型场景:DSH 用 `opencode-go` provider(`openai-completions` 协议)向 OpenCode Go 网关发请求时,网关需要 `x-opencode-session` 会话头来做会话亲和/路由/缓存(自 2026-09-06 起缺失即 400 `Model is unavailable`)。静态硬编码会让所有 DSH 运行共用同一个会话 id;本插件让**每个 DSH 进程(每个评测 run / 并行 runner)铸造一个唯一的随机会话 id,并在进程内保持稳定**,互不串会话,且不修改任何 DSH 源码。

## 原理

- 包装 `globalThis.fetch`(当前 `dsh-llm-deepseek` 与 `dsh-llm-pi-ai` 适配器都经由全局 `fetch` 发请求),对 URL 命中 `urlPatterns` 的请求,把模板值 `set()` 到请求头上(覆盖同名头,包括 pi-ai 的归属 `user-agent`)。
- **零默认**:`headers` 为空时插件完全惰性,不改任何请求、也不包 `fetch`。
- 卸载安全:仅当自己仍是当前包装器时才恢复上一个 `fetch`,不破坏后续包装者。
- `verbose` 日志自动脱敏 `authorization` / `cookie` / `api-key` 等凭据头。

## 安装

插件目前托管在 GitHub(尚未发布到 npm):

```sh
# 从 GitHub 安装
dsh plugin --profile web add github:MX1syk/dsh-x-opencode-session

# 本地目录开发(改代码调试时)
dsh plugin --profile web add link:/path/to/dsh-x-opencode-session
```

## 配置

包自带的 `cordis.patch.yml` 只插入一个**空 config** 的插件行(惰性 no-op)。把下面的完整 config 写到 profile 的 `cordis.patch.yml` 或 `$DSH_HOME/cordis.patch.yml`(同一 `id` 的补丁层会整体替换该行的 config):

```yaml
# $DSH_HOME/cordis.patch.yml
- insert:
    - id: dsh-x-opencode-session
      name: dsh-x-opencode-session
      config:
        # 只改这些 URL 的请求(大小写不敏感的子串匹配,命中任一项即注入)
        urlPatterns:
          - /chat/completions
        # 动态请求头:值 = 普通字符串,可含模板占位符
        headers:
          x-opencode-session: "${uuid}"            # 进程级唯一、进程内稳定
          x-opencode-request: "${uuid@request}"    # 每次请求新值
          x-opencode-client: "dsh"
          x-opencode-project: "dsh-bench"
          user-agent: "opencode/0.2.1"
        # 默认铸造作用域:run(进程级冻结)或 request(每次请求重铸)
        scope: run
        verbose: false
```

> 若网关 baseURL 路径不含 `/chat/completions`,把网关 host 也加进 `urlPatterns`,例如 `- console.opencode.go`。

### 值模板语法

| 模板 | 说明 |
| --- | --- |
| `${uuid}` | UUID v4 |
| `${hex:N}` | N 位小写十六进制(默认 16) |
| `${alnum:N}` | N 位字母数字(默认 12) |
| `${digits:N}` | N 位数字(默认 8) |
| `${int:min:max}` | `[min, max]` 内整数 |
| `${ts}` | epoch 毫秒 |
| `${iso}` | ISO-8601 时间 |
| `${env:NAME}` | `process.env.NAME` 在渲染时读取 |

作用域后缀:`@run`(默认,进程内铸造一次并冻结)或 `@request`(每次请求重铸)。`scope` 配置项决定**没有**后缀的占位符的默认作用域。注意:`${env:...}` 在 run 作用域下首次渲染后即冻结(如需每次重读环境变量,用 `@request`)。

未知函数 / 非法参数(如 `${hex:0}`、`${int:9:3}`)不会报错:保持原文发送,并在启动时告警,其余头照常生效。

### 与 provider 静态 headers 的取舍

- pi-ai provider profile 的 `headers` 只能写死静态值;本插件在其外层(fetch 层)覆盖,天然支持动态。
- 本插件可覆盖 `user-agent`(pi-ai 会把 profile 的 `user-agent` 剥离成归属 UA;fetch 层注入不受此限制),是否覆盖由你在 `headers` 里是否显式配置决定。
- 配置为组合层(composition entry)级别:修改需重启 DSH 生效。

## 本地开发与测试

```sh
node --test "tests/*.test.mjs"
```

- `tests/templates.test.mjs`:模板引擎(随机性、边界、非法 token 告警)。
- `tests/wrapper.test.mjs`:fetch 包装(URL 门控、头合并覆盖、run/request 作用域、卸载恢复、多层包装不被覆盖)。

用 `verbose: true` 观察实际注入的请求头(凭据头已脱敏)。

## 已知限制

- 依赖适配器通过全局 `fetch` 发请求(当前 DeepSeek 与 pi-ai 适配器均是);若未来某适配器改用自定义 dispatcher 则不在覆盖范围。
- 匹配目标是完整请求 URL 的子串;如需更精确匹配,请把完整 URL 片段写进 `urlPatterns`。
- 多个同样包装 `fetch` 的插件会互相覆盖:本插件卸载时只在自己仍是当前包装器时恢复原值。

Install

dsh plugin --profile web add github:MX1syk/dsh-x-opencode-session

Profile: web

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