@leonhardthust/dsh-decision-engine 0.0.0-stage → 1.9.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/LICENSE +21 -0
- package/README.md +55 -2
- package/README.zh.md +57 -0
- package/config.example.yml +436 -0
- package/cordis.patch.yml +14 -0
- package/docs/assets/config-page.png +0 -0
- package/docs/assets/decisions-tab.png +0 -0
- package/docs/assets/hero.jpeg +0 -0
- package/docs/assets/stats-charts-preview.png +0 -0
- package/docs/assets/stats-donut-toggle.png +0 -0
- package/docs/assets/stats-interactive-charts.png +0 -0
- package/docs/assets/stats-point-donut.png +0 -0
- package/docs/assets/stats-ranking-bars.png +0 -0
- package/docs/lessons/cloudflare-builds-root-directory.md +51 -0
- package/docs/lessons/cold-start-timeout.md +134 -0
- package/docs/lessons/endpoint-path-vs-model.md +26 -0
- package/docs/lessons/model-field-required-by-provider.md +31 -0
- package/docs/local-dev-link.md +54 -0
- package/docs/releasing.md +67 -0
- package/docs/security-revision.md +130 -0
- package/icon.svg +6 -0
- package/lib/adapters/agent.js +314 -0
- package/lib/adapters/route.js +144 -0
- package/lib/adapters/tools.js +186 -0
- package/lib/adapters/translate.js +143 -0
- package/lib/approval-detail.js +325 -0
- package/lib/client.charts.js +36 -0
- package/lib/client.js +8589 -0
- package/lib/config-file.js +136 -0
- package/lib/credentials.js +187 -0
- package/lib/decision-cache.js +188 -0
- package/lib/decision-points.js +205 -0
- package/lib/decision-store.js +774 -0
- package/lib/endpoint-fallback.js +143 -0
- package/lib/engine.js +312 -0
- package/lib/guard/advisory.js +100 -0
- package/lib/guard/audit.js +79 -0
- package/lib/guard/context.js +128 -0
- package/lib/guard/effects.js +96 -0
- package/lib/guard/fallback.js +139 -0
- package/lib/guard/listener.js +191 -0
- package/lib/guard/policy.js +28 -0
- package/lib/home-paths.js +86 -0
- package/lib/index.js +3823 -0
- package/lib/outcomes.js +169 -0
- package/lib/points/spec.js +645 -0
- package/lib/providers.js +958 -0
- package/lib/resilience.js +308 -0
- package/lib/scope.js +68 -0
- package/lib/server-config.js +351 -0
- package/lib/session-events.js +75 -0
- package/lib/stats-store.js +916 -0
- package/lib/stats.js +1293 -0
- package/lib/telemetry.js +465 -0
- package/lib/tokenizer.js +201 -0
- package/lib/tolerance.js +498 -0
- package/lib/vendor/microcharts-charts.css +47 -0
- package/lib/vendor-src/entry.js +13 -0
- package/lib/vendor-src/jsx-shim.js +34 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +101 -3
- package/scripts/migrate-profile.mjs +102 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 zuosus
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,56 @@
|
|
|
1
|
-
#
|
|
1
|
+
# dsh-decision-engine
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Published fork: **`@leonhardthust/dsh-decision-engine`**. Based on the MIT-licensed upstream by [zuosus](https://github.com/zuosus/dsh-decision-engine). Do not enable both packages at once. See [publishing and installation](docs/releasing.md).
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
**Free decision model usage provided**
|
|
8
|
+
|
|
9
|
+
[website](https://dsh.zuos.us/dsh-decision-engine/) ·
|
|
10
|
+
[config.example.yml](config.example.yml) · [DECISIONS.md](DECISIONS.md)
|
|
11
|
+
|
|
12
|
+
[简体中文](./README.zh.md)
|
|
13
|
+
|
|
14
|
+
A judgement layer for DeepSeek Harness: a cheap decision model judges before the
|
|
15
|
+
main model acts.
|
|
16
|
+
|
|
17
|
+
## Features
|
|
18
|
+
|
|
19
|
+
**Eight decision points**
|
|
20
|
+
|
|
21
|
+
- tool authorization
|
|
22
|
+
- model routing
|
|
23
|
+
- delegation
|
|
24
|
+
- compaction
|
|
25
|
+
- turn continuation
|
|
26
|
+
- retrieval necessity
|
|
27
|
+
- skill selection
|
|
28
|
+
- COT translation gate
|
|
29
|
+
|
|
30
|
+
**Modes**: off · observe · enforce
|
|
31
|
+
|
|
32
|
+
**Providers**: system one · bamboonode · 硅基流动 SiliconFlow (CN / Global) ·
|
|
33
|
+
Perplexity · OpenRouter · custom base URL
|
|
34
|
+
|
|
35
|
+
**Review tolerance**: autonomous · relaxed · default · cautious
|
|
36
|
+
|
|
37
|
+
**UI**: config page with collapsible sections · Decisions tab · stats ·
|
|
38
|
+
readable approval card
|
|
39
|
+
|
|
40
|
+
| Config page | Decisions tab |
|
|
41
|
+
|---|---|
|
|
42
|
+
|  |  |
|
|
43
|
+
|
|
44
|
+
> Screenshots predate the collapsible-section layout (DEC-051).
|
|
45
|
+
|
|
46
|
+
**Token saving**: exact cache · read-only tools bypass · state trimming
|
|
47
|
+
|
|
48
|
+
**Safety layers**: trusted host context → tool effects → mandatory permissions → model advisory → soft review tolerance → host outcome audit.
|
|
49
|
+
Unknown high-impact calls fail closed; Auto still runs decision review. Soft asks use a selected host model (including reasoning effort), the session model, allow, or deny.
|
|
50
|
+
Neither model review nor the allow fallback can replace mandatory approval.
|
|
51
|
+
|
|
52
|
+
See the [security revision and verification notes](docs/security-revision.md). The plugin remains disabled by default; observation mode does not enforce protection.
|
|
53
|
+
|
|
54
|
+
## License
|
|
55
|
+
|
|
56
|
+
MIT
|
package/README.zh.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# dsh-decision-engine
|
|
2
|
+
|
|
3
|
+
本分支发布包:**`@leonhardthust/dsh-decision-engine`**,基于 [zuosus 上游](https://github.com/zuosus/dsh-decision-engine) 的 MIT 代码。不要同时启用原包与本分支;安装与发布方法见 [发布说明](docs/releasing.md)。
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
**提供免费决策模型**
|
|
8
|
+
|
|
9
|
+
[网站](https://dsh.zuos.us/dsh-decision-engine/) ·
|
|
10
|
+
[config.example.yml](config.example.yml) · [DECISIONS.md](DECISIONS.md)
|
|
11
|
+
|
|
12
|
+
[English](./README.md)
|
|
13
|
+
|
|
14
|
+
给 DeepSeek Harness 的决策层:主模型动手之前,用一个便宜的决策小模型做结构化判断。
|
|
15
|
+
|
|
16
|
+
## 功能
|
|
17
|
+
|
|
18
|
+
**八个决策点**
|
|
19
|
+
|
|
20
|
+
- 工具授权
|
|
21
|
+
- 模型路由
|
|
22
|
+
- 子任务分派
|
|
23
|
+
- 上下文压缩
|
|
24
|
+
- 轮次延续
|
|
25
|
+
- 检索必要性
|
|
26
|
+
- 技能选择
|
|
27
|
+
- 思维链翻译
|
|
28
|
+
|
|
29
|
+
**三态**:关闭 · 观察 · 生效
|
|
30
|
+
|
|
31
|
+
**决策服务**:system one · bamboonode · 硅基流动 SiliconFlow(国内 / 国际)·
|
|
32
|
+
Perplexity · OpenRouter · 自定义 base URL
|
|
33
|
+
|
|
34
|
+
**人工审核比例**:自治 · 轻松 · 默认 · 谨慎
|
|
35
|
+
|
|
36
|
+
**界面**:配置页(四个可折叠分组)· 决策历史标签页 · 统计与对比 ·
|
|
37
|
+
审批卡正文可读化
|
|
38
|
+
|
|
39
|
+
| 配置页 | 决策历史 |
|
|
40
|
+
|---|---|
|
|
41
|
+
|  |  |
|
|
42
|
+
|
|
43
|
+
> 截图拍于分组折叠(DEC-051)之前的版式,当前界面为四个可折叠分组。
|
|
44
|
+
|
|
45
|
+
**省 token**:精确缓存 · 只读工具放行 · state 截断
|
|
46
|
+
|
|
47
|
+
**安全分层**:可信宿主上下文 → 工具副作用 → 强制权限策略 → 模型建议 → 软审核容忍度 → 宿主结果审计。
|
|
48
|
+
未知高影响操作不再异常放行;自动审查保留决策模型,并将软性“人工决定”交给所选 Fallback。
|
|
49
|
+
|
|
50
|
+
**自动审查 Fallback**:指定宿主模型(含 reasoning effort)· 沿用会话模型 · 全部允许 · 全部阻止。
|
|
51
|
+
“全部允许”只影响软审查,不能覆盖强制拒绝或必需的真人批准。
|
|
52
|
+
|
|
53
|
+
详见 [安全修订与验证说明](docs/security-revision.md)。默认仍未启用插件,观察模式不提供拦截保护。
|
|
54
|
+
|
|
55
|
+
## 许可证
|
|
56
|
+
|
|
57
|
+
MIT
|
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
# dsh-decision-engine 配置模板
|
|
2
|
+
#
|
|
3
|
+
# 用法:复制到数据目录,按需修改。
|
|
4
|
+
# mkdir -p ~/.dsh/dsh-decision-engine
|
|
5
|
+
# cp config.example.yml ~/.dsh/dsh-decision-engine/config.yml
|
|
6
|
+
#
|
|
7
|
+
# 文件名是 config.yml:本插件早已不是「只服务 startlux 一家」的插件,
|
|
8
|
+
# 而是任意决策服务(system one / bamboonode / 硅基流动 / custom)的决策层,
|
|
9
|
+
# 名字里再挂某个服务商只会误导。旧名 startlux.yml 仍会被自动读取并迁移,
|
|
10
|
+
# 升级不需要重新填 key。
|
|
11
|
+
#
|
|
12
|
+
# 插件按以下顺序找配置,取第一个存在的:
|
|
13
|
+
# ~/.dsh/dsh-decision-engine/config.yml (首选位置)
|
|
14
|
+
# ~/.dsh/dsh-decision-engine/startlux.yml (旧名,首次启动自动改名)
|
|
15
|
+
# ~/.dsh/dsh-startlux-decision/startlux.yml (上一代数据目录;自动拷到新目录)
|
|
16
|
+
# ~/.dsh/plugins/dsh-startlux-decision/startlux.yml
|
|
17
|
+
# ~/.dsh/plugins/dsh-startlux-guard/startlux.yml
|
|
18
|
+
#
|
|
19
|
+
# 数据目录(插件自动读取):
|
|
20
|
+
# <上述目录>/config.yml 配置
|
|
21
|
+
# <上述目录>/telemetry.jsonl 决策记录(人读的流水账)
|
|
22
|
+
# <上述目录>/stats.jsonl 统计记录(配置页「统计与对比」读它)
|
|
23
|
+
# <上述目录>/analytics.json 匿名统计的本地状态(安装 id,可删除以重置)
|
|
24
|
+
#
|
|
25
|
+
# stats.jsonl 记的是按 provider × model 分开的 token 与耗时,用于统计与
|
|
26
|
+
# 节省量对比;telemetry.jsonl 不含 provider 与 output token,满足不了统计
|
|
27
|
+
# 所需,因此两者分开存。两者都是追加写的 JSON Lines,可直接 tail 查看。
|
|
28
|
+
#
|
|
29
|
+
# 改完立即生效:每次工具调用 / 每一步前都会检查 mtime,无需重启 DSH。
|
|
30
|
+
|
|
31
|
+
# 总开关:true 才开始工作(默认 false,不会擅自介入你的会话)
|
|
32
|
+
enabled: false
|
|
33
|
+
|
|
34
|
+
# shadow = 只记录判断结果,绝不拦截(建议先用它观察一段时间)
|
|
35
|
+
# enforce = 真正执行各决策点的处置
|
|
36
|
+
#
|
|
37
|
+
# 注意:这一项现在只是「工具授权」这一个决策点的历史开关。
|
|
38
|
+
# 新写法是给每个决策点单独指定模式,见下面的 pointXxx。
|
|
39
|
+
# pointAuthorize 留 auto 时,就沿用这里的 mode(shadow→observe、enforce→enforce)。
|
|
40
|
+
mode: shadow
|
|
41
|
+
|
|
42
|
+
# ============================================================================
|
|
43
|
+
# 服务提供方(provider)
|
|
44
|
+
# ============================================================================
|
|
45
|
+
# 七选一:
|
|
46
|
+
# bamboonode 内置。StartLux 官方端点 POST /v1/decisions,本插件的原有默认值。
|
|
47
|
+
# systemone 内置。任意 System One 协议服务 POST /v1/systemone,
|
|
48
|
+
# 默认指向 TypeSafe(https://api.typesafe.ai/v1)。
|
|
49
|
+
# siliconflow 内置。硅基流动(国内站)https://api.siliconflow.cn/v1/systemone
|
|
50
|
+
# siliconflow-intl 内置。Silicon Flow 国际站 https://api.siliconflow.com/v1/systemone
|
|
51
|
+
# (与国内站是两套账号,key 互不通用)
|
|
52
|
+
# perplexity 内置。Perplexity Decider(api.perplexity.ai);
|
|
53
|
+
# 地址与默认模型待实测,端点风格 auto(404 自动换路径重试)
|
|
54
|
+
# openrouter 内置。OpenRouter(https://openrouter.ai/api/v1),
|
|
55
|
+
# 模型填 OpenRouter 的 slug(如 openai/gpt-4o-mini);同样待实测
|
|
56
|
+
# custom 自己填 base URL,接任何提供决策端点的服务
|
|
57
|
+
# (自建 llama.cpp / vLLM、企业网关、第三方中转)。
|
|
58
|
+
#
|
|
59
|
+
# 不写这一项 = bamboonode,老配置行为完全不变。
|
|
60
|
+
#
|
|
61
|
+
# siliconflow / siliconflow-intl 是「开箱即用」的:地址、路径、默认模型都已
|
|
62
|
+
# 预置,只要粘一个 API key 就能跑(详见下方「密钥」一节)。
|
|
63
|
+
#
|
|
64
|
+
# perplexity / openrouter 也已预置,但**端点风格与默认模型尚未实测**(接入时
|
|
65
|
+
# 按各家公开 API 地址写的):首次使用若 404,插件会自动换另一条路径重试;
|
|
66
|
+
# 跑通后建议把实测结论写回 lib/providers.js 的预设表。
|
|
67
|
+
provider: bamboonode
|
|
68
|
+
|
|
69
|
+
# ---- bamboonode 预设的地址覆盖 ----------------------------------------------
|
|
70
|
+
# 只在 provider=bamboonode 时生效。老版本唯一的地址字段,继续支持,因此
|
|
71
|
+
# 已有的自建 bamboonode 兼容地址不会因为升级被改回官方。
|
|
72
|
+
# 接受多种写法(等价):
|
|
73
|
+
# https://api.bamboonode.dev/v1
|
|
74
|
+
# https://api.bamboonode.dev/v1/decisions
|
|
75
|
+
# api.bamboonode.dev/v1 (会补 https://)
|
|
76
|
+
# 末尾斜杠会被规范化,不会拼出 //decisions 或 /v1/v1/decisions。
|
|
77
|
+
baseUrl: https://api.bamboonode.dev/v1
|
|
78
|
+
|
|
79
|
+
# ---- 模型(按 provider 分开存,切换时互不覆盖)------------------------------
|
|
80
|
+
# bamboonode 的模型。留空 = 自动(由服务端选当前默认决策模型),
|
|
81
|
+
# 这样服务商将来换模型名时,本配置不会失效。
|
|
82
|
+
model:
|
|
83
|
+
|
|
84
|
+
# system one 的模型。留空 = 服务端默认(jev-latest)。
|
|
85
|
+
# 与上面的 model 分开:否则切到 system one 会把 bamboonode 的模型名发过去,
|
|
86
|
+
# 得到 400 model not served。
|
|
87
|
+
systemoneModel: ""
|
|
88
|
+
|
|
89
|
+
# 硅基流动 / Silicon Flow 的模型。**留空 = 用预设默认 Kev-4B**——
|
|
90
|
+
# 这两个端点把 model 列为必填(实测省略或空串都回 400
|
|
91
|
+
# "Model field is required."),所以这里的「留空」不是「让服务端挑」,
|
|
92
|
+
# 而是用预设默认。想换模型就填 SemIf(官方目前只支持这两个决策模型)。
|
|
93
|
+
#
|
|
94
|
+
# 你写的 kev-4b 与 Kev-4B 是同一个模型:实测该端点对大小写不敏感
|
|
95
|
+
#(三种写法都 200),/v1/models 里的规范写法是 Kev-4B。
|
|
96
|
+
siliconflowModel: ""
|
|
97
|
+
siliconflowIntlModel: ""
|
|
98
|
+
|
|
99
|
+
# ---- custom 预设(provider=custom 时才生效)--------------------------------
|
|
100
|
+
# base URL 必填,且必须是 http/https 地址;不带 scheme 会被拒绝(内置预设
|
|
101
|
+
# 允许省略 scheme,custom 不允许——自定义地址必须显式,避免猜错协议)。
|
|
102
|
+
# customBaseUrl: https://api.example.com/v1
|
|
103
|
+
#
|
|
104
|
+
# 端点风格(**首选**路径,不是唯一路径):
|
|
105
|
+
# auto 地址已带 /decisions 或 /systemone 就原样用,否则先试 decisions
|
|
106
|
+
# decisions 先试 POST <base>/decisions
|
|
107
|
+
# systemone 先试 POST <base>/systemone
|
|
108
|
+
#
|
|
109
|
+
# 路径后缀由**服务商**决定,不由模型决定。实测(2026-10-25,真实端点):
|
|
110
|
+
# SiliconFlow 的 Kev-4B /v1/decisions → 404,/v1/systemone → 200
|
|
111
|
+
# bamboonode 的决策模型 两条路径都 200
|
|
112
|
+
#
|
|
113
|
+
# 所以首选路径返回 404 时,插件会自动改用另一条再试一次,并记住试通的那条。
|
|
114
|
+
# 只有 404 会触发换路径:400(模型/内容不合法)与 401(key 不对)都跟路径无关。
|
|
115
|
+
customEndpointStyle: auto
|
|
116
|
+
#
|
|
117
|
+
# custom 自己的模型(留空 = 服务端默认)。与内置预设的 model 分开存,
|
|
118
|
+
# 这样在两者之间来回切换不会互相覆盖。
|
|
119
|
+
customModel: ""
|
|
120
|
+
# custom 的 key;留空则读 customApiKeyEnv(环境变量或 .credentials.yaml 的 refs)
|
|
121
|
+
customApiKey: ""
|
|
122
|
+
customApiKeyEnv: ""
|
|
123
|
+
# 附加请求头,格式 `名称: 值`,多项用分号分隔。
|
|
124
|
+
# authorization / content-type / host 由插件固定,写了也会被忽略。
|
|
125
|
+
customHeaders: ""
|
|
126
|
+
|
|
127
|
+
# ============================================================================
|
|
128
|
+
# 密钥
|
|
129
|
+
# ============================================================================
|
|
130
|
+
# 每个 provider 有**自己的** key 名,各自保存各自的 key:
|
|
131
|
+
#
|
|
132
|
+
# system one -> TYPESAFE_API_KEY
|
|
133
|
+
# bamboonode -> BAMBOO_API_KEY
|
|
134
|
+
# 硅基流动(国内站) -> SILICONFLOW_API_KEY
|
|
135
|
+
# Silicon Flow 国际站 -> SILICONFLOW_INTL_API_KEY
|
|
136
|
+
# Perplexity Decider -> PERPLEXITY_API_KEY
|
|
137
|
+
# OpenRouter -> OPENROUTER_API_KEY
|
|
138
|
+
# custom -> customApiKeyEnv(没填时用 DECISION_ENGINE_CUSTOM_KEY)
|
|
139
|
+
#
|
|
140
|
+
# 各格互不覆盖,可以同时配好;切换 provider 不会串用别人的 key。
|
|
141
|
+
# 两个 SiliconFlow 站点是**两套账号**,key 不通用,因此各占一格——
|
|
142
|
+
# 共用一格的话,切过去就会拿错 key 得到 401,而用户看不出是拿错了还是失效了。
|
|
143
|
+
|
|
144
|
+
# 密钥存到哪里:
|
|
145
|
+
# credentials = ~/.dsh/.credentials.yaml 的 refs 段(默认,与其他服务统一托管)
|
|
146
|
+
# config = 本文件(自包含,便于随目录备份;注意这里是明文)
|
|
147
|
+
# 配置页上这一项不挨着 API Key,而是放在最后一组(匿名统计之后):它管的是
|
|
148
|
+
# 「key 存到哪」这件账务上的事,不是连接本身,夹在连接组里会打断
|
|
149
|
+
# 「provider → 模型 → key → 生效端点」这条阅读线。
|
|
150
|
+
keyStorage: credentials
|
|
151
|
+
|
|
152
|
+
# 变量名可以覆盖(留空即用上面的默认名):
|
|
153
|
+
# systemoneApiKeyEnv: ""
|
|
154
|
+
# bamboonodeApiKeyEnv: ""
|
|
155
|
+
# siliconflowApiKeyEnv: ""
|
|
156
|
+
# siliconflowIntlApiKeyEnv: ""
|
|
157
|
+
# perplexityApiKeyEnv: ""
|
|
158
|
+
# openrouterApiKeyEnv: ""
|
|
159
|
+
# customApiKeyEnv: ""
|
|
160
|
+
|
|
161
|
+
# 直接写明文 key 也可以(各 provider 一格,互不影响)。
|
|
162
|
+
# 若 keyStorage=credentials,在设置界面粘贴的 key 会写进 .credentials.yaml,
|
|
163
|
+
# 不会落到这里;只有 keyStorage=config 时下面这些字段才会被写入。
|
|
164
|
+
# systemoneApiKey: ""
|
|
165
|
+
# bamboonodeApiKey: ""
|
|
166
|
+
# siliconflowApiKey: ""
|
|
167
|
+
# siliconflowIntlApiKey: ""
|
|
168
|
+
# perplexityApiKey: ""
|
|
169
|
+
# openrouterApiKey: ""
|
|
170
|
+
# customApiKey: ""
|
|
171
|
+
|
|
172
|
+
# .credentials.yaml 里的形态就是 refs 段:
|
|
173
|
+
# refs:
|
|
174
|
+
# BAMBOO_API_KEY: sk-你的key
|
|
175
|
+
# TYPESAFE_API_KEY: sk-另一个key
|
|
176
|
+
# SILICONFLOW_API_KEY: sk-国内站的key
|
|
177
|
+
# SILICONFLOW_INTL_API_KEY: sk-国际站的key
|
|
178
|
+
# PERPLEXITY_API_KEY: sk-perplexity的key
|
|
179
|
+
# OPENROUTER_API_KEY: sk-openrouter的key
|
|
180
|
+
|
|
181
|
+
# ============================================================================
|
|
182
|
+
# 服务端下发(DEC-030)——配置页上叫「使用免费模型」
|
|
183
|
+
# ============================================================================
|
|
184
|
+
# 打开后,地址 / 模型 / key 由内置端点 https://dsh.zuos.us/api/provider-config
|
|
185
|
+
# 下发并直接使用。**地址不可配置**是刻意的:它就是「开箱即用」的全部含义。
|
|
186
|
+
#
|
|
187
|
+
# 名字为什么是「使用免费模型」而不是「跟随服务端下发」:它确实是免费下发的模型,
|
|
188
|
+
# 那是用户能直接感知到的事实;而配置页在这行说明下面还多一行小字「可能会失效」
|
|
189
|
+
# ——这条免费通道由项目方自掏额度维护,随时可能停用或换 key。风险写在界面上,
|
|
190
|
+
# 不给「免费」一个不存在的承诺。开关默认仍为 false,行为与改名前完全一样。
|
|
191
|
+
#
|
|
192
|
+
# 关于下发的那把 key(重要):
|
|
193
|
+
# - 只保存在插件进程的内存里,**永不落盘**:不写本文件、不写 .credentials.yaml、
|
|
194
|
+
# 不进遥测 / 统计 / 决策明细;任何接口只回传末四位(…abcd)。
|
|
195
|
+
# - 进程退出即消失,下次启动重新获取(下发带 TTL,默认 600 秒)。
|
|
196
|
+
# - 关掉这个开关会立刻把它从内存里清掉。
|
|
197
|
+
#
|
|
198
|
+
# 服务端不可用时(404 / 403 / 超时 / 载荷非法 / 已过期且刷新失败)**静默回落到下面的
|
|
199
|
+
# 本地配置**(包括你自己填的 key),配置页显示一行原因,不会中断守卫。
|
|
200
|
+
#
|
|
201
|
+
# 手动填 key 的整套流程完全不变;服务端生效期间本地值只是暂不生效,关掉开关立刻恢复。
|
|
202
|
+
#
|
|
203
|
+
# 可选门禁:Worker 侧若设了 PROVIDER_CONFIG_TOKEN,本机要能读到同一把令牌——
|
|
204
|
+
# 优先环境变量 DECISION_SERVER_CONFIG_TOKEN,其次下方 .credentials.yaml 的 refs 段同名键。
|
|
205
|
+
serverProvider: false
|
|
206
|
+
|
|
207
|
+
# 超时预算(毫秒)。超时仅使模型建议失效,强制策略仍生效;连续失败进入冷却。
|
|
208
|
+
#
|
|
209
|
+
# 为什么是 20000 而不是 8000:这个服务端有**冷启动尾延迟**。闲置约 110 秒后的
|
|
210
|
+
# 首发实测要 7.4–15.9 秒,焐热之后只要 1.0–1.3 秒。8 秒会把冷启动首发**稳定
|
|
211
|
+
# 误杀**,而那恰好是用户点「测试」时的常态——每次点都落在「闲置后首发」这个
|
|
212
|
+
# 最差点上。成功请求的延迟分布(n=2215)里 ≥8s 占 **0%**:不是没有慢请求,
|
|
213
|
+
# 是慢的那些全被 8 秒预算掐掉了,根本没算进成功。
|
|
214
|
+
# 代码里的 DEFAULT_TIMEOUT_MS 本来就是 20000,模板这里只是跟上。
|
|
215
|
+
timeoutMs: 20000
|
|
216
|
+
|
|
217
|
+
# 超时 / 网络错误的重试次数。**只对这两类重试**:4xx 是配置错(地址、模型、
|
|
218
|
+
# key),5xx 是服务端自己的故障,重试只是多烧一次额度、拿回同一个错误。
|
|
219
|
+
# 实测:冷启动首发被掐断时服务端其实已经被焐热,第二发 1.1–1.7 秒必中
|
|
220
|
+
# (4 组独立实验一致)。总预算封顶 min(2 × timeoutMs, 30s)。
|
|
221
|
+
retryAttempts: 1
|
|
222
|
+
|
|
223
|
+
# 冷却期的试探间隔(毫秒)。冷却不再是「整段全黑」:每隔这么久放行一次试探
|
|
224
|
+
# 请求,成功即彻底恢复。避免一次 3 秒的抖动换来 60 秒完全不工作。
|
|
225
|
+
cooldownProbeMs: 10000
|
|
226
|
+
|
|
227
|
+
# ---- 冷却与失败阈值(可选调优项)----
|
|
228
|
+
# 冷却已改为**半开 + 指数退避**:连续失败达到阈值进入冷却,冷却中每
|
|
229
|
+
# cooldownProbeMs 放行一次试探;试探失败则冷却时长按轮次翻倍
|
|
230
|
+
# (cooldownMs → 2× → 4× …,封顶 10 × cooldownMs),试探成功即彻底解除。
|
|
231
|
+
# 注意 cooldownMs 现在是**首轮**冷却时长,不再是上限——上限是它的 10 倍。
|
|
232
|
+
# cooldownMs: 60000 # 首轮冷却时长(上限为其 10 倍)
|
|
233
|
+
# failureThreshold: 3 # 连续失败多少次进入冷却
|
|
234
|
+
|
|
235
|
+
# 思考模式(startlux 的 think_mode),三档:
|
|
236
|
+
# never 不思考——最省延迟(实测约 1.9s vs 7.2s),默认值,热路径首选
|
|
237
|
+
# auto 仅在模型自己判断需要时思考——折中
|
|
238
|
+
# always 总是思考——判断更充分,但每次工具调用约多等 5 秒
|
|
239
|
+
# 该端点 output_tokens 恒为 0,思考开销不计入计量,所以省的主要是延迟。
|
|
240
|
+
thinkMode: never
|
|
241
|
+
|
|
242
|
+
# ============================================================================
|
|
243
|
+
# 决策模型参与点
|
|
244
|
+
# ============================================================================
|
|
245
|
+
# 三态:off 不参与 / observe 只记录不干预 / enforce 真正生效。
|
|
246
|
+
# 九个点全部已实装。新点默认 off —— 升级不会改变现有行为。
|
|
247
|
+
#
|
|
248
|
+
# 建议:先 observe 跑一段时间,对着 telemetry.jsonl 确认与人工判断一致,
|
|
249
|
+
# 再逐点切 enforce。热路径的点(route / delegate / cotTranslate)尤其如此。
|
|
250
|
+
|
|
251
|
+
# ---- 1. 工具授权:每次工具调用前判断能否放行 -------------------------------
|
|
252
|
+
# 替代 auto-review——后者把完整会话历史发给主模型,每次调用都跑一遍。
|
|
253
|
+
pointAuthorize: auto
|
|
254
|
+
|
|
255
|
+
# ---- 2. 模型路由:机械步骤下沉到便宜模型 -----------------------------------
|
|
256
|
+
# 热路径。三道闸控量:每轮最多 routeMaxStepsPerTurn 步、路由未变不问、
|
|
257
|
+
# 新用户输入后的步骤不问。
|
|
258
|
+
# 必须同时配好 routeCheapProvider + routeCheapModel 才会真的换模型;
|
|
259
|
+
# 两者留空时即便打开此点也只会记录「本该换」。
|
|
260
|
+
pointRoute: off
|
|
261
|
+
routeCheapProvider: ""
|
|
262
|
+
routeCheapModel: ""
|
|
263
|
+
# routeMaxStepsPerTurn: 3
|
|
264
|
+
# routeMaxScore: 0.4 # 能力需求归一化后超过此值就保留强模型
|
|
265
|
+
# routeMechanicalFloor: 0.6 # 「机械步骤」的最低置信
|
|
266
|
+
# routeRiskFloor: 0.3 # 风险达线一律保留强模型
|
|
267
|
+
|
|
268
|
+
# ---- 3. 子任务分派:接着做 / 开 subagent / 组 agent team -------------------
|
|
269
|
+
# 热路径。只在每轮第一步且带新用户输入时判断(分派只在这一刻可能改变)。
|
|
270
|
+
# 生效时注入一条提示,不替模型决定——工具选择仍归模型。
|
|
271
|
+
pointDelegate: off
|
|
272
|
+
# delegateConfidenceFloor: 0.5 # 三选项均分 0.33,实测需 ≥0.5 才算有倾向
|
|
273
|
+
# delegateBlockingFloor: 0.6 # 被本地事实阻塞时继续内联
|
|
274
|
+
# delegateParallelFloor: 0.5 # 组队还需真并行才有意义
|
|
275
|
+
|
|
276
|
+
# ---- 4. 上下文压缩:摘要 vs 只丢陈旧工具结果 -------------------------------
|
|
277
|
+
# 非热路径。只在实测 token 达触发线(compactThresholdRatio × 窗口)才问。
|
|
278
|
+
# 生效方式:先跑宿主的确定性工具结果裁剪;compaction-basic 随后重新测压,
|
|
279
|
+
# 低于阈值就跳过摘要——这才是真正省下的那一次调用。
|
|
280
|
+
pointCompact: off
|
|
281
|
+
# compactContextWindow: 0 # 0 = 用 compactTriggerTokens 绝对阈值
|
|
282
|
+
# compactThresholdRatio: 0.7 # 提前于 compaction-basic 的 0.8 介入
|
|
283
|
+
# compactTriggerTokens: 100000
|
|
284
|
+
# compactToolResultChars: 8192
|
|
285
|
+
# compactDistilledFloor: 0.6 # 结论已落地 → 允许只裁剪
|
|
286
|
+
# compactVerbatinFloor: 0.6 # 仍需逐字原文 → 一律摘要(安全否决优先)
|
|
287
|
+
|
|
288
|
+
# ---- 5. 轮次延续:再来一轮有没有增量价值 -----------------------------------
|
|
289
|
+
# 非热路径。生效方式是用 agent.steer() 续一轮,每轮最多 turnStopMaxSteers 次。
|
|
290
|
+
pointTurnStop: off
|
|
291
|
+
# turnStopMaxSteers: 1
|
|
292
|
+
# turnStopClosedFloor: 0.6
|
|
293
|
+
# turnStopUnfinishedFloor: 0.6
|
|
294
|
+
# turnStopValueFloor: 0.35 # 只作弱确认;主判据是 unfinished
|
|
295
|
+
# 「这一轮在等用户」的判定门槛(DEC-045)。达线即让位:不续轮,把决定权交还用户。
|
|
296
|
+
# 这条只用于**让位**,不会变成「所以替你选了方案 A」。
|
|
297
|
+
# 取 0.5 是因为两类错代价不对等:漏判 = 替你把选择顶掉(最不该犯的错),
|
|
298
|
+
# 误判 = 少续一轮(代价小得多)。
|
|
299
|
+
# turnStopAwaitingUserFloor: 0.5
|
|
300
|
+
|
|
301
|
+
# ---- 6. 检索必要性:这条信息是不是已经知道 ---------------------------------
|
|
302
|
+
# 非热路径。只对检索类工具生效,其余工具零开销。
|
|
303
|
+
pointRetrieval: off
|
|
304
|
+
# retrievalTools: [web_search, web_fetch, research, multi_search, advanced_search]
|
|
305
|
+
# retrievalCoveredFloor: 0.5 # 上下文已覆盖该事实
|
|
306
|
+
# retrievalWouldAddCeiling: 0.8 # 且再搜基本没有新信息
|
|
307
|
+
|
|
308
|
+
# ---- 7. 技能选择:该装哪个技能 ---------------------------------------------
|
|
309
|
+
# 非热路径。只对 skill 工具、且候选 ≥2 时判断。
|
|
310
|
+
# 生效时拦下不匹配的加载并指路,避免「装错再换」付两遍正文 token。
|
|
311
|
+
pointSkillPick: off
|
|
312
|
+
# skillPickCandidates: 8 # 送给模型挑选的候选上限(只带名称+描述)
|
|
313
|
+
# skillPickConfidenceFloor: 0.5
|
|
314
|
+
|
|
315
|
+
# ---- 8. 思维链翻译门槛:这条内容真的需要翻译吗 -----------------------------
|
|
316
|
+
# 热路径(每条消息)。本地先做免费预筛(去代码块/URL 后判断有无正文),
|
|
317
|
+
# 预筛不过的直接跳过,不发请求。生效时判为「不需要」则返回原文。
|
|
318
|
+
pointCotTranslate: off
|
|
319
|
+
# cotProseFloor: 0.5
|
|
320
|
+
# cotSameLanguageFloor: 0.8
|
|
321
|
+
|
|
322
|
+
# ============================================================================
|
|
323
|
+
# 自身开销护栏
|
|
324
|
+
# ============================================================================
|
|
325
|
+
# 决策模型自己也烧 token(实测约 1.9k/次,p50 约 0.5s),靠缓存挡住重复调用:
|
|
326
|
+
# 命中缓存就不发请求。本插件不限制每小时的总用量,因此没有预算字段。
|
|
327
|
+
# 「同类复用」软层默认关闭(fail-closed),工具授权点永久禁用;
|
|
328
|
+
# cacheSize / cacheTtlMs 同时约束精确层与(显式启用后的)软层。
|
|
329
|
+
|
|
330
|
+
# ---- 以下为可选调优项 ----
|
|
331
|
+
# cacheSize: 256 # 缓存条数上限
|
|
332
|
+
# cacheTtlMs: 600000 # 裁决存活时间
|
|
333
|
+
# recentMessages: 4 # 带给模型的上下文条数
|
|
334
|
+
# guardReadOnlyTools / guardExcludeTools / guardDeferOutsideWorkspace 保留旧键解析,
|
|
335
|
+
# 不再是绕过强制安全策略的白名单;越界写入不能无条件交给宿主。
|
|
336
|
+
# guardDenyConfidence 不再参与新授权策略。confidence 不能充当危险概率。
|
|
337
|
+
# guardIrreversibleCeiling: 0.2
|
|
338
|
+
# guardTaskRelevanceFloor: 0.5
|
|
339
|
+
|
|
340
|
+
# 新策略默认 enforce;observe 仅用于隔离对照诊断,不实施 mandatory 拦截。
|
|
341
|
+
# 只有 enabled=true、guardEnabled=true、pointAuthorize=enforce 才真正拦截。
|
|
342
|
+
guardPolicyMode: enforce
|
|
343
|
+
|
|
344
|
+
# 自动审查(宿主 auto 或 tolerance=autonomous)的软性 ask 和建议失败时:
|
|
345
|
+
# model 指定宿主注册的 provider / model / reasoning effort
|
|
346
|
+
# session 沿用当前会话 request/header 的模型和 reasoning effort(默认)
|
|
347
|
+
# allow 跳过软审查,仍不可覆盖 mandatory deny / requires_approval
|
|
348
|
+
# deny 阻止软审查请求
|
|
349
|
+
# 指定模型不可用、超时、响应非法一律拒绝,不再嵌套回退成 allow。
|
|
350
|
+
guardFallback: session
|
|
351
|
+
guardFallbackProvider: ""
|
|
352
|
+
guardFallbackModel: ""
|
|
353
|
+
guardFallbackReasoningEffort: ""
|
|
354
|
+
|
|
355
|
+
# 四档只调整软审核摩擦。mandatory deny 全档不变;requires_approval 必须
|
|
356
|
+
# 获得当前调用的宿主 allowed-once,无审批通道时拒绝,模型不能代批。
|
|
357
|
+
# autonomous 将软 ask 交给上述 Fallback,不等于直接放行。
|
|
358
|
+
# relaxed / default / cautious 保留既有软摩擦档位行为;旧默认裁决函数
|
|
359
|
+
# decideGuardLegacy 仅用于回放,不接入生产权限路径。
|
|
360
|
+
# severity 是排序分数,分位数就绪不代表危险概率已校准。
|
|
361
|
+
# tolerance: default
|
|
362
|
+
|
|
363
|
+
# ============================================================================
|
|
364
|
+
# 匿名使用统计(可选)
|
|
365
|
+
# ============================================================================
|
|
366
|
+
# 只上报「装了多少台、每天有多少人在用」,用来改进插件。字段只有七个:
|
|
367
|
+
# 匿名安装 id(首次运行随机生成的 UUIDv4,与账号无关)、插件版本、平台、
|
|
368
|
+
# 架构、宿主版本、当日决策数、事件类型。
|
|
369
|
+
#
|
|
370
|
+
# 绝不上报:API key、prompt / 工具参数、文件路径、provider 地址、会话内容、
|
|
371
|
+
# 用户名;服务端也不记录 IP。删掉 analytics.json 即换新身份。
|
|
372
|
+
#
|
|
373
|
+
# off 完全联网都不做(连版本检查都没有)
|
|
374
|
+
# install 仅首次运行上报一次「装了」
|
|
375
|
+
# daily 每天上报一次,附带当日决策数(默认)
|
|
376
|
+
#
|
|
377
|
+
# telemetryLevel: daily
|
|
378
|
+
# telemetryEndpoint: "" # 留空用内置端点
|
|
379
|
+
|
|
380
|
+
# ============================================================================
|
|
381
|
+
# 决策历史(DEC-022)——会话里的「决策历史」标签页
|
|
382
|
+
# ============================================================================
|
|
383
|
+
# 开启后,会话标签栏会在「对话」「轨迹」之后多出一个「决策历史」标签页,
|
|
384
|
+
# 按时间列出**本会话**里经本插件做出的每一次决策:决策点、provider、
|
|
385
|
+
# model、裁决、耗时、token,展开还能看到发给决策模型的现场(state)、
|
|
386
|
+
# 问题(questions)与它回来的回答(answers)。
|
|
387
|
+
#
|
|
388
|
+
# 数据只落在本机 $DSH_HOME/dsh-decision-engine/decisions.jsonl,
|
|
389
|
+
# **不经过任何网络请求**,也**不进**上面的匿名统计。
|
|
390
|
+
#
|
|
391
|
+
# 关掉之后**完全不写这个文件**(不采集内容、不占磁盘,标签页也随之消失)
|
|
392
|
+
# ——不是「写了藏起来」。明细里可能有会话正文与命令片段,用户说不记录
|
|
393
|
+
# 就该真的不落盘。
|
|
394
|
+
#
|
|
395
|
+
# decisionsTabEnabled: true # 默认开启;**这是唯一的开关**(DEC-026 / DEC-029):
|
|
396
|
+
# 开 = 记录明细,且**一定记录决策内容**;
|
|
397
|
+
# 关 = 完全不写 decisions.jsonl(见上),
|
|
398
|
+
# 没有「只存元数据」的中间档。
|
|
399
|
+
#
|
|
400
|
+
# 下面两项是**高级档位**,配置页上没有对应的开关:需要时手改本文件。
|
|
401
|
+
# (一个开关管「这个功能要不要用」就够了;「记多细、最多占多大」是要主动
|
|
402
|
+
# 去调的旋钮,不该天天摆在配置页上。)
|
|
403
|
+
#
|
|
404
|
+
# 单条内容的上限(字符)。超出时依次裁剪:工具参数预览 → 最近对话摘要 →
|
|
405
|
+
# 整个 state;只有连「问题 + 回答」都装不下时才退回只留元数据。
|
|
406
|
+
#
|
|
407
|
+
# decisionsMaxContentChars: 4000
|
|
408
|
+
#
|
|
409
|
+
# 明细文件体积上限(字节)。到顶轮转成 decisions.jsonl.1(只留一代),
|
|
410
|
+
# 因此磁盘占用最多约两倍上限。
|
|
411
|
+
#
|
|
412
|
+
# decisionsMaxBytes: 8388608 # 8 MB
|
|
413
|
+
|
|
414
|
+
# ============================================================================
|
|
415
|
+
# 审批卡正文可读化(DEC-043)——审批卡上那块命令怎么显示
|
|
416
|
+
# ============================================================================
|
|
417
|
+
# 默认**开启**,不需要做任何事就能得到:插件接管宿主的
|
|
418
|
+
# conversation.approval.detail,把标题下那块命令改成「摘要 + 可展开的原文」——
|
|
419
|
+
# 先说清「几步、其中哪几步是危险动作」(rm -rf / curl … | sh / sudo 这类会被
|
|
420
|
+
# 标出来),再逐条列出每个步骤;原文默认收起,点开可逐字核对。
|
|
421
|
+
#
|
|
422
|
+
# 摘要由**确定性规则**切分(&& / || / ; / | / 换行,heredoc 整段识别成「执行
|
|
423
|
+
# 一段脚本(N 行)」),**不经过决策模型**——端点只有 choice / score / noul
|
|
424
|
+
# 三种题型、没有自由文本,让模型写一句人话解释在架构上做不到。
|
|
425
|
+
#
|
|
426
|
+
# **真正执行的永远是原文**。摘要只是导读,与原文不一致就是欺骗,所以原文
|
|
427
|
+
# 永远可展开核对。
|
|
428
|
+
#
|
|
429
|
+
# 想保留宿主自己的样子就关掉这一项:关 = 完全不接管,宿主自己的渲染原样回来,
|
|
430
|
+
# 与 1.5.x 逐字一致(换行照旧由宿主折叠成一个长条)。
|
|
431
|
+
#
|
|
432
|
+
# 一句实话:接管这块意味着宿主将来对它的改进**不会自动落到我们这里**,直到我们
|
|
433
|
+
# 跟上;步骤清单本身是启发式的(刻意不做完整 shell 解析)。这两点是「保留这个
|
|
434
|
+
# 开关、并让原文永远可展开」的理由,不是把可读卡片藏起来的理由。
|
|
435
|
+
#
|
|
436
|
+
# approvalDetailReadable: true # 默认开启;关掉则完全沿用宿主渲染
|
package/cordis.patch.yml
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# dsh-decision-engine 的 bundle 层。
|
|
2
|
+
#
|
|
3
|
+
# 这里**刻意不写 config**。
|
|
4
|
+
#
|
|
5
|
+
# 原因:bundle patch 属于 profile 配置层,而 DSH 传给插件 apply() 的 config
|
|
6
|
+
# 是 Schemastery 解析后的完整默认值(enabled:false / mode:shadow ...),
|
|
7
|
+
# 并非用户显式配置。若在此硬编码,会盖掉用户在配置页保存的选择,
|
|
8
|
+
# 表现为「一按保存就自动弹回关闭」。
|
|
9
|
+
#
|
|
10
|
+
# 运行时配置的唯一来源是插件目录下的 config.yml(配置页保存的也是它)。
|
|
11
|
+
# 插件内的 DEFAULTS 只负责兜底,不在此重复声明。
|
|
12
|
+
- insert:
|
|
13
|
+
- id: decision-engine
|
|
14
|
+
name: '@leonhardthust/dsh-decision-engine'
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workers Builds 的「root directory not found」= 配置指向的路径在仓库里不存在。
|
|
3
|
+
*
|
|
4
|
+
* 2026-10-28 实测(Cloudflare Workers Builds,Worker `dsh-worker`):
|
|
5
|
+
*
|
|
6
|
+
* 提交 check run 结果
|
|
7
|
+
* ────────────── ───────────────── ────────────────────────
|
|
8
|
+
* 047c3283 (前) (无) 不触发构建
|
|
9
|
+
* 4ef171f (无) 不触发构建
|
|
10
|
+
* 755fd28a Workers Builds failure
|
|
11
|
+
* d1ea5c3e Workers Builds failure
|
|
12
|
+
* 8dd4e7c4 Workers Builds failure
|
|
13
|
+
* f7c2ac94 Workers Builds failure
|
|
14
|
+
*
|
|
15
|
+
* 四次失败都是同一个错:
|
|
16
|
+
*
|
|
17
|
+
* Initializing build environment...
|
|
18
|
+
* Success: Finished initializing build environment
|
|
19
|
+
* Cloning repository...
|
|
20
|
+
* Failed: root directory not found
|
|
21
|
+
*
|
|
22
|
+
* 判读要点(这三条决定了怎么定位):
|
|
23
|
+
*
|
|
24
|
+
* 1. **错在 clone 之后、build 之前**。所以不是依赖装不上、不是构建脚本写错、
|
|
25
|
+
* 不是 wrangler 配置有语法错误——构建根本没开始跑。往「检查 package.json /
|
|
26
|
+
* 改 build command」方向找是白找。
|
|
27
|
+
*
|
|
28
|
+
* 2. **Root directory 是建站时设的,不会跟着仓库长出来**。本例里 site/ 目录
|
|
29
|
+
* 是在连好 Workers Builds 之后才提交进仓库的(4ef171f),而 Root directory
|
|
30
|
+
* 指向的正是 site/。连的时候路径不存在,Cloudflare 不报错,只是每次构建
|
|
31
|
+
* 到 clone 阶段就失败。
|
|
32
|
+
*
|
|
33
|
+
* 3. **「没有 check run」和「失败的 check run」是两回事**,前者说明构建压根没
|
|
34
|
+
* 触发(路径不存在时直接跳过),后者才是触发了但失败。别把「历史提交没有
|
|
35
|
+
* check run」当成「历史提交构建成功了」。
|
|
36
|
+
*
|
|
37
|
+
* 另一个坑:**Root directory 改成仓库根也不一定对**。Workers Builds 会在
|
|
38
|
+
* Root directory 及其仓库根执行自动依赖安装(npm ci)。本仓库根 package.json
|
|
39
|
+
* 的 peerDependencies 里有 @deepseek-ai/dsh-session,它依赖的
|
|
40
|
+
* @deepseek-ai/dsh-type-meta 不在公共 npm registry 上(实测 E404),
|
|
41
|
+
* 自动安装会直接失败。宿主自带的包不该由插件仓库去装。
|
|
42
|
+
*
|
|
43
|
+
* 定位手法(没有权限读构建配置时也能用):
|
|
44
|
+
*
|
|
45
|
+
* - GitHub check run 的 name("Workers Builds: <worker>")区分是哪个 Worker;
|
|
46
|
+
* - started_at 与用户看到的构建日志时间戳对得上,确认是同一次构建;
|
|
47
|
+
* - details_url 里有 build UUID;
|
|
48
|
+
* - 同一仓库里哪些提交「有 check run」、哪些「没有」,能反推配置变更的时点;
|
|
49
|
+
* - 本地 clone 后手动跑一遍 build + wrangler deploy --dry-run,
|
|
50
|
+
* 把「代码有问题」和「配置有问题」分开。
|
|
51
|
+
*/
|