cortico-world-workbuddy 0.3.0 → 0.3.4
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/CHANGELOG.md +127 -2
- package/README.md +71 -54
- package/SECURITY.md +29 -16
- package/describe.json +2 -2
- package/dist/webui.js +58 -72
- package/package.json +3 -3
- package/scripts/clean-legacy-injection.mjs +77 -0
- package/scripts/clean-workbuddy.mjs +101 -0
- package/scripts/contract-regression.mjs +221 -0
- package/scripts/contract.mjs +45 -17
- package/scripts/reinstall.ps1 +15 -4
- package/scripts/selfcheck.mjs +1 -1
- package/scripts/verify-ui.mjs +19 -33
- package/src/ENV_PROMPT.md +4 -10
- package/src/config.js +5 -16
- package/src/credentials.js +11 -3
- package/src/definition.js +3 -3
- package/src/promo.js +64 -12
- package/src/upstream.js +31 -63
- package/src/usage.js +27 -21
- package/src/wbproc.js +0 -7
- package/src/webui/client.js +62 -84
- package/src/world.js +96 -139
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,130 @@
|
|
|
1
1
|
# 更新日志
|
|
2
2
|
|
|
3
|
+
## 0.3.4
|
|
4
|
+
|
|
5
|
+
按复核结论做减法:移除反复「假开启」的「中转站优先」功能,只保留可确认的事实。
|
|
6
|
+
|
|
7
|
+
### 删掉的功能
|
|
8
|
+
|
|
9
|
+
- **「中转站优先」整体移除**:详情页页签与复选框、`worlds.workbuddy.prefer` 配置、
|
|
10
|
+
`priority` 面板方法(`state` / `set` / `process`)、环境提示词里的「每轮先 `wb_chat`」强制规则、
|
|
11
|
+
第三盏「中转站优先」灯,以及主进程退出时自动熄灯的逻辑全部删除。`wb_*` 工具改为按需调用:
|
|
12
|
+
Coo 在用户点名 WorkBuddy 或明显更合适时才调用,不再每轮强制消耗积分。
|
|
13
|
+
- **`storage: [{ key: 'workbuddy-catalog' }]` 声明删除**:宿主不再为本扩展生成空的「数据清理」页签。
|
|
14
|
+
- **死代码**:`world.js` 的 `canRelay`、未使用的 `dailyWindowText` / `DEFAULT_SAFE_MODEL` /
|
|
15
|
+
`SAFE_MODEL_IDS` 导入,`wbproc.js` 的 `describeProc`,`upstream.js` 里永远为空的
|
|
16
|
+
`X-User-Id` / `X-Domain` 请求头,一并删除。
|
|
17
|
+
|
|
18
|
+
### 修正
|
|
19
|
+
|
|
20
|
+
- **主进程状态改为只读**:放在「模型目录」面板顶部(6 秒轮询,状态翻转才推送),不再参与任何开关。
|
|
21
|
+
- **优惠状态判定**:`wb_list_models` 的「生效中 / 即将生效」改用 `promoActiveAt()`,
|
|
22
|
+
只有徽标、不改价的促销不再被误标成「即将生效」。
|
|
23
|
+
- **环境提示词收敛**:倍率说明改成「模型自身价格 + 本桥接此刻能核实的限时改价(含免费窗口)」,
|
|
24
|
+
并明确「只挂徽标的优惠可能不改价」;`{{workbuddy.priority}}` 变量与其段落删除。
|
|
25
|
+
- 契约与 UI 验证同步更新:断言没有 `priority` 面板、只有两盏灯、无 `storage`、配置无 `prefer`;
|
|
26
|
+
UI 脚本改为断言页签不含「是否启用 WorkBuddy」与「数据清理」。
|
|
27
|
+
|
|
28
|
+
## 0.3.3
|
|
29
|
+
|
|
30
|
+
按 0.3.2 审查结果修复现有功能,不新增模型、面板或上游能力。
|
|
31
|
+
|
|
32
|
+
- **折扣时间**:纯日期 `validFrom` / `validUntil` 按 `schedule.timezone` 的当地午夜解释,
|
|
33
|
+
`validUntil` 包含所写日期的整日;`daily` 省略时区时默认 `Asia/Shanghai`,非法时区仍回退 UTC。
|
|
34
|
+
- **用量准确性**:分段 SSE `usage` 改为逐字段合并,末帧只有 `credit` 时不再丢 token;
|
|
35
|
+
未回传积分与明确 0 积分分开统计,面板以 `+ ?` 标出未知缺口;账本补记折扣前倍率,
|
|
36
|
+
并在响应完成时取倍率,避免跨折扣窗口写旧值。
|
|
37
|
+
- **只做减法**:删除未接线的 `usageState(days)`、`spanDays` / `windowDays`;按模型表固定为
|
|
38
|
+
近 30 天并明确标注,与概览同口径。
|
|
39
|
+
- **开关就绪**:环境提示词与第三盏灯同时检查主进程、登录态和已选模型,模型为空时不再假开启。
|
|
40
|
+
- **卸载清理**:新增显式 `scripts/clean-workbuddy.mjs --check | --clean`,只清本扩展的配置块、
|
|
41
|
+
三份数据文件与 `.env` 的 `accessToken` 行。普通 `stop()` / 重启不删数据;宿主界面卸载后
|
|
42
|
+
执行该脚本即可无残留,其他配置和密钥不受影响。
|
|
43
|
+
- 文案只称“本机已登录的 WorkBuddy 客户端”,删除多余的区域版本区分。
|
|
44
|
+
|
|
45
|
+
## 0.3.2
|
|
46
|
+
|
|
47
|
+
只桥接本机已登录的 WorkBuddy 桌面端,不再提供区域切换;同时把「用量」面板对齐宿主的
|
|
48
|
+
「用量与成本」口径。仍然只在本机验证,未推送 / 未发布。
|
|
49
|
+
|
|
50
|
+
### 删掉的功能
|
|
51
|
+
|
|
52
|
+
- **区域(region)配置整体移除**:`worlds.workbuddy.region`、`WB_REGION_BASE`、区域枚举与
|
|
53
|
+
对应的上游 / 计费域切换全部删除。扩展现在固定走
|
|
54
|
+
`copilot.tencent.com`(目录 / 对话)与 `www.codebuddy.cn`(积分);自定义 `baseUrl` 仍可用,
|
|
55
|
+
它同时替换这两个域。README、SECURITY、CHANGELOG、`describe.json`、环境提示词里的相关文案同步删除。
|
|
56
|
+
- 环境提示词不再输出 `workbuddy.region` 变量;`catalog.json` 与账本里也不再写 `region` 字段
|
|
57
|
+
(旧文件里的该字段读入后直接忽略)。
|
|
58
|
+
|
|
59
|
+
### 修正
|
|
60
|
+
|
|
61
|
+
- **开关可以「假开启」**:`priority/set` 以前只检查主进程,登录态失效或没选模型时也能点亮,
|
|
62
|
+
结果每轮 `wb_chat` 都失败。现在开启前依次校验主进程、登录态、模型目录,分别返回
|
|
63
|
+
`no-process` / `no-auth` / `no-model`,面板按原因提示;没有选过模型时自动落到
|
|
64
|
+
`preferredSafeModel(safeModelIds())` 并持久化。
|
|
65
|
+
- **环境提示词与实际状态脱节**:`workbuddy.priority` 只有在「开关开 + 主进程在跑 + 已登录」
|
|
66
|
+
时才输出 `on`,避免提示词命令桌宠调用一个必然失败的通道。
|
|
67
|
+
- `loadTokens()` / `setToken()` 成功时清空 `lastError`,登录态恢复后面板不再挂着旧错误。
|
|
68
|
+
- `usageState(days)` 支持区间参数(0/1/7/30/90,默认 30);`summarize().spanDays` 不再恒为 1。
|
|
69
|
+
- 面板「用量」改名「用量与成本」:区间概览新增失败数、缓存命中、合计 token 与「全部」一行,
|
|
70
|
+
按模型聚合同样补上失败数与合计 token;数据仍全部来自账本,不新增任何存储。
|
|
71
|
+
- `world.js` 构造器补上漏声明的 `_procConfirm`,删掉 0.3.0 遗留的孤儿 JSDoc。
|
|
72
|
+
|
|
73
|
+
## 0.3.1
|
|
74
|
+
|
|
75
|
+
按 0.3.0 审查报告复核并修复(仍只在本机验证,未推送 / 未发布)。
|
|
76
|
+
|
|
77
|
+
### 高 / 中优先级
|
|
78
|
+
|
|
79
|
+
- **`/v3/config` 401/403 的错误分类(最严重)**:`upstream.js` 把 `kind` 字符串当成
|
|
80
|
+
`WbUpstreamError` 的第二参(`info` 对象)传,错误恒为 `kind='server'`、`status=0`;
|
|
81
|
+
连锁导致 `models.refresh` 不返回 `noAuth`、`toolChat` 不清 token、前端不提示重新登录。
|
|
82
|
+
现在传 `{ status: 401|403, kind: 'session_dead' }`;`fetchCatalog` 每次重置认证标记,
|
|
83
|
+
`fetchModelsLegacy` 的 403 也判 `session_dead`。
|
|
84
|
+
- **`dailyUnusable` 恒为 false**:`parseSchedule` 过滤后 `daily` 是 `[]` 而不是 `undefined`,
|
|
85
|
+
写错的时段会被当成「全天打折」。现在按「上游给了时段但一条都解析不出来」判定,
|
|
86
|
+
并让该促销按「不生效」处理(宁可少报一次折扣)。
|
|
87
|
+
- **`rediscover` 静默覆盖手动 token**:手动粘贴 token 后点「重新检测」,0.3.0 仍写
|
|
88
|
+
`wb-auto` 把密钥库里的真 token 覆盖掉,重启后丢失。现在只有密钥库里确实是
|
|
89
|
+
`wb-cleared` 登出哨兵、且探测成功时才改写。
|
|
90
|
+
- **「今日积分」跨午夜不归零**:新增 `localDay()` / `rollTodayIfNeeded()`,
|
|
91
|
+
`envPromptVars()` / `webUi()` / `toolChat()` 累加前都翻篇;详情页徽标、环境提示词与
|
|
92
|
+
用量面板 `summary.totals.today` 从此一致。
|
|
93
|
+
- **发布流程**:Release 不再与 CI 各自监听 `v*` tag。现在 `release.yml` 里 `publish`
|
|
94
|
+
`needs: verify`(同一条流水线跑 contract / 构建 / dist 一致性),CI 校验没过就不会发布;
|
|
95
|
+
`ci.yml` 只负责 push/PR,tag 触发交给 Release。
|
|
96
|
+
- **0.2.x 升级残留**:新增 `scripts/clean-legacy-injection.mjs`(`--check` / `--clean`,
|
|
97
|
+
幂等、只删本扩展留下的三样东西、绝不覆盖 `index.html` 其他内容)。扩展本体仍
|
|
98
|
+
**一个字节都不改宿主文件**,清理是用户主动跑的一次性迁移工具。
|
|
99
|
+
- **SECURITY.md 自相矛盾**:删掉「下次启动会重新注入」的残句,写清 0.3.0 起不碰宿主、
|
|
100
|
+
自定义 `baseUrl` 时 token 会发往该主机、可执行文件覆盖两种安装形态。
|
|
101
|
+
- **`refresh()` 死代码**:`WbUpstream.refresh()` 与 `/v2/auth/refresh` 全仓库无调用点,
|
|
102
|
+
README 原理图却列了它。现在删掉未接入的实现与原理图那一行,如实写明
|
|
103
|
+
「登录态失效 → 重新从本机凭据发现」;`credentials.js` 仍解析 `refreshToken`(不外发),
|
|
104
|
+
chat 请求绝不携带它。
|
|
105
|
+
- **`candidateAppExecutables()` 漏 `WorkBuddy AI.exe`**:桌面端两种安装形态的目录名与
|
|
106
|
+
exe 名都覆盖,另一种形态也能自动解封 at-rest 密钥。
|
|
107
|
+
|
|
108
|
+
### 低优先级 / 一致性
|
|
109
|
+
|
|
110
|
+
- `wb_chat` 描述补回 "Requires the WorkBuddy desktop app to be running"(`WB_TOOL_DECLS`、
|
|
111
|
+
`definition.js`,`describe.json` 重新生成)。
|
|
112
|
+
- 英文面板不再写已删除的「开始页 Relay first 按钮」;`dist/webui.js` 重新构建。
|
|
113
|
+
- `writeBalance()` 走与账本同一条写队列、临时文件名带 pid;`usageState()` 只在确有
|
|
114
|
+
超期行时才整文件重写账本。
|
|
115
|
+
- `clearToken` 当下就写 `lastError`(可操作提示不必等重启);`tools()` handler 不再假设
|
|
116
|
+
`args` 一定存在;`offlineChecks()` 与 CI 语法检查覆盖 `scripts/lib/*.mjs`;
|
|
117
|
+
`reinstall.ps1` 删掉空 `if` 死代码。
|
|
118
|
+
- README 统一:CI 是「改跑离线检查」而非「跳过」、三个域名口径、版本号与安装示例。
|
|
119
|
+
- `reinstall.ps1` 的 `npm pack` 不再被误判:Windows PowerShell 5.1 在
|
|
120
|
+
`$ErrorActionPreference='Stop'` 下把 npm 的 stderr `notice` 当 `NativeCommandError` 抛出,
|
|
121
|
+
于是静默退回手工 tar、绕过 `prepack`(审查报告第 6 条的真正触发点)。现在临时降为
|
|
122
|
+
`Continue` 并按真实退出码判断,打包必走 `prepack`。
|
|
123
|
+
- `contract.mjs` 从 68 条扩到 95 条(+27):新增 `scripts/contract-regression.mjs`
|
|
124
|
+
承载 0.3.1 回归防线(session_dead 分类与不降级、无效时段不打折、
|
|
125
|
+
rediscover 不覆盖手动 token、跨日归零、两种安装形态、余额快照并发写),
|
|
126
|
+
并修掉 0.3.0 的断言数量口径(声称「补 25 条」,实际 55→68 只 +13)。
|
|
127
|
+
|
|
3
128
|
## 0.3.0
|
|
4
129
|
|
|
5
130
|
**撤除主界面注入,并按复检报告修掉 9 处中优先级问题。**
|
|
@@ -63,8 +188,8 @@
|
|
|
63
188
|
- **`clearToken` 真的清得掉**:写不清空时返回失败不再是「假成功」;清空后写哨兵 `wb-cleared`,
|
|
64
189
|
`loadTokens()` 见到哨兵就当作已登出(`rediscover` 才回落到本机凭据库)。
|
|
65
190
|
- **`/v3/config` 失败不再静默**:非 2xx、空数据、无模型条目分别打警告,方便判断是不是被降级到旧接口。
|
|
66
|
-
-
|
|
67
|
-
|
|
191
|
+
- **计费域固定**:`WbUpstream` 的 `billingUrl()` 使用 `WB_BILLING_BASE`
|
|
192
|
+
(早期版本按域名子串猜,自定义 `baseUrl` 时会掉到错误的计费域)。
|
|
68
193
|
- **SSE 收尾不再丢 usage**:流结束时 `decoder.decode()` 冲刷残留字节,并把最后一段没有换行的 `data:`
|
|
69
194
|
交给同一解析器 —— 以前末尾那段(正好带 `usage`)会被丢掉。
|
|
70
195
|
- **429 两种性质分开**:`classifyHttpFailure()` 按文案把「额度耗尽」判成 `hard_credit`,其余 429 才是
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# cortico-world-workbuddy
|
|
2
2
|
|
|
3
|
-
把 **本机已登录的 WorkBuddy
|
|
3
|
+
把 **本机已登录的 WorkBuddy 客户端**的模型桥接进
|
|
4
4
|
[Coopanion](https://github.com/Pal-AI-Lab/Coopanion) 桌宠:Coo 可以直接调用你
|
|
5
5
|
WorkBuddy 账号里的模型,World 面板里可以浏览模型目录、查看每个模型的
|
|
6
6
|
**默认积分倍率**(如 `x0.79`)并点选要用的模型;World 详情页有一个「是否启用Workbuddy」
|
|
@@ -14,7 +14,7 @@ WorkBuddy 账号里的模型,World 面板里可以浏览模型目录、查看
|
|
|
14
14
|
> 按上游给出的倍率真实扣费;扩展不提供账号、不共享凭据、不绕过计费。
|
|
15
15
|
> 请自行评估账号风险,官方 WorkBuddy 客户端始终是最安全的选择。
|
|
16
16
|
|
|
17
|
-
## 安装(0.3.
|
|
17
|
+
## 安装(0.3.4,Coopanion 0.2.17 实机验证)
|
|
18
18
|
|
|
19
19
|
一条命令(推荐,脚本会做完打包、装卸、哈希与版本校验):
|
|
20
20
|
|
|
@@ -32,7 +32,7 @@ powershell -NoProfile -ExecutionPolicy Bypass -File scripts/reinstall.ps1
|
|
|
32
32
|
cd "C:\Users\<你>\AppData\Local\Programs\Coopanion\data\extensions"
|
|
33
33
|
node "C:\Users\<你>\AppData\Local\Programs\Coopanion\resources\app\node_modules\pnpm\bin\pnpm.cjs" remove cortico-world-workbuddy
|
|
34
34
|
node "C:\Users\<你>\AppData\Local\Programs\Coopanion\resources\app\node_modules\pnpm\bin\pnpm.cjs" `
|
|
35
|
-
add "$env:LOCALAPPDATA\cortico-world-workbuddy\build\cortico-world-workbuddy-0.3.
|
|
35
|
+
add "$env:LOCALAPPDATA\cortico-world-workbuddy\build\cortico-world-workbuddy-0.3.4.tgz" `
|
|
36
36
|
--config.strict-dep-builds=false `
|
|
37
37
|
--store-dir "C:\Users\<你>\AppData\Local\Programs\Coopanion\data\pnpm\store\v11"
|
|
38
38
|
```
|
|
@@ -43,9 +43,9 @@ powershell -NoProfile -ExecutionPolicy Bypass -File scripts/reinstall.ps1
|
|
|
43
43
|
|
|
44
44
|
```json
|
|
45
45
|
"workbuddy": {
|
|
46
|
-
"enabled": true, "
|
|
46
|
+
"enabled": true, "model": "deepseek-v4.1-flash",
|
|
47
47
|
"credentialsDir": "", "baseUrl": "", "maxTokens": 2048,
|
|
48
|
-
"envPrompt": true
|
|
48
|
+
"envPrompt": true
|
|
49
49
|
}
|
|
50
50
|
```
|
|
51
51
|
|
|
@@ -63,13 +63,25 @@ powershell -NoProfile -ExecutionPolicy Bypass -File scripts/reinstall.ps1
|
|
|
63
63
|
|
|
64
64
|
## 卸载与还原
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
66
|
+
1. 在「World 扩展」里卸载,或执行 `pnpm remove cortico-world-workbuddy`,然后重启 Coopanion。
|
|
67
|
+
详情页入口与 `wb_*` 工具随之消失,Coopanion 主体和其他 World 不受影响。
|
|
68
|
+
2. 宿主的卸载接口只删除扩展包,不会调用扩展清理逻辑,也不会删除部署配置和账本。
|
|
69
|
+
因此在源码目录再执行一次显式清理(先检查、后清理):
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
node scripts/clean-workbuddy.mjs --check
|
|
73
|
+
node scripts/clean-workbuddy.mjs --clean
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
清理范围只有:`config.json` 的 `worlds.workbuddy` 块、`.env` 的 `accessToken` 行
|
|
77
|
+
(真实 token 或 `wb-cleared` / `wb-auto` 哨兵),以及数据目录里的
|
|
78
|
+
`workbuddy-usage.jsonl`、`workbuddy-catalog.json`、`workbuddy-balance.json`。
|
|
79
|
+
其他配置、其他密钥和宿主文件不动,命令输出也不会显示 token。
|
|
80
|
+
- **不碰宿主程序文件**:0.3.0 起扩展不再往 Coopanion 主界面注入脚本或按钮,
|
|
81
|
+
`resources\app` 不会被改写。普通 `stop()` / 重启不会删除账本;只有上面的显式卸载清理会删。
|
|
82
|
+
- **旧版本残留(0.2.x → 0.3.x)**:装过 0.2.x 的机器,另外执行
|
|
83
|
+
`node scripts/clean-legacy-injection.mjs --check` 并按结果使用 `--clean`,清除旧版留在
|
|
84
|
+
`build\console\` 的注入行、脚本与备份;脚本不覆盖 `index.html` 的其他内容。
|
|
73
85
|
|
|
74
86
|
## 工作原理
|
|
75
87
|
|
|
@@ -82,10 +94,9 @@ Coopanion (Coo)
|
|
|
82
94
|
├─ 上游客户端 copilot.tencent.com(对话)/ www.codebuddy.cn(计费)
|
|
83
95
|
│ ├─ GET /v3/config 模型目录 + 促销(models / modelPromotions / modelTiers)
|
|
84
96
|
│ ├─ POST /v2/chat/completions 对话(SSE 流式)
|
|
85
|
-
│ ├─ POST /v2/auth/refresh 刷新 token(X-Refresh-Token)
|
|
86
97
|
│ └─ POST /v2/billing/meter/get-user-resource 积分余额(只读)
|
|
87
98
|
├─ 工具 wb_list_models / wb_select_model / wb_chat / wb_credits
|
|
88
|
-
└─ WebUI 面板
|
|
99
|
+
└─ WebUI 面板 模型目录(含只读主进程状态)、账号、用量与成本
|
|
89
100
|
```
|
|
90
101
|
|
|
91
102
|
- **主进程检测**:桌面端的渲染进程都是主进程的子进程,所以「有 `WorkBuddy.exe`」等价于
|
|
@@ -98,34 +109,31 @@ Coopanion (Coo)
|
|
|
98
109
|
token 只经 `ctx.storeSecret()` 进部署的密钥库,**不写配置、不进日志、面板只显示掩码**。
|
|
99
110
|
- **积分倍率**:完全来自上游目录的 `credits` 字段,扩展不写死;刷新后缓存到
|
|
100
111
|
`workbuddy-catalog.json`,重启不丢。
|
|
101
|
-
-
|
|
102
|
-
|
|
112
|
+
- **登录态失效**:`/v3/config` 返回 401/403 时直接判 `session_dead` 并清掉本次 token;
|
|
113
|
+
下一次调用重新从本机凭据发现(桌面端自行刷新落盘)。本扩展不调用刷新接口,
|
|
114
|
+
chat 请求也绝不携带 refresh token。
|
|
115
|
+
- **上游**:目录与对话固定走 `copilot.tencent.com`,积分余额走 `www.codebuddy.cn`。
|
|
116
|
+
本扩展只支持这一套上游(本机已登录的 WorkBuddy 桌面端);配了自定义 `baseUrl` 时两个域都由它替换。
|
|
103
117
|
|
|
104
|
-
##
|
|
118
|
+
## 主进程状态与按需调用
|
|
105
119
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
| 入口 | 位置 | 行为 |
|
|
109
|
-
|---|---|---|
|
|
110
|
-
| 详情页开关 | 「World 扩展」→ WorkBuddy 桥接 →「是否启用Workbuddy」 | 勾选=开;取消=关 |
|
|
120
|
+
0.3.4 起没有「中转站优先」开关,也没有任何「每轮强制走 WorkBuddy」的行为:
|
|
111
121
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
-
|
|
119
|
-
- 主进程在 6 秒轮询里退出时,开关自动熄灭,避免亮着却调不通。
|
|
122
|
+
- 「模型目录」面板顶部只读显示 WorkBuddy 主进程是否在跑(6 秒轮询,翻转时才推送);
|
|
123
|
+
勾选框已删除,状态不参与任何开关逻辑。
|
|
124
|
+
- `wb_*` 工具由 Coo 按需调用:用户点名 WorkBuddy、或某个 WorkBuddy 模型明显更合适时才用。
|
|
125
|
+
不调用就不花积分——这是「每个调用都真实扣积分」的默认前提。
|
|
126
|
+
- 环境提示词只描述事实(登录态、模型、倍率、主进程状态、今日用量)和工具用法,
|
|
127
|
+
不再命令「每轮先 `wb_chat`」。
|
|
128
|
+
- 主进程退出时面板状态会变成「未检测到」,工具调用直接返回明确错误,不需要切换任何开关。
|
|
120
129
|
|
|
121
130
|
## 面板
|
|
122
131
|
|
|
123
132
|
| 面板 | 内容 |
|
|
124
133
|
|---|---|
|
|
125
|
-
| 模型目录 |
|
|
134
|
+
| 模型目录 | 顶部只读显示 WorkBuddy 主进程状态;刷新目录;逐模型一行:名称/id、**合规档位**、**此刻倍率**(含限时折扣时显示 `x0.5 ← x0.79 23:00–07:50`,x0 标「免费」)、上下文、推理档、「选用」按钮;默认只列安全清单,勾选「显示全部模型(含不建议项)」才展开其余项 |
|
|
126
135
|
| 账号 | 登录态来源(本机发现 / 手动)、掩码 token、积分余额查询、重新检测、手动 token 存取 |
|
|
127
|
-
|
|
|
128
|
-
| 用量 | 区间概览(今天 / 近 7 天 / 近 30 天)、按模型聚合、积分包明细、限时优惠清单、最近调用;带「刷新余额」「清空本地账本」 |
|
|
136
|
+
| 用量与成本 | 区间概览(今天 / 近 7 天 / 近 30 天 / 全部,列:调用、失败、积分、输入/输出/缓存命中/合计 token)、按模型近 30 天聚合、积分包明细、限时优惠清单、最近调用;带「刷新余额」「清空本地账本」 |
|
|
129
137
|
|
|
130
138
|
### 安全清单(合规闸门)
|
|
131
139
|
|
|
@@ -152,8 +160,9 @@ WorkBuddy 官方对话给出的口径是:只调用「官方公开目录里、
|
|
|
152
160
|
|
|
153
161
|
- 目录来自 `GET /v3/config`(应用身份 UA):一次同时拿到 `models`、`modelPromotions`、`modelTiers`。
|
|
154
162
|
用 CLI 身份只能读到精简目录,促销字段会整段缺失——这是「倍率永远显示原价」的根因。
|
|
155
|
-
- 一条促销的生效条件是 `schedule`:`timezone
|
|
156
|
-
`daily` 时段(支持 `23:00`→`07:50`
|
|
163
|
+
- 一条促销的生效条件是 `schedule`:`timezone`(省略时按 `Asia/Shanghai`)、`validFrom`/`validUntil`、
|
|
164
|
+
`daily` 时段(支持 `23:00`→`07:50` 这类跨零点窗口)。纯日期按当地自然日解释,`validUntil` 包含当天;
|
|
165
|
+
命中的条目按 `priority` 取最高,平手时促销优先于档位。
|
|
157
166
|
- `discount.discountedCredits`(如 `0.50x`)**就是生效倍率本身**,不是相对原价的系数。
|
|
158
167
|
`displayMode: "replace"` 直接替换显示,`"strikethrough"` 表示「划线原价 + 新价」并排。
|
|
159
168
|
- `badge.display: "activeOnly"` 的徽标只在生效时段出现(如「限时免费」试用)。
|
|
@@ -161,8 +170,9 @@ WorkBuddy 官方对话给出的口径是:只调用「官方公开目录里、
|
|
|
161
170
|
### 用量统计口径
|
|
162
171
|
|
|
163
172
|
- 每次 `wb_chat` 记一行到 `%APPDATA%\..\Coopanion\data\home\companion\data\workbuddy-usage.jsonl`
|
|
164
|
-
(实机路径;实际就是 `ctx.dataDir`):`ts/model/
|
|
165
|
-
- `credit` 取 SSE
|
|
173
|
+
(实机路径;实际就是 `ctx.dataDir`):`ts/model/ok/promptTokens/completionTokens/totalTokens/cachedTokens/reasoningTokens/credit/multiplier/baseMultiplier/promoId/source/durationMs`。
|
|
174
|
+
- `credit` 取 SSE 各段合并后的 `usage.credit`,即**上游真实扣费**;倍率 0.11 的模型单次请求不足 1 分时上游就是 0,这里照抄不折算。
|
|
175
|
+
上游未回传时记为未知,概览用 `+ ?` 标出缺口,绝不当成 0;`multiplier` 是响应完成时的生效倍率,`baseMultiplier` 是目录原价。
|
|
166
176
|
- 积分包余额另存 `workbuddy-balance.json`(`POST /v2/billing/meter/get-user-resource` 的 `*Precise` 字段求和),
|
|
167
177
|
面板上的「刷新余额」会重取一次。
|
|
168
178
|
- 账本只保留 90 天,读的时候顺带裁掉;「清空本地账本」会把它清成空文件,服务端数据不受影响。
|
|
@@ -180,13 +190,11 @@ WorkBuddy 官方对话给出的口径是:只调用「官方公开目录里、
|
|
|
180
190
|
|
|
181
191
|
| 键 | 默认 | 说明 |
|
|
182
192
|
|---|---|---|
|
|
183
|
-
| `region` | `cn` | `cn` / `global` |
|
|
184
193
|
| `model` | `""` | 当前模型 id(面板点选即写这里) |
|
|
185
194
|
| `credentialsDir` | `""` | 自定义凭据目录,留空自动发现(重启生效) |
|
|
186
195
|
| `baseUrl` | `""` | 自定义上游地址,代理/中转用(重启生效) |
|
|
187
196
|
| `maxTokens` | `2048` | `wb_chat` 单次输出上限 |
|
|
188
|
-
| `envPrompt` | `true` | 是否把桥接状态写进 system
|
|
189
|
-
| `prefer` | `false` | 「中转站优先」,由详情页开关写入 |
|
|
197
|
+
| `envPrompt` | `true` | 是否把桥接状态写进 system 前缀 |
|
|
190
198
|
| `safeOnly` | `true` | 只允许调用安全清单内的公开对话模型;关掉会放行 disabled / 别名 / 预览等项,风险自负 |
|
|
191
199
|
|
|
192
200
|
## 开发与校验
|
|
@@ -198,7 +206,8 @@ WorkBuddy 官方对话给出的口径是:只调用「官方公开目录里、
|
|
|
198
206
|
node scripts/build-web.mjs
|
|
199
207
|
|
|
200
208
|
# 契约检查(不依赖宿主,CI 必跑):describe.json 与源码一致、版本号与 CHANGELOG 对齐、
|
|
201
|
-
# 促销/安全清单/账本断言,以及哨兵、计费域、429 软硬、面板白名单、并发、SSE flush
|
|
209
|
+
# 促销/安全清单/账本断言,以及哨兵、计费域、429 软硬、面板白名单、并发、SSE flush 等回归断言;
|
|
210
|
+
# 0.3.1 另加 session_dead 分类、无效时段、rediscover 覆盖、跨日归零等防线(contract-regression.mjs)
|
|
202
211
|
node scripts/contract.mjs
|
|
203
212
|
|
|
204
213
|
# 由源码重新生成 describe.json(改过工具声明或 ENV_PROMPT.md 之后)
|
|
@@ -218,7 +227,7 @@ UI 验证脚本的两个约定(踩过坑,别再用固定 sleep):每轮
|
|
|
218
227
|
并把「路由挂载」与「面板渲染」拆成两条断言——否则一次产物没加载就会被误判成「按钮没了」。
|
|
219
228
|
|
|
220
229
|
版本号规范:任何改动都 bump `package.json` 的 `version`,备份目录按版本命名
|
|
221
|
-
(`F:\coo-connect-wb\0.3.
|
|
230
|
+
(`F:\coo-connect-wb\0.3.4\`),再用 `scripts/reinstall.ps1` 装;它先把 tgz 解出来,再拿**解出来的内容**与安装目录逐文件比对哈希,
|
|
222
231
|
不一致直接非零退出。
|
|
223
232
|
|
|
224
233
|
打包注意:**不要用 PowerShell 的 `Get-Content -Raw | Set-Content` 改 `package.json`**
|
|
@@ -226,7 +235,7 @@ UI 验证脚本的两个约定(踩过坑,别再用固定 sleep):每轮
|
|
|
226
235
|
用 node 读写 JSON;tgz 必须以 `package/` 为前缀:
|
|
227
236
|
|
|
228
237
|
```bash
|
|
229
|
-
tar -czf cortico-world-workbuddy-0.3.
|
|
238
|
+
tar -czf cortico-world-workbuddy-0.3.4.tgz -C <stage> package
|
|
230
239
|
```
|
|
231
240
|
|
|
232
241
|
协议细节参照 [dsh-connect-workbuddy](https://github.com/dingminhua/dsh-connect-workbuddy)
|
|
@@ -235,16 +244,22 @@ tar -czf cortico-world-workbuddy-0.3.0.tgz -C <stage> package
|
|
|
235
244
|
|
|
236
245
|
## 宿主文件:一个字节都不改
|
|
237
246
|
|
|
238
|
-
0.3.0 起本扩展**不再往 Coopanion
|
|
239
|
-
|
|
247
|
+
0.3.0 起本扩展**不再往 Coopanion 主界面注入任何东西**——详情页只有三个只读/配置面板,
|
|
248
|
+
没有开关勾选框,`resources\app` 下不会有任何改动;部署配置、账本与手动 token 按上一节的显式步骤清理。
|
|
249
|
+
|
|
250
|
+
如果你装过 0.2.x,宿主 `build\console\` 里可能还留着三处痕迹。扩展本体不会自动改
|
|
251
|
+
宿主文件(这正是 0.3.0 起的承诺),请用一次性迁移脚本清理:
|
|
240
252
|
|
|
241
|
-
|
|
253
|
+
```bash
|
|
254
|
+
node scripts/clean-legacy-injection.mjs --check # 只列出会动的项
|
|
255
|
+
node scripts/clean-legacy-injection.mjs --clean # 执行清理(幂等)
|
|
256
|
+
```
|
|
242
257
|
|
|
243
|
-
| 文件 |
|
|
258
|
+
| 文件 | 脚本会做什么 |
|
|
244
259
|
|---|---|
|
|
245
|
-
| `<app>\build\console\index.html` |
|
|
246
|
-
| `<app>\build\console\workbuddy-home.js` |
|
|
247
|
-
| `<app>\build\console\index.html.workbuddy-backup` |
|
|
260
|
+
| `<app>\build\console\index.html` | 只剥掉 `<script type="module" src="./workbuddy-home.js"></script>` 这一行,保留原有换行风格与其余内容 |
|
|
261
|
+
| `<app>\build\console\workbuddy-home.js` | 删除旧的注入脚本 |
|
|
262
|
+
| `<app>\build\console\index.html.workbuddy-backup` | 删除首次注入前的原件备份 |
|
|
248
263
|
|
|
249
264
|
## 发布(GitHub / npm / 扩展市场)
|
|
250
265
|
|
|
@@ -266,12 +281,12 @@ Action 定时扫 npm 生成市场目录,所以发版顺序是:**先 npm publ
|
|
|
266
281
|
|
|
267
282
|
```bash
|
|
268
283
|
# 1. 发版前三连检(需要本机真实宿主)
|
|
269
|
-
node scripts/contract.mjs #
|
|
284
|
+
node scripts/contract.mjs # 不依赖宿主,全部断言
|
|
270
285
|
node scripts/selfcheck.mjs # dry-mount 框架契约
|
|
271
286
|
node scripts/verify-ui.mjs --runs 3
|
|
272
287
|
|
|
273
288
|
# 2. 提交并打 tag
|
|
274
|
-
git tag v0.3.
|
|
289
|
+
git tag v0.3.4 && git push --tags
|
|
275
290
|
|
|
276
291
|
# 3. 发布(prepack 会自动重建 dist/webui.js)
|
|
277
292
|
npm publish --access public
|
|
@@ -283,13 +298,15 @@ gh issue create -R Pal-AI-Lab/cortico-extensions --title "[sync] cortico-world-w
|
|
|
283
298
|
对标签有异议用 `[tags]`、申请蓝标认证用 `[certify]`、被拉黑申诉用 `[appeal]`,
|
|
284
299
|
正文一行一项 `键: 值`(`package` / `add` / `remove` / `reason` / `evidence`)。
|
|
285
300
|
|
|
286
|
-
CI 里没有 Coopanion
|
|
301
|
+
CI 里没有 Coopanion:自检改跑离线检查(全部源码 `node --check` + `contract`),
|
|
302
|
+
不会红叉,也不会无条件算通过:
|
|
287
303
|
|
|
288
304
|
```bash
|
|
289
305
|
node scripts/selfcheck.mjs --allow-missing-host # 找不到宿主 → 警告 + 退出码 0
|
|
290
306
|
```
|
|
291
307
|
|
|
292
|
-
凭据读取范围与网络出口见 [SECURITY.md](./SECURITY.md)
|
|
308
|
+
凭据读取范围与网络出口见 [SECURITY.md](./SECURITY.md):读哪些文件、默认只发给哪两个官方域名
|
|
309
|
+
(配了自定义 `baseUrl` 时从该出口走)、哪些从不写盘。
|
|
293
310
|
|
|
294
311
|
## 免责
|
|
295
312
|
|
package/SECURITY.md
CHANGED
|
@@ -11,34 +11,47 @@ judge the risk before installing.
|
|
|
11
11
|
| `%LOCALAPPDATA%\CodeBuddyExtension\Data\Public\auth\workbuddy-desktop.info` | To learn your WorkBuddy login | `auth.accessToken`, `auth.refreshToken`, `auth.expiresAt`, `auth.domain`, `account` |
|
|
12
12
|
| `%APPDATA%\WorkBuddy*\*.json` (if present) | Older WorkBuddy builds store the login here | same fields when stored in plain text |
|
|
13
13
|
| `%LOCALAPPDATA%\CodeBuddyExtension\Data\Public\auth` (fallback) | Same as above, directory scan | same fields |
|
|
14
|
-
| `
|
|
15
|
-
| `<Coopanion data>\home\companion\config.json` | Read
|
|
14
|
+
| `WorkBuddy.exe` / `WorkBuddy AI.exe` (known install locations) | Only to ask the app for its own at-rest key | the key payload printed by the app's own `loggerGet()` binding; never stored |
|
|
15
|
+
| `<Coopanion data>\home\companion\config.json` | Read `worlds.workbuddy` | model id, `envPrompt` / `safeOnly` flags |
|
|
16
16
|
|
|
17
17
|
The token is decrypted in memory only when the file is encrypted, is used only as the
|
|
18
18
|
`Authorization: Bearer` header for WorkBuddy's own endpoints, and is never written anywhere except
|
|
19
19
|
the Coopanion deployment `.env` if you paste one in the account panel yourself (the framework's
|
|
20
|
-
`storeSecret`).
|
|
20
|
+
`storeSecret`). Refresh tokens are never sent with chat requests.
|
|
21
21
|
|
|
22
22
|
## Where data goes
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
By default, only these two hosts, both WorkBuddy's:
|
|
25
25
|
|
|
26
|
-
- `https://copilot.tencent.com` — model catalogue and chat completions
|
|
27
|
-
- `https://www.codebuddy.cn` — credit balance
|
|
28
|
-
- `https://www.workbuddy.ai` — catalogue, chat, credits (region `global`)
|
|
26
|
+
- `https://copilot.tencent.com` — model catalogue and chat completions
|
|
27
|
+
- `https://www.codebuddy.cn` — credit balance
|
|
29
28
|
|
|
30
|
-
|
|
29
|
+
If you set `worlds.workbuddy.baseUrl` (a proxy or mirror), **every** request — catalogue,
|
|
30
|
+
chat and credit balance — goes to that host instead, and the token is sent there too. That is
|
|
31
|
+
your own configuration choice, not a default. No other hosts are contacted. No logs contain
|
|
32
|
+
tokens: every log line goes through `maskToken()`.
|
|
31
33
|
|
|
32
34
|
## What it writes
|
|
33
35
|
|
|
34
|
-
- `<Coopanion data>/
|
|
35
|
-
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
- `<Coopanion data>/home/companion/data/workbuddy-catalog.json` — cached model list, no credentials.
|
|
37
|
+
- `<Coopanion data>/home/companion/data/workbuddy-usage.jsonl` and `workbuddy-balance.json` — local
|
|
38
|
+
usage ledger and credit snapshot, no tokens.
|
|
39
|
+
- `worlds.workbuddy.*` in the companion config (model, `envPrompt`, `safeOnly`).
|
|
40
|
+
- The deployment `.env` — only when you paste a token or clear it in the Account panel
|
|
41
|
+
(the sentinels `wb-cleared` / `wb-auto` are written there; a real token only if you pasted one).
|
|
42
|
+
|
|
43
|
+
**Coopanion program files are never touched by the running extension.** Since 0.3.0 it does not
|
|
44
|
+
inject anything into `resources/app/build/console` and keeps no backup of host files. Coopanion's
|
|
45
|
+
own uninstall route removes only the package; it does not run extension cleanup code. After
|
|
46
|
+
uninstalling, run `node scripts/clean-workbuddy.mjs --check`, then `--clean`, from the source tree.
|
|
47
|
+
That explicit command removes only the `worlds.workbuddy` config block, the three data files above,
|
|
48
|
+
and the `accessToken` line in `.env`; it preserves every other setting and secret and never prints
|
|
49
|
+
the token. Ordinary `stop()` and restart never delete usage data.
|
|
50
|
+
|
|
51
|
+
If you upgraded from 0.2.x, an old one-line `<script>` reference, `workbuddy-home.js` and
|
|
52
|
+
`index.html.workbuddy-backup` may still be left over from that older version. Remove them once with
|
|
53
|
+
`node scripts/clean-legacy-injection.mjs --clean` (`--check` lists what it would touch). Neither
|
|
54
|
+
cleanup script runs automatically, and the extension never re-adds the injection.
|
|
42
55
|
|
|
43
56
|
## Reporting a vulnerability
|
|
44
57
|
|
package/describe.json
CHANGED
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
},
|
|
48
48
|
{
|
|
49
49
|
"name": "wb_chat",
|
|
50
|
-
"description": "Ask the selected WorkBuddy model a single-turn question and return its answer. This spends the user's own WorkBuddy credits at the model's multiplier; keep prompts concise. Use the model parameter only to override the selected model for one call.",
|
|
50
|
+
"description": "Ask the selected WorkBuddy model a single-turn question and return its answer. This spends the user's own WorkBuddy credits at the model's multiplier; keep prompts concise. Use the model parameter only to override the selected model for one call. Requires the WorkBuddy desktop app to be running.",
|
|
51
51
|
"summary": {
|
|
52
52
|
"zh": "向当前选中的 WorkBuddy 模型发一句单轮提问并取回答,会消耗用户自己的 WorkBuddy 积分。",
|
|
53
53
|
"en": "Asks the selected WorkBuddy model a single-turn question; spends the user's own WorkBuddy credits."
|
|
@@ -103,5 +103,5 @@
|
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
105
|
],
|
|
106
|
-
"envPrompt": "## WorkBuddy bridge\n\nThis machine has a WorkBuddy desktop
|
|
106
|
+
"envPrompt": "## WorkBuddy bridge\n\nThis machine has a signed-in WorkBuddy desktop app bridged in (signed in: {{workbuddy.authed}}).\nThe model catalog holds {{workbuddy.catalogSize}} models. The currently selected model is `{{workbuddy.model}}` with default credit multiplier {{workbuddy.multiplier}}.\nWorkBuddy desktop main process: {{workbuddy.process}}.\nSpent today through the bridge: {{workbuddy.todayCredit}} credits / {{workbuddy.todayTokens}} tokens (locally recorded).\nThe multiplier above is the model's own price plus any time-limited price change this bridge can verify at the moment (including free windows). An offer that only shows a badge may not change the price; `wb_list_models` marks which offers are active and their hours.\n\n- Use `wb_list_models` to see every model with its multiplier before choosing; prefer low-multiplier models for casual tasks.\n- Safe-list gate: {{workbuddy.safeOnly}}. When it is `on`, only the models WorkBuddy publishes as public chat models are callable — `disabled` entries, internal routing aliases (`auto`, `fast-model`, `balanced-model`, `deep-model`), media/code models and delisted ones are refused. Do not try to work around a refusal; tell the user why and offer a safe model instead. `wb_list_models` with `all=true` shows the refused ones with reasons.\n- Use `wb_select_model` when the user asks to switch the WorkBuddy model.\n- `wb_chat` only works while the WorkBuddy desktop main process is running; otherwise it returns「未检测到 WorkBuddy 主进程」. Every call spends the user's own credits at that model's multiplier. Call it when the user asks for WorkBuddy or when a WorkBuddy model would clearly help; do not route every turn through it.\n- `wb_credits` is read-only and costs nothing (also requires the desktop process)."
|
|
107
107
|
}
|