create-openclaw-bot 5.13.9 → 5.14.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 CHANGED
@@ -7,7 +7,7 @@
7
7
  *Run one command → open the dashboard → your bot is live. Windows · macOS · Linux · VPS — Docker-powered, auto-installed for you.*
8
8
 
9
9
  <p align="center">
10
- <a href="https://github.com/tuanminhhole/openclaw-setup/releases"><img src="https://img.shields.io/badge/RELEASE-v5.13.9-0EA5E9?style=for-the-badge" alt="Version 5.13.9" /></a>
10
+ <a href="https://github.com/tuanminhhole/openclaw-setup/releases"><img src="https://img.shields.io/badge/RELEASE-v5.14.1-0EA5E9?style=for-the-badge" alt="Version 5.14.1" /></a>
11
11
  <a href="https://github.com/tuanminhhole/openclaw-setup?tab=MIT-1-ov-file"><img src="https://img.shields.io/badge/LICENSE-MIT-success?style=for-the-badge" alt="MIT License" /></a>
12
12
  <a href="https://www.npmjs.com/package/create-openclaw-bot"><img src="https://img.shields.io/npm/v/create-openclaw-bot?style=for-the-badge&label=CLI&color=2563EB&logo=npm&logoColor=white" alt="NPM Version" /></a>
13
13
  <a href="https://github.com/tuanminhhole/openclaw-setup/stargazers"><img src="https://img.shields.io/github/stars/tuanminhhole/openclaw-setup?style=for-the-badge&color=eab308&logo=github&logoColor=white" alt="GitHub Stars" /></a>
@@ -37,11 +37,25 @@
37
37
 
38
38
  ---
39
39
 
40
- ## 🆕 What's New in v5.13.9
40
+ ## 🆕 What's New in v5.14.1
41
+
42
+ - 🦞 **Zalo bots acknowledge your message with a reaction**: an icon lands on your message right away, so you can see the bot picked it up while the answer is still being written. It runs in the channel layer, so it **costs no tokens**. On by default for new Zalo bots, and **existing ones pick it up on update**; change or disable it via `messages.ackReaction` in `openclaw.json`. Needs Zalo Connect 3.0.15+.
43
+
44
+ <details>
45
+ <summary><b>Previous: What's new in v5.14.0</b></summary>
46
+
47
+ - 🛠️ **Bots build their own skills**: ask your bot for a reusable capability ("make me a skill for X") and it writes the skill and puts it to work in the same reply — no approval step, no config editing. The skill is saved to `skills/<name>/SKILL.md` in the bot's workspace and loads itself. **Existing bots pick this up automatically on update.**
48
+
49
+ </details>
50
+
51
+ <details>
52
+ <summary><b>Previous: What's new in v5.13.9</b></summary>
41
53
 
42
54
  - 🧠 **Always-on memory for every bot (learning-memory)**: a new context-engine plugin injects your curated `MEMORY.md` + `USER.md` into **every** turn — including group chats, which the default recall skips. Bots stop forgetting context and rules over time: no more chiming in when nobody called them, or re-asking things you already told them. Auto-installed for new bots + a 1-click card in the dashboard.
43
55
  - 🧹 **Retired TencentDB Agent Memory** in favor of the always-on engine above (no external service needed). Existing bots are auto-migrated on update — the old learning-memory *skill* and the TencentDB plugin are removed automatically.
44
56
 
57
+ </details>
58
+
45
59
  <details>
46
60
  <summary><b>Previous: What's new in v5.13.4</b></summary>
47
61
 
package/README.vi.md CHANGED
@@ -7,7 +7,7 @@
7
7
  *Chạy một lệnh → mở dashboard → bot lên sóng. Windows · macOS · Linux · VPS — chạy trên Docker, tự cài giúp bạn.*
8
8
 
9
9
  <p align="center">
10
- <a href="https://github.com/tuanminhhole/openclaw-setup/releases"><img src="https://img.shields.io/badge/RELEASE-v5.13.9-0EA5E9?style=for-the-badge" alt="Version 5.13.9" /></a>
10
+ <a href="https://github.com/tuanminhhole/openclaw-setup/releases"><img src="https://img.shields.io/badge/RELEASE-v5.14.1-0EA5E9?style=for-the-badge" alt="Version 5.14.1" /></a>
11
11
  <a href="https://github.com/tuanminhhole/openclaw-setup?tab=MIT-1-ov-file"><img src="https://img.shields.io/badge/LICENSE-MIT-success?style=for-the-badge" alt="MIT License" /></a>
12
12
  <a href="https://www.npmjs.com/package/create-openclaw-bot"><img src="https://img.shields.io/npm/v/create-openclaw-bot?style=for-the-badge&label=CLI&color=2563EB&logo=npm&logoColor=white" alt="NPM Version" /></a>
13
13
  <a href="https://github.com/tuanminhhole/openclaw-setup/stargazers"><img src="https://img.shields.io/github/stars/tuanminhhole/openclaw-setup?style=for-the-badge&color=eab308&logo=github&logoColor=white" alt="GitHub Stars" /></a>
@@ -37,11 +37,25 @@
37
37
 
38
38
  ---
39
39
 
40
- ## 🆕 Có gì mới trong v5.13.9
40
+ ## 🆕 Có gì mới trong v5.14.1
41
+
42
+ - 🦞 **Bot Zalo thả reaction báo đã nhận tin**: một icon xuất hiện ngay trên tin bạn vừa gửi, nên bạn biết bot đã nhận trong khi nó còn đang viết trả lời. Chạy ở tầng kênh chat nên **không tốn token**. Bật mặc định cho bot Zalo mới, **bot cũ tự nhận khi cập nhật**; đổi icon hay tắt thì sửa `messages.ackReaction` trong `openclaw.json`. Cần Zalo Connect 3.0.15+.
43
+
44
+ <details>
45
+ <summary><b>Trước đó: Có gì mới trong v5.14.0</b></summary>
46
+
47
+ - 🛠️ **Bot tự tạo skill cho chính nó**: nhờ bot làm một kỹ năng dùng lại ("tạo cho anh skill X") là nó viết xong và dùng được ngay trong cùng câu trả lời — không còn bước chờ duyệt, không phải sửa cấu hình. Skill lưu vào `skills/<tên>/SKILL.md` trong workspace của bot và tự nạp. **Bot cũ tự nhận khi cập nhật.**
48
+
49
+ </details>
50
+
51
+ <details>
52
+ <summary><b>Trước đó: Có gì mới trong v5.13.9</b></summary>
41
53
 
42
54
  - 🧠 **Trí nhớ always-on cho mọi bot (learning-memory)**: plugin context-engine mới nạp `MEMORY.md` + `USER.md` đã chắt lọc vào **MỌI lượt** — kể cả trong nhóm (điều recall mặc định bỏ qua). Bot hết quên ngữ cảnh/quy tắc theo thời gian: không còn "nói leo" khi không ai gọi, không hỏi lại điều bạn đã dặn. Tự cài cho bot mới + có card 1-chạm trên dashboard.
43
55
  - 🧹 **Bỏ TencentDB Agent Memory**, thay bằng engine always-on ở trên (không cần dịch vụ ngoài). Bot cũ tự migrate khi cập nhật — *skill* learning-memory cũ và plugin TencentDB được gỡ tự động.
44
56
 
57
+ </details>
58
+
45
59
  <details>
46
60
  <summary><b>Trước đó: Có gì mới trong v5.13.4</b></summary>
47
61
 
@@ -114,10 +114,34 @@
114
114
  // nửa đêm và đặt cron/lịch vào quá khứ. Lấy tz người dùng chọn ở UI Cài đặt (mặc định VN).
115
115
  userTimezone,
116
116
  compaction: { mode: 'safeguard' },
117
- // Trim stale tool results before Anthropic's prompt-cache TTL expires so the
118
- // re-cache write stays small lower token cost on long sessions, zero downside.
119
- // The stable system prompt (AGENTS.md/SOUL.md…) stays cached above the boundary.
120
- contextPruning: { mode: 'cache-ttl', ttl: '5m' },
117
+ // Trim stale tool results from context before each LLM call. Lowers token
118
+ // cost on long sessions AND keeps a heavy multi-step turn (deep research +
119
+ // file/PDF gen) from piling up tool output that overflows the model window
120
+ // mid tool-loop. These bots run on 9router (no Anthropic prompt cache), so a
121
+ // short 2m TTL lets pruning engage sooner inside a long turn — no cache
122
+ // downside. The stable system prompt (AGENTS.md/SOUL.md…) is never pruned.
123
+ contextPruning: { mode: 'cache-ttl', ttl: '2m' },
124
+ // Compress vision inputs — these bots are image-heavy (infographics, PDF
125
+ // charts, screenshots). "efficient" keeps vision-token cost down so an
126
+ // image-rich turn is far less likely to blow past the context window.
127
+ imageQuality: 'efficient',
128
+ // Downscale image payloads when sanitizing transcript/tool-result content
129
+ // (OpenClaw default is 1200px). Verified failure mode: the bot generated 4K
130
+ // infographics for a PDF and then read them back with the image tool — each
131
+ // read landed a ~100KB base64 blob in the transcript, and the overflow
132
+ // precheck counts that base64 as plain text (~14k tokens per image). Eight of
133
+ // them in one turn = 214k estimated tokens against a 180k budget → abort with
134
+ // "nothing to compact". 1024px keeps charts/screenshots legible to vision
135
+ // while roughly halving the payload.
136
+ imageMaxDimensionPx: 1024,
137
+ // Cap each persisted tool result. The model-context auto default is huge
138
+ // (64k chars/result at 200k tokens), so one heavy turn (e.g. deep research
139
+ // with 40+ web fetches) can pile up 200k+ tokens of tool output in a SINGLE
140
+ // unsplittable turn — which then can't be compacted ("nothing to compact")
141
+ // and poisons the session until a manual reset. 12k chars (~3k tokens) per
142
+ // result keeps per-source content substantial while making that runaway
143
+ // impossible. Applies to persisted results + overflow recovery.
144
+ contextLimits: { toolResultMaxChars: 12000 },
121
145
  // Agent-TURN budget (seconds). 120 was too short for multi-step cloud turns (OCR +
122
146
  // file gen + tool calls). 900 = OpenClaw's own native default and the practical max
123
147
  // we use. This is the turn budget — a DIFFERENT layer from 9router's per-request
@@ -159,6 +183,26 @@
159
183
  };
160
184
  }
161
185
 
186
+ // ── messages (ack reaction) ───────────────────────────────────────────────
187
+ // Drop a reaction on inbound messages so people can see the bot registered theirs
188
+ // before the reply lands. This happens in the channel transport — the model is never
189
+ // involved, so it costs no tokens.
190
+ //
191
+ // Zalo-only, and deliberately so: zalo-connect reads this GLOBAL key (it has no
192
+ // per-channel ackReaction of its own), but the same key also feeds Telegram, Discord,
193
+ // Slack and WhatsApp, which each accept only their own fixed reaction set. Seeding an
194
+ // arbitrary emoji globally would make those channels reject every ack, so other
195
+ // channels keep their existing behaviour until someone picks a value valid there.
196
+ //
197
+ // 🦞 is sent as a Zalo *custom* reaction (emoji as rIcon + a hash as rType), which
198
+ // needs zalo-connect ≥3.0.15 — earlier versions only knew the 55 built-ins and would
199
+ // drop it silently. Scope "all" covers DMs and groups; in a mention-gated group the
200
+ // plugin still only reacts to messages that address the bot, since non-addressed ones
201
+ // are buffered as passive context before the reaction step.
202
+ if (isZaloPersonal(channelKey)) {
203
+ cfg.messages = { ackReaction: '🦞', ackReactionScope: 'all', removeAckAfterReply: false };
204
+ }
205
+
162
206
  // ── commands ──────────────────────────────────────────────────────────────
163
207
  cfg.commands = { native: 'auto', nativeSkills: 'auto', restart: true, ownerDisplay: 'raw' };
164
208
  if (selectedSkills.includes('scheduler')) {
@@ -240,8 +284,17 @@
240
284
  const skillEntries = buildSkillsEntries(skills, selectedSkills);
241
285
  // NOTE: the "zalo-actions" skill was removed — its guidance now lives in the `zalo-connect`
242
286
  // tool description itself (fork ≥ v3.0.2), so no per-bot skill entry is needed anymore.
287
+ //
288
+ // Skill Workshop `approvalPolicy: "auto"` lets the assistant author its own
289
+ // workspace skills end-to-end when the user asks ("tạo skill X"): create the
290
+ // proposal AND apply it in one turn, without a separate operator approval.
291
+ // Apply is still scanner-gated + workspace-scoped + rollback-tracked, so this
292
+ // stays safe. Workspace SKILL.md files auto-load via the skills watcher — no
293
+ // per-skill openclaw.json entry is needed. `autonomous.enabled` stays false so
294
+ // the bot only creates skills on explicit request, never spontaneously.
295
+ cfg.skills = { workshop: { approvalPolicy: 'auto' } };
243
296
  if (Object.keys(skillEntries).length > 0) {
244
- cfg.skills = { entries: skillEntries };
297
+ cfg.skills.entries = skillEntries;
245
298
  }
246
299
 
247
300
  // ── plugins (memory-core dreaming + openclaw-zalo-mod) ────────────────────────────
@@ -261,6 +261,24 @@ if(touched){console.log('[patch-9router] Applied Codex compatibility patch.');}e
261
261
  // context-engine plugin). Drop their config entries so they stop loading; the skill
262
262
  // folders + tencentdb install are removed by the shell steps that follow.
263
263
  const deprecatedCleanupScript = `const fs=require('fs'),path=require('path');const p=path.join(process.cwd(),'.openclaw','openclaw.json');if(fs.existsSync(p)){const c=JSON.parse(fs.readFileSync(p,'utf8'));let ch=false;if(c.plugins&&c.plugins.entries&&c.plugins.entries['memory-tencentdb']){delete c.plugins.entries['memory-tencentdb'];ch=true;}if(c.plugins&&Array.isArray(c.plugins.allow)){const n=c.plugins.allow.filter(x=>x!=='memory-tencentdb'&&x!=='@tencentdb-agent-memory/memory-tencentdb');if(n.length!==c.plugins.allow.length){c.plugins.allow=n;ch=true;}}if(c.skills&&c.skills.entries&&c.skills.entries['learning-memory']){delete c.skills.entries['learning-memory'];ch=true;}if(ch)fs.writeFileSync(p,JSON.stringify(c,null,2));}`;
264
+ // One-shot upgrade for projects created by an older setup (their openclaw.json was
265
+ // generated before these defaults existed, and bot-config-gen only runs when a bot is
266
+ // created/regenerated — so a plain rebuild would never pick them up):
267
+ // • skills.workshop.approvalPolicy:'auto' → the assistant can author a workspace
268
+ // skill end-to-end on request instead of stopping at "proposal awaiting approval".
269
+ // (messages.ackReaction is handled separately, below, because it is Zalo-only.)
270
+ // • imageMaxDimensionPx / imageQuality / contextLimits.toolResultMaxChars → keep one
271
+ // heavy turn (deep research, 4K chart read-back) from overflowing the context
272
+ // window mid tool-loop, which cannot be compacted and poisons the session.
273
+ // Each key is only filled in when absent, so an operator's own tuning is never clobbered.
274
+ const contextDefaultsScript = `const fs=require('fs'),path=require('path');const p=path.join(process.cwd(),'.openclaw','openclaw.json');if(fs.existsSync(p)){const c=JSON.parse(fs.readFileSync(p,'utf8'));let ch=false;c.skills=c.skills||{};c.skills.workshop=c.skills.workshop||{};if(!c.skills.workshop.approvalPolicy){c.skills.workshop.approvalPolicy='auto';ch=true;}const d=(c.agents&&c.agents.defaults)?c.agents.defaults:null;if(d){if(d.imageMaxDimensionPx===undefined){d.imageMaxDimensionPx=1024;ch=true;}if(d.imageQuality===undefined){d.imageQuality='efficient';ch=true;}d.contextLimits=d.contextLimits||{};if(d.contextLimits.toolResultMaxChars===undefined){d.contextLimits.toolResultMaxChars=12000;ch=true;}}if(ch)fs.writeFileSync(p,JSON.stringify(c,null,2));}`;
275
+ // Companion backfill for the same older projects: their TOOLS.md was generated before the
276
+ // skill-authoring / long-turn guidance existed, and workspace files are only written when a
277
+ // bot is created — so a rebuild alone leaves the assistant stopping at "proposal awaiting
278
+ // approval" even once approvalPolicy is 'auto'. (TOOLS.md is listed in AGENTS.md as required
279
+ // reading, so guidance lands there rather than in the main manual.) Appends the block once
280
+ // per workspace, keyed off the `skill_workshop` marker, never rewriting a file that has it.
281
+ const agentsGuidanceScript = `const fs=require('fs'),path=require('path');const vi=['','## 🛠️ Tự tạo skill & việc dài','','**Tự tạo skill:** Khi user nhờ tạo một kỹ năng/quy trình dùng lại (vd _"tạo skill X"_), bạn TỰ làm từ đầu đến cuối — dùng tool **skill_workshop**: tạo proposal RỒI **apply luôn trong cùng lượt** (môi trường này bật approvalPolicy auto, không cần chờ ai duyệt). Skill ghi vào skills/<tên>/SKILL.md và **tự nạp** qua watcher — KHÔNG cần sửa openclaw.json. Đừng dừng ở _"đã tạo proposal, chờ duyệt"_. KHÔNG nhúng bí mật vào skill — đọc từ biến môi trường lúc chạy.','','**Việc dài, nhiều bước (research sâu, dựng báo cáo/PDF):** ảnh/chart bạn vừa tạo thì **đừng đọc lại** bằng tool ảnh (chèn thẳng file vào tài liệu; kiểm bằng file tồn tại / build thành công) — đọc lại ảnh lớn ngốn ngữ cảnh gấp nhiều lần bạn tưởng. Tạo hình cạnh dài khoảng 1280px, đừng 4K trừ khi user yêu cầu. Research nhiều nguồn thì dùng **sessions_spawn** mỗi nhánh một subagent, bảo chúng **ghi dữ liệu thô ra file** và **chỉ trả tóm tắt ngắn kèm đường dẫn**; bạn tổng hợp từ file.',''].join('\\n');const en=['','## 🛠️ Authoring skills & long work','','**Authoring skills:** When the user asks for a reusable capability (e.g. _"make a skill for X"_), do it end-to-end — use the **skill_workshop** tool: create the proposal AND **apply it in the same turn** (this environment sets approvalPolicy auto, so no separate approval is needed). The skill lands in skills/<name>/SKILL.md and **auto-loads** via the watcher — no openclaw.json edit required. Do not stop at _"proposal created, awaiting approval"_. Never hardcode secrets into a skill — read them from environment variables at runtime.','','**Long multi-step work (deep research, building reports/PDFs):** do not read back an image or chart you just made (drop the file straight in; verify via file exists / build succeeded) — re-reading a large image costs far more context than it looks. Render at about 1280px on the long edge, skip 4K unless asked. For multi-source research, use **sessions_spawn** with one subagent per branch, have them **write raw findings to files** and **return only a short summary plus paths**; synthesize from the files.',''].join('\\n');const root=path.join(process.cwd(),'.openclaw');let dirs=[];try{dirs=fs.readdirSync(root).filter(n=>n.indexOf('workspace')===0);}catch(e){}for(const d of dirs){const f=path.join(root,d,'TOOLS.md');try{if(!fs.existsSync(f))continue;const cur=fs.readFileSync(f,'utf8');if(cur.indexOf('skill_workshop')!==-1)continue;const isVi=/Kỹ năng|Ghi chú|Xử lý lỗi|môi trường/.test(cur);fs.appendFileSync(f,(cur.endsWith('\\n')?'':'\\n')+(isVi?vi:en));}catch(e){}}`;
264
282
  const securityCompatScript = `const fs=require('fs'),path=require('path');const scopes=['operator.admin','operator.pairing','operator.approvals'];function uniq(a){return Array.from(new Set([...(Array.isArray(a)?a:[]),...scopes]));}function walk(v){if(!v||typeof v!=='object')return;if(Array.isArray(v)){v.forEach(walk);return;}if(Array.isArray(v.scopes)||Array.isArray(v.approvedScopes)){v.scopes=uniq(v.scopes);v.approvedScopes=uniq(v.approvedScopes);}Object.values(v).forEach(walk);}const home=process.env.OPENCLAW_HOME||path.join(process.cwd(),'.openclaw');const state=process.env.OPENCLAW_STATE_DIR||home;const cfgPath=path.join(process.cwd(),'.openclaw','openclaw.json');if(fs.existsSync(cfgPath)){const c=JSON.parse(fs.readFileSync(cfgPath,'utf8'));const p=c.models&&c.models.providers&&c.models.providers['9router'];if(p){p.request=Object.assign({},p.request,{allowPrivateNetwork:true});}fs.writeFileSync(cfgPath,JSON.stringify(c,null,2));}for(const root of Array.from(new Set([home,state]))){const f=path.join(root,'devices','paired.json');if(fs.existsSync(f)){const d=JSON.parse(fs.readFileSync(f,'utf8'));walk(d);fs.writeFileSync(f,JSON.stringify(d,null,2));}}`;
265
283
 
266
284
  const runtimeParts = runtimeCommandParts.filter(Boolean);
@@ -327,6 +345,13 @@ if(touched){console.log('[patch-9router] Applied Codex compatibility patch.');}e
327
345
  // native ZaloConnect actions.
328
346
  const zaloConnectSpec = common.ZALO_CONNECT_PLUGIN_SPEC || 'clawhub:openclaw-zalo-connect';
329
347
  runtimeParts.push(`ensure_plugin zalo-connect "${zaloConnectSpec}"`);
348
+ // Backfill the inbound-message ack reaction for projects created before it was
349
+ // seeded. Kept out of the shared migration because zalo-connect reads the GLOBAL
350
+ // messages.ackReaction, and that same key also feeds Telegram/Discord/Slack/
351
+ // WhatsApp — which accept only their own fixed reaction sets and would reject an
352
+ // arbitrary emoji. Absent-only, so an operator's own choice is never overwritten.
353
+ const ackReactionScript = `const fs=require('fs'),path=require('path');const p=path.join(process.cwd(),'.openclaw','openclaw.json');if(fs.existsSync(p)){const c=JSON.parse(fs.readFileSync(p,'utf8'));let ch=false;c.messages=c.messages||{};if(c.messages.ackReaction===undefined){c.messages.ackReaction='🦞';ch=true;}if(c.messages.ackReactionScope===undefined){c.messages.ackReactionScope='all';ch=true;}if(ch)fs.writeFileSync(p,JSON.stringify(c,null,2));}`;
354
+ runtimeParts.push(`node - <<'NODE'\n${ackReactionScript}\nNODE`);
330
355
  }
331
356
  // Always-on memory context engine for every bot (see bot-config-gen: plugins.slots
332
357
  // .contextEngine = "learning-memory"). ensure_plugin skips if already installed.
@@ -335,6 +360,9 @@ if(touched){console.log('[patch-9router] Applied Codex compatibility patch.');}e
335
360
  runtimeParts.push(`node - <<'NODE'\n${deprecatedCleanupScript}\nNODE`);
336
361
  runtimeParts.push('find "$OPENCLAW_HOME" -maxdepth 4 -type d -path "*/skills/learning-memory" -exec rm -rf {} + 2>/dev/null || true');
337
362
  runtimeParts.push('if [ -d "$OPENCLAW_HOME/extensions/memory-tencentdb" ] || openclaw plugins list 2>/dev/null | grep -q memory-tencentdb; then openclaw plugins uninstall memory-tencentdb --force 2>/dev/null || true; fi');
363
+ // Backfill skill-authoring + context defaults for configs from an older setup (see above).
364
+ runtimeParts.push(`node - <<'NODE'\n${contextDefaultsScript}\nNODE`);
365
+ runtimeParts.push(`node - <<'NODE'\n${agentsGuidanceScript}\nNODE`);
338
366
  runtimeParts.push('openclaw gateway run');
339
367
  const runtimeScript = ['#!/bin/sh', 'set -e', ...runtimeParts].join('\n');
340
368
  let browserInstall = '';
@@ -1180,9 +1180,15 @@ description: Guide for utilizing tools and skills
1180
1180
  : (isVi
1181
1181
  ? `Reaction phải nhắm vào **tin nhắn mới nhất của user** (inbound hiện tại), KHÔNG phải tin cũ hơn hay tin của chính mình.\n- Cách đúng: tool \`message\` với \`action: "react"\`, ${reactValue}, **KHÔNG truyền \`messageId\`** — tool sẽ tự reaction vào inbound message mới nhất. Chỉ truyền \`messageId\` khi cần reaction vào một tin CỤ THỂ không phải tin mới nhất.`
1182
1182
  : `The reaction MUST target the **user's latest (current inbound) message**, not an older one or your own message.\n- Correct: \`message\` tool with \`action: "react"\`, ${reactValue}, **do NOT pass \`messageId\`** — the tool auto-reacts to the latest inbound message. Only pass \`messageId\` to react to a specific OLDER message.`);
1183
- const dmOverride = isVi
1184
- ? `\n\n## Reaction khi nhắn riêng (DM) — BẮT BUỘC\n- Khi DM với user, PHẢI luôn dùng tool/action reaction native để thả reaction CÙNG LÚC khi trả lời.\n- KHÔNG thả reaction trong group chat.\n- Chọn theo cảm xúc/ngữ cảnh tin của user. ${reactList}\n- ${reactHow}\n- ${reactExamples}`
1185
- : `\n\n## Reactions in DMs MANDATORY\n- In DMs with the user, you MUST always use the native reaction tool/action to react WHILE replying.\n- Do NOT react in group chats.\n- Pick by the user's emotion/context. ${reactList}\n- ${reactHow}\n- ${reactExamples}`;
1183
+ // Zalo bots no longer carry this: the channel now drops an ack reaction on every
1184
+ // inbound message by itself (messages.ackReaction), so telling the model to react
1185
+ // as well only spends tokens and risks a second reaction on the same message.
1186
+ // Channels without that automatic ack keep the instruction.
1187
+ const dmOverride = isZalo
1188
+ ? ''
1189
+ : isVi
1190
+ ? `\n\n## ⚡ Reaction khi nhắn riêng (DM) — BẮT BUỘC\n- Khi DM với user, PHẢI luôn dùng tool/action reaction native để thả reaction CÙNG LÚC khi trả lời.\n- KHÔNG thả reaction trong group chat.\n- Chọn theo cảm xúc/ngữ cảnh tin của user. ${reactList}\n- ${reactHow}\n- ${reactExamples}`
1191
+ : `\n\n## ⚡ Reactions in DMs — MANDATORY\n- In DMs with the user, you MUST always use the native reaction tool/action to react WHILE replying.\n- Do NOT react in group chats.\n- Pick by the user's emotion/context. ${reactList}\n- ${reactHow}\n- ${reactExamples}`;
1186
1192
 
1187
1193
  // Doc structure mirrors OpenClaw's default TOOLS.md (local environment notes + why it is a
1188
1194
  // separate file), followed by the repo's tool-usage rules and the mandatory DM reaction guide.
@@ -1231,6 +1237,14 @@ Skills dùng chung. Setup là của riêng bạn. Tách ra nghĩa là cập nh
1231
1237
 
1232
1238
  - Xem chi tiết hướng dẫn các kỹ năng được cài đặt tại thư mục [skills](./skills/).
1233
1239
 
1240
+ **🛠️ Tự tạo skill:** Khi user nhờ tạo một kỹ năng/quy trình dùng lại (vd _"tạo skill X"_), bạn TỰ làm được từ đầu đến cuối — dùng tool \`skill_workshop\`: tạo proposal RỒI **apply luôn trong cùng lượt** (môi trường này đã bật \`approvalPolicy: auto\` nên không cần chờ ai duyệt). Skill sẽ được ghi vào \`skills/<tên>/SKILL.md\` trong workspace và **tự nạp** qua watcher — KHÔNG cần sửa \`openclaw.json\`. Đừng dừng ở bước _"đã tạo proposal, chờ sếp duyệt rồi áp dụng"_: user bảo tạo nghĩa là tạo xong dùng được ngay. Tuyệt đối KHÔNG nhúng bí mật (mật khẩu/token/tài khoản) vào nội dung skill — đọc chúng từ biến môi trường lúc chạy.
1241
+
1242
+ **🧠 Việc dài, nhiều bước (research sâu, dựng báo cáo/PDF):** cửa sổ ngữ cảnh là tài nguyên — một lượt nhồi quá nhiều sẽ vỡ giữa đường và KHÔNG nén lại được. Ba quy tắc:
1243
+
1244
+ - **Ảnh/chart bạn vừa tạo thì đừng đọc lại** bằng tool ảnh để "xem cho chắc". Chèn thẳng file vào tài liệu; muốn kiểm thì xem file có tồn tại / build thành công. Đọc lại một ảnh lớn tốn ngữ cảnh gấp nhiều lần bạn tưởng.
1245
+ - **Tạo hình ở cỡ vừa đủ** (cạnh dài ~1280px là đẹp cho báo cáo). Đừng làm 4K trừ khi user yêu cầu rõ.
1246
+ - **Research nhiều nguồn thì chia việc:** \`sessions_spawn\` mỗi nhánh một subagent (mỗi con có cửa sổ riêng), bảo chúng **ghi dữ liệu thô ra file** trong workspace và **chỉ trả về tóm tắt ngắn kèm đường dẫn file**. Bạn tổng hợp từ file. Đừng tự mình kéo hàng chục trang web vào một lượt.
1247
+
1234
1248
  ## 📁 File & Workspace
1235
1249
 
1236
1250
  - Bot có thể đọc/ghi file trong thư mục workspace: \`${workspacePath}\`
@@ -1282,6 +1296,14 @@ Skills are shared. Your setup is yours. Keeping them apart means you can update
1282
1296
 
1283
1297
  - See detailed guidelines of installed skills in the [skills](./skills/) directory.
1284
1298
 
1299
+ **🛠️ Authoring skills:** When the user asks you to build a reusable capability (e.g. _"make a skill for X"_), you can do it end-to-end — use the \`skill_workshop\` tool: create the proposal AND **apply it in the same turn** (this environment sets \`approvalPolicy: auto\`, so no separate approval is needed). The skill lands in \`skills/<name>/SKILL.md\` in the workspace and **auto-loads** via the watcher — no \`openclaw.json\` edit required. Don't stop at _"proposal created, awaiting approval"_: if they asked you to build it, finish it so it works right away. Never hardcode secrets (passwords/tokens/accounts) into a skill's contents — read them from environment variables at runtime.
1300
+
1301
+ **🧠 Long multi-step work (deep research, building reports/PDFs):** the context window is a budget — cram too much into one turn and it blows up mid-flight, with nothing left to compact. Three rules:
1302
+
1303
+ - **Don't read back an image or chart you just made** to "double-check" it. Drop the file straight into the document; verify by checking the file exists or that the build succeeded. Re-reading a large image costs far more context than it looks.
1304
+ - **Render images at a sane size** (~1280px on the long edge looks great in a report). Skip 4K unless the user explicitly asks.
1305
+ - **Split multi-source research:** \`sessions_spawn\` one subagent per branch (each gets its own window), have them **write raw findings to files** in the workspace and **return only a short summary plus the file paths**. You synthesize from the files. Don't pull dozens of web pages into a single turn yourself.
1306
+
1285
1307
  ## 📁 File & Workspace
1286
1308
 
1287
1309
  - Bot can read/write files in workspace: \`${workspacePath}\`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-openclaw-bot",
3
- "version": "5.13.9",
3
+ "version": "5.14.1",
4
4
  "description": "Interactive CLI installer for OpenClaw Bot",
5
5
  "main": "dist/cli.js",
6
6
  "bin": {