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.
Files changed (3) hide show
  1. package/README.md +21 -0
  2. package/package.json +1 -1
  3. 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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wechat-opencode-bot",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "微信 ⇄ opencode 桥接机器人:微信消息通过 opencode serve 驱动 AI 回复,支持定时任务主动推送、媒体收发,跨平台(macOS/Windows/Linux)。",
5
5
  "type": "module",
6
6
  "bin": {
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
- // 无进度兜底:长时间没有任何新 part 则视为卡死,abort session 避免永久 busy
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
- }, 15_000);
439
+ }, 10_000);
429
440
 
430
441
  try {
431
442
  while (!done) {