@chbo297/infoflow 2026.5.7-beta.3 → 2026.5.8

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 +34 -18
  2. package/dist/src/bot.js +37 -22
  3. package/package.json +3 -2
package/README.md CHANGED
@@ -43,22 +43,30 @@ BAIDU_NPM_REGISTRY=http://registry.npm.baidu-int.com bash scripts/deploy.sh
43
43
 
44
44
  方式 A:通过独立 tools 包安装并部署(推荐,支持 `update` 子命令)
45
45
 
46
+ <!-- sync:infoflow-plugin-version -->
46
47
  ```bash
47
48
  # 正式版(latest)
48
- npx -y @chbo297/infoflow-openclaw-tools update --version 2026.5.6 --registry https://registry.npmjs.org
49
+ npx -y @chbo297/infoflow-openclaw-tools update --version 2026.5.8 --registry https://registry.npmjs.org
50
+ ```
51
+ <!-- /sync:infoflow-plugin-version -->
49
52
 
50
- # Beta 版(示例)
51
- npx -y @chbo297/infoflow-openclaw-tools@beta update --version 2026.5.7-beta.2 --registry https://registry.npmjs.org
53
+ ```bash
54
+ # Beta 版(示例,版本号请按实际预发包替换)
55
+ npx -y @chbo297/infoflow-openclaw-tools@beta update --version 2026.5.8-beta.1 --registry https://registry.npmjs.org
52
56
  ```
53
57
 
54
58
  方式 B:通过 OpenClaw 插件命令安装
55
59
 
60
+ <!-- sync:infoflow-plugin-version -->
56
61
  ```bash
57
62
  # 正式版
58
- openclaw plugins install @chbo297/infoflow@2026.5.6
63
+ openclaw plugins install @chbo297/infoflow@2026.5.8
64
+ ```
65
+ <!-- /sync:infoflow-plugin-version -->
59
66
 
60
- # Beta 版(示例)
61
- openclaw plugins install @chbo297/infoflow@2026.5.7-beta.2
67
+ ```bash
68
+ # Beta 版(示例,版本号请按实际预发包替换)
69
+ openclaw plugins install @chbo297/infoflow@2026.5.8-beta.1
62
70
  ```
63
71
 
64
72
  安装后建议检查插件状态:
@@ -72,9 +80,11 @@ openclaw plugins inspect infoflow
72
80
 
73
81
  发布到 npm 后,可直接通过独立 tools 包执行安装/升级:
74
82
 
83
+ <!-- sync:infoflow-plugin-version -->
75
84
  ```bash
76
- npx -y @chbo297/infoflow-openclaw-tools update --version 2026.5.6 --registry https://registry.npmjs.org
85
+ npx -y @chbo297/infoflow-openclaw-tools update --version 2026.5.8 --registry https://registry.npmjs.org
77
86
  ```
87
+ <!-- /sync:infoflow-plugin-version -->
78
88
 
79
89
  常用参数:
80
90
 
@@ -97,28 +107,34 @@ npx -y @chbo297/infoflow-openclaw-tools update --version 2026.5.6 --registry htt
97
107
 
98
108
  ### 版本升级、打 tag、推送与 npm 发布流程
99
109
 
100
- 每次发布新版本(例如 `2026.5.6`)建议按以下顺序执行:
110
+ 每次发布新版本时,先将 `package.json` 的 `version` 设为待发版本号,再按下述顺序执行。上文「首次安装 / npx 更新」与下文发版流程中,各 bash 代码块外侧有一对用于自动替换的 HTML 注释标记;发版前请执行 **`npm run sync-readme-install-version`**,脚本会按当前 `package.json` 的 `version` 更新这些块内的版本号,以免 README 与 npm 不一致。
101
111
 
112
+ <!-- sync:infoflow-plugin-version -->
102
113
  ```bash
103
114
  # 1) 修改版本号(会同步 package-lock.json)
104
- npm version 2026.5.6 --no-git-tag-version
115
+ npm version 2026.5.8 --no-git-tag-version
105
116
 
106
- # 2) 发布前校验
117
+ # 2) 同步 README 中标记块内的推荐安装命令与下文中的 tag / commit 示例版本号
118
+ npm run sync-readme-install-version
119
+
120
+ # 3) 发布前校验
107
121
  npm run typecheck
108
122
  npm run test
109
123
  npm run build
110
124
 
111
- # 3) 提交版本变更
112
- git add package.json package-lock.json README.md scripts src
113
- git commit -m "2026.5.6"
125
+ # 4) 提交版本变更(含 README、CHANGELOG 等)
126
+ git add package.json package-lock.json README.md CHANGELOG.md scripts src
127
+ git commit -m "2026.5.8"
114
128
 
115
- # 4) 打 tag 并推送代码与 tag
116
- git tag 2026.5.6
129
+ # 5) 打 tag 并推送代码与 tag
130
+ git tag 2026.5.8
117
131
  git push origin main
118
- git push origin 2026.5.6
132
+ git push origin 2026.5.8
119
133
 
120
- # 5) 发布 npm(可按需指定 registry)
134
+ # 6) 发布 npm(可按需指定 registry)
121
135
  npm publish
122
136
  # 或
123
137
  # npm publish --registry https://registry.npmjs.org
124
- ```
138
+ ```
139
+ <!-- /sync:infoflow-plugin-version -->
140
+
package/dist/src/bot.js CHANGED
@@ -211,12 +211,10 @@ function checkReplyToBot(bodyItems, accountId) {
211
211
  }
212
212
  return false;
213
213
  }
214
- // ---------------------------------------------------------------------------
215
- // Shared reply judgment rules (reused across prompt builders)
216
- // ---------------------------------------------------------------------------
217
214
  /** Shared judgment rules and reply format requirements for all conditional-reply prompts */
218
- function buildReplyJudgmentRules() {
219
- return [
215
+ function buildReplyJudgmentRules(options) {
216
+ const variant = options?.variant ?? "default";
217
+ const lines = [
220
218
  "# Rules for Group Message Response",
221
219
  "",
222
220
  "## When to Reply",
@@ -231,19 +229,12 @@ function buildReplyJudgmentRules() {
231
229
  "Do NOT reply if ANY of the following is true:",
232
230
  "- The message is casual chatter, banter, emoji-only, or has no actionable question/request",
233
231
  "- The user explicitly indicates they don't want your response",
234
- "- The message is directed at another person, not at you",
235
- "- You lack the context or knowledge to give a useful answer (e.g., private/internal info you don't have access to)",
236
- "- The message intent is ambiguous and a wrong guess would be more disruptive than silence",
237
- "",
238
- "## Response Format",
239
- "",
240
- "- If you can answer: respond directly and concisely. Do not explain why you chose to answer. Do not add filler or pleasantries.",
241
- "- If you cannot answer: output exactly `NO_REPLY` — nothing else, no explanation, no apology.",
242
- "",
243
- "## Guiding Principle",
244
- "",
245
- "When in doubt, prefer silence (`NO_REPLY`). A missing reply is far less disruptive than an irrelevant or incorrect one in a group chat.",
246
- ].join("\n");
232
+ ];
233
+ if (variant === "default") {
234
+ lines.push("- The message is directed at another person, not at you");
235
+ }
236
+ lines.push("- You lack the context or knowledge to give a useful answer (e.g., private/internal info you don't have access to)", "- The message intent is ambiguous and a wrong guess would be more disruptive than silence", "", "## Response Format", "", "- If you can answer: respond directly and concisely. Do not explain why you chose to answer. Do not add filler or pleasantries.", "- If you cannot answer: output exactly `NO_REPLY` — nothing else, no explanation, no apology.", "", "## Guiding Principle", "", "When in doubt, prefer silence (`NO_REPLY`). A missing reply is far less disruptive than an irrelevant or incorrect one in a group chat.");
237
+ return lines.join("\n");
247
238
  }
248
239
  /**
249
240
  * Build a GroupSystemPrompt for watch-mention triggered messages.
@@ -251,10 +242,11 @@ function buildReplyJudgmentRules() {
251
242
  */
252
243
  function buildWatchMentionPrompt(mentionedId) {
253
244
  return [
254
- `Someone in the group @mentioned ${mentionedId}. As ${mentionedId}'s assistant, you observed this message.`,
255
- "Decide whether you can answer on their behalf or provide help.",
245
+ `Someone in the group @mentioned ${mentionedId}. You are ${mentionedId}'s assistant and you see this message.`,
246
+ "Before you write your reply, use the visible thread context, quoted/reply context if any, and your knowledge and tools to decide whether you can add value (a direct answer, a concrete next step, or a useful pointer). Prefer making a genuine attempt to help when context makes it reasonable; do not send exploratory or partial messages to the group—produce a single final message.",
247
+ "If you can provide worthwhile help or leads, reply with that information clearly and concisely. If, after that effort, you still have nothing useful to add, output exactly NO_REPLY and nothing else.",
256
248
  "",
257
- buildReplyJudgmentRules(),
249
+ buildReplyJudgmentRules({ variant: "watchAssistant" }),
258
250
  "",
259
251
  "# Examples",
260
252
  "",
@@ -283,7 +275,7 @@ function buildWatchRegexPrompt(patterns) {
283
275
  `The message content matched one of the configured watch patterns ${label}.`,
284
276
  "As the group assistant, you observed this message. Decide whether you can provide help or a valuable reply.",
285
277
  "",
286
- buildReplyJudgmentRules(),
278
+ buildReplyJudgmentRules({ variant: "watchAssistant" }),
287
279
  ].join("\n");
288
280
  }
289
281
  /**
@@ -317,6 +309,21 @@ function buildProactivePrompt() {
317
309
  buildReplyJudgmentRules(),
318
310
  ].join("\n");
319
311
  }
312
+ /**
313
+ * Appended last to every group-chat GroupSystemPrompt. Keeps the visible group reply
314
+ * conclusion-oriented: no raw tool transcripts or retrieval dumps; multi-step work
315
+ * stays in subagent (or equivalent) with only a synthesized answer to the group.
316
+ */
317
+ function buildGroupOutputHygienePrompt() {
318
+ return [
319
+ "# Group chat output (hard constraint)",
320
+ "",
321
+ "- Reply to the group with **only the final user-facing answer** in one concise message (or a few short messages if the channel requires splitting).",
322
+ "- **Do not** include tool-call traces, raw intermediate search/retrieval payloads, or long scratchpad-style reasoning in the group-visible text.",
323
+ "- If the task needs exploration across multiple steps, do that work in a **subagent** (or equivalent isolated context) and return **only** the merged conclusion to the group.",
324
+ "- If the user explicitly asks for your reasoning or steps, satisfy that with a **brief** numbered or bulleted summary **inside the same** conclusion-style reply — still **not** raw tool logs or full intermediate dumps.",
325
+ ].join("\n");
326
+ }
320
327
  // ---------------------------------------------------------------------------
321
328
  // Group reply tracking (in-memory) for follow-up window
322
329
  // ---------------------------------------------------------------------------
@@ -930,6 +937,12 @@ export async function handleInfoflowMessage(params) {
930
937
  ? `${existing}\n\n---\n\n${groupCfg.systemPrompt}`
931
938
  : groupCfg.systemPrompt;
932
939
  }
940
+ // Default output hygiene for every dispatched group message (always last)
941
+ const hygiene = buildGroupOutputHygienePrompt();
942
+ const beforeHygiene = ctxPayload.GroupSystemPrompt ?? "";
943
+ ctxPayload.GroupSystemPrompt = beforeHygiene
944
+ ? `${beforeHygiene}\n\n---\n\n${hygiene}`
945
+ : hygiene;
933
946
  }
934
947
  // Build unified target: "group:<id>" for group chat, username for private chat
935
948
  const to = isGroup && groupId !== undefined ? `group:${groupId}` : fromuser;
@@ -1008,3 +1021,5 @@ export const _extractMentionIds = extractMentionIds;
1008
1021
  export const _checkWatchRegex = checkWatchRegex;
1009
1022
  /** @internal — Check if message is a reply to one of the bot's own messages. Only exported for tests. */
1010
1023
  export const _checkReplyToBot = checkReplyToBot;
1024
+ /** @internal — Group output hygiene fragment appended to GroupSystemPrompt. Only exported for tests. */
1025
+ export const _buildGroupOutputHygienePrompt = buildGroupOutputHygienePrompt;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chbo297/infoflow",
3
- "version": "2026.5.7-beta.3",
3
+ "version": "2026.5.8",
4
4
  "description": "OpenClaw Infoflow (如流) channel plugin for Baidu enterprise messaging",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -47,7 +47,8 @@
47
47
  "scripts": {
48
48
  "build": "rm -rf dist && tsc -p tsconfig.build.json",
49
49
  "typecheck": "tsc --noEmit",
50
- "test": "vitest run"
50
+ "test": "vitest run",
51
+ "sync-readme-install-version": "node scripts/sync-readme-install-version.mjs"
51
52
  },
52
53
  "devDependencies": {
53
54
  "typescript": "^6.0.3",