Files
mtfyun 7d2e8fed8e 小鲸娘 v1.0:悬浮宠物完整工程
- 106 动画 + 2366 表情包 + 语义标签
- 三层记忆 / 心情系统 / 9 可配置插件 / 10 技能
- DeepSeek 对话直连 + MCP/HTTP 接入 + 接入文档
- 动画随机链 + 物理引擎 + 贴边碰撞校准
- 大资源(动画webp/表情图)由 scripts/ 再生成,不入库
2026-11-08 08:07:09 +00:00

13 KiB
Raw Permalink Blame History

桌宠推送接入文档(workbuddy / DeepSeek 等)

桌宠在设备本机开了一个 HTTP 服务,任何 App 只要拿到授权码就能向它推送任务通知。

  • 地址:http://127.0.0.1:7350
  • 授权码:在桌宠面板「接入 → 推送授权」里查看/复制/生成(可多个、可单独吊销)
  • 鉴权:写请求必须带 X-Pet-Token: <码>(也支持 ?token=<码>)
  • 只读接口 GET /api/state、GET /api/health 无需授权

调用方 App 需允许明文 HTTP:android:usesCleartextTraffic="true", 或 network-security-config 放行 127.0.0.1。


接口一览

方法 路径 说明
GET /api/health 应用信息、动画数、authRequired、端点清单
GET /api/state 当前动画、气泡、朝向
POST /api/task 任务状态通知(推荐)
POST /api/notify 通用通知(按 level 或 state)
POST /api/anim 点播任意动画(中文名)
POST /api/broadcast 只说一句话,不改动画
POST /api/clear 清空气泡

POST /api/task

{ "state": "working", "text": "正在生成周报…", "durationMs": 8000, "meme": "m09" }

state → 动画映射:

state 动画
start / thinking 工作状态-思考冒泡
working 工作状态-忙碌点按
result 工作状态-清点归档
waiting 工作状态-原地踱步张望
done / success 工作状态-雀跃庆祝
error / failed 工作状态-垂头叹气冒汗

POST /api/notify

{ "level": "error", "text": "构建失败", "durationMs": 10000, "meme": "m24" }

level 可选:info result working waiting success error。 durationMs 期间宠物会保持这个动作,随机动画链不会覆盖。

meme 可选,取值 m01~m27(气泡里的表情包,见面板动作页预览)。


调用示例

curl

TOKEN=2caa9cb98fea488e
curl -X POST http://127.0.0.1:7350/api/task \
  -H 'Content-Type: application/json' \
  -H "X-Pet-Token: $TOKEN" \
  -d '{"state":"working","text":"正在生成周报…"}'

Kotlin(无第三方依赖)

import org.json.JSONObject
import java.net.HttpURLConnection
import java.net.URL

fun pushToPet(token: String, state: String, text: String, durationMs: Long = 8000) {
    Thread {
        runCatching {
            val conn = (URL("http://127.0.0.1:7350/api/task").openConnection() as HttpURLConnection)
            conn.requestMethod = "POST"
            conn.doOutput = true
            conn.connectTimeout = 2000
            conn.readTimeout = 2000
            conn.setRequestProperty("Content-Type", "application/json")
            conn.setRequestProperty("X-Pet-Token", token)
            val body = JSONObject()
                .put("state", state)
                .put("text", text)
                .put("durationMs", durationMs)
                .toString()
            conn.outputStream.use { it.write(body.toByteArray()) }
            conn.responseCode          // 200 = 成功,401 = 授权码不对
            conn.disconnect()
        }
    }.start()
}

// 用法
pushToPet(token = "2caa9cb98fea488e", state = "working", text = "正在整理对话…")
pushToPet(token = "2caa9cb98fea488e", state = "done",    text = "整理完成 ✅")
pushToPet(token = "2caa9cb98fea488e", state = "error",   text = "请求失败:超时")

JavaScript / Node(workbuddy 若是前端/Node)

async function pushToPet(token, state, text, durationMs = 8000) {
  const res = await fetch('http://127.0.0.1:7350/api/task', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', 'X-Pet-Token': token },
    body: JSON.stringify({ state, text, durationMs })
  });
  if (!res.ok) console.warn('pet push failed', res.status, await res.text());
}

排错

现象 原因
401 unauthorized 授权码不对 / 该应用被删除 / 面板里授权已关闭
连接被拒绝 桌宠没在运行(服务随宠物存活)
404 not-found 路径写错(注意是 /api/task 不是 /task)
调用成功但没反应 宠物面板「外观 → 距离/透明度」设得太小看不见;或气泡已超时消失
cleartext not permitted 调用方 App 没开明文 HTTP

行为约定

  • 通知展示时长内(durationMs)随机动画链暂停,保证通知动作完整播完。
  • 同一时刻只有一条气泡,后到的覆盖前面的。
  • 桌宠本身不存储通知历史(当前版本),错过了就没了。

语义标签(AI 调用推荐方式)

每个动作和表情包都带内部标签。AI 不必记中文名,按语义调用即可。

标签表

标签 含义 典型动作 / 表情包
work workstatus 工作状态 思考冒泡 / 忙碌点按 / 清点归档 / 踱步张望 / 雀跃庆祝 / 垂头叹气冒汗
thinking working result waiting success error 六档细分 对应上面六种工作状态
happy celebrate praise 开心/庆祝/夸奖 雀跃庆祝、开心跃动、厉害了我的鲸、可爱
sad error fail 沮丧/出错 垂头叹气冒汗、死掉了、完蛋了把黄油删了
busy stress 忙碌/压力 忙碌点按、压力一只大肥鱼、大烧货
eat food 吃东西 吃什么分类全部(12 个)
play fun 玩耍/搞笑 玩耍分类(27 个)+ Ciallo、就骚了怎么滴吧
rest sleep lazy 休息/摸鱼 待机呼吸、小憩沉眠、哈欠连天、深度睡眠
festival season 节日/时令 时节分类(21 个:春节/中秋/圣诞/万圣…)
money token need 余额/token 余额动画 6 档、token给妈妈保管、鱼片有资源吗
warn urgent alert 预警/紧急 大的要来啦、大的药来了、电死你
greet wave hello 打招呼 元气挥手、Ciallo
shy surprise angry tsundere 情绪 害羞惊讶、傲娇生气
drag click move turn idle look walk picked 交互池 拖拽悬空、点击回应、移动走路、转向张望、待机
text talk whisper 文字/说话 文字分类 2 个、碎碎念 3 个
category + 分类名 分类归属 小动作 / 玩耍 / 吃什么 / 时节 / 文字

新增 / 增强的接口

方法 路径 说明
GET /api/catalog 返回全部动作与表情包及其标签(免授权)
POST /api/meme `{tag
POST /api/anim 现在支持 {tag:"play"} 按标签点播
POST /api/task /api/notify 新增 withMeme:true 或 memeTag:"success" 自动配图

典型用法

# 开始干活:播「忙碌点按」+ 自动配工作风表情包
curl -X POST http://127.0.0.1:7350/api/task \
  -H 'Content-Type: application/json' -H 'X-Pet-Token: 你的授权码' \
  -d '{"state":"working","text":"正在生成周报…","withMeme":true}'

# 干完了:播「雀跃庆祝」+ 夸奖表情包
curl -X POST http://127.0.0.1:7350/api/task \
  -H 'Content-Type: application/json' -H 'X-Pet-Token: 你的授权码' \
  -d '{"state":"done","text":"周报已生成 ✅","memeTag":"praise"}'

# 出错了
curl -X POST http://127.0.0.1:7350/api/task \
  -H 'Content-Type: application/json' -H 'X-Pet-Token: 你的授权码' \
  -d '{"state":"error","text":"构建失败","withMeme":true}'

# 随手玩一下
curl -X POST http://127.0.0.1:7350/api/anim  -H 'Content-Type: application/json' \
  -H 'X-Pet-Token: 你的授权码' -d '{"tag":"play"}'
curl -X POST http://127.0.0.1:7350/api/meme  -H 'Content-Type: application/json' \
  -H 'X-Pet-Token: 你的授权码' -d '{"tag":"fun"}'

# 让 AI 自己发现可用标签
curl http://127.0.0.1:7350/api/catalog

自动配图规则

withMeme:true 时会按状态自动挑标签: done/success → success,praise;error → error,fail;working → working,busy; waiting → warn;start/thinking → working,busy。

表情包标签(随图入库)

表情包最终以 config.json 里每条的 tags 为准(官方 27 张 + 动画帧生成 24 张 + 梗鲸档案馆收录)。 常用梗图情绪标签:angry sad happy praise thinking fun confused complain love money waiting greet eat work error rest。

  • GET /api/catalog 返回每张表情包的 tags
  • POST /api/meme {"tag":"..."} 按标签随机弹一张
  • POST /api/task {"state":"working","withMeme":true} 按状态自动配图
  • 应用内长按表情包可隐藏(写进 pet_prefs.hidden_memes)

动作节奏与随机

接口 说明
POST /api/settings {"chainGapSeconds":8,"idleAfterSeconds":120} 切换间隔(0–60s)、空闲回待机(0=关闭,最多 3600s)
POST /api/anim {"random":true} 随机播一个动作(排除事件池)
POST /api/anim {"idle":true} 回到待机动作(待机池)
GET /api/health 返回 memes / tags / catalog / docs* 等入口

应用内也有:设置 → 动作(切换间隔、空闲回待机、随机播一个动作、回到待机)。

推送与动作节奏

推送(/api/task、/api/notify、/api/anim、/api/meme、/api/broadcast)现在也纳入动作节奏循环:

  • 推送的动画会完整播放(占满其时长)
  • 之后额外等待「切换间隔」(chainGapSeconds)才继续随机动作链
  • 推送会重置「空闲回待机」计时(视为有活动)
  • 多次推送连续到达时,以最后一条的时长重新排程

扩展能力:技能 / 插件 / MCP

技能(Skills)

声明式动作序列,一次调用播一串。

接口 说明
GET /api/skills 列出内置技能
POST /api/skill {"id":"work_done"} 执行;可带 text 覆盖首个气泡文字

内置:work_start 开工 · work_done 收工 · work_error 出错了 · slack 摸鱼 · meal 干饭 · greet 打招呼 · sleep 睡觉 · report 汇报。 应用内:动作页顶部「技能」卡片点一下即触发。

插件(JS)

接口 说明
POST /api/plugin {"id":"x","code":"..."} 安装/覆盖插件(存 App 私有目录)
GET /api/plugins 已装插件列表
POST /api/plugin/remove {"id":"x"} 卸载
GET /api/plugins.js 合并后的插件代码(宠物 WebView 自动加载)

插件运行在宠物 WebView 里,可用桥接 Pet: Pet.say(text, ms)、Pet.notify(state, text, withMeme)、Pet.anim({tag}|{name}|{random:true})、 Pet.meme({tag}|{name})、Pet.skill(id)、Pet.status()、Pet.on(evt, fn)。

示例插件:{"id":"clock","code":"setInterval(function(){Pet.say('整点啦~')},3600000)"}

MCP(Model Context Protocol)

本机 MCP Server:POST http://127.0.0.1:7350/mcp?token=授权码(JSON-RPC 2.0)

  • initialize → protocolVersion 2024-11-05
  • tools/list → pet_status pet_say pet_notify pet_play pet_meme pet_skill pet_catalog
  • tools/call → {name, arguments},返回 content[0].text(JSON 字符串)
curl -X POST 'http://127.0.0.1:7350/mcp?token=你的授权码' \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"pet_notify","arguments":{"state":"working","text":"MCP 调用测试","withMeme":true}}}'

内置插件(首启自动安装)

id 名称 行为
greet_daily 时段问候 早/中/下午/晚各问候一次(按天去重)
water_reminder 喝水提醒 每小时一句补水提醒
sit_reminder 久坐提醒 每 45 分钟提醒起身
clock_chime 整点报时 整点轻声报时
tap_counter 戳戳吐槽 连戳 5 次吐槽一句
random_meme 随机表情包 每 2 小时随机弹一张

全部 23:00–07:00 静默。设置 → 内置插件 可逐个开关;GET /api/plugins 查已装列表。

技能新增:hydrate 喝水 · stretch 伸懒腰(共 10 个)。

新增内置插件(v2)

id 名称 行为
fish_memory 鱼的记忆 七秒记忆梗:约 25 分钟一次有 35% 概率忘事;被戳 12% 概率问「刚才说什么来着」
fish_mood 鱼的心情 心情值 0–100,戳+4、被甩-1,按小时自然衰减;每 90 分钟按心情说一句并配 happy/sad 动作
proactive_talk 主动搭话 40–80 分钟随机主动说一句(关心/闲聊/白米饭),夜间静默

插件配置(v3)

内置插件支持参数配置:设置 → 扩展 → 插件 → 点某个插件 → 滑条/开关 → 保存(自动按新配置重装)。

存储:pet_prefs.plugin_cfg_<id>(JSON),安装时以 var CFG = {...}; 注入代码前缀。

插件 可调参数
时段问候 夜间免打扰、启动延迟(0–60s)
喝水提醒 / 久坐提醒 提醒间隔(15–240 / 15–180 分钟)、夜间免打扰
整点报时 只报 7–23 点
戳戳吐槽 每戳几次吐槽(2–20)
随机表情包 间隔(30–480 分钟)、夜间免打扰
鱼的记忆 间隔(10–120 分钟)、触发概率(0–100%)、被戳概率
鱼的心情 表达间隔(30–240 分钟)、被戳加点(0–20)、初始心情
主动搭话 最短/最长间隔(分钟)、夜间免打扰

自定义插件同样能用 CFG:安装时把常量写成 var CFG = {...} 前缀即可。