nekowhale-meme
Local meme-sticker library: import from a file, a folder or the agent tool, tag images in a review queue you confirm yourself, group them, then let the agent search and send by mood. A design descendant of Loping151/dsh-nekowhale-stickers (no shared code; its sticker_* tool names differ, so the two
Install
dsh plugin --profile web add nekowhale-meme
Sandbox test results
| Stage | Result |
|---|---|
| 1 install | ✓ |
| 2 list | ✓ |
| 3 mount | ✓ |
| 4 boot | — |
Four stages run in an isolated sandbox: install (network on) → list → mount → boot (last three with no network).
README
nekowhale-meme
大肥鱼表情库 —— DSH 表情库插件
把散落的表情图收进一个可检索、可分组、可被 AI 调用的本地库。
初始表情包直接连公开站点 kiriyuki.com
(清单 /api/manifest、图 /media/gif、作者标注 /meme/kit/nekowhale.json)。
本插件基于 dsh-nekowhale-stickers 二创,增加导入表情包功能。
功能
- 收集:页面上传 / 文件夹导入 /
meme_import工具,都只进队列,不自动识别 - 识别打标签:串行、可中止,25 个中文情绪单选 + 自由标签;识别模型在队列页选,选定后固定不跟随全局默认
- 分组管理:多分组、只读组(角色包)、移图、重命名、删除
- AI 检索发图:
meme_search/meme_send工具,只搜「AI 可用组」里已入库且启用的图 - 应景斗图:每轮往上下文塞一条提示,由模型自己判断要不要贴图(提示本身占少量上下文 token,关掉开关就完全不注入)
- 输入框候选窗:聊天输入框旁点鲸鱼娘图标 → 4×4 表情网格,标签条切「常用/分组」、悬停放大预览、点图直接送进输入框回车即发;设置页「真斗图」开关选图片模式(静态图自动缩小省 token,双方可见)或文字模式(更省 token,自己气泡显文本)
- 一键下载初始表情包:从 kiriyuki.com 直连,可自选包,自动套用作者的人工标注
页面
默认进入队列页(全宽),右上角 ⚙ 整页跳转到设置页,设置页左上角 ← 返回。
队列页(三 Tab 三等分)
Tab · 能做什么
待识别 · 全选 / 识别勾选 / 删除勾选;识别模型下拉(红字「识别需要消耗 token」);识别进度条 + 中止;失败项红字显示原因
已标识·待确认 · 按情绪二级筛选(「全部」+ 25 情绪按钮,带张数,该情绪没图的置灰不可点);确认入库(可选目标组)/ 重新识别 / 删除勾选;每项「情绪|描述|关键词」+ 编辑面板
已入库·可用 · 分组选择器 + 管理分组(新建/重命名/删除都在这里);按情绪二级筛选(同上);移出到待确认 / 改分组 / 删除勾选
三个状态的图都能编辑(显示名 / 情绪 / 标签 / 适用场景 / 描述):待识别可先填标注,
待确认正好用来核对模型输出,库内日常修正。唯一例外是只读组(从站点下载的角色包),组里的图不可编辑;
但整个包可以移除——管理分组 里该组一侧是「移除包」,会连组里的图和磁盘文件一起删,之后重新导入会重新下载。
点击任意缩略图可放大预览:页面居中显示,不超过原图尺寸;右上角 ✕ 或点图外空白关闭。
设置页
- 基础
- 数据目录(可改,不写死 C 盘)
- 路径只能通过「选择…」挑选,输入框只读(不允许手打,避免绕过校验与迁移逻辑)
- 「选择…」优先调系统原生目录选择框(Electron dialog / Windows FolderBrowserDialog / Linux zenity),
远程访问时自动回退到内置目录浏览器
- 换目录时把图库与索引整体搬迁到新目录(剪切,旧目录随即清空),不占双份磁盘
- 新目录已有同名文件时跳过不覆盖;有文件搬失败则中止切换并保留原目录,不会出现半截数据
- 换到新目录会记住:旧目录留指针,重启后沿链跟随
- 下载初始表情包:从 kiriyuki.com 直连,带进度条与包维度进度
- 包选择器:下拉多选,带搜索 / 全选 / 清空 / 每包张数与体积 / 「已下 N 张」标记
- 已选合计超过 500MB 显示红色提示
- 每个包建成一个独立只读组(组名=包名),组里的图只能看不能改
- 双人包不支持(本项目不处理双人方向),会从选择器剔除且接口拒绝下载
- 斗图:一个「斗图」总开关(默认关,开着才会往上下文里放提示)、频率步进器(每 10 轮最多 1–10 张)、
触发方式(情绪词匹配 / 模型判断)——插件自己不额外发起模型请求:前者用纯关键词匹配算出情绪再告诉模型,
后者只说明「该发哪个由你判断」。这条提示会作为一条消息进入上下文,本身要占会话 token
- 真斗图(候选窗点击行为开关,默认开):开=输入框候选窗点图发图片附件(静态图自动缩小到 ≤360px 省 token,发送方与 AI 双方可见);
关=发 Markdown 文字(每条只占几十 token,但自己的消息气泡显示原始文本,宿主不渲染用户消息里的 Markdown 图)。
只影响候选窗点图这一条路;AI 侧 meme_send 发图不受它控制(永远是图片)
- AI 可用组:下拉多选(带张数、搜索、全选、清空)。没勾的组 AI 完全看不到;新建组默认不勾
保存规则
保存按钮是唯一的写入途径。 队列页与设置页顶部栏结构完全一致:
nekowhale-meme ● 未保存 [放弃] [保存] [⚙] ← 队列页 设置 ● 未保存 [放弃] [保存] [←] ← 设置页
- 改任何设置后出现「● 未保存」,
放弃/保存才可点 - 不点保存就离开(返回队列页、关掉插件页)一律视为放弃,磁盘不会有任何写入
- 从系统选择框选目录只填进输入框,同样要点保存才生效
- 悬停/切换皮肤时配色自动适配(所有表面色用系统底色混出不透明实色,不叠在皮肤背景上)
安装
dsh plugin --profile desktop add github:jimmyalxe/nekowhale-meme
装完刷新插件页即可(工具/接口在插件装载后即生效)。
也可以从 npm 装(同一个包,版本号与 package.json 一致):
dsh plugin --profile desktop add nekowhale-meme
换版本必须先 remove 再 add,不能覆盖安装:
dsh plugin --profile desktop remove nekowhale-meme dsh plugin --profile desktop add github:jimmyalxe/nekowhale-meme
本地开发
开发目录用 link: 装,改完代码热重载即可,不用碰 GitHub:
dsh plugin --profile desktop add "link:<开发目录绝对路径>"
两个前提:
1. 开发目录里要能解析 peer 依赖 @deepseek-ai/schemastery,否则宿主加载失败会静默留在旧版本。
本机做法是把 profile 的依赖链进来:
New-Item -ItemType Junction -Path node_modules\@deepseek-ai -Target <profile>\node_modules\@deepseek-ai
2. CLI 的 add/remove 只改依赖,不触发宿主重载。要让新代码真正生效,走插件管理器接口:
POST /api/plugin-manager/remove {"id":"nekowhale-meme"} → POST /api/plugin-manager/install {"spec":"link:..."}
→ 轮询 GET /api/plugin-manager/status?job=<jobId> 到 phase=done。
数据目录
默认 $DSH_HOME/nekowhale-meme(与其他 DSH 插件的约定一致,不会写死某个盘符)。
设置页里可以改成任意位置(包括别的盘)。
换目录时会把图库与索引整体搬迁到新目录(剪切,旧目录随即清空),不占双份磁盘;
新目录已有同名文件时跳过不覆盖;有文件搬失败则中止切换并保留原目录,不会出现半截数据。
<dataDir>
├── config.json 配置(数据目录、识别模型、斗图、AI 可用组)
├── index.json 索引:分组 + 条目(写前留 index.json.bak)
├── health.json 失效清单(只增不减,点「知道了」整体清空)
├── inbox/ 上传/下载中转(不参与索引)
├── pending/ 待识别队列
│ └── 20261029T014312-a3f9c1.jpg
└── library/
├── 大肥鱼/ 从 kiriyuki 下载的只读组(保留原名)
└── 我的收藏/ 默认自定义组
命名与去重
阶段 · 文件名
进队列 · <YYYYMMDDTHHMMSS>-<6位哈希>.<ext>
入库后 · <组id>-<时间戳>-<6位哈希>.<ext>
从站点下载 · 保留原名(只读组,不参与重命名规则)
磁盘文件名永不重命名;用户改名只改索引里的 displayName
(界面主标题=显示名,副标题=原文件名 + 日期)。
进队列时算 SHA-1,库里已有就跳过并提示「这张已经在库里(组 X 下)」。
情绪与标签
沿用 25 个中文情绪(与作者标注表完全一致,含顺序),单选:
开心 大笑 喜欢 害羞 得意 兴奋 惊讶 疑惑 思考 无语 难过 哭 生气 害怕 疲惫 赞同 拒绝 打招呼 感谢 道歉 卖萌 搞怪 嘲讽 安慰 其他
标签从两个渠道来:
1. 作者的标注表(下载时自动套用)
站点公开的 /meme/kit/nekowhale.json 有 322 条人工标注。站点是模板化的
(同一 stem 在不同包里是同一动作换角色重渲染),所以按 stem 匹配后
可选包命中率约 97%。desc 含角色名,只有「大肥鱼」包保留。
2. AI 识别(要花 token):套不上标注的走队列识别。
输出尺度对齐作者标注实测分布:tags 4–7 个、use 10–20 字、desc 40–70 字。
状态机
pending ──识别成功──▶ tagged ──确认入库──▶ library
▲ │ │
└──识别失败──────────┘ │
└──移出──────────────┘
任意状态 ──勾选删除──▶ 移除(二次确认)
AI 只检索 library 中 enabled:true 的条目;pending / tagged 一律不参与。
识别
- 串行逐张,绝不并发;点中止后当前这张跑完就停,其余保持待识别
- 模型:队列页所选;首次自动取「DSH 原生默认 + 支持视觉」的模型并固定,
之后改全局默认不跟随;所选模型消失则回落,仍无则提示手动选
- 失败退回待识别并记原因,可重试
- >8MB、空文件、非图片后缀在进队列时就被拒(给出具体原因)
作者实测(2026-10-31):DeepSeek v4.1-flash 打标签完美命中;Qwen(千问) 无法命中大部分标签,
基本只返回「其他」;其他大模型未做测试。
斗图
回合结束后,代码没有能力再去改模型已经发出去的那条回复——所以「自动往对话里追加一张图」
在协议上做不到。这里的做法是在回合开始前给模型立规矩:
1. 每轮在上下文末尾追加一条 plugin:nekowhale-meme 提示,写明「情绪明显时才发」「一次一张」
以及这张图该怎么发出去(见下);
2. 模型自己判断这条消息要不要配图,要就调 meme_send,图直接出现在回复正文里;
3. 关掉「斗图」这一个开关就完全不注入,也就不会为它多花 token。
两种渠道,两种发法
meme_send 的返回值里同时给出「Markdown 图片行」和「本地文件绝对路径」,提示会按当前渠道
告诉模型用哪一个:
渠道 · 判定方式 · 发法
Web / 桌面 · 普通会话 · 把 !名字 原样放进回复正文
IM(QQ / 微信 / 飞书 …) · 入站消息被 dsh-im 包了 <dsh_im_source> · 调 dsh_im_return_file({ path }),把本地原文件交给宿主上
…(truncated)
Rendered from the README published on npm. Formatted only, not edited.
Versions
Published on npm::5,最后更新 2026-11-06