wechat-opencode-bot 0.2.0 → 0.2.1
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 +21 -0
- package/package.json +1 -1
- package/src/bridge.js +15 -4
package/README.md
CHANGED
|
@@ -58,6 +58,27 @@ wechat-bot install # macOS 生成 launchd plist 并加载
|
|
|
58
58
|
- **图片/文件**:接收时下载到本地供 AI 读取(`[图片: 路径]`);发送时用 `[media: /绝对/路径]` 标记上传。
|
|
59
59
|
- **自动重连**:网络错误指数退避,session 过期自动提示重新登录。
|
|
60
60
|
|
|
61
|
+
## 权限配置
|
|
62
|
+
|
|
63
|
+
opencode serve 为无人值守环境。建议在 opencode 配置(`~/.config/opencode/opencode.json`)中设置权限,让工具自动执行而不触发权限确认(权限确认在无头环境会卡住会话):
|
|
64
|
+
|
|
65
|
+
```json
|
|
66
|
+
{
|
|
67
|
+
"permission": {
|
|
68
|
+
"bash": { "*": "allow" },
|
|
69
|
+
"read": { "*": "allow" },
|
|
70
|
+
"write": { "*": "allow" },
|
|
71
|
+
"edit": { "*": "allow" },
|
|
72
|
+
"skill": { "*": "deny" },
|
|
73
|
+
"question": "allow",
|
|
74
|
+
"webfetch": "allow"
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
- `bash`/`read` 等放行:微信里可直接让 AI 执行 `tea`、`git` 等命令并读取文件
|
|
80
|
+
- `skill` 设为 `deny`:skill 工具在 serve 环境可能不触发事件结束(卡住会话),建议禁止
|
|
81
|
+
|
|
61
82
|
## 数据文件
|
|
62
83
|
|
|
63
84
|
- `sessions.json`:微信用户 → opencode session 映射
|
package/package.json
CHANGED
package/src/bridge.js
CHANGED
|
@@ -357,8 +357,7 @@ async function askOpenCodeStream(sessionId, text, onChunk) {
|
|
|
357
357
|
[schedule_list] 查看当前定时任务
|
|
358
358
|
[schedule_del: 任务ID] 删除指定定时任务
|
|
359
359
|
到点后系统会调用你生成内容并主动推送给用户。
|
|
360
|
-
回复要求:
|
|
361
|
-
重要约束: 本环境是无人工值守的微信会话,不要调用 skill、读取/写入文件、执行 shell 命令等工具,不要触发权限确认。直接基于已有信息回答即可,避免因工具等待权限确认导致回复卡死。`;
|
|
360
|
+
回复要求: 请给出完整、详细、原样的回答,把你在命令行中会输出的全部内容直接发过来,不要缩略、不要只给总结或要点提示,确保用户看到完整答案。如果执行了代码或命令,把关键输出也一并附上。`;
|
|
362
361
|
|
|
363
362
|
// 确认 session 存在
|
|
364
363
|
await api(`/session/${sessionId}`, {}, 5000);
|
|
@@ -413,10 +412,22 @@ async function askOpenCodeStream(sessionId, text, onChunk) {
|
|
|
413
412
|
}
|
|
414
413
|
}, MAX_LLM_RESPONSE_TIME_MS);
|
|
415
414
|
|
|
416
|
-
//
|
|
415
|
+
// 兜底检测:SSE 可能漏发 idle 事件(工具执行后),定期轮询 session 状态判断是否真正结束;
|
|
416
|
+
// 长时间无任何新 part 则视为卡死,abort session 避免永久 busy
|
|
417
417
|
let lastProgress = Date.now();
|
|
418
418
|
const stallTimer = setInterval(async () => {
|
|
419
419
|
if (done) return;
|
|
420
|
+
// 兜底:SSE 漏发 idle 时,主动查 session 状态结束循环
|
|
421
|
+
try {
|
|
422
|
+
const status = await api(`/session/status`, {}, 5000);
|
|
423
|
+
const entry = status?.[sessionId];
|
|
424
|
+
const st = typeof entry?.type === 'string' ? entry.type : entry?.status?.type;
|
|
425
|
+
if (st === 'idle') {
|
|
426
|
+
log(`SSE 未收到 idle,经轮询确认 session 已空闲`);
|
|
427
|
+
done = true;
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
} catch {}
|
|
420
431
|
if (Date.now() - lastProgress > 90_000) {
|
|
421
432
|
log(`流式无进度超时(90s),abort session ${sessionId}`);
|
|
422
433
|
try {
|
|
@@ -425,7 +436,7 @@ async function askOpenCodeStream(sessionId, text, onChunk) {
|
|
|
425
436
|
ctrl.abort();
|
|
426
437
|
done = true;
|
|
427
438
|
}
|
|
428
|
-
},
|
|
439
|
+
}, 10_000);
|
|
429
440
|
|
|
430
441
|
try {
|
|
431
442
|
while (!done) {
|