dsh-zen-free 1.0.3 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
- # dsh-opencode-zen
1
+ # dsh-zen-free
2
2
 
3
- 给 DSH 加一个**免费**供应商 `opencode-zen`,带两个模型:
3
+ 给 DSH 加一个**免费**供应商 `zenfree`,带两个模型:
4
4
 
5
5
  | DSH 模型 id | 上游模型 | 说明 |
6
6
  |---|---|---|
@@ -10,34 +10,76 @@
10
10
  - **不需要 API Key**,不需要账号,不需要 9Router。
11
11
  - **请求强制直连**:不走 `HTTP(S)_PROXY` / `ALL_PROXY`,也不经过 Harness 的全局代理
12
12
  dispatcher —— 本机 Clash(7897)从 CONNECT 隧道打 `opencode.ai` 会 TLS 失败,所以必须绕开。
13
+ - **带设置页**:模型参数(上下文窗口 / 输出上限 / 图片输入)与请求统计都在
14
+ 设置 → 「zenfree 模型」和「zenfree 统计」里。
13
15
 
14
16
  ## 安装
15
17
 
18
+ ### 标准安装(npm 包)
19
+
20
+ GUI 设置 → 插件 → 安装框输入包名 `dsh-zen-free`。
21
+ (`installBundle` 会读本包的 `dsh.bundle.patch` → `cordis.patch.yml`,装完即启用。)
22
+
23
+ 装完在模型选择器里会多出供应商 **zenfree**,下面两个模型。
24
+
16
25
  ### 手工挂载(本地开发)
17
26
 
18
- 1. 把本目录拷进 `$DSH_HOME/profiles/<profile>/node_modules/`(目录名保持 `dsh-opencode-zen`)。
27
+ 1. 把本目录拷进 `$DSH_HOME/profiles/<profile>/node_modules/`(目录名保持 `dsh-zen-free`)。
19
28
  2. 在 `$DSH_HOME/profiles/<profile>/cordis.patch.yml` 末尾追加:
20
29
 
21
30
  ```yaml
22
31
  - insert:
23
- - id: opencode-zen
24
- name: 'dsh-opencode-zen'
32
+ - id: zenfree
33
+ name: 'dsh-zen-free'
25
34
  ```
26
35
 
27
36
  3. 生效:`cordis.patch.yml` 的改动由 HMR 即时生效;**新插件代码**首次加载若未被拾取,
28
37
  关闭并重新打开 DeepSeek Harness。
29
38
 
30
- ### 标准安装(npm 包)
39
+ ## 设置页
31
40
 
32
- GUI 设置 → 插件 → 安装框输入包名 `dsh-opencode-zen`。
33
- (`installBundle` 会读本包的 `dsh.bundle.patch` → `cordis.patch.yml`,装完即启用。)
41
+ ### zenfree 模型
42
+
43
+ 每个模型一张卡片,三个字段:
44
+
45
+ | 字段 | 含义 | 默认 |
46
+ |---|---|---|
47
+ | 上下文窗口 | 该模型声明给 Harness 的上下文长度 | `200000` |
48
+ | 单次输出上限 | `max_tokens` | `32768` |
49
+ | 图片输入 | 是否接受图片(关闭后图片以占位文字发给上游) | 开启 |
50
+
51
+ 改动写入插件的运行期配置,点「保存」立即生效,不用重启。校验从严:非正整数、
52
+ 输出上限大于上下文窗口都会被拒并显示原因。
53
+
54
+ 也可以在 `cordis.patch.yml` 的挂载行直接写配置(页面改的是同一份设置):
55
+
56
+ ```yaml
57
+ - insert:
58
+ - id: zenfree
59
+ name: 'dsh-zen-free'
60
+ config:
61
+ models:
62
+ ds4.1f: { contextWindow: 200000, maxTokens: 32768, input: [text, image] }
63
+ glm5.3f: { contextWindow: 200000, maxTokens: 32768, input: [text] }
64
+ ```
34
65
 
35
- 装完在模型选择器里会多出供应商 **OpenCode Zen(免费)**,下面两个模型。
66
+ `input` 里 `text` 始终保留(没有文本模态的模型在 Harness 里不可用),
67
+ `image` 完全由配置决定。
68
+
69
+ ### zenfree 统计
70
+
71
+ 进程内的请求统计,5 秒自动刷新一次:
72
+
73
+ - 请求总数 / 成功 / 失败 / 输入 tokens / 输出 tokens / 图片数;
74
+ - 按模型分布(请求数、失败数、平均耗时、token 与图片数);
75
+ - 最近 20 次请求明细(时间、模型、结果、耗时、token);
76
+ - 错误码直方图(`RATE_LIMIT` / `TRANSPORT` / `EMPTY_RESPONSE` …)。
77
+
78
+ 数据只在内存里,**进程重启清零** —— 它是「这次用得怎么样」的观察窗,不是持久账单。
36
79
 
37
80
  ## 免费是怎么成立的
38
81
 
39
- OpenCode Zen 的免费池不校验密钥,只校验「你像不像 OpenCode 客户端」。三条准入规则
40
- (全部在客户端复刻,来源见 `../opencode-zen-free/README.md`):
82
+ OpenCode Zen 的免费池不校验密钥,只校验「你像不像 OpenCode 客户端」。三条准入规则:
41
83
 
42
84
  1. `User-Agent` 能解析出 `opencode/<major>.<minor>.<patch>` 且 **≥ 1.18.0**
43
85
  → 本插件固定发 `opencode/1.18.31`。
@@ -57,39 +99,31 @@ OpenCode Zen 的免费池不校验密钥,只校验「你像不像 OpenCode 客
57
99
  `dsh-http-proxy` 安装代理的入口。
58
100
  - 该 Agent 不带任何 `proxy` 选项,只做 TCP/TLS 直连 + keep-alive。
59
101
 
60
- 自检里有一条对照断言:把 `HTTPS_PROXY` / `HTTP_PROXY` / `ALL_PROXY` 全指向
61
- `http://127.0.0.1:7897`(Clash)后,请求依然成功返回文本。
62
-
63
102
  ## 已知限制
64
103
 
65
- - **图片不支持**:两个模型都声明为纯文本路由,图片由 Harness 投影成文本占位符。
66
104
  - **占位 `bash` 工具**:准入只认名字,Harness 在 Windows 上没有 `bash`(只有 `pwsh`)。
67
105
  若模型仍然去调用这个占位工具,Harness 会给出「未知工具」的工具结果。
68
106
  - **限流挂在出口 IP**:免费池按出口 IP / 账号限流,命中时失败码是 `RATE_LIMIT`(429)。
69
- - **地区限制**:部分免费模型(如 `muse-spark-*`)对某些地区返回 `403 RegionError`。
70
- 那与准入门槛无关,是另一道闸。
107
+ - **地区限制**:部分免费模型对某些地区返回 `403 RegionError`。那与准入门槛无关,是另一道闸。
71
108
  - 未列出的模型 id 会**原样透传**到上游,因此也可以手输其它 `-free` 模型。
72
-
73
- ## 自检
74
-
75
- `lib/index.js` 的宿主契约(注册、目录、`resolveModel`、序列化、准入三要素、
76
- StreamChunk 协议、失败码、取消语义)与真实直连端到端共 39 条断言,全部通过:
77
-
78
- ```
79
- ds4.1f → "好的,收到。" finish {kind:'stop'}
80
- glm5.3f → "OK" (HTTPS_PROXY=127.0.0.1:7897 在场) finish {kind:'stop'}
81
- ```
109
+ - 设置页里的模型参数是**运行期配置**,重启 DSH 后回到 `cordis.patch.yml` 里写的值。
110
+ 想永久生效就写进 patch 的 `config`。
82
111
 
83
112
  ## 结构
84
113
 
85
114
  | 文件 | 作用 |
86
115
  |---|---|
87
- | `lib/index.js` | 适配器全部实现(无第三方依赖,只用 `node:https` 与 `node:crypto`) |
116
+ | `lib/index.js` | 适配器 + 设置页的 host 侧服务(无第三方依赖,只用 `node:https` 与 `node:crypto`) |
117
+ | `lib/client.js` | 设置页的浏览器侧(`__ModuleLoader__` 入口,`dsh.client` 声明) |
88
118
  | `cordis.patch.yml` | bundle patch:一条 loader 挂载行 |
89
- | `package.json` | 标准 DSH 插件包契约(`dsh.bundle.patch` + `files` + peer) |
119
+ | `package.json` | 标准 DSH 插件包契约(`dsh.bundle.patch` + `dsh.client` + `files` + peer) |
90
120
 
91
121
  本包**不 import** 任何 `@deepseek-ai/*` 运行时包:第三方插件装在 profile 的
92
122
  `node_modules` 下,解析不到 asar 内的官方包。所需的 `LlmAdapter` 方法形状按契约实现,
93
123
  失败码则通过 Error 上的自有 `code` / `failure` 数据属性给出 —— Harness 的
94
124
  `normalizeLlmFailure` 专门采纳这条跨包副本路径(`AUTH` / `RATE_LIMIT` /
95
125
  `TRANSPORT` / `TIMEOUT` / `ABORTED` …)。
126
+
127
+ 设置页走 typert 的 Remote 通道:host 侧用 `ctx.typert.register()` 写入 invocation
128
+ descriptor 并 `ctx.provide()` 一个带 `typertRemote` 绑定的服务,浏览器侧用同一套
129
+ descriptor 通过 `ctx.remote.$mount()` 消费。两边的 descriptor 必须逐字段一致。
package/cordis.patch.yml CHANGED
@@ -1,10 +1,15 @@
1
1
  # dsh-zen-free bundle patch — one loader entry mounting the plugin package.
2
2
  #
3
3
  # 挂载行是普通的 cordis loader entry(id + 包名)。插件在 apply() 里向 llm
4
- # 服务注册 opencode-zen 路由,因此不需要任何 config。
4
+ # 服务注册 zenfree 路由,因此不需要任何 config。
5
+ #
6
+ # 可选配置(全部可省略):
7
+ # models:
8
+ # ds4.1f: { contextWindow: 200000, maxTokens: 32768, input: [text, image] }
9
+ # glm5.3f: { contextWindow: 200000, maxTokens: 32768, input: [text, image] }
5
10
  #
6
11
  # 手工挂载:把同一行加进 profile 的 cordis.patch.yml。
7
12
  # 标准安装:GUI 插件页安装框(installBundle 会自己读本文件)。
8
13
  - insert:
9
- - id: opencode-zen
14
+ - id: zenfree
10
15
  name: 'dsh-zen-free'