🐔 dsh-chicken-pet
一只住在 DeepSeek Harness Web 界面里的原创像素鸡。 你干活的时候它搬砖,你思考的时候它托腮,等你回复的时候它翘首以盼—— 而它闲下来的时候会自己找事做:打盹、踱步、啄米、抖毛、转球、投篮。
它和别的桌宠有什么不一样
这个品类已经很热闹了,头部项目在「动画数量」和「养成系统」上做得很深。这只鸡选了另一条路:把功夫花在「自主行为」上。
大多数桌宠的待机是一个循环动画播到天荒地老。这只鸡不是——它有一套行为调度器:每隔几秒掷一次加权骰子,从 10 种待机行为里抽一个来演。
也就是说,你不理它,它也在自己玩。
| 待机时它会…… | 权重 | 台词 |
|---|---|---|
| 站着发呆 | 26 | — |
| 左右张望 | 16 | ? |
| 低头啄米 | 14 | 咕咕… |
| 抖抖羽毛 | 11 | 抖抖毛~ |
| 来回踱步 | 10 | 溜达溜达 |
| 扑棱翅膀 | 8 | 扑棱扑棱 |
| 打盹 | 7 | Zzz… |
| 指尖转球 🏀 | 5 | 看我转球! |
| 原地运球 🏀 | 4 | 运球中… |
| 挥手打招呼 | 3 | 嘿~ |
「活跃度」可以在配置里调:0 就是一只安静的鸡,1 就是一刻不停的鸡。
全部 20 个动作
素材是程序化生成的原创像素画,不是任何现有形象的二创。20 行动画、每行最多 8 帧,全部由代码画出(scripts/chicken.mjs)。
| 分类 | 动作 |
|---|---|
| 待机 | idle 呼吸眨眼 · look 张望 · peck 啄米 · ruffle 抖毛 · pace 踱步 · sleep 打盹 · flap 扑棱 |
| 篮球 | dribble 运球 · spin-ball 指尖转球 · shoot 投篮 · celebrate 庆祝 |
| 工作 | work 搬砖 · think 思考 · wait 等待 · sad 低落 |
| 互动 | wave 挥手 · startle 惊吓 · jump 跳跃 · walk-right / walk-left 走路 |
它怎么跟着 Agent 的状态走
| Agent 发生了什么 | 鸡的反应 | 气泡 |
|---|---|---|
| 有工具在执行 | 搬砖 | 搬砖中… |
| 工具跑完了 | 思考 | 想想… |
| 等待审批 / 提问 | 翘首以盼 | 等你哦~ |
| AI 说完一句回答 | 挥手 + 咕咕叫 | 咕咕! |
| 一个回合干净结束 | 投篮庆祝 🏀 | 好球! |
| 请求出错 | 蔫了 | 呜…出错了 |
| 你戳它一下 | 吓一跳 + 叫 | 干嘛~ |
| 你拖着它走 | 跟着跑 | — |
注意「AI 说完一句回答」这一行。
多数桌宠只在整个任务结束时才有反应。这只鸡监听的是 agent/assistant-stream 的提交帧——也就是模型每答完一段就回应一次。多步任务里它会陪你一路咕咕叫。
(防抖 6 秒,所以一个连续的多步回合不会变成噪音。)
安装
# 从 GitHub 安装
dsh plugin --profile web add "github:lizhuangCoding/dsh-chicken-pet#main"
# 或从本地目录安装(开发时用)
dsh plugin --profile web add /path/to/dsh-chicken-pet
装完重启 dsh web(bundle 层在启动时组合),右下角就会出现这只鸡。
配置(在 dsh 设置页里改)
不用编辑任何文件。 打开 dsh 的 设置 → 插件配置,会看到一张「🐔 小鸡桌宠」卡片:
| 选项 | 说明 |
|---|---|
| 显示桌宠 | 关掉后小鸡从界面消失,设置保留 |
| 活跃度 | 0 = 几乎不动,1 = 一刻不停 |
| 最短/最长间隔 | 两次自主行为之间的秒数 |
| 大小 | 渲染宽度(像素) |
| 停靠角落 | 四个角任选 |
| 叫声 | AI 每答完一段是否叫一声 |
| 音量 | 0 ~ 1 |
保存后立刻生效,不用重启。改过的字段旁边会出现「重置」按钮,点一下恢复默认。
活跃度参考值
实测(浏览器里跑 2 分钟统计发呆占比):
| 活跃度 | 发呆占比 | 感觉 |
|---|---|---|
| 0.1 | 69% | 大部分时间站着 |
| 0.5 | 60% | 偶尔动动 |
| 0.75 | 33% | 默认,比较活泼 |
| 0.95 | 23% | 基本不停 |
高级:直接写配置文件
设置页只是 cordis.patch.yml 的图形界面。想批量配置或做版本管理,可以直接写 $DSH_HOME/profiles/web/cordis.patch.yml:
- id: chicken-pet
config:
liveliness: 0.3
idleMinSec: 10
idleMaxSec: 30
⚠️ dsh 的 patch 是整块替换 config,不是字段合并。这里没写的字段会回落到插件默认值(所以只写两项是安全的),但别指望它和设置页的改动叠加。
关于声音
AI 每答完一段时,桌宠会播放 assets/voice.mp3。
没有这个文件时,它会自动回落到浏览器合成的双音啁啾(OscillatorNode)——所以删掉音频文件插件依然可用,只是没有语音。
换成你自己的音频:替换 assets/voice.mp3 即可,任意 mp3 都行,重启 dsh 生效。
首次交互前浏览器会拦截自动播放——这是浏览器策略,点一下页面后就会正常响。
素材版权
精灵图:全部原创,零版权风险。
assets/spritesheet.png 由 scripts/build-sprites.mjs 逐像素程序化生成,不是截图、不是二创、不是任何现有形象的衍生。鸡的造型(奶白身体、红冠、橙喙、肉垂、橙色篮球)是原创设计。
想换成别的形象?改 scripts/chicken.mjs 里的调色板和几何参数,重跑 npm run sprites。
音频:assets/voice.mp3 不是本项目的原创作品。
它是一段网络流传的二创梗语音片段,含公众人物声音,版权归原作者所有,仅供个人学习交流使用,请勿用于商业用途。若您是权利人且不希望它被展示,请联系删除。
商用请自行替换为你拥有权利的音频,或直接删除该文件(插件会自动回落到合成音)。
项目结构
dsh-chicken-pet/
├── src/
│ ├── index.ts # bundle 包入口(无运行时代码,本体是 cordis.patch.yml)
│ ├── host/index.ts # Host 半:注册精灵图 HTTP 路由(带内容哈希缓存)
│ └── client/
│ ├── index.ts # Client 半入口:挂载桌宠 + 注册设置卡片
│ ├── pet.ts # 桌宠本体:DOM 渲染、拖动、点击、事件订阅、音效
│ ├── card.ts # 设置页卡片:8 个控件,读写设置命名空间
│ ├── config.ts # 配置类型、默认值、共享样式
│ ├── brain.ts # 自主行为引擎(纯状态机,零 DOM 依赖,可单独测试)
│ └── sheet.ts # 精灵图几何与帧时长表
├── scripts/
│ ├── png.mjs # 零依赖 PNG 编码器 + 软件光栅器
│ ├── chicken.mjs # 像素鸡的解剖结构(参数化绘制)
│ ├── animations.mjs # 20 行动画的姿势函数
│ ├── build-sprites.mjs # 生成 assets/spritesheet.png
│ ├── build-plugin.mjs # 用 tsc 编译到 lib/
│ ├── bundle-client.mjs # 把浏览器半打包成 dsh 要求的 __ModuleLoader__ 格式
│ └── preview.mjs # 渲染预览图到 docs/
├── assets/ # spritesheet.png(生成物,已入库)
├── demo/index.html # 独立演示页,不需要 DSH
└── cordis.patch.yml # bundle 补丁:插入 chicken-pet 行
开发
npm install
npm run sprites # 重新生成精灵图
npm run build # 编译 Host 半 + 打包浏览器半
npm test # 构建 + 冒烟测试(9 项)
npm run typecheck # 用真实 DSH 源码做类型检查
npm run preview # 重新渲染文档预览图
npx serve . # 然后打开 /demo/index.html
演示页不依赖 DSH,可以直接调活跃度、模拟各种 Agent 事件、看全部 20 个动作。
npm test 检查的都是只有发布后才会暴露的问题,其中三项来自真实事故:
- 合并包安全:dsh 把同一批浏览器插件拼成一个文件下发。如果我的包里有语法错误,后面所有插件都注册不上,整个界面会崩——不只是桌宠不显示。
- 产物格式:浏览器半必须是
window.__ModuleLoader__.load({id, factory})的闭包工厂,不能是 ES module。 - 依赖白名单:浏览器只能
require平台表里的模块(react、cordis 等)。用到schemastery这类包会在加载时抛错。
技术说明
为什么要 Host 半? 浏览器插件读不到包目录里的文件,精灵图必须由 Host 注册一条 HTTP 路由。路由 URL 带内容哈希 + immutable 缓存头,升级插件后刷新即生效,不会吃到旧图。
为什么用 DOM 而不是 React? 桌宠是一块浮在界面上的独立元素,不需要参与 dsh 的 Slot 布局系统。用裸 DOM 让它不依赖任何 React 版本、也不占用布局槽位——只有精灵本身接收指针事件,不会挡住后面的聊天。
为什么事件和轮询都用? 事件是准确来源,立刻送达。但社区实践中出现过「事件在某个部署的总线上送不到插件」的情况,所以还有一路 700ms 轮询 ctx.agents 兜底,避免鸡永远卡在搬砖姿势。
自主行为引擎是纯的。 ChickenBrain 不碰 DOM、不碰计时器实现(时钟可注入),所以能脱离浏览器测试。liveliness 是作用在权重上的过滤器而不是独立掷硬币——后者会让高活跃度照样经常发呆,实测下来动作频率和设置对不上。
License
代码 MIT。素材(assets/spritesheet.png)同样是本项目生成的原创作品,随 MIT 一并授权。
No comments yet. Be the first to write one.