Skip to content
dsh.fish
Bundle

dsh-session-slm-router

Shadow-mode SLM router for DeepSeek Harness: per-turn weak/strong prediction via vertical-small-model CLI, writes ~/.dsh/slm-shadow/session-slm-shadow.jsonl; does NOT change the active model (S1 shadow only).

Source
NinjaSln-labs
License
MIT
Updated
Updated 6 days ago

Readme

# dsh-session-slm-router

[![npm version](https://img.shields.io/npm/v/dsh-session-slm-router)](https://www.npmjs.com/package/dsh-session-slm-router)
[![License](https://img.shields.io/badge/license-MIT-blue)](LICENSE)

Shadow-mode SLM 路由插件 for DeepSeek Harness。每轮通过 `vertical-small-model` CLI 预测用户发言的强弱分类(weak/strong),记录影子日志 JSONL,不改变会话活跃模型。

> ⚠️ **S1 阶段**:默认 `shadow` 模式,只观察不换模。`weak-only` 模式(S3 灰度)可执行降档换模,仅放行 weak→strong 降档,不改变用户原模型持久化。

[English](README.en.md)

## 安装

```bash
# 通过 dsh plugin 安装(推荐,自动处理 bundle 注册)
dsh plugin add dsh-session-slm-router

# 或手动添加到 profile package.json 的 dependencies + dsh.profile.bundles
```

## 配置

### 模式选择

| mode | 行为 |
|------|------|
| `shadow`(默认) | 只预测 + 写影子日志,**不换模** |
| `weak-only`(S3 灰度) | 真正换模,但**只放行 `switch_to_weak`**(降档);`switch_to_strong` 记录但不放行 |
| `off` | 关闭插件 |

### 完整配置示例

```yaml
# 宿主 settings.yaml 或 cordis 行内 config
session-slm-router:
  mode: shadow                    # shadow | weak-only | off
  weakOnlyMainOnly: true          # weak-only 是否只对主会话换模
  predictCmd: "python3 <path-to>/vertical-small-model/scripts/route_predict.py"
  predictModel: "<path-to>/vertical-small-model/data/eval/routing-v0/model-r1.json"
  timeoutMs: 250
  logPath: "slm-shadow/session-slm-shadow.jsonl"
  weakSlots:
    - { provider: <provider>, model: <model> }
  strongSlots:
    - { provider: <provider>, model: <model> }
```

- `predictCmd` / `predictModel`:**必填**,指向 [vertical-small-model](https://github.com/NinjaSln-labs/vertical-small-model) 项目的 CLI 脚本与模型文件
- `weakSlots` / `strongSlots`:运行时模型槽位候选表,按你想使用的 provider/model 填写
- 路径统一使用 WSL 本地副本(若有);最高优先级为 `cordis.patch.yml` 行内 config,其次为 `settings.yaml`

### 槽位健康缓存(weak-only 换模顺序)

weakSlots 的**配置顺序 ≠ 生效顺序**。插件维护一个持久化健康缓存:

- 缓存文件:`~/.dsh/slm-shadow/slot-order-cache.json`(删除即重建)
- 生效顺序:可用 `free` 槽 → 可用非 free 槽 → 瞬态未知槽(原配置序)→ 死亡槽(沉底)
- 死亡判定:provider 已注销 / 模型实测不可用(404 / NO_ADAPTER 等)→ 沉底
- 刷新时机:启动、`llm/adapters-updated`、24h TTL 过期

## 数据

影子日志写在 `~/.dsh/slm-shadow/session-slm-shadow.jsonl`(一行一条 JSON),字段:

| 字段 | 说明 |
|------|------|
| `v` | schema 版本(当前 1) |
| `ts` | 时间戳 |
| `session_id` | 会话 ID |
| `turn_seq` | 轮次序号 |
| `utterance_hash` | 用户发言 sha256 前 16 位(脱敏) |
| `utterance_preview` | 前 80 字(脱敏) |
| `suggested_tier` | CLI 预测强弱结果 |
| `confidence` | 预测置信度 |
| `actual_tier` | 当前实际模型档位 |
| `switch` | 决策结果:`stay` / `switch_to_weak` / `switch_to_strong` |
| `bound` | weak-only 是否实际换模(shadow 恒 false) |
| `predict_ok` | 预测是否成功 |
| `error` | 预测失败原因摘要 |

## 开发

```bash
git clone https://github.com/NinjaSln-labs/dsh-session-slm-router.git
cd dsh-session-slm-router
npm install --legacy-peer-deps   # peer 由宿主 dsh 提供
npm run build                    # tsc → lib/
npm test                         # node --test(零外部依赖,纯逻辑)
npm run mount                    # 挂载冒烟测试(验证 apply 运行 + 影子管线端到端)
```

## 测试

测试使用 Node 内置 test runner,零外部依赖,不触网:

```bash
npm test
# 23 用例:switch 判定表 / health 标记 / would_bind 语义 / tierOf / extractUtterance / 超时降级
```

## 依赖

- **运行时**:`@deepseek-ai/cordis`(dsh 宿主)
- **外部**:`vertical-small-model` CLI(预测器,需独立部署)
- **开发**:TypeScript + Node 内置 test runner

## 贡献

见 [CONTRIBUTING.md](CONTRIBUTING.md)。

## License

MIT © 2026 ninjasln

Install

dsh plugin --profile web add github:NinjaSln-labs/dsh-session-slm-router#31dcbf96791b9c859fb5ffd4a2b08b7cc20b45e8

Profile: web

  • This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
Source