mirror of
https://gitcode.com/JianFeeeee/homeagent-sdk.git
synced 2026-09-20 17:08:01 +00:00
docs(example): 为每个插件补 README
此前 example/ 下 21 个插件里,13 个完全没有 README,另 4 个是 `hmapdev init` 生成的脚手架样板(`# <name>` + `plugin build` + `Install` 三行, 等于从没被写过)。只有 deepsearch / vikunja / plugindev / luademo 是真实文档。 本次为 **17 个**插件写了真文档(13 个缺失 + 4 个样板),现在 21 个全部有内容。 ## 写法 每个 README 覆盖:能力一句话 → 为什么需要 → 工具表 → 配置项表 → 通道与钩子(有才写)→ 构建 → 已知边界。 **事实全部从源码读出来,不推测**: - 工具名核对到注册点(含 `tp+"x"` / `p.name+"_x"` 前缀拼接,展开成最终名) - 配置键与默认值取自 `RegisterDef` / getStr 默认值 - 通道名、钩子名、依赖命令逐条 grep 确认 - 版本号与已部署实例交叉核对,17 个里 16 个一致 ## 几处按源码写、与直觉不同的点 - **rss**:订阅时会把抓到的历史条目一次性标为 seen,所以订阅一个源 **不会**把历史文章全推一遍 —— 这是避免刷屏的关键,写进了文档。 - **files**:路径校验是**两道**(规范化后判断 + 解析符号链接后再判断), 只做前者的话沙箱里的软链接就能逃逸。两种情况报错文案不同。 - **qq**:身份必须**绑帧**而非存插件全局,源码注释记录了由此产生的两个真实故障 (中断抢占恢复后权限门整体失效、运行中到达的消息改写正在跑那一轮的身份)。 多来源合并时权限取**交集**。硬私有工具按前缀一律拒绝。这些是安全关键, 单独成节写清楚。 - **memo**:待办与备忘录**刻意分两类**(一提醒一不提醒),提醒注入带 NoMemory。 - **sanitizer**:不注册任何工具,只挂三个阶段钩子;依赖 ABI v2 的 stage 写回能力。 - **editdoc**:本目录是 v1.0.0(单工具),而线上跑 v2.0.0(全能版,源码未公开)—— 在文档开头显式标注,**不按 v2 描述**,避免读者以为这里就是线上那份。 ## 验证 - 21/21 文件非空且非样板(最小 913B,最大 6845B) - 逐个核对 README 中出现的工具名能在源码找到依据;5 处报警经复核**全是误报** (`ai_image_generate`/`music_*` 前缀来自 metadata 的 name,`on_input` 等是钩子不是工具) - README 版本号 vs 线上 plugin.json:16/17 一致,editdoc 的差异已显式说明 注:本仓既有未提交改动(example/qq/plugin.go、sdk/plugin.go)**未纳入本次提交**。
This commit is contained in:
47
example/a2a/README.md
Normal file
47
example/a2a/README.md
Normal file
@ -0,0 +1,47 @@
|
||||
# a2a · Agent-to-Agent 通信
|
||||
|
||||
让本 Agent 与其他 Agent **双向互调**:既能对外暴露自己的能力,也能去问别的 Agent。
|
||||
|
||||
## 两个方向
|
||||
|
||||
| 方向 | 怎么实现 |
|
||||
|---|---|
|
||||
| **入站**(别人问我) | 插件起一个 HTTP 服务端,暴露 `/agent-card`(能力描述)与 `/a2a`(JSON-RPC 入口) |
|
||||
| **出站**(我问别人) | 提供 `a2a_query` / `a2a_discover` 工具,主动向远端 A2A Agent 发起请求 |
|
||||
|
||||
## HTTP 端点
|
||||
|
||||
| 路径 | 作用 |
|
||||
|---|---|
|
||||
| `GET /agent-card` | 返回 Agent Card:本 Agent 的能力描述,供对方发现 |
|
||||
| `POST /a2a` | JSON-RPC 2.0 入口,接收对方的任务请求 |
|
||||
|
||||
## 工具
|
||||
|
||||
| 工具 | 说明 |
|
||||
|---|---|
|
||||
| `a2a_a2a_query` | 向另一个 A2A Agent 发查询并取回复 |
|
||||
| `a2a_a2a_discover` | 取对方的 Agent Card(能力描述) |
|
||||
| `a2a_a2a_status` | 看本插件运行状态(监听地址、当前配置) |
|
||||
| `a2a_a2a_configure` | 改配置并自动重启服务(可动态改监听地址) |
|
||||
| `a2a_a2a_restart` | 重启 HTTP 服务端(连接异常或改配置后用) |
|
||||
|
||||
> 工具名前缀取自插件名(`tp`),按默认 `a2a_` 列出。
|
||||
|
||||
## 配置项
|
||||
|
||||
| 键 | 默认 | 说明 |
|
||||
|---|---|---|
|
||||
| `listen` | `127.0.0.1:12000` | 服务端监听地址。**设为空可禁用 HTTP 服务**(只出站、不入站) |
|
||||
|
||||
## 典型用法
|
||||
|
||||
1. **先发现再调用**:`a2a_discover` 拿对方能力 → 决定要不要发、发什么 → `a2a_query`。
|
||||
跳过 discovery 直接问,容易问出对方不支持的东西。
|
||||
2. **只出站**:把 `listen` 设为空,本 Agent 不外露端口,但仍能主动联系别人。
|
||||
|
||||
## 构建
|
||||
|
||||
```bash
|
||||
hmapdev build
|
||||
```
|
||||
51
example/acp/README.md
Normal file
51
example/acp/README.md
Normal file
@ -0,0 +1,51 @@
|
||||
# acp · Agent Client Protocol 通信
|
||||
|
||||
[ACP](https://agentclientprotocol.com/) 桥接:本 Agent 既能**当服务端**接别人的任务,也能**当客户端**去调别的 ACP Agent。
|
||||
|
||||
## 两个方向
|
||||
|
||||
| 角色 | 行为 |
|
||||
|---|---|
|
||||
| **服务端** | 在本机起 HTTP 服务,处理 `session/new` / `session/update`,接受其他 Agent 的任务请求 |
|
||||
| **客户端** | 通过 `acp_query` 向远程 ACP Agent 发 `session/new` 并读回复 |
|
||||
|
||||
## 协议端点
|
||||
|
||||
- `POST /api/session` —— JSON-RPC,支持 `session/new` 与 `session/update`
|
||||
- 客户端侧同时兼容**两种服务端**:SSE 型(流式 `session/reply`)与同步 JSON 型
|
||||
|
||||
## 工具
|
||||
|
||||
| 工具 | 说明 |
|
||||
|---|---|
|
||||
| `acp_acp_query` | 向远程 ACP Agent 发起会话并等待回复,返回最终回答文本 |
|
||||
| `acp_acp_status` | 查看运行状态与**当前活跃会话数** |
|
||||
| `acp_acp_configure` | 改监听配置并重启 HTTP 服务 |
|
||||
|
||||
> 工具名前缀取自插件名(`tp`),按默认 `acp_` 列出。
|
||||
|
||||
`acp_query` 可指向的远端举例(源码注释给的):
|
||||
|
||||
- opencode:`http://127.0.0.1:13000`
|
||||
- pi bridge:`http://127.0.0.1:12011`
|
||||
- 回环到自身:`http://127.0.0.1:12001`
|
||||
|
||||
## 配置项
|
||||
|
||||
| 键 | 默认 | 说明 |
|
||||
|---|---|---|
|
||||
| `listen` | `127.0.0.1:12001` | 服务端监听地址。**设为空可禁用 HTTP 服务**(只出站) |
|
||||
|
||||
## 与 a2a 的区别
|
||||
|
||||
| | a2a | acp |
|
||||
|---|---|---|
|
||||
| 面向 | Agent ↔ Agent 对等通信 | 客户端 → Agent 会话(每次一个 session) |
|
||||
| 会话 | 一问一答 | 有 session 生命周期,可续 |
|
||||
| 发现 | `/agent-card` | 无(需已知地址) |
|
||||
|
||||
## 构建
|
||||
|
||||
```bash
|
||||
hmapdev build
|
||||
```
|
||||
@ -1,13 +1,34 @@
|
||||
# ai_image
|
||||
# ai_image · 文生图
|
||||
|
||||
ai_image plugin
|
||||
按文字提示生成图片,下载到本地并返回**文件路径**。
|
||||
|
||||
## Build
|
||||
## 工具
|
||||
|
||||
| 工具 | 说明 |
|
||||
|---|---|
|
||||
| `ai_image_generate` | 按 prompt 生成图片 |
|
||||
|
||||
返回值是**本地文件路径**(永久,不过期)。要把图给用户看,再用导出的通道
|
||||
以 `type=image`、`payload=<该路径>` 发送。
|
||||
|
||||
## 配置项
|
||||
|
||||
| 键 | 默认 | 说明 |
|
||||
|---|---|---|
|
||||
| `api_key` | 空 | OpenAI / Stable Diffusion 的 API Key |
|
||||
| `base_url` | 空 | 自定义 OpenAI 兼容网关(**不带 `/v1` 尾缀**,如 `http://127.0.0.1:8081`)。留空走官方 `https://api.openai.com` |
|
||||
| `provider` | `openai` | 服务方:`openai` / `stability` |
|
||||
| `model` | `dall-e-3` | 模型名(如 `dall-e-3`、`sd-xl`) |
|
||||
| `size` | `1024x1024` | 默认尺寸,也可 `1024x1792` / `1792x1024` |
|
||||
|
||||
## 实现要点
|
||||
|
||||
- **返回本地路径而不是远端 URL**:远端图床链接会过期,写进记忆就成了悬空指针。
|
||||
下载到本地后路径稳定,可交给媒体存储做内容寻址。
|
||||
- 配了 `base_url` 就能指向自建/兼容网关,不必依赖官方接口。
|
||||
|
||||
## 构建
|
||||
|
||||
```bash
|
||||
hmapdev build
|
||||
```
|
||||
|
||||
## Install
|
||||
|
||||
Upload the .hmap file through the Plugin Manager API.
|
||||
|
||||
43
example/bili/README.md
Normal file
43
example/bili/README.md
Normal file
@ -0,0 +1,43 @@
|
||||
# bili · B站视频下载
|
||||
|
||||
用 [yt-dlp](https://github.com/yt-dlp/yt-dlp) 把 B 站视频下载到本地。
|
||||
|
||||
## 前置依赖
|
||||
|
||||
需要系统里装有 `yt-dlp`:
|
||||
|
||||
```bash
|
||||
pip install -U yt-dlp # 或 apt install yt-dlp
|
||||
```
|
||||
|
||||
## 工具
|
||||
|
||||
| 工具 | 说明 |
|
||||
|---|---|
|
||||
| `bili_video` | 下载 B 站视频;不指定 `format` 时先返回可用清晰度列表,指定后真正下载并返回文件路径 |
|
||||
|
||||
参数:
|
||||
|
||||
| 参数 | 说明 |
|
||||
|---|---|
|
||||
| `url` | 视频地址 |
|
||||
| `format` | 格式 ID。常用:`30112`/`30080`=1080P、`30064`=720P、`30032`=480P、`30016`=360P。不指定则自动选最优 |
|
||||
|
||||
## 配置项
|
||||
|
||||
| 键 | 默认 | 说明 |
|
||||
|---|---|---|
|
||||
| `output_dir` | `/tmp/bili_videos` | 下载目录 |
|
||||
| `proxy` | 空 | yt-dlp 使用的 HTTP 代理(如 `http://127.0.0.1:7890`)。留空则不设代理 |
|
||||
|
||||
## 实现要点
|
||||
|
||||
- **`output_dir` 有安全校验**:它是配置项,但会拒绝被配成系统目录,避免 yt-dlp 往任意位置写文件。
|
||||
- 两阶段用法:先不传 `format` 拿到清晰度清单(`format_id` + `format_note`),再带上选定的 ID 下载。这样模型不会盲选一个不存在的格式。
|
||||
- B 站在部分网络环境下需要代理,见上面的 `proxy`。
|
||||
|
||||
## 构建
|
||||
|
||||
```bash
|
||||
hmapdev build
|
||||
```
|
||||
66
example/browser/README.md
Normal file
66
example/browser/README.md
Normal file
@ -0,0 +1,66 @@
|
||||
# browser · 统一浏览器
|
||||
|
||||
一个插件覆盖三种"访问网页"的能力,从最轻到最重。**按需选层**是这个插件的重点 ——
|
||||
绝大多数抓取用 HTTP 就够,不该为了一句话启动 Chromium。
|
||||
|
||||
## 三种能力层
|
||||
|
||||
| 层 | 工具 | 何时用 |
|
||||
|---|---|---|
|
||||
| **搜索** | `browser_search` | 要的是"找到哪些页面",不是页面本身 |
|
||||
| **quick(纯 HTTP)** | `browser_fetch`(`mode=quick`) | 静态页、API、能直接拿到 HTML |
|
||||
| **normal(无头渲染)** | `browser_render` / `browser_fetch`(`mode=render`) | JS 渲染的页面,HTTP 拿不到内容 |
|
||||
| **interactive(CDP)** | `browser_start` + `navigate`/`click`/`type`/`scroll`/`html`/`screenshot` | 需要交互:登录、点按、翻页 |
|
||||
|
||||
`browser_fetch` 的 `mode`:
|
||||
|
||||
- `auto`(默认):先试 HTTP,**遇 403/429 才降级**用 Chromium 渲染
|
||||
- `render`:强制 Chromium
|
||||
- `quick`:纯 HTTP,不降级
|
||||
|
||||
## 工具
|
||||
|
||||
| 工具 | 说明 |
|
||||
|---|---|
|
||||
| `browser_search` | 网页搜索 |
|
||||
| `browser_fetch` | 抓取 URL 内容,三种 mode 见上 |
|
||||
| `browser_render` | 无头 Chromium 渲染并提取文本(normal) |
|
||||
| `browser_start` | 启动交互式浏览器会话(CDP) |
|
||||
| `browser_navigate` | 导航到指定 URL |
|
||||
| `browser_click` | 点击元素 |
|
||||
| `browser_type` | 输入文本 |
|
||||
| `browser_scroll` | 滚动页面 |
|
||||
| `browser_html` | 取当前页 HTML |
|
||||
| `browser_screenshot` | 截图 |
|
||||
| `browser_install` | 安装 systemd 托管的共享浏览器后端 |
|
||||
| `browser_close` | 关闭会话 |
|
||||
|
||||
## 共享浏览器后端
|
||||
|
||||
`browser_install` 安装 `homeagent-browser.service`(systemd 托管)。
|
||||
装上之后**所有 agent 共享同一个 Chromium 实例与登录态**,各自占独立标签页互不干扰
|
||||
(同 source 复用自己的标签页)。
|
||||
|
||||
前提:本机已有 chromium 二进制,没有会提示先装(`apt install chromium` 或等价)。
|
||||
|
||||
## 实现要点
|
||||
|
||||
- **搜索用 `cn.bing.com` 而不是 `www.bing.com`**:后者对程序化请求常回 302(同意/重定向页),
|
||||
根本拿不到结果块。
|
||||
- **标题取 `<h2>` 里的 `<a>`**:直接抓结果块里第一个 `<a>` 会拿到来源行而非标题。
|
||||
- **摘要认 `b_lineclamp`**:旧版 Bing 用 `b_caption`,新版已迁走,两套都匹配。
|
||||
- **有 SSRF 防护**:见源码 `SSRF` 段,抓取前校验目标地址,避免被诱导访问内网。
|
||||
|
||||
## 测试
|
||||
|
||||
```bash
|
||||
go test -count=1 ./...
|
||||
```
|
||||
|
||||
`testdata/bing_cn.html` 是搜索解析的固定样本,用它做离线断言,避免测试依赖真实网络。
|
||||
|
||||
## 构建
|
||||
|
||||
```bash
|
||||
hmapdev build
|
||||
```
|
||||
@ -1,13 +1,57 @@
|
||||
# calendar
|
||||
# calendar · 日历事件
|
||||
|
||||
calendar plugin
|
||||
事件管理:支持**重复事件**与**多档提醒**。
|
||||
|
||||
## Build
|
||||
## 工具
|
||||
|
||||
| 工具 | 说明 |
|
||||
|---|---|
|
||||
| `calendar_event_add` | 添加事件 |
|
||||
| `calendar_event_list` | 列出即将到来的事件(含日期、时间、重复规则) |
|
||||
| `calendar_event_update` | 更新事件(**只改传入的字段**;会重置提醒状态) |
|
||||
| `calendar_event_delete` | 删除事件(连带**该事件及之后的所有重复实例**) |
|
||||
| `calendar_today` | 今日事件 + 倒计时 |
|
||||
| `calendar_week` | 本周事件,按天分组 |
|
||||
| `calendar_month` | 月历网格,带事件标记点 |
|
||||
| `calendar_search` | 按关键词搜标题 / 地点 / 备注 |
|
||||
|
||||
`calendar_event_add` 的时间格式:`YYYY-MM-DD HH:MM`;只给 `YYYY-MM-DD` 表示全天事件。
|
||||
|
||||
## 重复规则
|
||||
|
||||
`repeat` 取值:
|
||||
|
||||
| 值 | 含义 |
|
||||
|---|---|
|
||||
| `none` | 不重复 |
|
||||
| `daily` | 每天 |
|
||||
| `weekday` | 每个工作日 |
|
||||
| `weekly` | 每周 |
|
||||
| `biweekly` | 每两周 |
|
||||
| `monthly` | 每月 |
|
||||
| `yearly` | 每年 |
|
||||
| `lunar_yearly` | **按农历年**(生日、传统节日用) |
|
||||
|
||||
`lunar_yearly` 是刻意加的:农历节日按公历写死会逐年偏移。
|
||||
|
||||
## 提醒
|
||||
|
||||
`remind_before` 单位是**分钟**,可给多个、逗号分隔:
|
||||
|
||||
```
|
||||
15,60,1440 # 提前 15 分钟 + 1 小时 + 1 天
|
||||
0 或留空 # 不提醒
|
||||
```
|
||||
|
||||
到点通过 `InjectInterruptText` 注入提醒,带 `NoMemory: true` ——
|
||||
提醒是瞬时信号,不是记忆内容。通道 `calendar` 同样声明为 NoMemory。
|
||||
|
||||
## 存储
|
||||
|
||||
事件存为 JSON,插件重启后保留。
|
||||
|
||||
## 构建
|
||||
|
||||
```bash
|
||||
hmapdev build
|
||||
```
|
||||
|
||||
## Install
|
||||
|
||||
Upload the .hmap file through the Plugin Manager API.
|
||||
|
||||
49
example/editdoc/README.md
Normal file
49
example/editdoc/README.md
Normal file
@ -0,0 +1,49 @@
|
||||
# editdoc · Office 文档编辑
|
||||
|
||||
编辑 `.docx` / `.xlsx` / `.pptx` 内容:查找替换、改单元格、插行。
|
||||
|
||||
> ⚠️ **版本说明**:本目录是 **v1.0.0**,只有 `edit_document` 一个工具。
|
||||
> 线上部署的 v2.0.0(全能办公版,支持新建/读取/转换 docx·xlsx·pptx·md·csv·txt)
|
||||
> **源码尚未公开**,本文档不描述那些能力。参见 `plugin.json` 的 `version`。
|
||||
|
||||
## 工具
|
||||
|
||||
| 工具 | 说明 |
|
||||
|---|---|
|
||||
| `edit_document` | 编辑文档内容,**编辑后原文件被覆盖** |
|
||||
|
||||
参数:
|
||||
|
||||
| 参数 | 说明 |
|
||||
|---|---|
|
||||
| `file` | 文档路径(必填) |
|
||||
| `operation` | `replace_text`(查找替换)/ `set_cell`(设置单元格)/ `insert_row`(插入行)(必填) |
|
||||
| `target` | 要查找的文本(`replace_text` 用) |
|
||||
| `replacement` | 替换为的文本(`replace_text` 用) |
|
||||
| `sheet` | 工作表名(xlsx 可选) |
|
||||
| `row` | 行号(`set_cell` / `insert_row` 用) |
|
||||
| `col` | 列号(`set_cell` 用) |
|
||||
| `value` | 单元格值(`set_cell` 用) |
|
||||
|
||||
编辑前建议先读一遍内容确认目标文本 —— 查找替换是**全文件覆盖写**,没有撤销。
|
||||
|
||||
## 配置项
|
||||
|
||||
| 键 | 默认 | 说明 |
|
||||
|---|---|---|
|
||||
| `script_path` | 空 | `edit_doc.py` 的绝对路径。留空则用插件可执行文件同目录下的 `edit_doc.py` |
|
||||
| `venv_python` | 空 | 执行 `edit_doc.py` 的 Python 解释器(建议用 venv 里的)。**必须配置,留空会报错** |
|
||||
|
||||
## 工作原理
|
||||
|
||||
本插件是 Go 写的薄壳:把参数序列化成 JSON,交给 Python 脚本 `edit_doc.py` 执行实际文档操作。
|
||||
文档解析依赖 Python 侧的库(python-docx / openpyxl / python-pptx 之类),所以:
|
||||
|
||||
- **需要自备 `edit_doc.py`**:它不在本目录里。
|
||||
- 用 `venv_python` 指向装了这些库的解释器,避免污染系统 Python。
|
||||
|
||||
## 构建
|
||||
|
||||
```bash
|
||||
hmapdev build
|
||||
```
|
||||
44
example/files/README.md
Normal file
44
example/files/README.md
Normal file
@ -0,0 +1,44 @@
|
||||
# files · 沙箱文件操作
|
||||
|
||||
读写与编辑文件,**全部操作限制在沙箱目录内**。
|
||||
|
||||
## 工具
|
||||
|
||||
| 工具 | 说明 |
|
||||
|---|---|
|
||||
| `files_read` | 读文件内容,支持 `offset` / `limit` 读大文件 |
|
||||
| `files_write` | 写文件,**自动创建父目录** |
|
||||
| `files_edit` | 按精确字符串替换改文件 |
|
||||
| `files_ls` | 列目录(目录名带 `/` 后缀) |
|
||||
|
||||
`files_edit` 用 `edits[]` 传多组替换,每组 `{old, new}`:
|
||||
|
||||
- 每个 `old` 必须在**原文件**中**恰好出现一次** —— 不唯一会报错,避免改错地方。
|
||||
- 所有替换都针对**原内容**匹配,不要在同一个 `edits` 里写相互重叠的改动。
|
||||
|
||||
## 配置项
|
||||
|
||||
| 键 | 默认 | 说明 |
|
||||
|---|---|---|
|
||||
| `dir` | 空 | 允许访问的根目录。留空用默认沙箱(主数据目录下的 `files_sandbox`)。**不建议设为 `/`** |
|
||||
|
||||
## 沙箱实现
|
||||
|
||||
路径校验不止一次,是两道:
|
||||
|
||||
1. **规范化后判断**:`filepath.Abs` + `filepath.Clean`,再用 `withinSandbox`
|
||||
检查结果是否在根目录之下(`/` 作为特例放行)。
|
||||
2. **解析符号链接后再判断**:`filepath.EvalSymlinks` 求出真实路径,**再查一次**沙箱。
|
||||
|
||||
第 2 步是关键:只做第 1 步的话,沙箱内一个指向外部的软链接就能绕过限制
|
||||
(`.../sandbox/link -> /etc`)。报错文案也区分了这两种情况
|
||||
(`path outside sandbox` vs `path escapes sandbox via symlink`)。
|
||||
|
||||
对不存在的路径(`write` 会用到),求真实路径时只对已存在的部分做 `EvalSymlinks`,
|
||||
其余保留为未创建的尾部。
|
||||
|
||||
## 构建
|
||||
|
||||
```bash
|
||||
hmapdev build
|
||||
```
|
||||
43
example/memo/README.md
Normal file
43
example/memo/README.md
Normal file
@ -0,0 +1,43 @@
|
||||
# memo · 待办与备忘录
|
||||
|
||||
两类条目,行为**刻意不同**:
|
||||
|
||||
| 类型 | 用途 | 是否主动提醒 |
|
||||
|---|---|---|
|
||||
| **待办**(todo) | 有截止概念、需要被催的事 | ✅ 会 |
|
||||
| **备忘录**(memo) | 纯记事,供以后查阅 | ❌ 不会 |
|
||||
|
||||
分开的理由:把"提醒我"和"记一下"混成一类,要么备忘录天天弹、要么待办被忘掉。
|
||||
|
||||
## 工具
|
||||
|
||||
| 工具 | 说明 |
|
||||
|---|---|
|
||||
| `memo_todo_add` | 添加待办(会被主动提醒) |
|
||||
| `memo_todo_complete` | 标记待办完成(不再提醒) |
|
||||
| `memo_todo_list` | 列出未完成待办(含 ID、内容、创建时间) |
|
||||
| `memo_todo_delete` | 删除待办(含已完成的) |
|
||||
| `memo_memo_create` | 创建备忘录(纯记事,不提醒) |
|
||||
| `memo_memo_list` | 列出全部备忘录 |
|
||||
| `memo_memo_delete` | 删除备忘录 |
|
||||
|
||||
> 工具名前缀取自插件名(`p.tp`),上面按默认的 `memo_` 写法列出。
|
||||
|
||||
## 提醒机制
|
||||
|
||||
- 后台 **每 5 分钟**检查一次未完成待办数;有则通过 `InjectInterruptText` 注入一条
|
||||
「注意,你还有 N 条待办未完成,请检查」。
|
||||
- 注入带 **`NoMemory: true`** —— 这是定时提醒,不是记忆内容,不该进向量化。
|
||||
- 通道声明为 **`NoMemory`**(`RegisterInputChannel(p.name, ChannelDef{NoMemory:true})`),
|
||||
理由同上:提醒是瞬时信号。
|
||||
- 另有 `StagePreAction` 钩子,在每轮动作前参与。
|
||||
|
||||
## 存储
|
||||
|
||||
条目落在数据目录的 `todos.json`,插件重启后仍在。
|
||||
|
||||
## 构建
|
||||
|
||||
```bash
|
||||
hmapdev build
|
||||
```
|
||||
30
example/music/README.md
Normal file
30
example/music/README.md
Normal file
@ -0,0 +1,30 @@
|
||||
# music · 音乐搜索
|
||||
|
||||
按关键词搜歌、按 ID 查歌词(数据来自网易云音乐公开接口)。
|
||||
|
||||
## 工具
|
||||
|
||||
| 工具 | 说明 |
|
||||
|---|---|
|
||||
| `music_search` | 按关键词搜歌,返回歌曲列表(含歌曲 ID) |
|
||||
| `music_lyrics` | 按歌曲 ID 取歌词 |
|
||||
|
||||
典型两段式用法:先 `music_search` 拿 ID,再 `music_lyrics` 取词。
|
||||
|
||||
## 实现要点
|
||||
|
||||
- 请求打的是 `https://music.163.com/api/...`,并固定带上 `Referer: https://music.163.com/` ——
|
||||
该接口对缺少来源头的请求会拒绝。
|
||||
- 是**只读**插件:不下载音频、不写本地文件,因此没有需要清理的副作用。
|
||||
|
||||
## 已知边界
|
||||
|
||||
- 依赖第三方(网易云)公开接口,其可用性与返回结构不受本插件控制;
|
||||
接口变动时可能返回空列表,而不是报错。
|
||||
- 仅覆盖"搜索 + 歌词",不含播放地址解析。
|
||||
|
||||
## 构建
|
||||
|
||||
```bash
|
||||
hmapdev build
|
||||
```
|
||||
40
example/ocr/README.md
Normal file
40
example/ocr/README.md
Normal file
@ -0,0 +1,40 @@
|
||||
# ocr · 图片文字识别
|
||||
|
||||
从图片里提取文字(中英文),基于 [Tesseract](https://github.com/tesseract-ocr/tesseract) OCR 引擎。
|
||||
|
||||
## 前置依赖
|
||||
|
||||
需要系统里装有 `tesseract` 可执行文件:
|
||||
|
||||
```bash
|
||||
# Debian/Ubuntu
|
||||
apt install tesseract-ocr tesseract-ocr-chi-sim
|
||||
```
|
||||
|
||||
中文识别需要 `chi_sim` 语言包;缺它时中文会识别成乱码而非报错。
|
||||
|
||||
## 工具
|
||||
|
||||
| 工具 | 说明 |
|
||||
|---|---|
|
||||
| `ocr_ocr_image` | 对图片做 OCR,返回识别文本 |
|
||||
|
||||
参数:
|
||||
|
||||
| 参数 | 说明 |
|
||||
|---|---|
|
||||
| `image_url` | 图片的 HTTP/HTTPS 地址(与 `image_data` 二选一) |
|
||||
| `image_data` | 图片的 base64 数据,**不含** `data:image/...` 前缀(与 `image_url` 二选一) |
|
||||
| `language` | 识别语言,默认 `chi_sim+eng`;可选 `chi_sim` / `eng` / `chi_sim+eng` |
|
||||
|
||||
## 实现要点
|
||||
|
||||
- 传入的图先落到临时目录,OCR 完 `defer os.RemoveAll` 清掉,不残留。
|
||||
- 调用参数固定 `--psm 3`(全自动页面分割),适合截图与常规排版图片;对单行小图或竖排文本效果会下降。
|
||||
- **`Cleaner`**:工具返回的是 JSON(含 `text`、`language` 等字段),进记忆计算前只取 `text` 正文 —— 否则 JSON 结构本身会参与向量化。
|
||||
|
||||
## 构建
|
||||
|
||||
```bash
|
||||
hmapdev build
|
||||
```
|
||||
167
example/qq/README.md
Normal file
167
example/qq/README.md
Normal file
@ -0,0 +1,167 @@
|
||||
# qq · QQ 消息桥接
|
||||
|
||||
通过 [NapCat](https://github.com/NapNeko/NapCatQQ) 把 QQ 接成 HomeAgent 的一个 IO 通道:
|
||||
让 agent 收发 QQ 消息、读群/好友信息、传文件。
|
||||
|
||||
> ⚠️ 这是**安全敏感**插件:它让外部 QQ 用户能触达 agent 的工具。
|
||||
> 本文档的「权限模型」一节请务必读完。
|
||||
|
||||
## 通道与钩子
|
||||
|
||||
| 类型 | 名称 | 说明 |
|
||||
|---|---|---|
|
||||
| 出站 | `qq` | `CapText` + `CapFile` + `CapImage` + `CapAudio`;发消息/文件给 QQ |
|
||||
| 入站 | `qq` | `NoMemory: true` + `Cleaner` + `RecallPolicy: None` |
|
||||
|
||||
四个阶段钩子(全部 `StageScopeGlobal`):
|
||||
|
||||
| 钩子 | 作用 |
|
||||
|---|---|
|
||||
| `on_input` | 把本轮 QQ 身份**绑到帧上** |
|
||||
| `before_toolcall` | 权限门:逐个工具判断是否放行 |
|
||||
| `post_action` | 清掉被拒绝时模型已经吐出的废话 |
|
||||
| `after_output` | 收尾时清理插件全局身份 |
|
||||
|
||||
## 工具(20 个)
|
||||
|
||||
| 工具 | 说明 |
|
||||
|---|---|
|
||||
| `qq_get_message` | 按 `message_id` 取消息正文、发送者、附件 |
|
||||
| `qq_get_history` | 取群/私聊最近历史消息 |
|
||||
| `qq_list_chats` | 会话列表(按最新消息排序,带未读数与摘要) |
|
||||
| `qq_mark_read` | 把某会话未读数清零 |
|
||||
| `qq_send_file` | 发文件/图片(私聊或群聊) |
|
||||
| `qq_get_groups` | 群列表,可按关键词搜 |
|
||||
| `qq_get_friends` | 好友列表,可按昵称/备注搜 |
|
||||
| `qq_get_recent_contacts` | 最近有消息的联系人与群 |
|
||||
| `qq_resolve_name` / `qq_resolve_nickname` | 名字 ↔ QQ 号互查 |
|
||||
| `qq_get_group_member_info` | 群成员信息 |
|
||||
| `qq_group_manage` | 群综合管理(见下) |
|
||||
| `qq_friend_action` | 好友操作 |
|
||||
| `qq_get_group_files` | 群文件列表 |
|
||||
| `qq_download_file` / `qq_upload_group_file` / `qq_get_download_tasks` | 文件传输与任务 |
|
||||
| `qq_read_document` | 读 QQ 传来的文档 |
|
||||
| `qq_video_download` | 下载视频 |
|
||||
| `qq_send_like` | 点赞 |
|
||||
|
||||
`qq_group_manage` 一个工具承载多种操作(`command` 参数):
|
||||
`leave` 退群、`kick` 踢人、`ban`/`unban` 禁言解禁、`rename` 改名、`mute-all` 全员禁言、
|
||||
`set-card` 设名片、`set-admin` 设管理、`set-title` 设头衔、`member-list`、`group-info`、
|
||||
`msg-history`、`recall` 撤回、`pin-msg` 精华、`list-files`、`pending-requests`、`folder-create` 等。
|
||||
|
||||
**破坏性操作**(`leave`/`kick`/`ban`/`unban`/`rename`/`mute-all`/`set-card`/`set-admin`/
|
||||
`set-title`/`recall`/`pin-msg`/`folder-create`)**必须显式传 `confirm: true`**。
|
||||
|
||||
## 权限模型
|
||||
|
||||
这是本插件最重要的部分。
|
||||
|
||||
### 身份分级
|
||||
|
||||
| 身份 | 权限 |
|
||||
|---|---|
|
||||
| **owner**(Bot 所有者) | 私聊或群聊均**完整放行** |
|
||||
| **普通 QQ 用户** | 只放行白名单内的工具 |
|
||||
|
||||
### 身份必须「绑帧」,不能只存插件全局
|
||||
|
||||
源码注释记录了两个真实故障,这就是绑帧的原因:
|
||||
|
||||
1. **中断抢占后身份丢失**:中断会抢占当前轮、把现场压栈。中断轮收尾时
|
||||
`after_output` 会清空插件**全局**身份;随后外层被恢复(`resumeTask` 复用同一帧、
|
||||
**不重跑 `on_input`**)。若身份只存全局,恢复后的外层就是"无身份",
|
||||
`before_toolcall` 在 `!auth.active` 处直接返回 —— **整个权限门失效**。
|
||||
2. **运行中到达的消息改写身份**:新消息会调 `activateAuthContext` 改写全局身份,
|
||||
把**正在跑的那一轮**换成另一方的身份(换高=越权,换低=误拒)。
|
||||
|
||||
帧上的 `Extra` 随帧一起压栈/恢复,正好是"这一轮的身份"。
|
||||
|
||||
### 合并取最小权限
|
||||
|
||||
多来源被内核合并到同一推理时,权限**取交集**而非并集:
|
||||
|
||||
```go
|
||||
p.auth.owner = p.auth.owner && next.owner
|
||||
```
|
||||
|
||||
防的是"非所有者请求 + 随后所有者消息"意外把前一个请求提权。
|
||||
|
||||
### 硬私有工具
|
||||
|
||||
非所有者**一律拒绝**(不看白名单),按前缀拦截:
|
||||
`calendar_`、`email_`、`mail_`、`agentmail_`、`memory_`、`knowledge_`、`device_`、
|
||||
`devicectl_`、`terminal_`、`shell_`、`command_`、`exec_`、`filesystem_`、`agentfs_`、
|
||||
`config_`、`settings_`、`plugin_`、`plugins_`,
|
||||
外加 `read_file`、`write_file`、`edit_file`、`delete_file`、`list_files`、`run_command`、
|
||||
`homeagent_config`、`homeagent_restart`、`output_send__email`、`output_send__mail`。
|
||||
|
||||
### 参数与会话一致性校验
|
||||
|
||||
光看工具名不够,还要检查**参数指向的会话与当前身份一致**,否则可以拿别人的
|
||||
`message_id` 去读别处内容:
|
||||
|
||||
- 带 `message_id` 的工具:该 ID 必须属于当前 QQ 会话(`lookupMsgRef` 校验 peer 与群/私聊类型)。
|
||||
- `get_group_member_info` / `get_group_files`:`group_id` 必须是**当前群**。
|
||||
|
||||
### 频率与重复控制
|
||||
|
||||
| 键 | 作用 |
|
||||
|---|---|
|
||||
| `max_qq_tool_calls` | 单轮工具调用上限 |
|
||||
| `max_qq_output_calls` | 单轮输出调用上限 |
|
||||
| `max_duplicate_qq_send` | 重复发送上限,防刷屏 |
|
||||
| `batch_window_ms` / `batch_max_ms` | 消息合批窗口 |
|
||||
|
||||
被拒时只允许**发一次权鉴说明**,之后锁止本轮剩余工具调用
|
||||
(`clearDeniedResponse` 再把模型已写出的内容清掉,避免输出里带一堆"我不能…")。
|
||||
|
||||
## 配置项
|
||||
|
||||
### 连接
|
||||
|
||||
| 键 | 默认 | 说明 |
|
||||
|---|---|---|
|
||||
| `napcat_url` | — | NapCat 服务地址 |
|
||||
| `listen` | — | 本插件 HTTP 监听地址 |
|
||||
| `webhook_token` | — | webhook 校验令牌 |
|
||||
|
||||
### 身份与准入
|
||||
|
||||
| 键 | 默认 | 说明 |
|
||||
|---|---|---|
|
||||
| `owner` | 空 | Bot 所有者 QQ 列表(逗号分隔),拥有完整权限 |
|
||||
| `admin` | 空 | **旧配置名**,`owner` 为空时作为所有者列表(兼容用) |
|
||||
| `dm_policy` | `open` | 私聊策略:`open` / `allowlist` / `disabled` |
|
||||
| `allow_from` | 空 | 私聊白名单(QQ 号,逗号分隔) |
|
||||
| `group_policy` | `open` | 群聊策略:`open` / `allowlist` / `disabled` |
|
||||
| `group_allow_from` | 空 | 群白名单 |
|
||||
| `private_tool_allowlist` | 空 | 私聊下非所有者可用的工具 |
|
||||
| `group_tool_allowlists` | 空 | 按群配置的工具白名单 |
|
||||
|
||||
### 文件与转发
|
||||
|
||||
| 键 | 说明 |
|
||||
|---|---|
|
||||
| `files_dir` | 本地文件目录 |
|
||||
| `remote_dir` | 供 NapCat 容器访问的目录(发文件前先复制到这里) |
|
||||
| `agentfs_dir` | agent 文件系统目录 |
|
||||
| `forward_rules` | JSON 数组,每项 `{group_id,host,port,password,template}`:匹配的群消息经 **RCON** 转发到 Minecraft;`template` 支持 `{nickname}` / `{message}` 占位 |
|
||||
|
||||
## 部署前提
|
||||
|
||||
需要**自行部署 NapCat**(本插件不含 QQ 协议实现,只是 NapCat 的客户端)。
|
||||
发文件前会先把文件复制到 `remote_dir`,因为 NapCat 通常在容器里,看不到宿主任意路径。
|
||||
|
||||
## 测试
|
||||
|
||||
```bash
|
||||
go test -count=1 -race ./...
|
||||
```
|
||||
|
||||
含权限门与绑帧的回归测试。改动权限相关代码后务必跑 `-race`。
|
||||
|
||||
## 构建
|
||||
|
||||
```bash
|
||||
hmapdev build
|
||||
```
|
||||
53
example/recoverydiag/README.md
Normal file
53
example/recoverydiag/README.md
Normal file
@ -0,0 +1,53 @@
|
||||
# recoverydiag · 快速检查 / 崩溃取证
|
||||
|
||||
给 guard 与 failback 用的**确定性诊断工具集**。
|
||||
|
||||
设计基调(源码原话):**返回结论而非原文,确定性检出,不消耗 LLM token。**
|
||||
崩溃后最忌讳的是把几万行日志塞进模型上下文让它"看看",那既慢又不可靠 ——
|
||||
这里每个工具都在本地算出结论再返回。
|
||||
|
||||
## 工具
|
||||
|
||||
| 工具 | 说明 |
|
||||
|---|---|
|
||||
| `recoverydiag_diag_triage` | 快速分诊:按退出码 / 信号 / 存活状态粗分类别(进程死亡 vs 配置类不可达 vs 正常) |
|
||||
| `recoverydiag_diag_db` | config.db 完整性(`PRAGMA integrity_check`)+ LLM 源解析校验(`core.llm.sources.*` 必备字段),逐项 ok/fail |
|
||||
| `recoverydiag_diag_log_scan` | 在日志目录的时间窗内统计已知错误签名(panic / OOM / 网络不可达 / provider 失败 / sql / 致命)出现次数,给出主导结论 |
|
||||
| `recoverydiag_diag_delta` | 对比 baseline(上次 good 快照/目录)与现状,列出 created / modified / deleted 清单与摘要,判定"改了什么" |
|
||||
| `recoverydiag_diag_loc` | 综合前四项结论,按**因果强度正交排序**定位根因并给出推荐恢复动作 |
|
||||
|
||||
## 用法顺序
|
||||
|
||||
```
|
||||
diag_triage → diag_db → diag_log_scan → diag_delta → diag_loc
|
||||
(各自独立,可只跑需要的) (要传前四项的结论)
|
||||
```
|
||||
|
||||
`diag_loc` 需要你把它余下的结论**作为参数传进去**(`triage` / `db` / `log` / `delta` 四个对象),
|
||||
它不自己去调 —— 这样它只做归因,不重复执行。
|
||||
|
||||
## 配置项
|
||||
|
||||
| 键 | 默认 | 说明 |
|
||||
|---|---|---|
|
||||
| `db_check_cmd` | `auto` | `diag_db` 用的 `sqlite3` 命令。留空=auto:可用时用 sqlite3,缺失则回退读内核 Settings |
|
||||
| `recovery_kb_dir` | 空 | `diag_loc` 结论 JSON 的落盘目录。缺省 `<data_dir>/recovery_kb` |
|
||||
|
||||
## 不注册通道与钩子
|
||||
|
||||
本插件**只提供工具**,不订阅输入、不挂阶段钩子 —— 它是被 guard 或 agent 主动调用的,
|
||||
不做后台干预。
|
||||
|
||||
## 测试
|
||||
|
||||
```bash
|
||||
go test -count=1 ./...
|
||||
```
|
||||
|
||||
`diag_test.go` 覆盖各诊断项的判定逻辑。
|
||||
|
||||
## 构建
|
||||
|
||||
```bash
|
||||
hmapdev build
|
||||
```
|
||||
@ -1,13 +1,44 @@
|
||||
# rss
|
||||
# rss · RSS/Atom 订阅监控
|
||||
|
||||
rss plugin
|
||||
订阅 RSS/Atom 源,**有新文章时主动通知** agent(不必每轮去问)。
|
||||
|
||||
## Build
|
||||
## 工具
|
||||
|
||||
| 工具 | 说明 |
|
||||
|---|---|
|
||||
| `rss_subscribe` | 订阅一个 RSS/Atom 源 |
|
||||
| `rss_unsubscribe` | 取消订阅 |
|
||||
| `rss_list` | 列出全部订阅 |
|
||||
| `rss_check_now` | 立即检查所有源(不等轮询周期) |
|
||||
|
||||
## 配置项
|
||||
|
||||
| 键 | 默认 | 说明 |
|
||||
|---|---|---|
|
||||
| `poll_interval` | `30` | 默认轮询间隔(**分钟**) |
|
||||
|
||||
订阅时可对单个源覆盖间隔。
|
||||
|
||||
## 通知机制
|
||||
|
||||
- 后台按各自间隔轮询(默认 30 分钟)。
|
||||
- 发现新条目时通过 `InjectInterruptText` 注入,格式形如
|
||||
`📡 <源标题> (<URL>) — N 篇新文章:` 后跟条目。
|
||||
- 注入带 **`NoMemory: true`**,通道 `rss` 也声明为 `NoMemory` ——
|
||||
订阅推送是信号不是知识,不该进向量化挤掉别的记忆。
|
||||
|
||||
## 实现要点
|
||||
|
||||
- **订阅时就记下全部已有 GUID**:`handleSubscribe` 会把抓取到的历史条目
|
||||
一次性标为 `seenGUIDs`,所以**订阅一个源不会把它的历史文章全部推送一遍**。
|
||||
只有订阅之后新出现的条目才通知。这是避免刷屏的关键。
|
||||
- **去重按「源 URL + GUID」**:不同源可能用相同 GUID,只用 GUID 会互相误判。
|
||||
GUID 缺失时回退用 `link`;两者都缺则跳过该条。
|
||||
- `seenGUIDs` 有清理逻辑,不会无限增长。
|
||||
- 解析用 [gofeed](https://github.com/mmcdole/gofeed)(`v1.4.0`)。
|
||||
|
||||
## 构建
|
||||
|
||||
```bash
|
||||
hmapdev build
|
||||
```
|
||||
|
||||
## Install
|
||||
|
||||
Upload the .hmap file through the Plugin Manager API.
|
||||
|
||||
48
example/sanitizer/README.md
Normal file
48
example/sanitizer/README.md
Normal file
@ -0,0 +1,48 @@
|
||||
# sanitizer · 文本清洗
|
||||
|
||||
**不注册任何工具**,只挂三个阶段钩子,在 Agent 全链路上洗掉两类污染:
|
||||
|
||||
1. **坏字节**:坏 UTF-8、`U+FFFD`(替换符)、ANSI 转义序列
|
||||
2. **思维泄漏**:LLM 输出里残留的工具调用标记
|
||||
|
||||
## 为什么需要它
|
||||
|
||||
坏字节会**被 LLM 复读**。一次工具返回乱码(比如源码里带 ANSI 颜色码、或二进制片段被当文本读出来),
|
||||
这些字节会进上下文,之后模型每次生成都可能把它抄一遍 —— 越滚越脏。
|
||||
在每个入口洗掉,比事后清理便宜得多。
|
||||
|
||||
思维泄漏则是另一种:模型有时把 `<tool_call>...</tool_call>` 这类内部标记直接写进正文,
|
||||
用户就看到一堆不该出现的 XML。
|
||||
|
||||
## 挂载的三个阶段
|
||||
|
||||
| 阶段 | 处理对象 | 作用 |
|
||||
|---|---|---|
|
||||
| `on_input` | `ctx.RawMessage` | 洗用户输入,脏字节不进后续链路 |
|
||||
| `after_toolcall` | `ctx.ToolResults` | 洗工具结果,**坏字节不进 LLM 上下文** |
|
||||
| `post_action` | `ctx.LLMText` | 洗模型输出:先清思维泄漏,再清乱码 |
|
||||
|
||||
每次有改动都打一行日志(`cleaned N bytes`),便于确认它真的在工作而不是静默失败。
|
||||
|
||||
## 识别哪些泄漏形态
|
||||
|
||||
按正则匹配多种标记写法,覆盖不同模型家族的习惯:
|
||||
|
||||
- `<tool_call>…</tool_call>`、`<invoke>…</invoke>`、`<tool>…</tool>`
|
||||
- `<function>…</function>`
|
||||
- 上述标记包在 ```xml / ```json 代码块里的形态
|
||||
- 中文括号变体:`【tool_call】…【/tool_call】`
|
||||
|
||||
## 实现要点
|
||||
|
||||
- 依赖 **ABI v2 的 stage 写回能力**:插件对 `StageContext` 的修改会同步回内核。
|
||||
在 v1 上改了不生效。
|
||||
- 读写 `StageContext` 时按约定加 `ctx.Lock()`。
|
||||
|
||||
## 构建
|
||||
|
||||
```bash
|
||||
go build -buildmode=plugin -o sanitizer.so .
|
||||
```
|
||||
|
||||
或经 `hmapdev build` 打包为 `.hmap`。
|
||||
77
example/vanblog/README.md
Normal file
77
example/vanblog/README.md
Normal file
@ -0,0 +1,77 @@
|
||||
# vanblog · VanBlog 博客管理
|
||||
|
||||
用管理 API 操作 [VanBlog](https://vanblog.mereith.com/) 开源博客系统:
|
||||
文章增删改查、分类标签、草稿发布、备份导出等。
|
||||
|
||||
## 配置项
|
||||
|
||||
| 键 | 默认 | 说明 |
|
||||
|---|---|---|
|
||||
| `url` | `https://blog.jianfgit.xyz` | VanBlog 站点基地址 |
|
||||
| `token` | 空 | 管理员 API Token(长期令牌,从后台「Token 管理」创建) |
|
||||
| `reset_token` | 空 | 用于 `auth/restore` 重置管理员密码的**特殊** Token |
|
||||
|
||||
`token` 与 `reset_token` 都是 `password` 类型(界面遮蔽)。
|
||||
|
||||
## 工具(28 个)
|
||||
|
||||
### 文章
|
||||
|
||||
| 工具 | 说明 |
|
||||
|---|---|
|
||||
| `vanblog_list_articles` | 列文章,支持分页与搜索 |
|
||||
| `vanblog_get_article` | 取单篇完整内容 |
|
||||
| `vanblog_create_article` | 新建(`title` 与 `category` 必填) |
|
||||
| `vanblog_update_article` | 更新(**只传要改的字段**) |
|
||||
| `vanblog_delete_article` | 删除(**软删除**) |
|
||||
| `vanblog_search_articles` | 按链接搜索文章 |
|
||||
|
||||
### 草稿
|
||||
|
||||
`vanblog_manage_drafts`:`list` / `get` / `create` / `update` / `delete` / **`publish`**
|
||||
|
||||
### 内容组织
|
||||
|
||||
| 工具 | 命令 |
|
||||
|---|---|
|
||||
| `vanblog_manage_categories` | `list` / `get` / `create` / `update` / `delete` |
|
||||
| `vanblog_manage_tags` | `list` / `get` / `rename` / `delete` |
|
||||
|
||||
### 站点与运维
|
||||
|
||||
| 工具 | 说明 |
|
||||
|---|---|
|
||||
| `vanblog_manage_site` / `_settings` / `_menu` / `_social` / `_links` | 站点配置类 |
|
||||
| `vanblog_manage_about` / `_pages` | 关于页与自定义页面 |
|
||||
| `vanblog_manage_images` | 图床管理 |
|
||||
| `vanblog_manage_rewards` | 赞赏配置 |
|
||||
| `vanblog_manage_backup` | 备份 |
|
||||
| `vanblog_manage_caddy` | Caddy 配置 |
|
||||
| `vanblog_manage_isr` | ISR 增量静态渲染 |
|
||||
| `vanblog_manage_pipelines` | 流水线 |
|
||||
| `vanblog_manage_collaborators` | 协作者 |
|
||||
| `vanblog_manage_tokens` | Token 管理 |
|
||||
| `vanblog_get_analysis` / `_logs` / `_meta` | 统计、日志、元信息 |
|
||||
| `vanblog_auth` | 认证相关(含 `restore` 重置密码) |
|
||||
|
||||
> 工具名前缀取自插件名(`tp`),上面按默认 `vanblog_` 列出。
|
||||
|
||||
## 实现要点
|
||||
|
||||
- 走的是 VanBlog 的管理 API(`/api/admin/...`),所以必须配 **admin token**,
|
||||
不是前台只读接口。
|
||||
- `update_article` 是**部分更新**:只传想改的字段,没传的保持不变。
|
||||
(不要为了改标题而把正文一起传一遍。)
|
||||
- `delete_article` 是**软删除**,内容仍在,可在后台恢复。
|
||||
- 早期版本把 token 放在内核配置(`plugin.vanblog.token`)里,
|
||||
现在会**自动迁移**到插件配置,迁移后清空内核侧取值。
|
||||
|
||||
## 前置
|
||||
|
||||
需要一个可访问的 VanBlog 实例,并在后台创建一个长期 Token。
|
||||
|
||||
## 构建
|
||||
|
||||
```bash
|
||||
hmapdev build
|
||||
```
|
||||
@ -1,13 +1,33 @@
|
||||
# weather
|
||||
# weather · 天气查询
|
||||
|
||||
weather plugin
|
||||
给 agent 补上天气查询能力(基于 [wttr.in](https://wttr.in),无需 API Key)。
|
||||
|
||||
## Build
|
||||
## 工具
|
||||
|
||||
| 工具 | 说明 |
|
||||
|---|---|
|
||||
| `weather_current` | 查询某城市当前天气 |
|
||||
| `weather_forecast` | 查询未来几天预报 |
|
||||
| `weather_set_location` | 设置默认城市 |
|
||||
|
||||
`weather_current` / `weather_forecast` 都接受 `location`(城市名,如 `Beijing`、`Shanghai`);
|
||||
省略时用配置里的默认城市。`weather_current` 另有 `units`:`metric`(摄氏,默认)或 `imperial`(华氏)。
|
||||
|
||||
## 配置项
|
||||
|
||||
| 键 | 默认 | 说明 |
|
||||
|---|---|---|
|
||||
| `default_location` | 空 | 默认城市名。留空则每次调用都必须传 `location` |
|
||||
|
||||
## 实现要点
|
||||
|
||||
- **`NoMemory: true`**:天气是外部实时数据,对记忆计算无长期价值,跳过向量化与关键词提取(原文仍保留在对话里)。
|
||||
- **`Cleaner`**:输出参与记忆计算前先过滤,只保留摘要行 —— 天气查询会反复出现,全文进记忆会挤占上下文预算,而"上周三北京多少度"通常并不需要召回。
|
||||
|
||||
## 构建
|
||||
|
||||
```bash
|
||||
hmapdev build
|
||||
```
|
||||
|
||||
## Install
|
||||
|
||||
Upload the .hmap file through the Plugin Manager API.
|
||||
产出 `.hmap` 后经 Plugin Manager API 安装。
|
||||
|
||||
Reference in New Issue
Block a user