|
|
@@ -0,0 +1,190 @@
|
|
|
+# 提示词:让容器按 Fmode App 最新规范自我优化
|
|
|
+
|
|
|
+> **用法**:整份发给容器,它会自己对照检查、改代码、验证、回报。
|
|
|
+> **依据**:全部来自 2026-11-11 对 `agent-node-lj-test` 的实测与代码取证。
|
|
|
+> **配套文档**:`docs/03-interface/容器接入完整指南-v2-20261111.md`
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 你的任务
|
|
|
+
|
|
|
+对照下面 **6 条检查项**逐条自查你当前的实现。
|
|
|
+每条给出:**当前状态 + 证据(文件:行号 或 实测输出)+ 需要改什么**。
|
|
|
+
|
|
|
+**做不到的如实说「做不到 + 原因」,不要声称已完成。** App 侧会回读 Matrix 事件和云函数数据核实。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 检查项 1:本轮结束信号 —— 用 ✅ reaction,不要用 typing
|
|
|
+
|
|
|
+### 背景(实测数据)
|
|
|
+```
|
|
|
++6.7s typing=true
|
|
|
++14.8s typing=false ← 早于正文 0.6 秒 ✗
|
|
|
++15.3s 消息「3 乘以 7 等于 21。」
|
|
|
++15.4s reaction ✅ ← 晚于正文 ✓
|
|
|
+```
|
|
|
+
|
|
|
+### 要求
|
|
|
+- [ ] `MATRIX_REACTIONS=true`(别关)
|
|
|
+- [ ] 每轮结束时你会打出 ✅(失败打 ❌)
|
|
|
+- [ ] **不要**用 `m.typing=false` 当结束信号(时序天然是反的)
|
|
|
+- [ ] 如果之前装过发 typing 的插件,**禁用掉**
|
|
|
+
|
|
|
+### 自查命令
|
|
|
+```bash
|
|
|
+grep -n "MATRIX_REACTIONS" /opt/data/.env
|
|
|
+hermes plugins list | grep -i typing
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 检查项 2:`currentSessions` 按会话上报(**最容易做错**)
|
|
|
+
|
|
|
+### 背景
|
|
|
+用户实测投诉:「在其他会话里也能看到当前会话的容器状态」。
|
|
|
+根因:你只报了容器级 `status`,App 只能拿它冒充会话状态。
|
|
|
+
|
|
|
+### 要求
|
|
|
+每条 `currentSessions` 记录必须包含:
|
|
|
+
|
|
|
+```json
|
|
|
+{
|
|
|
+ "sessionKey": "!roomId 或 $approot_xxx",
|
|
|
+ "userId": "@用户的mxid:fmode.cn",
|
|
|
+ "status": "running",
|
|
|
+ "task": "本轮用户提问首行,60 字内",
|
|
|
+ "turnStartAt": 1699999999000,
|
|
|
+ "updatedAt": 1699999999000,
|
|
|
+ "ttlMs": 600000
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+| 字段 | 要求 |
|
|
|
+|---|---|
|
|
|
+| `sessionKey` | 优先 `thread_id`(`$approot_xxx`),拿不到退 `chat_id`(`!xxx`) |
|
|
|
+| `userId` | 从 `state.db.sessions.user_id` 查,查不到就省略(别写空串) |
|
|
|
+| `task` | `pre_llm_call` 的 `user_message` 首行,60 字;**只在 running 时有值** |
|
|
|
+| `status` | running / idle |
|
|
|
+
|
|
|
+### 自查命令
|
|
|
+```bash
|
|
|
+python3 -c "
|
|
|
+import sqlite3,json
|
|
|
+c=sqlite3.connect('file:/opt/data/state.db?mode=ro',uri=True)
|
|
|
+for r in c.execute('SELECT id,thread_id,chat_id,user_id FROM sessions ORDER BY started_at DESC LIMIT 5'):
|
|
|
+ print(r)
|
|
|
+"
|
|
|
+```
|
|
|
+
|
|
|
+回答:你现在上报的 `sessionKey` 用的是哪个字段?`userId` 和 `task` 有没有?
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 检查项 3:心跳必须带 `currentSessions`
|
|
|
+
|
|
|
+### 背景
|
|
|
+只在 turn 首尾写 `currentSessions` 的话,turn 结束后状态会滞后,
|
|
|
+App 最长要等 15 秒轮询才纠正。
|
|
|
+
|
|
|
+### 要求
|
|
|
+- [ ] 心跳(每 3600s + 0~900s 抖动)**也要带上** `currentSessions`
|
|
|
+- [ ] `idle` 记录有 TTL 清理(建议 10 分钟)
|
|
|
+
|
|
|
+### 自查
|
|
|
+回答:你的心跳上报函数在哪(文件:行号)?有没有带 `currentSessions`?
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 检查项 4:正文排版规范
|
|
|
+
|
|
|
+### 4.1 不要用 `~` 表示数值范围
|
|
|
+```
|
|
|
+❌ 全天 8~16℃ ← 两个 ~ 会被 markdown 解析成 ~~删除线~~,整段被划掉
|
|
|
+✅ 全天 8~16℃ 或 全天 8 至 16℃
|
|
|
+```
|
|
|
+App 已做兜底(转成 HTML 实体),但仍建议容器侧规范。
|
|
|
+
|
|
|
+### 4.2 **App 完整支持 Markdown 表格**(重要)
|
|
|
+实测:`marked.parse('| a | b |\n|---|---|')` → 正常输出 `<table>`,
|
|
|
+且 `md-render.ts:212` 有完整表格样式(边框、内边距、首列宽度)。
|
|
|
+
|
|
|
+**所以不要因为「Matrix 客户端不支持表格」就降级成「标签: 值」列表。**
|
|
|
+直接写标准 Markdown 表格即可:
|
|
|
+```markdown
|
|
|
+| 城市 | AQI | 等级 |
|
|
|
+|---|---|---|
|
|
|
+| 北京 | 95 | 良 |
|
|
|
+```
|
|
|
+
|
|
|
+### 4.3 过程行独占一行
|
|
|
+工具进度行以固定 emoji 开头(`💻` `🔍` `📖` `✍️` `🐍` `⚙️`),
|
|
|
+**不要和中文结论混在同一行**。
|
|
|
+
|
|
|
+### 自查
|
|
|
+回答:你最近一轮回复里,有没有出现「因为客户端不支持表格所以改用列表」这种降级?
|
|
|
+如果有,改成表格。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 检查项 5:会话归属(thread)
|
|
|
+
|
|
|
+### 要求
|
|
|
+- [ ] 回复**沿用 App 给的 thread 根**,不自己新开
|
|
|
+- [ ] 如果收到带 `m.relates_to{rel_type:m.thread, event_id:$approot_xxx}` 的消息,
|
|
|
+ 回复也要带同样的 thread 关系
|
|
|
+
|
|
|
+### 自查
|
|
|
+```bash
|
|
|
+python3 -c "
|
|
|
+import sqlite3
|
|
|
+c=sqlite3.connect('file:/opt/data/state.db?mode=ro',uri=True)
|
|
|
+q='SELECT COUNT(*), SUM(thread_id IS NOT NULL AND thread_id!=\"\") FROM sessions WHERE source=\"matrix\"'
|
|
|
+print('matrix 总数 / 有 thread:', c.execute(q).fetchone())
|
|
|
+"
|
|
|
+```
|
|
|
+回答:你的 matrix 会话里 thread 覆盖率多少?没有 thread 的那些是什么来源?
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 检查项 6:能力边界(决定哪些能改)
|
|
|
+
|
|
|
+```bash
|
|
|
+ls -ld /opt/hermes /opt/data
|
|
|
+test -w /opt/data/plugins && echo "plugins 可写" || echo "不可写"
|
|
|
+```
|
|
|
+
|
|
|
+回答:
|
|
|
+- `/opt/hermes` 你能写吗?
|
|
|
+- `/opt/data` 你能写吗?
|
|
|
+- 插件放哪、怎么启停、怎么让配置生效?
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 交付格式
|
|
|
+
|
|
|
+| 检查项 | 当前状态 | 证据 | 要改什么 |
|
|
|
+|---|---|---|---|
|
|
|
+| 1. 结束信号 | | 文件:行号 / 实测 | |
|
|
|
+| 2. currentSessions | | | |
|
|
|
+| 3. 心跳带会话 | | | |
|
|
|
+| 4. 排版规范 | | | |
|
|
|
+| 5. thread 归属 | | | |
|
|
|
+| 6. 能力边界 | | | |
|
|
|
+
|
|
|
+最后给一段结论:**哪些已满足、哪些要改、哪些做不到及原因**。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## ⚠️ 三条纪律
|
|
|
+
|
|
|
+1. **不要声称「已完成」而不给证据** —— App 侧会回读 Matrix 事件和云函数数据核实。
|
|
|
+ 之前有容器说「改完了」,实际改的是只读文件,一个字没生效。
|
|
|
+2. **做不到就说做不到** —— `/opt/hermes` 无写权限是环境限制,不是你的错。
|
|
|
+ 如实说明比假装完成有用得多。
|
|
|
+3. **改完必须实测回读** —— 用 `/sync` 看真实事件,或直接回读云函数 `extra`。
|
|
|
+ 不要只看日志、看自己发的文本。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+*本提示词基于 2026-11-11 的实测与代码取证编写。所有结论均可验证,未做推测。*
|