chore(工作区): 全量入库 + 补齐 .gitignore(以工作区为准)
- 变更规模:新增 514 / 修改 62 / 重命名 155 / 删除 4(归档重组与文档轮次) - .gitignore 修:`归档/**/db-cwd归一-备份-*/` —— 原规则写绝对层级(归档/db-cwd归一-…), 目录搬进 归档/配置与备份/ 后**静默失效**,43 MB 的 DB 备份又变成未跟踪 - .gitignore 补:嵌套 git 内部数据(归档/内嵌git-20261008/、归档/skills-git-旧线-20261007/dotgit-原样移出/) - .gitignore 补:运行态与部署副本(.workbuddy/collab/、.workbuddy/tools/、.workbuddy/.load-pending、.workbuddy/tmp-*) - .gitignore 补:备份件(*.bak-*) - 未跟踪文件从 2190 降到 890(其余为 归档/ 归档件与 .workbuddy/memory/ 知识文件,按口径入库)
This commit is contained in:
1 parent
30b46dbd0c
commit
c1b5e4d966
735 files changed
+153192
-2415
No files matched your search
@@ -0,0 +1,238 @@
|
||||
# 「唤醒」的解决方式 · 官方文档核对 + 方案分析(2026-09-30)
|
||||
|
||||
> 用户议题:**处理完成后分析唤醒的解决方式,再看看官方文档;如果找不到办法,是不是可以用一个会话当主会话、用手机给当前会话发消息的方式唤醒。**
|
||||
> 用户补充(关键):**「之前手机记得是通过 gateway 连接的」** —— 对,手机走的是**我们自研的那条 gateway 通道**,不是官方微信助理。
|
||||
|
||||
---
|
||||
|
||||
## 0 三句话结论
|
||||
|
||||
1. **官方文档里没有"分钟级定时"这回事** —— 官方唯一的时间驱动是**自动化**,本机实测出现的 recurrence 只到 `FREQ=HOURLY;INTERVAL=1`(**每小时**为最小)。
|
||||
2. **但官方把"手机发消息 → 电脑执行"做成了产品**(微信助理 / 企微助理),而且它的形态写得很直白:
|
||||
**「助理(远程任务):仅一个会话,所有远程指令集中处理」** ⇒ **正是你说的"用一个会话当主会话"**。
|
||||
3. **你的思路成立,而且不用新造轮子** —— 我们自研的 gateway 通道**本来就具备"往会话投一条消息"的能力且已验收**(手机接入线 V2)。**唯一的硬前提是:那个会话必须是桌面"当前打开的那一个"(live)**;不是 live ⇒ `reply` 一律 `409`。
|
||||
⚠️ **后续追加(13:0x)**:用户提出"回到自动任务,建**间隔 5 分钟**自动运行的会话" ⇒ **§11 给出源码级判定:做不到**(FREQ 硬白名单),且一次运行=一个新会话 ⇒ 附能做的三档。
|
||||
|
||||
---
|
||||
|
||||
## 1 官方文档核对(逐条附原文)
|
||||
|
||||
| 项 | 官方怎么说 | 出处 |
|
||||
|---|---|---|
|
||||
| 自动化的定位 | 「自动化在**本地客户端**保存定时任务配置…在指定时间**以您当前的登录身份自动发起 Agent 任务**」 | `.../Function-Description/Automation-Guide` |
|
||||
| 频率粒度 | 只举「**每周一、三、五 09:00**」「**每月 1 日、15 日、28 日 09:00**」;**通篇未承诺分钟级** | 同上 |
|
||||
| 谁在跑 | 「任务**仅在配置的时间规则触发时**执行,受任务频率、最大执行时长与系统并发控制限制」 ⇒ **是"时间规则",不是"事件/条件"** | 同上 |
|
||||
| 需要电脑开着 | 同页未直说;**非官方**来源明确:「本机执行…需要保持电脑开机、WorkBuddy 客户端处于运行状态」 | 第三方(标记:**非官方**) |
|
||||
| **手机通道(有)** | 「接入微信助理让您可以通过**手机微信远程控制电脑上的 WorkBuddy**。在微信中发送任务指令,WorkBuddy 在电脑上自动执行,并将结果同步回微信聊天窗口」 | `WeixinBot-Guide` |
|
||||
| **助理 = 单会话** | 「**助理(远程任务):仅一个会话,所有远程指令集中处理**」;「工作目录:**固定使用助理专属文件夹**」;「上下文:**保留完整对话历史,不可清空**」 | `Wecom-Guide` §远程任务与普通任务的区别 |
|
||||
| 企微可 @机器人 | 「在**群聊中 @机器人**下发团队协作任务」;「创建**专属任务群**,长期绑定」;含「任务提醒/发布通知」 | `Wecom-Guide` |
|
||||
| 官方推荐形态 | 「**专属常开主机**:如果您的项目需要长期运行的任务(如定时巡检、持续集成监控等),可以使用一台专用的…电脑,保持 WorkBuddy 持续运行」 | `WeixinBot-Guide` |
|
||||
| 版本门槛 | 需 **WorkBuddy ≥ 4.6.4** ⇒ **本机实测 5.6.2 ✅**(能力在,只是没启用) | 两份 Guide |
|
||||
| 「条件触发」 | ⚠️ **只有非官方来源**提「条件触发(有新邮件/文件更新/关键词出现)」;**官方 Automation-Guide 只写"时间规则"** ⇒ **当作未证实,不作为设计依据** | 非官方 |
|
||||
|
||||
> 📌 **一句话**:官方给的两条"人能远程驱动电脑"的路,一条是**定时(最小 1 小时)**,一条是**手机发消息(人驱动,粒度任意)**。**官方没有第三条**。
|
||||
|
||||
---
|
||||
|
||||
## 2 两条手机通道别混(你记得对:我们用的是 gateway 那条)
|
||||
|
||||
| | **官方**(微信/企微助理) | **我们的**(自研覆盖网络 + 垫片 + gateway) |
|
||||
|---|---|---|
|
||||
| 手机 → 电脑 | 微信/企微 → 官方助理服务(长连接) | ai1net 覆盖网络 **443** → 本机垫片 `127.0.0.1:20090` → **WorkBuddy gateway(动态口)** |
|
||||
| 能投到哪些会话 | **只能进"助理"那一个会话** | **可投到任意"同工作目录且 live"的会话** ✅ 更通用 |
|
||||
| 是否单会话 | 是(助理天生单会话) | 不限定(但 `reply` 只认 live) |
|
||||
| 依赖 | 微信/企微账号绑定、电脑常开 | 覆盖网络 + 垫片常驻 + 账号核对 |
|
||||
| 本机现状 | **未启用**(库里 **0 条**远程来源会话;但客户端里有 `settings.claw.*` 字样 ⇒ 能力在) | ✅ **已通**(见 §3) |
|
||||
|
||||
会话侧契约(`交付物/手机App经覆盖网络操作WorkBuddy-架构定稿v3-20260929.md` §2.2,**已实测**):
|
||||
|
||||
```
|
||||
⑤ 发消息
|
||||
· 目标 = live 会话 ⇒ POST /api/v1/sessions/{id}/reply {"text":"…"} ← 官方路径,不夺 writer
|
||||
(缺 text ⇒ 400;**非 live ⇒ 409**)
|
||||
· 目标 ≠ live ⇒ 只能走 ACP 借用(session/load + session/prompt)
|
||||
⚠️ 被 writer 占用 ⇒ -32000 writer_occupied ⇒ **夺不了,也不许抢**(T2/红线)
|
||||
④ 哪个是 live ⇒ GET /api/v1/sessions/live → {sessionId, writerOccupied}
|
||||
🔴 网关只读写"与自己同 cwd"的会话(跨项目一律 404)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3 本机实测读数(**只读**,口令未回显、未落盘)
|
||||
|
||||
| 查什么 | 读数 |
|
||||
|---|---|
|
||||
| 环境里的网关口令 | **在**(长度 43) |
|
||||
| 垫片 `127.0.0.1:20090` | **在听**(PID 39220) |
|
||||
| 网关口 `56975` | **活着**;`GET /api/v1/info` ⇒ `cwd = E:\ProgramData\AIProject\ai1net-dsh-server`(正是本工作区)✅ |
|
||||
| **当前活会话** `GET /sessions/live` | 🔴 **`fe146dd9-…`,且 `writerOccupied: true`** |
|
||||
| 看板认定的"主会话" | `6ecf6d98`(=我当前所在的这个接续会话) |
|
||||
| 自动化台账 | ACTIVE:`once` **59 条** / `recurring` 2 条;PAUSED recurring 1 条 |
|
||||
| 本机出现过的 recurrence | `FREQ=HOURLY;INTERVAL=1`(**最小=每小时**)、`FREQ=DAILY;BYHOUR=6`、`FREQ=DAILY;INTERVAL=3;BYHOUR=9` |
|
||||
| 有没有分钟级 | `MINUTELY`/`SECONDLY` 命中 **0** ⇒ 本机从未有过分钟级 |
|
||||
|
||||
### 3.1 🔴 最关键的一条:**"主会话"现在不是 live**
|
||||
|
||||
`reply` 只认 live,而**当前 live 是 `fe146dd9`,不是主会话 `6ecf6d98`**。
|
||||
|
||||
⇒ **现在用手机发消息,只会进 `fe146dd9`,进不了主会话。** 这不是权限问题,是这个 API 的设计(不夺 writer 的代价就是"只认当前打开的那个")。
|
||||
|
||||
---
|
||||
|
||||
## 4 你的方案判定:**可行** —— 但成立与否只取决于一个前提
|
||||
|
||||
> 你的原话:**「用一个会话当主会话,用手机给当前会话发消息的方式唤醒」**
|
||||
|
||||
**判定:✅ 技术通路已存在、已验收,不需要新造。** 拆开看:
|
||||
|
||||
| 你的构想 | 对应现实 | 判定 |
|
||||
|---|---|---|
|
||||
| 「用一个会话当主会话」 | 机制里已有"主会话"概念(`collabd` / 看板同一套判据),也有 `wake.sessionId` 登记 | ✅ 现成 |
|
||||
| 「用手机发消息」 | 自研通道已验收 V2:**手机发出的消息进入桌面会话** | ✅ 现成 |
|
||||
| 「唤醒」 | 一条消息落进会话 ⇒ 会话被驱动起一轮 ⇒ **这就是唤醒** | ✅ 语义成立 |
|
||||
| 「给**当前**会话发」 | `POST /sessions/{id}/reply`,**不夺 writer**;但**必须是 live** | ⚠️ **唯一硬前提** |
|
||||
|
||||
**⇒ 落地要点:让"主会话"="桌面上一直开着的那一个"。**
|
||||
只要你**固定同一个会话、并在桌面一直开着它**,它就恒为 live,手机消息就恒能进去 —— 这就是你说的方案的最小实现,**零新增组件**。
|
||||
|
||||
---
|
||||
|
||||
## 5 三条路(粒度 / 是否需要人 / 现状 / 风险)
|
||||
|
||||
| # | 路 | 粒度 | 要人在场 | 现状 | 主要风险 |
|
||||
|---|---|---|---|---|---|
|
||||
| **A** | **人用手机发一条消息**(走自研 443 通道,或官方微信助理) | **任意** | 要 | ✅ 立即可用 | 必须目标会话 live,否则 409(⛔ 不许抢 writer) |
|
||||
| **B** | **外部定时器**(手机快捷指令 / 服务器 cron 47.77.182.89)→ 走**同一条 443 通道** → `reply` | **可到分钟级** | 不要 | 🔧 通道已通,缺"定时那一端" | 需账号凭据载体;须守 V7 七条(限流/超时/不夺会话);静默失败要有告警 |
|
||||
| **C** | 启用**官方微信/企微助理**,把主会话搬到"助理"那个唯一会话 | 人驱动=任意;自动仍受 1 小时限 | 看谁发 | ⚠️ **未启用**(版本够) | 助理**工作目录固定**(不是本项目)⇒ 我们的机制按 cwd 判归属会**不认它**;跨设备/群聊语义也不同 |
|
||||
|
||||
### 🔴 为什么"5 分钟级自动唤醒"只能走 B
|
||||
|
||||
| 通道 | 能不能到分钟级 | 为什么 |
|
||||
|---|---|---|
|
||||
| 网关 `scheduled-tasks` | ❌ | 桌面端硬编码 `CODEBUDDY_DISABLE_CRON=1`,调度器**从不启动**(已定案) |
|
||||
| WorkBuddy 自动化 | ❌ | 实测最小 `FREQ=HOURLY;INTERVAL=1` = **1 小时**;官方文档也只举周/月 |
|
||||
| 钩子 | ❌ | 事件驱动;**没人动 = 没事件** |
|
||||
| 常驻进程(本机) | ❌ | 不是 WorkBuddy 后代 ⇒ **读不到网关口令** |
|
||||
| **外部定时器 → 443 通道** | ✅ | 定时器在**外面**(不受 WorkBuddy 限制),投递走**已建好的通道** |
|
||||
|
||||
---
|
||||
|
||||
## 6 四个必须同时满足的前提(缺一即失败)
|
||||
|
||||
| # | 前提 | 现状 | 不满足会怎样 |
|
||||
|---|---|---|---|
|
||||
| 1 | 目标会话 **= 桌面当前打开的那个**(live) | 🔴 **当前不满足**(live 是 `fe146dd9`) | `reply` ⇒ **409**;若改走 ACP 借用 ⇒ 目标被 writer 占用时**夺不了**,且 **T2 明令不许抢** |
|
||||
| 2 | 该会话的 **cwd = 网关 cwd** | ✅ 已是本工作区 | 网关跨 cwd 一律 **404 SESSION_NOT_FOUND** |
|
||||
| 3 | 电脑常开 + WorkBuddy 运行 + 垫片/覆盖网络在 | ✅ 20090 在听、网关活着 | 通道整条断(官方也这么要求) |
|
||||
| 4 | 守 **V7 七条**(单向依赖/不夺会话/限流/超时熔断/不占资源…) | ✅ 已定稿 | 违反即事故:**绝不允许"手机侧的问题"变成"WorkBuddy 异常"** |
|
||||
|
||||
---
|
||||
|
||||
## 7 建议(已定项,不是征询)
|
||||
|
||||
1. **主会话 = 一个固定会话 + 桌面一直开着它**。这是你方案的最小实现,**先按这个用**(人发即唤醒,零新增组件)。
|
||||
2. **机制侧补一条"一致性校验",不改选择逻辑**:在收尾自判/看板里增加一项 —— 用 `GET /api/v1/sessions/live` 核「主会话是否就是 live」,**不一致就在看板上标黄**(而不是偷偷投不到)。理由:`reply` 的客观判据就是 live,现在机制里的"主会话"是**按标题/工作区猜**的,两者会漂移(今天实测就差了一个)。
|
||||
3. **要不要"自动"由你定**:
|
||||
- 选**接受人发** ⇒ 到此为止,最省、最符合"别老用自动任务"。
|
||||
- 选**要自动(分钟级)** ⇒ 只能走 **B**:在**手机侧或服务器**放定时器,走 443 通道 `reply`;⚠️ 这条要单独评审(凭据载体 + 限流 + 静默失败告警),**不建议今天顺手做**。
|
||||
4. ⛔ **不建议**为了"能投到任意会话"去动 `reply` 的语义或抢 `writer_occupied` —— 那是 `v3 §0.5 T2` 与红线明文禁止的。
|
||||
|
||||
---
|
||||
|
||||
## 8 图:唤醒消息的实际路径(这条链比"定时"更可靠)
|
||||
|
||||
```
|
||||
[你/定时器] [外面] [本机] [桌面]
|
||||
手机 App ──┐
|
||||
├─→ ai1net 覆盖网络 ──→ 垫片 20090 ──→ WorkBuddy gateway ──→ 会话
|
||||
服务器 cron ┘ (HTTPS 443) (注入 x-access-token) (动态口 56975) ↑
|
||||
(剥掉 Origin) │
|
||||
必须是 live ⚠️
|
||||
失败方向:关掉自己(503/409)→ ⛔ 绝不影响 WorkBuddy
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9 顺带发现(⚠️ 未处理,仅报告)
|
||||
|
||||
| # | 发现 | 影响 |
|
||||
|---|---|---|
|
||||
| 1 | 库里 **59 条 `once` 自动化仍是 ACTIVE**(早已跑完) | 统计虚高(旧坑 P7);⛔ 我没动(不擅自清) |
|
||||
| 2 | 本机**未启用**官方微信/企微助理(0 条远程来源会话) | 备选路 C 处于"可开未开"状态 |
|
||||
| 3 | 客户端源码里有 `settings.claw.*` 系列文案 ⇒ 助理能力确实在,只是没绑定 | 与版本 5.6.2 ≥ 4.6.4 一致 |
|
||||
|
||||
---
|
||||
|
||||
## 10 出处
|
||||
|
||||
| 内容 | 位置 |
|
||||
|---|---|
|
||||
| 官方 · 自动化 | `https://www.workbuddy.cn/docs/workbuddy/From-Beginner-to-Expert-Guide/Function-Description/Automation-Guide` |
|
||||
| 官方 · 微信助理 | `https://www.workbuddy.cn/docs/workbuddy/WeixinBot-Guide` |
|
||||
| 官方 · 企微助理(**含"助理=单会话"对比表**) | `https://www.workbuddy.cn/docs/workbuddy/Wecom-Guide` |
|
||||
| 本项目 · 会话侧契约(实测) | `交付物/手机App经覆盖网络操作WorkBuddy-架构定稿v3-20260929.md` §2.2 / §0.5 |
|
||||
| 本项目 · 唤醒为何从未响(定案) | `交付物/查唤醒为什么断-结论-20260930.md` |
|
||||
| 非官方(已标注未证实) | `ima.qq.com` 知识库里的 WorkBuddy 教程文("条件触发"来源) |
|
||||
|
||||
---
|
||||
|
||||
## 11 追加判定(13:0x):「间隔 **5 分钟**自动运行的会话」——**产品层面做不到**
|
||||
|
||||
> 用户提议:**「一个会话不能多个主会话同时执行,所以还是只能回到自动任务,考虑在主会话工作区下创建间隔 5 分钟自动运行的会话」**
|
||||
> 判定:**5 分钟这个粒度不存在**,且"自动化会话"与"唤醒主会话"是两件事。下面是证据。
|
||||
|
||||
### 11.1 源码级证据:`FREQ` 是**硬白名单**
|
||||
|
||||
客户端自带的 rrule 解析器(`app.asar` → `/main/log-acl-guard.js`,偏移 ≈403.6 KB 起)原文:
|
||||
|
||||
```js
|
||||
const rawFreq = map.get("FREQ");
|
||||
if (!rawFreq) invalidRule("missing FREQ");
|
||||
if (rawFreq !== "HOURLY" && rawFreq !== "DAILY" && rawFreq !== "WEEKLY"
|
||||
&& rawFreq !== "MONTHLY" && rawFreq !== "YEARLY")
|
||||
invalidRule(`unsupported FREQ=${rawFreq}`);
|
||||
...
|
||||
interval: parsePositiveInt(map.get("INTERVAL"), 1) // INTERVAL ≥ 1,单位由 FREQ 决定
|
||||
```
|
||||
|
||||
| 事实 | 读数 |
|
||||
|---|---|
|
||||
| 全包检索 `MINUTELY` / `SECONDLY` | **命中 0 处** |
|
||||
| `INTERVAL` 下限 | `parsePositiveInt(..., 1)` ⇒ **≥1**,单位=FREQ ⇒ `HOURLY;INTERVAL=1` = **每小时 = 理论最小** |
|
||||
| 是否只是 UI 限制 | ❌ **不是**。源码注释明写:同一实现**在 workbuddy-server `automation/schedule-utils.ts` 与 VSCode 扩展 `automation-storage.ts` 各有一份等价副本,多处必须同步改** ⇒ **三层一致** |
|
||||
| `HOURLY` 能否错开分钟 | ⚠️ `formatRRule` 对 HOURLY 只输出 `FREQ=HOURLY;INTERVAL=n;BYDAY=…`,**不产出 BYMINUTE** ⇒ HOURLY 一律落在**整点那一分钟** |
|
||||
|
||||
⇒ **无法创建"间隔 5 分钟"的自动任务。**
|
||||
🔴 若绕过 UI 手改 DB 塞 `FREQ=MINUTELY` ⇒ 解析器抛 `unsupported FREQ=MINUTELY` ⇒ 该自动化**永不触发** —— **正是今天刚查过的那类"幽灵任务"**(有登记、有状态、从不执行)⇒ **⛔ 不做**。
|
||||
|
||||
### 11.2 代价证据:**一次运行 = 一个新会话**(从不复用)
|
||||
|
||||
| 读数 | 值 |
|
||||
|---|---|
|
||||
| `automation_runs` 总运行 / 不同 thread | **74 / 74 ⇒ 1:1** |
|
||||
| 举例:`b9aaabff`(每日日报) | 跑 **4 次 → 4 个不同会话** |
|
||||
| 会话表 58 条里,后台自动化会话 | **47 条** |
|
||||
|
||||
⇒ 若真按 5 分钟跑:**288 个新会话 / 天**,每次还要起一次 agent、烧一次积分、往会话列表里灌一条 ⇒ 直接撞上"**会话洪泛**"(旧坑 P6)。
|
||||
|
||||
### 11.3 🔴 更要紧的一条:**自动任务会话 ≠ 唤醒主会话**
|
||||
|
||||
自动化每次开的是**新会话**,它自己跑;**它不会让已存在的主会话"活过来"**。
|
||||
要真唤醒主会话,那条自动化的 prompt 必须**显式调用** `POST /api/v1/sessions/{id}/reply` —— 而这条 API **只认 live**。
|
||||
⇒ **绕了一圈又回到同一个硬前提:主会话必须是"桌面当前打开的那一个"。**
|
||||
|
||||
### 11.4 能做的三档(按可行性排序)
|
||||
|
||||
| 档 | 做法 | 粒度 | 代价 | 判定 |
|
||||
|---|---|---|---|---|
|
||||
| **①** | **1 小时自动化**(官方唯一可用粒度)prompt = 写触发戳 + `reply` 投主会话 | **1 h** | **24 会话/天** | ✅ 现成,今天可建 |
|
||||
| **②** | **外部定时器**(手机快捷指令 / 服务器 cron `47.77.182.89`)→ 走**已建好的 443 通道** → `reply` | **5 分钟可做** | 🔴 **0 个新会话**(只往已有会话投一条消息) | ✅ **唯一能到 5 分钟、且最省**;缺"定时那一端"+凭据载体 ⇒ **需单独评审** |
|
||||
| **③** | 手写 DB 塞 `FREQ=HOURLY;BYMINUTE=0,5,10…` | 未验证 | 未验证 | ⚠️ 解析器**认** BYMINUTE,但 HOURLY 的 `formatRRule` 不产出它、**调度器是否真按分钟触发未知** ⇒ 只能**先试 1 条并观察是否真触发**;不成就退回 ① |
|
||||
|
||||
### 11.5 建议(已定项)
|
||||
|
||||
1. ⛔ **不要再往"5 分钟自动任务"上使劲** —— 产品层面不存在这个粒度,硬塞只会得到幽灵任务。
|
||||
2. **要 5 分钟节奏 ⇒ 走 ②**:定时器放在 **WorkBuddy 外面**(手机侧或服务器),投递走**同一条已验收的 443 通道**。它同时满足三件事:真 5 分钟、不爆会话列表、不烧 288 次积分。
|
||||
3. **接受 1 小时 ⇒ 走 ①**:一条 recurring 自动化(`FREQ=HOURLY;INTERVAL=1`),prompt 只做两步(写触发戳 + `reply` 唤醒主会话)。
|
||||
4. ⚠️ **无论哪一档,"主会话必须 live"绕不过** ⇒ 请**固定一个会话并在桌面上一直开着它**;否则 `reply` 只会 409,而改走 ACP 借用会**夺走你正在看的会话**(红线 T2 禁止)。
|
||||
|
||||
Reference in new issue
Block a user