DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

bestlike093 /

bestlike093/dsh-cyrene-balance

Verified

昔涟桌面桌宠(DSH 版):透明置顶、气泡台词、十张内置背景、状态面板与 DeepSeek 余额,接管对话提问 / 风险审批 / 任务进程,支持 QQ 官方机器人远程拍板;形象可换单图 / GIF / 视频 / 精灵图,也能切成只留审批卡片的卡片模式。

★ 4 Stars0 Forks2 IssuesN/A Community rating0 Confirmed installs
View on GitHubProject homepage
READMESource: main@18124f7a

dsh-cyrene-pet

昔涟桌面桌宠的 DeepSeek Harness(DSH)版:透明置顶窗口、拖拽贴边、点击穿透、气泡台词、状态面板、右键菜单,并接管对话提问、风险审批与任务进程。2.0 起加入九张内置背景、陪伴数据同步与设置合并,以及 QQ 官方机器人远程拍板;形象可换成单图 / GIF / 视频 / 多帧 sprite,也可以切成不加载立绘的卡片模式。但是必须注意,为了对轴,这版并不稳定

仓库名 dsh-cyrene-balance 是它最早做余额插件时留下的,包名与插件目录已经改成 dsh-cyrene-pet。安装时认包名和目录,不认仓库名。

  • 作者:bestlike093
  • 适用平台:Windows
  • 当前版本:2.0.0

2.0 带来了什么

变化 说明
桌面背景 内置 9 张背景,支持自定义图片、遮罩浓度、定时轮换
陪伴数据同步 好感、身体状态、念头、开口账本、消费账本、小游戏战绩可按文件跨端合并
设置合并 网页设置与桌宠窗口同时改设置时按字段合并,不会互相覆盖
QQ 远程拍板 审批和提问可以转到 QQ 官方机器人,在外面也能处理
发行形态 公开包不带 Live2D 模型与运行时,默认用图片形象;Live2D 需要自备

文档怎么看

你想做的事 看哪一节
先装起来 五分钟上手、安装
换形象、换背景、调配色 换形象、桌面背景、设置浮层
少被打扰、只看余额 常见场景怎么设、气泡模式
在手机上处理审批 QQ 远程拍板
数据存在哪、怎么备份 数据文件、备份与恢复
想了解她怎么说话、怎么记事 架构总览、内部实现与审计结论
想了解已知问题与修复计划 内部实现与审计结论
出问题了 常见问题、Agent(dsh)升级后可能产生的后果

五分钟上手

  1. 下载 cyrene-pet-dsh-2.0.0.zip 并解压到任意目录,例如 D:\plugins\dsh-cyrene-pet。

  2. 在终端执行:

    dsh plugin --profile desktop add D:\plugins\dsh-cyrene-pet
    
  3. 重启 dsh。

  4. 桌面上出现透明立绘,单击会说话,说明运行时部署成功。

  5. 右键立绘 →「换形象」→「数据」→「余额与 API Key」,填入 DeepSeek API Key;不填也可以,插件会依次读环境变量 DEEPSEEK_API_KEY 和 ~/.dsh/.credentials.yaml。

  6. 在「数据 → 余额与 API Key」里点「刷新余额」,状态面板出现数字,两边握手完成。

装完可以用这几件事自查:

检查 通过的样子
运行时 立绘出现,单击有台词和动作
宿主通信 状态面板有 CPU / 内存 / 余额数字,刷新余额会变化
三块接管 Agent 提问弹在桌宠、越权审批弹在桌宠、长按立绘有任务播报
卡片模式 不加载立绘,桌面只剩审批与提问卡片,其余区域点击穿透

它现在能做什么

能力 状态
透明无边框置顶窗口 ✅
Live2D 模型渲染(moc3 + 物理 + 纹理) ⚠️ 需自备模型与运行时,公开包不含
12 个表情 / 5 组动作 / 自动眨眼与呼吸 ⚠️ 仅 Live2D 形象可用
视线跟随鼠标 ✅(Live2D 形象可用)
点击命中区域触发表情与动作 ✅
鼠标拖拽移动、拖到屏幕边缘吸附贴边 ✅
窗口位置与缩放记忆 ✅
非立绘区域点击穿透,不挡桌面操作 ✅
气泡台词轮换、说话时口型动画 ✅
自定义形象:单图 / GIF / 视频 / 多帧 sprite / Live2D 五类 ✅(Live2D 需自备)
内置背景:9 张(7 张官方插画 + 夜色 / 樱两张),可固定、轮换或换成自己的图片 ✅
陪伴数据同步:好感、身体状态、念头、开口 / 消费账本、小游戏战绩按文件合并 ✅
设置合并:网页设置与桌宠窗口同时改,按字段合并,不互相覆盖 ✅
QQ 官方机器人远程拍板:审批与提问可以在 QQ 里处理 ✅
好感与主动开口:会记住相处方式,也会在合适的时候先说话 ✅
记忆注入:新会话会带上固定、常提、最近的几条记忆;日常发言里的自述与偏好也会自动记下 ✅
陪伴状态概览:关系档 / 今日开口 / 记忆条数 ✅
能力中心:石头剪刀布 + 本地战绩 ✅
最近会话:标题列表 + 点开看最近十条(只读) ✅
念出声:系统中文语音,只念主动开口 ✅
状态面板(CPU / 内存 / GPU / 网速 / 电量 / 余额) ✅
状态面板三档详细度 + 折叠 ✅
dsh 设置页「昔涟 · 桌宠」卡片:启动 / 重启 / 关闭、人格编辑、记忆管理、能力中心 ✅
右键菜单(换形象 / 一键归位) ✅
设置浮层(昵称 / 缩放 / 气泡 / 状态栏 / 提问 / 互动 / 余额) ✅
DeepSeek 余额与今日消费 ✅
对话提问由桌宠逐题接管(ask_user_question,四种模式) ✅
风险审批(approval/request):桌宠里「允许一次 / 拒绝」 ✅
任务进程:读 todos 投影,长按播报当前进度 ✅
系统托盘 ✅(无托盘图标资源时自动跳过)

架构总览

桌宠分成两层:lib/ 跑在 dsh 进程里,管设置、余额、会话桥、提问审批、QQ 通道;pet/ 是独立的 Electron 窗口,只管画立绘、接鼠标、气泡和设置面板。一次对话走五段:输入归一化 → 状态写入与存储 → 召回与拼装 → 模型 → 输出与回写。

下面三张图出自 2026-11-10 的全链路审计,按真实调用点绘制,不以注释和命名判断。实线是通的,虚线是空转或断点。

主链路

flowchart LR
  subgraph IN[输入]
    A1[桌面 IPC / 桌面 /send]
    A2[QQ 桥 私聊 + 群]
    A3[DSH 会话]
    A4[识屏 / 天气 / IP / 余额]
    A5[图片]
  end

  subgraph NORM[归一化]
    B[text / spoken / scope / source / speaker]
  end

  subgraph STATE[状态写入]
    C1[记忆抽取<br/>六类句式]
    C2[结构化事实<br/>inner-state 断言]
    C3[关系事件<br/>bond / closeness / irritation]
    C4[精力结算<br/>body]
    C5[日程 ensure<br/>agenda]
    C6[情绪识别<br/>local-emotion]
    C7[群画像 / 梗库]
  end

  subgraph STORE[存储]
    D1[(memory.json<br/>明文)]
    D2[(facts.json 加密)]
    D3[(bond.json 加密)]
    D4[(body.json 加密)]
    D5[(agenda-runtime.json)]
    D6[afterglow / needs]
    D7[lastEmotionText]
  end

  subgraph RECALL[召回]
    E1[memoryText<br/>默认关闭]
    E2[factNote]
    E3[affinityNote]
    E4[bodyNote]
    E5[companionNote<br/>心情/日程/话头/表情]
    E6[reviewNote<br/>仅 QQ]
    E7[intimacyNote<br/>仅桌面]
    E8[socialNote<br/>随句变化]
  end

  subgraph PROMPT[开口拼装]
    F[buildPromptSections<br/>stable + turn]
    F1[stable:persona 无上限 + source 200 + social 300]
    F2[turn:memory 600 / fact 400 / companion 500<br/>affinity 200 / review 200 / body 200<br/>intimacy 420 / proactive 200 / sticker 300]
  end

  subgraph MODEL[模型]
    G[DeepSeek 请求<br/>7 路并发取数,memoryText 无超时]
  end

  subgraph OUT[输出]
    H1[parseEmojiTag<br/>图:id]
    H2[parseStickerTag<br/>表情:标签]
    H3[guardReply<br/>清控制标签 / 并复读]
    H4[群聊引用归属纠正]
    H5[filterIntimacy 红线]
    H6[气泡 / 立绘 / TTS]
    H7[QQ splitReply<br/>≥90 字拆 2 条]
  end

  subgraph BACK[回流]
    I1[historyTurns + persistTurn]
    I2[onExchange 记忆写入]
    I3[companion.endTurn<br/>话头 / 表情降权]
  end

  A1 --> B
  A2 --> B
  A3 --> B
  A4 --> B
  A5 -.不进模型.-> X1[空转:入表情库]
  B --> C1 --> D1 --> E1
  B --> C2 --> D2 --> E2
  B --> C3 --> D3 --> E3
  B --> C4 --> D4 --> E4
  B --> C5 --> D5 --> E5
  B --> C6 --> D6 --> E5
  C6 --> D7 -.无读取.-> X2[空转]
  B --> C7 --> E8
  E1 --> F
  E2 --> F
  E3 --> F
  E4 --> F
  E5 --> F
  E6 --> F
  E7 --> F
  E8 --> F1
  F --> F1
  F --> F2
  F1 --> G
  F2 --> G
  G --> H1
  G --> H2
  H1 --> H3
  H2 --> H3
  H3 --> H4 --> H5
  H5 --> H6
  H5 --> H7
  H5 --> I1
  H5 --> I2
  H5 --> I3
  I3 -.下一轮.-> E5

memoryText 在早期草稿里被记成「恒空」,第四轮补审后修正为「默认关闭」:开关打开后链路是通的,只是回写不等待,也没有超时。图里其余断点(图片不进模型、lastEmotionText 无读取方)均在代码里可复核。

单轮数据流

同一轮对话拆得更细,标出了每一处断点在代码里的位置。

flowchart TB
  subgraph IN[输入]
    I1[桌面 IPC / send]
    I2[QQ webhook / bridge]
    I3[主动开口]
    I4[图片]
  end

  subgraph GATE[入口与闸门]
    G1[scopeOf<br/>desktop / qq:private / qq:group]
    G2[enabled / provider / busy / rate / budget / key]
    G3[matchWake → spoken]
  end

  subgraph READ[并行取数]
    R1[historyTurns = bucketFor scope]
    R2[getMemoryDigest<br/>BM25 + 可选向量]
    R3[companion.beginTurn]
    R4[fact / affinity / body / intimacy / social / sticker]
    R5[getCompanionExtra<br/>日程 / 承接 / 穿搭 / 环境]
  end

  subgraph BUILD[拼装]
    B1[buildPromptSections<br/>stable + turn]
    B2[system + trimTurns history + user]
  end

  subgraph MODEL[模型]
    M1[DeepSeek chat completions]
    M2[工具轮循环<br/>共享 AbortController]
  end

  subgraph CLEAN[清洗]
    C1[parseEmojiTag]
    C2[parseStickerTag]
    C3[guardReply]
    C4[cleanVoice]
    C5[fixMisattributedQuote]
    C6[filterIntimacy]
  end

  subgraph SINK[输出与回写]
    S1[气泡 / 立绘]
    S2[TTS planSpeak]
    S3[QQ splitReply]
    S4[historyTurns.push]
    S5[companion.endTurn]
    S6[onExchange async 未 await]
    S7[persistTurn 同步调用]
    S8[QQ 主动开口不拆]
    S9[stickerNote 混排]
  end

  subgraph AUX[支线数据流]
    A1[社交画像 / 梗词典<br/>getSocialNote 每条群消息同步跑]
    A2[B 站 API / 写动作 / 动态]
    A3[设置同步 sync + syncCrypto]
    A4[日程 daily-plan / agenda-runtime / moment-clock]
  end

  I1 --> G1
  I2 --> G1
  I3 --> G1
  I4 -.不进模型.-> X1[stickerInbox]
  G1 --> G2
  G2 --> G3
  G3 --> R1
  G3 --> R2
  G3 --> R3
  G3 --> R4
  G3 --> R5
  R1 --> B2
  R2 --> B1
  R3 --> B1
  R4 --> B1
  R5 --> B1
  B1 --> B2
  B2 --> M1
  M1 --> M2
  M2 --> C1
  C1 --> C2
  C2 --> C3
  C3 --> C4
  C4 --> C5
  C5 --> C6
  C6 --> S1
  C6 --> S2
  C6 --> S3
  C6 --> S4
  C6 --> S5
  C6 --> S6
  C6 --> S7
  S4 -.下一轮.-> R1
  S5 -.下一轮.-> R3
  S6 -.下一轮.-> R2
  S7 -.重启.-> R1
  G2 -.检查与置位之间有 6 个 await.-> X2[并发窗口]
  R2 -.无超时.-> X3[整轮悬挂]
  S6 -.async 未 await.-> X4[记忆写丢 / 异常逃逸]
  R1 -.桶永不释放.-> X5[内存累积]
  S7 -.hydrate 丢 scope.-> X6[assistant 归桌面]
  R2 -.memoryEnabled 默认 false.-> X7[默认无长期记忆]
  G1 -.openId 为空.-> X8[同类型会话共桶]
  C6 -.主动开口.-> S8
  S3 -.汇报拼在 reply 后.-> S9
  S3 -.首条成功补发失败.-> X9[部分发送记成功]
  R4 -.每条群消息.-> A1
  A1 -.O(k²) 同步计算.-> X10[群消息阻塞主进程]
  A1 -.重复 observe 同批样本.-> X11[词典 seen 虚高]
  A2 -.policy 缺省.-> X12[写操作崩溃]
  A3 -.apply 后才 ack.-> X13[崩溃窗口重复合并]
  A4 -.质量闸只查总时长.-> X14[偏移的一天能过]

主链本身是通的,真正的断点在「等待与互斥」:busy 的检查与置位之间夹着 6 个 await;记忆摘要没有超时;onExchange 是 async 却没有 await。记忆链的默认状态是断的,因为 companion.memory.enabled 默认 false。

人格层链路

人格提示词确实在驱动参数,但这条管道是单向的:参数从不回流到提示词。七段决定「她是谁」,7 个参数只决定「她多久开口、多久消气、好感涨多快」。

flowchart LR
  subgraph IN[人格输入]
    P1[七段:身份 / 身世 / 世界观<br/>人生观 / 价值观 / 相处 / 表达]
    P2[昵称]
    P3[记忆 8 条 × 200 字]
    P4[额外说明]
    P5[此刻:心情 / 关系阶段<br/>烦躁 / 精力]
  end

  P1 --> B[buildPersonaPrompt]
  P2 --> B
  P3 --> B
  P4 --> B
  P5 --> B
  B --> TXT[完整提示词文本]
  TXT --> LLM[模型]
  TXT --> D[deriveTraits<br/>5 类关键词]
  D --> T8[7 个速度参数<br/>+ recallBias]
  Q[六维问卷 24 题] --> QD[traitsFromDimensions]
  QD --> T8
  T8 --> R[runtime traitsNow]
  R --> SCH[开口间隔 / 精力消耗<br/>好感涨速 / 消气 / 亲近门槛]
  R --> NOW[烦躁档判定]
  Q -.只显示草稿.-> UI[设置页 personaDraft]
  P3 -.关键词污染.-> D
  P4 -.关键词污染.-> D
  P5 -.关键词污染.-> D

问卷六维被压成同一组参数,personaDraft 只显示、不回填。代码里的「8 个维度」是 7 个速度参数加 1 个念旧倾向,全部是节奏维度,没有表达形态维度。

反思 / 召回 / 筛选 / 选择 / 时间那张专题图更细,留在审计台账里。

开发与测试

lib/vault/ 是密钥仓库。它把 API Key 加密后存在本机,配置文件里只留解密不了的密文。仓库自带一份只依赖 node 原生模块的测试:

npm test
# 只跑单个文件
node --test test/vault.test.mjs

npm test 会依次跑六个文件:vault、persona、session-bridge、companion-sync、companion-runtime、ability。

测试覆盖 vault 加解密(写入取回、密文不含明文、空 key 拒绝、错误口令、密文篡改检测)、人格注入、会话桥、陪伴层同步、宿主节奏与能力中心。

公开安装包为控制体积不带 test/,要跑测试请从源码仓库检出完整目录。测试只依赖 Node 原生模块,Node 18 以上直接 npm test,不需要 npm install。

下载

来源 地址
GitHub Release cyrene-pet-dsh-2.0.0.zip
源码包 v2.0.0.zip
夸克网盘 旧版安装包
  • 安装包:cyrene-pet-dsh-2.0.0.zip(约 80 MB,含全套立绘表情素材)
  • 打开方式:复制链接后在浏览器访问,或打开夸克 APP 自动识别。
  • Release 附件即完整安装包,解压到任意目录后 dsh plugin --profile desktop add <目录> 即可安装。
  • Release 页同时提供 SHA-256,下载后可以核对完整性。

安装

方式一:从压缩包

解压后把整个 dsh-cyrene-pet/ 目录放到 dsh 的插件目录,再注册:

dsh plugin --profile desktop add <解压后的 dsh-cyrene-pet 目录>

方式二:从源码目录

dsh plugin --profile desktop add <本目录>

装好后需要重启 dsh,插件会在启动时自动部署桌宠运行时并拉起桌宠进程。

首次启动会做什么

桌宠复用 dsh 自带的 Electron 运行时,不额外下载一套。首次启动时自动执行:

  1. 在 ~/.dsh/storages/cyrene-pet/runtime/ 下,用硬链接复制 dsh 安装目录里的 Electron 文件(必须与 dsh 同盘;跨盘时硬链接会被系统拒绝,改用复制)
  2. 删除 resources/app.asar,把 resources/app 目录链接到本插件的 pet/ 目录
  3. 用这个运行时启动 DeepSeek Harness.exe --no-sandbox

resources/app 是目录链接,所以改 pet/ 下的代码后重启桌宠进程即可生效,不需要重新部署运行时。

宿主若以 Node 模式运行(ELECTRON_RUN_AS_NODE=1,用 Electron 二进制跑 Node),桌宠会被当成 Node 直接退出。宿主半在 spawn 时会把这个标记从子进程环境里摘掉;手动排查时也记得先 Remove-Item Env:ELECTRON_RUN_AS_NODE。

卸载与重装

  1. 右键桌宠 →「换形象」→「数据」→「桌宠进程」→ 关掉桌宠。
  2. 在 dsh 里移除插件。
  3. 需要彻底清理时,再删除 ~/.dsh/storages/cyrene-pet/(设置、账本、运行时都在里面)。

只删插件目录不会自动清掉 ~/.dsh/storages/cyrene-pet/,下次装回来设置还在。

安全边界

  • 渲染层保持 contextIsolation: true、nodeIntegration: false,preload 只暴露窗口控制、背景图与命令 IPC,没有 fs 直通。
  • 页面 CSP 只允许 'self' pet-media: data:,不加载远程脚本。
  • 形象素材与 Live2D 模型走 pet-media://local 受限协议,只映射 plugin/ 与 models/ 两个根,越界路径直接 404;渲染层 sandbox: true、webSecurity: true。
  • 宿主 Electron 本身若以 --no-sandbox 启动,那是宿主启动参数,插件不再额外放开渲染层沙箱。
  • API Key 存在 Vault 密文里,不写进 state.json,也不会出现在日志、备份说明或前端状态快照中。

日常怎么用

立绘与窗口

  • 拖动立绘移动窗口,松手后自动贴边。
  • 单击立绘:随机台词 + 动作。
  • 长按立绘:说一遍当前任务进度。
  • 立绘以外的透明区域点击会穿透,不挡桌面操作。
  • 窗口位置和缩放会记住,下次启动还原。

换形象(单图 / GIF / 视频 / 多帧 / Live2D)

设置 →「她的样子」→「形象素材」。五种素材各有用处:

类型 适合什么 说明
单图 一张立绘 最省资源,静态显示
GIF 循环小动画 按原速循环播放
视频 更长的动作或氛围 跟随窗口尺寸铺满
多帧 sprite 逐帧动画 按帧序列播放,适合手绘小动效
Live2D 手里已有模型的人 需要自备模型与运行时,公开包不含
  • 素材通过 pet-media://local 受限协议读取,只认 plugin/ 与 models/ 两个根,越界路径直接 404。
  • 换形象会重新加载渲染层;切换前先把当前设置落盘,避免刚调的缩放或气泡样式被冲掉。
  • 没有合适的图时,公开包里的 assets/default.png 就是默认形象,不影响其他功能。

桌面背景

设置 →「她的样子」→「桌面背景」。背景是窗内壁纸,不会改系统桌面。

  • 内置 9 张:builtin-cyrene-01 ~ 07 是官方插画,另外两张是 builtin-night(夜色)与 builtin-sakura(樱)。
  • 自定义:上传的图片会复制进数据目录 backgrounds/,换版本、重装插件都不会丢。
  • 淡化:遮罩浓度 0 ~ 0.85。数值越高,背景越淡,人物越突出。
  • 轮换:填分钟数后按间隔自动换下一张;填 0 表示不轮换。
  • 「下一张」可以立即切到下一张,不用等轮换时间。
  • 删除只删数据目录里的副本,内置图不受影响。

卡片模式(没有立绘也能用)

如果你已经有自己的桌宠形象,只想让 dsh 的审批和提问有个不占地方的落点,可以把界面模式切成「只显示审批卡片」:

  • 右键 →「换形象」→「界面模式」→「只显示审批卡片」,保存后桌宠会自动重开。
  • 窗口缩成 380 × 240 的透明小窗,不加载 Live2D,也不显示状态栏、气泡和右键菜单。
  • 有审批或提问时,卡片出现在窗口里,点「允许一次 / 拒绝」即可;其余时间整窗点击穿透,不挡桌面操作。
  • 卡片收起后窗口留在原地,不抢焦点,也不占任务栏。
  • 想切回完整立绘:托盘图标 →「打开设置」→「界面模式」→「完整立绘」。卡片模式没有右键菜单,托盘是固定入口。

卡片模式仍然保留完整能力:对话提问接管、风险审批、托盘菜单和设置里的所有选项都能用,只是不再渲染立绘与状态面板。打开设置时窗口会临时放大到 480 × 560,关掉设置再缩回卡片大小。

右键菜单

右键立绘或状态面板,只有两个入口:

  • 换形象:直接打开设置里的「她的样子」,换立绘、调背景都在这一页
  • 一键归位:把桌宠拉回主屏右下角

其余互动收在设置页与长按里:长按立绘播报任务进度,单击说一句随机台词。

设置浮层

右键 →「换形象」,左侧五个分组。第一次打开会先显示三步引导(挑形象 / 填 Key / 调声音),点「知道啦」后不再出现:

组 设置项
概览 当前关系与状态、常用动作、三步上手
她的样子 界面模式(完整立绘 / 只显示审批卡片)、昵称、缩放、气泡字号 / 形状 / 不透明度、形象素材、状态栏、桌面背景(上传 / 淡化 / 删除 / 自动轮换 / 下一张)
说话与互动 自动换姿势、音效、念出声、闲聊提问、对话与审批模式
人格 启用开关、七段(身份 / 来历 / 世界观 / 生活观 / 价值 / 说话方式 / 风格)、额外设定
数据 余额与 API Key、桌宠进程、备份与恢复

几条合并规则:

  • 「开启提问 + 提问间隔」合并为一个下拉,选「关闭」即原来的关闭。
  • 「自动换姿势 + 间隔」合并为一个下拉,选「关闭」即原来的关闭。
  • 「音效开关 + 音量」合并为一个下拉,选「关闭」即静音。
  • 念出声默认关闭;打开后只用系统中文语音念主动开口的气泡,余额、审批和任务提示不念。离线可用,之后接本地 TTS 时只换引擎。
  • 气泡字号三档,气泡形状去掉了 2px 这一档,气泡模式去掉了「只显示余额数字」。
  • 余额刷新固定 30 秒缓存,设置里不再单列。
  • 旧的 avatar、x、y 三个从未生效的字段已移除。

旧版 state.json 会在加载时自动迁移:askEnabled: false → askEveryMinutes: 0,idlePose: false → poseSeconds: 0,soundEnabled: false → soundVolume: 0。

API Key 的解析顺序:设置面板填写的 Key → 环境变量 DEEPSEEK_API_KEY → ~/.dsh/.credentials.yaml 里的 DEEPSEEK_API_KEY。已经用 dsh 登录过 DeepSeek 的机器不需要再填一次。

陪伴模块

她有一份自己的状态,不靠一个好感数字撑起来。数据落在 ~/.dsh/cyrene-pet/ 下的几个 JSON 里,分三层。

层 文件 管什么
好感 bond.json 三个维度、事件记录、每日上限、关系档
状态 body.json、thoughts.json、inner-state 身体状态、念头、情绪余韵
节奏 opening.json 今天主动开口几次、被接住几次、要不要安静几天

好感分三个维度

维度 范围 起始 会怎么变
亲近 affinity -100 ~ 100 0 你找她说话、贴近一会儿会涨;被冷落会掉,也能被哄回来
信任 trust 0 ~ 100 50 安慰、道歉被接住、疲惫被体贴时涨,掉得很慢
熟悉 familiarity 0 ~ 100 0 共同经历堆出来的,只增不减

关系档按熟悉度分四段:还陌生(0)、认识(15)、熟悉(40)、亲近(70)。

事件与每日上限

每次互动按事件表记一笔,不是想加就加:

事件 维度 单次 每日净上限
你主动找她说话 亲近 +1 +20
一起在 DSH 里忙了一阵 熟悉 +1 +3
贴近了一小会儿 亲近 +2 +6
她难过时你安慰了她 信任 +2 +6
她认错,你接住了 信任 +2 +4
她有点生气,你哄好了 亲近 +2 +4

上限管的是「每天净变化」:正向封顶,负向封底。规则放在可覆盖的 JSON 里,想调数值不必改代码。

会安静,也会自己回来

连续几次主动开口都没被接住,概览里会标「先安静几天」,她不会一直问。安静时段与作息由 quiet-hours、schedule 控制,避免半夜弹气泡。

记忆模块

dsh 设置页的「昔涟 · 桌宠」卡片里展开「她记住的事」,可以看四槽记忆(身份 / 偏好 / 事件 / 关系)、按槽新增、固定 / 取消固定,以及二次确认后忘掉一条。

固定条目不会随时间衰减,也不参与清理;普通条目按 30 天半衰期淡出。这里写入的 memory.json 同时供主动开口的记忆回访和会话里的记忆召回使用。

会话这边会把固定、常提、最近的记忆取前 8 条,拼成「你记得的事」放进人格提示词,所以新会话也能接住上次的话。记忆增删改后会马上重挂;内容没变化时不动系统提示,避免每轮都刷新 prompt。

除了手动添加,桌宠也会从最近的用户发言里自动挑出「我叫…… / 我喜欢…… / 我最近在……」这类明确自述,写进 memory.json。代码、问句和太长的句子会被跳过,同一句话只累计提及次数,不会重复入库。

记忆的进出规则

项目 行为
存储 本机 memory.json,不进 DSH 会话历史
衰减 普通条目按 30 天半衰期淡出
固定 不衰减、不参与清理,只有手动取消或删除
注入 只取固定、常提、最近的 8 条,不把全部记忆塞进提示词

写入有三条路:

  • 设置页按槽新增、固定、取消固定,或二次确认后忘掉一条。
  • 日常发言里的明确自述自动入库,就是上面那段规则。
  • 对话里出现明确要记住的意图时,memory-intent.mjs 判断该不该写,memory-guard.mjs 在落盘前再过滤一次,避免把一时的情绪或敏感内容当成长期事实。

检索分两条:memory-search.mjs 负责「她记不记得这件事」,memory-facts.mjs 负责「这件事具体是什么」。两者都不直接改写原始记忆,只读。

功能中心(能力中心)

入口在 dsh 设置页「昔涟 · 桌宠」卡片。

概览只放三件能一眼看懂的事:

显示 含义
关系档 还陌生 / 认识 / 熟悉 / 亲近
今日开口 今天主动说了几次
记忆条数 四槽里现在有多少条

连续几次没被接住时,会多一个「先安静几天」的标记,方便确认她为什么突然不说话了。

陪她玩一局

石头剪刀布。胜 / 负 / 平、胜率、当前连胜都写在本机 ability.json:

  • 不进 DSH 会话,不占上下文。
  • 不参与好感计算,输赢不改变关系档。
  • 关掉桌宠后战绩还在;删掉 ability.json 就清零。

陪伴数据同步与设置合并

这是两套不同的机制,别混在一起。

陪伴数据同步(sync-bridge.mjs)

项目 说明
同步范围 bond.json(好感)、opening.json(开口账本)、body.json(身体状态)、thoughts.json(念头)、ledger.json(消费账本)、ability.json(小游戏战绩)
不进入同步 密钥仓库、记忆密文、Live2D 模型、语音缓存、日志
时间基准 每条记录以文件 mtime 作为 HLC 的 wall
冲突处理 按后写优先合并,冲突原样上报,不静默覆盖
文件完整性 只同步完整 JSON;写了一半的文件不参与,避免把坏文件推到别的端

同步桥本身不启动服务,目录、节点名和传输方式都由调用方注入。

设置合并(state-merge.mjs)

  • 网页设置和桌宠窗口都能改设置,两边只提交自己改动的字段。
  • 宿主按整份对象做浅合并,缺失字段保留原值,避免后写的一方抹掉先写的字段。
  • background、intimacy、persona、schedule 是多属性对象,会再按属性合并一层。
  • 带 rev 的客户端会做版本校验,版本过期直接拒绝;不带 rev 的旧客户端仍按兼容模式合并。

最近会话

设置卡片里还有一块「最近会话」:列出近期有标题的会话,点一条会在下面展开最近十条消息。这里只读,不会把内容发给第三方,也没有发送入口。当前会话由顶部任务卡单独展示,所以不会重复占位。

气泡模式

模式 内容
rotate 台词与余额交替
info 一直显示余额
talk 只显示台词
today 今日消费

状态面板与余额

状态面板默认显示 CPU、内存、GPU、网速、电量、余额。详细度三档,双击右上角 ··· 折叠。

余额来自 https://api.deepseek.com/user/balance,默认 30 秒缓存。今日消费由余额变化推断,充值不会冲掉已记录的消费。

对话提问接管

对话里 ask_user_question 的题目可以交给桌宠:宿主半把整批题目写进 live.json 的 ask 字段(带 source: "conversation"),桌宠用提问气泡逐题问,答完一次性回传。

「设置 → 提问 → 对话与审批」有四种模式(风险审批也按同一个模式走):

值 行为
pet-all(默认) 桌宠逐题问。一批多题时气泡里显示「第 2/3 题」,答完整批一起交回;某题点「跳过」就记成空选项
pet-single 桌宠只接单题批次,多题批次直接交给网页卡片
both 网页卡片照常弹、桌宠也问,谁先答用谁的
web 完全不接管,只走网页卡片

规则:

  • 每题都带选项、且没有 intent 的批次才会进桌宠;需要自由作答或 plan-review 审阅的整批仍交给网页卡片。
  • 多选题在气泡里点选后按「答好了♪」提交;单选项点一下直接进下一题。
  • 等待时长 = 题数 × 每题作答秒数(默认 30 秒,设置里可调);到时把请求 next() 交还网页卡片。
  • 桌宠没运行、被禁用,或已经有一批题在等回答时,新的请求直接走网页卡片。
  • 回答通过 pet-command.json 的 { action: "answer", askId, answers: [{ id, selected }] } 回到宿主半。
  • 提问到达时如果桌宠是收起状态,会自动显示出来(不抢焦点)。

风险审批

沙箱越权这类操作会走 dsh 的 approval/request waterfall,桌宠接在同一条链路的入口。

  • 气泡显示「想请你批准一下」,正文是「工具名 + 想越权执行」和本地化理由(displayReason 优先中文,退回英文,再退回审计原因)。
  • 只有两个决定:允许一次 / 拒绝,结果原样回给审批服务(allowed-once / rejected)。
  • 60 秒没决定、请求被撤回或桌宠没运行,就交还网页卡片;撤回按 cancelled 结算。
  • 审批和对话提问共用「设置 → 对话与审批」这一个模式开关。
  • 同一时间只挂起一个审批,第二个请求会走网页卡片。

QQ 通道:远程拍板与提问

出门在外也能回一句「允许」,不用守着电脑。走 QQ 开放平台的官方机器人,不依赖任何第三方协议端。

这条通道只做两件事:把需要你拍板的请求推到 QQ,把你的回复带回来。它不是聊天窗口,下面会写清边界。

设置 → 说话与互动 → QQ 远程拍板:

字段 说明
启用官方通道 打开后才会监听 webhook
AppID 开放平台机器人页面的 AppID
AppSecret 只写进本机密文仓库 qq.vault.json,state.json 与设置页都不回显
主人 openid 只有这几个 openid 能拍板,留空时谁都拍不了
发到哪 / 目标 openid 私聊(c2c)或群聊(group)以及对应 openid
Webhook 端口 默认 17321,路径默认 /qq/webhook

能做什么、做不到什么

能做 做不到
收到审批请求,回「允许 / 拒绝」或 1 / 2 自由聊天、主动闲聊
收到一批提问,逐题作答 发图片、表情包、文件
私聊(c2c)或群聊(group)二选一 在同一个群里分别跟不同人对话
最多 5 个主人 openid 非主人拍板
  • 服务只绑 127.0.0.1;要让 QQ 回调进来,自己用 cloudflared / frp 之类的隧道转发,开放平台里填隧道地址。
  • 签名校验不过返回 401,非 POST 返回 405,请求体上限 256KB。
  • 卡片只带「工具名 + 一句理由」,不复制 context、prompt、消息正文;回复会被亲密层过滤后再发出去。
  • 主人回复「允许 / 拒绝」(或 1 / 2)才算数;非主人只能问,不能拍板。
  • 超时或通道掉线,决定权原样交还桌宠与网页卡片,不会自行放行。

表情包

她有自己的表情包,也能把聊天里看到的图收进来。这一层在 packages/companion-core 里已经完整提供(sticker-library.mjs、sticker-inbox.mjs),dsh 插件当前还没有对应的界面入口,所以下面写的是能力本身和素材协议。

挑图与发送

表情清单汇总成一份,给聊天层挑图、预览页展示、QQ 发送共用。

  • id 是「来源:相对路径」,渲染层只传 id,绝对路径由主进程自己还原,不接受任意路径。
  • 扫描结果缓存 30 秒,一句话里问几次不会反复读盘。
  • chat=false 的目录只用来兜底解析历史图片,不参与挑图。
  • listed=false 的目录不出现在预览页,避免把别人的图混进她的表情包。

收图与入库

QQ 里收到的图不会直接进素材包:

阶段 位置 说明
收到 packs/.inbox 先落待审核队列;以点开头,不会被当成素材包
审核 预览页 点「入库」才移动到 packs/<packId>/emoji
自动收下 packs/qq-auto/emoji 满足条件的小图直接归到这个包,和手动入库分开

限制:

  • 同一张图按内容指纹去重,只收一次;重复出现只累计 seenCount。
  • 指纹表最多留 2000 张;待审核最多 200 张,超出从最旧的开始丢。
  • 自动收下的上限是 1.6 MB、最长边 1024 px;更大的更像照片或截图,留给人工判断。

任务进程

桌宠宿主半读 dsh 的 todos 会话投影(dsh-tool-todo 写的那份),把最近一次活动的根会话里的任务写进 live.json 的 todos 字段。

  • 任务面板列出任务清单(最多 6 条,✓ 已完成 / ▶ 进行中 / · 待办),显示「任务进程 x/y 完成」。
  • 长按立绘口头播报进度,例如「任务 2/5 完成,正在做『接入任务进程』,还排着 2 件…」。
  • 面板会挡住气泡,所以完整清单放在右键菜单「任务进程」里看。
  • 只跟根会话走:子代理的会话不会顶掉你正在做的任务。

常见场景怎么设

想要的效果 建议
专心工作,不想被桌宠打断 提问模式选 web,或把「闲聊提问」选「关闭」
边工作边顺手回答 Agent 保持默认 pet-all,桌宠会逐题问
怕点错授权 保持 pet-all,审批只在桌宠里点「允许一次」或「拒绝」;不放心就选 web 回网页卡片
桌宠太挡视线 拖到屏幕边缘自动贴边,或在设置里改缩放;透明区点击穿透
只想看余额 气泡模式选 info 或 today
觉得动作太频繁 「自动换姿势」调长或关闭
换电脑 插件目录可以直接带走;API Key 绑在本机,新机器上要重新填一次
已经有自己的桌宠形象 界面模式选「只显示审批卡片」,不加载立绘,只保留审批 / 提问卡片
切了卡片模式想换回来 托盘图标 →「打开设置」→「界面模式」→「完整立绘」
想让背景更自然 「她的样子 → 桌面背景」把遮罩浓度调低,直到人物边缘和背景不打架
背景想每天都不一样 桌面背景里填轮换分钟数(例如 1440 表示一天一换),填 0 关闭
在外面也想处理审批 「数据 → QQ 远程拍板」填 AppID / AppSecret,把隧道地址填进开放平台
换电脑保留好感与账本 「数据 → 备份与恢复」导出 JSON,新机器导入后再填一次 Key

常见问题

装完桌宠没出现

  1. 确认 dsh 已经重启过,插件是在启动时拉起桌宠进程的。
  2. 看 ~/.dsh/storages/cyrene-pet/ 有没有生成 runtime/。没有生成说明宿主半没跑起来,先看 dsh 日志里插件有没有加载失败。
  3. 有 runtime/ 但进程刚起就退,删掉 runtime/ 再启动 dsh 重新部署。
  4. 如果 dsh 是用 Electron 二进制跑 Node(ELECTRON_RUN_AS_NODE=1),先清掉这个环境变量再试。

立绘出现但白屏

多半是 resources/app 链接失效,或者 app.asar 被 dsh 升级重建了。关掉 dsh,删 ~/.dsh/storages/cyrene-pet/runtime/,再启动。

状态面板没有数字

状态面板的数据来自宿主半挂在 dsh webServer 上的路由。先重启 dsh 和桌宠;仍然没有,就看 dsh 是否改了本地服务端口、路由前缀或鉴权方式。

余额一直不更新

  • 余额默认 30 秒缓存,刚充值或刚跑完任务时会有延迟。
  • Key 的解析顺序是:设置里填的 → DEEPSEEK_API_KEY → ~/.dsh/.credentials.yaml。三处都没有就会显示为空。
  • 今日消费由余额变化推断,第一次启动当天从 0 开始累计,不是平台账单的实时数字。

提问没有弹在桌宠

  • 检查「设置 → 说话与互动 → 对话与审批」是不是 web。
  • 只有「每题都带选项、且没有 intent」的批次才会进桌宠;自由作答和 plan-review 会回网页卡片。
  • 已经有一批题在等回答时,第二批直接走网页卡片。
  • 每题作答时间默认 30 秒、可在设置里调,多题按题数累加;超时就交还网页卡片。

审批只有一个按钮能点

审批只提供一次性授权:允许一次 / 拒绝。没有「总是允许」,也没有规则记忆。同一时间只挂起一个审批。

换了背景没变化

  • 确认点的是「保存」,不是只选了图。
  • 遮罩浓度太高时背景会几乎看不见,把它调低。
  • 轮换填 0 时不会自动切;点「下一张」可以立即验证是否生效。

想彻底卸载

  1. 右键桌宠 →「换形象」→「数据」→ 关掉桌宠。
  2. 在 dsh 里移除插件。
  3. 手动删除 ~/.dsh/storages/cyrene-pet/(设置、账本、背景、运行时都在里面)。

只删插件目录不会清掉数据目录,下次装回来设置还在。

换电脑能不能直接带走

插件目录可以带走,但 secret.vault.json 绑本机解锁,API Key 要重新填一次。陪伴数据可以走备份导出再导入。

记忆保存在哪,怎么删

记忆在 ~/.dsh/storages/cyrene-pet/ 下(memory.vault.json 与兼容用的 memory.json)。界面上在 dsh 设置页「昔涟 · 桌宠」→「她记住的事」里删;固定条目不会被时间衰减,需要先取消固定。

QQ 收不到审批消息

  • 服务只绑 127.0.0.1,公网回调要靠 cloudflared / frp 之类的隧道,开放平台里填隧道地址。
  • 签名校验不过会返回 401;确认 AppSecret 填的是当前机器人那一份。
  • 只有「主人 openid」列表里的账号能拍板,留空时谁都拍不了。
  • 通道掉线或超时,决定权会交还桌宠与网页卡片,不会自行放行。

Agent(dsh)升级后可能产生的后果

桌宠依赖 dsh 的内部结构和它自带的 Electron 运行时。dsh 升级不一定坏,但下面这些情况需要知道。

1. 运行时副本失效

现象:重启 dsh 后桌宠不出现,或进程刚起就退出。

原因:~/.dsh/storages/cyrene-pet/runtime/ 里的 Electron 是从旧安装目录硬链接/复制来的。dsh 换安装路径、换 Electron 主版本、或重装后,旧副本指向的文件已经不存在或版本不匹配。

处理:关掉 dsh,删除 ~/.dsh/storages/cyrene-pet/runtime/,再启动 dsh,插件会重新部署。

2. app.asar 结构变化

现象:桌宠启动后白屏,或 resources/app 链接指向错误位置。

原因:插件会把 resources/app.asar 删掉,换成指向 pet/ 的目录链接。dsh 升级如果重建了 app.asar,或改变了 resources 布局,链接会被覆盖。

处理:删除 runtime/ 重新部署;仍不行就检查 resources/ 下是否又出现了 app.asar。

3. 插件 API 或注入点变化

现象:设置页「昔涟 · 桌宠」卡片消失;提问/审批不再弹在桌宠;控制台报 ctx.tools、ctx.webServer、sessionProjections 之类找不到。

原因:宿主半用的是 dsh 的插件接口(tools、webServer、approval/request、sessionProjections)。这些接口在 dsh 大版本升级时可能改名或改签名。

处理:等插件适配新版本,或回退 dsh。升级前可以先看 dsh 的更新说明里有没有插件 API 变更。

4. 任务进程读不到

现象:长按立绘说「现在手上还没有任务卡呢」,但对话里明明有任务。

原因:todos 投影的字段或存放位置变了,或者 dsh 换了写投影的插件。

处理:这属于只读展示,不影响 Agent 本身;等适配即可。

5. 审批链路顺序变化

现象:审批不再弹在桌宠,或者网页卡片和桌宠同时弹。

原因:approval/request waterfall 的挂载顺序变了,或被别的插件抢先处理。

处理:把提问模式改成 both 观察谁在接;或临时用 web 回网页卡片。

6. 端口或 webServer 变化

现象:状态面板没数字、刷新余额没反应,但立绘正常。

原因:宿主半的 HTTP 路由挂在 dsh 的 webServer 上。dsh 改了端口、路由前缀或鉴权,桌宠轮询就会失败。

处理:重启 dsh 和桌宠;仍不行就看 dsh 是否改了本地服务的监听方式。

7. 升级时正在进行的提问或审批

现象:升级/重启 dsh 时,桌宠气泡里的问题突然消失。

原因:提问和审批都有超时,超时或进程退出会把请求交还网页卡片(审批按 cancelled 结算)。

处理:升级前先答完或取消挂起的请求,避免半途丢状态。

8. 数据兼容

state.json 的旧字段会在加载时自动迁移。但如果新版本删除了某个字段,旧值会被忽略,不会报错。ledger.json 的账本按天归档,跨版本一般能继续读。

9. 卸载或更换 dsh

桌宠运行时依赖 dsh 安装目录,卸载 dsh 后桌宠也会随之中断。重装 dsh 后需要重新部署运行时(删 runtime/ 再启动)。

10. 不保证向前兼容

插件会尽量跟着 dsh 更新,但不承诺每个 dsh 新版本都能直接用。升级 dsh 前,建议先备份 ~/.dsh/storages/cyrene-pet/。

数据文件

全部位于 ~/.dsh/storages/cyrene-pet/:

文件 作用
state.json 插件设置(界面模式、昵称、阈值、缩放、背景、亲密层等,不含 API Key)
secret.vault.json API Key 密文,绑本机解锁
memory.vault.json 记忆密文(当前格式)
memory.json 旧格式记忆,加载时迁移到密文版本
live.json 宿主半写给桌宠的实时数据(台词、余额、HUD、提问、任务)
pet-status.json 桌宠渲染层回报的状态(模型尺寸、HUD 位置、渲染像素统计)
pet-window.json 窗口位置与当前缩放
pet-command.json 桌宠发回宿主半的命令(改设置、刷新余额、回答提问)
client-seen.json 网页客户端最后一次可见 / 心跳记录
heartbeat.json 宿主半心跳
ledger.json 本地消费账本(用于算今日消费)
bond.json 好感四维与每日事件记录(密文,绑本机)
bonds-peers.json 群友与陌生人的好感、烦躁(密文,绑本机)
body.json 身体状态(疲惫、精力等,密文,绑本机)
thoughts.json 念头池(密文,绑本机)
intimacy.json 亲密层阶段与解锁记录(密文,绑本机)
opening.json 主动开口账本(密文,绑本机)
ability.json 小游戏战绩(石头剪刀布的胜负、胜率、连胜)
backgrounds/ 自定义背景副本
speech/ 语音缓存
runtime/ 从 dsh 安装目录部署的 Electron 运行时

live.json 每 4 秒刷新一次,pet-command.json 每 1.2 秒轮询一次。

陪伴数据在落盘前会封装成 cyrene-sealed-v1 信封:AES-256-GCM,口令由本机 MachineGuid + 当前用户名派生,文件名也参与派生。文件被拷走、被网盘同步、被上传时都解不开;换机器或换 Windows 用户同样解不开。第一次读到旧明文时会先留一份 .plain.bak,再写密文,备份不会自动删除。备份导出与多端同步在这一层做翻译,读到/发出的是明文,落到各自机器上再按本机口令加密。

余额接口只访问 https://api.deepseek.com/user/balance,默认 30 秒缓存;今日消费由余额变化推断,充值不会冲掉已记录的消费。

备份与恢复

设置页 →「数据」→「导出备份」:

  • 文件名形如 cyrene-pet-backup-2026-11-07.json,可选加密,加密后后缀是 .enc.json。
  • 只收陪伴数据:bond、opening、body、thoughts、ledger、ability。
  • 不收密钥仓库、记忆密文、Live2D 模型、语音缓存与日志,所以备份文件可以放心交给别人看。
  • 恢复时导入同一份 JSON,按字段写回;目标版本没有的字段会被忽略,不会报错。

换机器时建议「备份 → 导入 → 重新填 API Key」三步走,比整个数据目录搬过去稳。

宿主接口

桌宠进程通过本地文件与宿主半通信,宿主半同时暴露这些 HTTP 路由(挂在 dsh 的 webServer 上):

  • GET /cyrene-pet/state / POST /cyrene-pet/state
  • POST /cyrene-pet/control(action: start | stop | restart)
  • GET /cyrene-pet/balance
  • GET /cyrene-pet/hud
  • GET /cyrene-pet/asset/:name

会话(只读)

  • GET /cyrene-pet/sessions:工作区与会话列表,只读文件元信息
  • GET /cyrene-pet/sessions/recent:近期有标题的会话,供设置卡片列出来
  • POST /cyrene-pet/sessions/bind:{ id },绑定当前会话
  • GET /cyrene-pet/sessions/history?id=&limit=:历史消息
  • GET /cyrene-pet/stream?id=:SSE 增量推送(ready / sync / messages / error)
  • POST /cyrene-pet/send:固定 501 { code: "send-unavailable" }

最后一条是能力边界,不是临时占位:DSH 0.2.1-rc.3 宿主侧没有可调用的发送入口, session/prompt 是远端 claim,需要 owner peer。细节见 docs/会话接入结论.md。 桌宠的 live 数据里带 session 字段(标题、是否在生成、最后一条消息)。

陪伴(好感 / 记忆 / 开口)

  • GET /cyrene-pet/companion:好感概览、今日事件、记忆条数、开口账本
  • POST /cyrene-pet/companion/bond:{ type, amount? },手动记一次好感事件
  • GET /cyrene-pet/companion/memory:列出记忆
  • POST /cyrene-pet/companion/memory:{ text, slot? },手动记一条
  • POST /cyrene-pet/companion/memory/pin:{ id, pinned? },固定或取消固定一条
  • POST /cyrene-pet/companion/memory/forget:{ id },忘掉一条

和 Cyrene 版桌宠的差别

能力 Cyrene 版「昔涟 · 桌面桌宠」 本仓库(DSH 版)
宿主 Cyrene 客户端 dsh + 独立的 Electron 渲染进程
立绘 8 种姿态、44 张小表情(静态素材) Live2D 模型:12 个表情、5 组动作、眨眼呼吸、视线跟随(公开包需自备模型);也支持单图 / GIF / 视频 / 多帧
窗口 桌面透明立绘 透明无边框置顶、拖拽贴边、点击穿透
气泡 台词、提问卡、任务气泡 台词气泡 + 口型动画 + 四种气泡模式
状态面板 三档详细度 CPU / 内存 / GPU / 网速 / 电量 / 余额,三档 + 折叠
余额 有 有(同一套 DeepSeek 接口,30 秒缓存)
提问 提问卡 接管 ask_user_question,四种模式
风险审批 — 接管 approval/request,允许一次 / 拒绝
任务 任务气泡 读 todos 投影,长按播报
安装 Cyrene 插件目录 dsh plugin add 或解压到插件目录

和旧版 dsh-cyrene-balance 的差别

项目 旧版 现在
形态 纯工具插件,5 个余额工具 桌面桌宠 + 宿主半
界面 无 透明置顶窗口、Live2D、气泡、状态面板
余额 deepseek_balance 等工具 桌宠显示,宿主半提供 /cyrene-pet/balance
配置 cordis.patch.yml 设置浮层 + state.json
提问 / 审批 / 任务 无 全部接管
包名 dsh-cyrene-balance dsh-cyrene-pet

内部实现与审计结论

这一节记录 2026-11-10 对 v2.0.0 的一次全链路审计。审计沿数据流逐格核对,只看真实调用点,不以注释和命名判断;问题编号分 IN-(输入)、MEM-(记忆与陪伴)、SYS-(系统)、OUT-(输出)四组,状态分「合格」「已确认」「待确认」。完整台账与逐条证据在源码仓库的 docs/audits/2026-11-10-项目审计总账.md。

总体判断

主链路是通的:输入 → 归一化 → 状态写入 → 召回拼装 → 模型 → 五道清洗 → 气泡 / TTS / QQ / 回写。问题集中在三处——同一语义有多套并行实现、默认值让闸门失效、回写是单向的。单条修能改善体感,不解决「谁是唯一真源」,下一轮还会长出同样的分叉。

六个系统性病灶

病灶 具体表现
同一语义多套实现 记忆三套、关系两套、情绪四套、时间四套、词库四套,接口之间没有唯一真源
衰减与裁剪方向反了 decay 重复扣(越聊越淡)、trim 留归档丢活跃、clampSection 从头截、affinity 先丢对方态度
默认值让闸门失效 confidence 默认 0.7 让 unsure 恒空;主人好感起点 60–70 让关系阶段只剩天数;dailyCap 让 minGapMs 形同虚设
写得多,读得少 13 槽只有 4 槽有写入入口、6 槽没有入口;反思只写不读;天气、识屏、余额只在主动开口出现
预算与优先级错位 11 段单项预算、没有总预算;affinity 200 字先截掉最有用的两行;companion 500 字先死表情候选
注释与代码脱节 「四维」实为三维;CUE_KINDS 说顺序即优先级,实际是加权随机;trim 注释与实现相反

修复顺序

P0:方向反了,先停损。

  1. decay 改成按「上次结算点到现在的增量」扣,不再每次调用都按总天数全量扣
  2. trim 保留活跃条目,不再优先丢活跃的弱记忆
  3. 主人好感起点降到阶段门槛以下,或把阶段分数改成归一化值
  4. affinity 与 companion 的裁剪顺序倒过来,先保「对方刚才的态度」和表情候选
  5. 11 段单项预算之外补一个总预算,先定义「这一轮最该让她知道什么」

P1:接通断掉的通道。

  • 人格参数推导不再读记忆、额外说明与「此刻」,避免关键词污染 deriveTraits
  • 六维问卷的结果回填到行为,不只改开口间隔
  • 记忆回写加上 await 与超时;memoryText 开启后不再恒空
  • knowledge 不再静默改名为 preference
  • 反思结果接回下一轮,不再只落盘
  • 情绪与身体状态接进开口闸门

P2:人格结构与契约。

补关系姿态(主人 / 熟人 / 生人 / 群聊的距离感)、冲突与修复(被冒犯后怎么冷、怎么道歉、怎么和好)、表达形态(句长、语气词、比喻、反问、标点)与知识边界句式;13 槽补齐或明确砍掉;两套 prompt 构建器与两套关系档表收敛。

P3:清洁与文档。

.bak 清理、注释口径统一(四轴 / 五轴、六段 / 七段)、过时文档结论、输出层 busy 与 QQ 连发策略。

审计时未确认的入口

台账里有 15 条「待确认」,需要打开真实入口才能定论。影响最大的几条:

编号 待确认
MEM-055 CompanionCore 是否真的导出 onUserMessage;不存在则桌面陪伴层整条静默失效
OUT-001 QQ 与桌面是否共用同一个 chatService 实例
MEM-017 向量检索是否默认关闭,实际走意图还是向量
MEM-097 body 是否在别的层接进了开口闸
MEM-127 桌宠 settings.json 与 DSH state 是否同一份人格参数

这一节记录的是审计基线,不随每次发版自动更新。已修复的条目会在台账里改成「合格」并保留原编号,方便对照。

已知限制

  • 只支持 Windows 的透明置顶窗口行为
  • 公开包不含 Live2D 模型与渲染运行时,默认用图片形象;要 Live2D 需自备模型
  • 陪伴数据同步不覆盖 memory.vault.json,记忆不会跨端合并
  • 自定义背景只存在本机数据目录,换机器要重新导入
  • 运行时依赖 dsh 安装目录,卸载 dsh 后桌宠也会随之中断
  • 余额接口受 DeepSeek 平台限流影响,默认 30 秒缓存一次
  • ledger.json 只记录本插件运行期间的余额变化,首次启动时今日消费从 0 开始累计
  • 提问只支持「从选项里选」;需要自由输入的题、以及 plan-review 审阅,仍要回网页卡片
  • 同一时间只接管一批提问,第二批会走网页卡片
  • 审批只提供一次性授权(allowed-once),没有「总是允许」或规则记忆;需要长期放行请改会话的审批策略
  • 卡片模式没有立绘,单击说话、表情、视线跟随、状态面板都不出现;需要这些请切回完整立绘
  • 卡片模式切换会重启一次桌宠进程,正在挂起的审批会交还网页卡片
  • QQ 通道目前只在本地契约、签名样例与模拟 webhook 上验证过,没有接真实开放平台账号做端到端实测;公网回调需要自己准备隧道
  • QQ 通道一次只发一个目标会话,不做多群广播;换账号要重填 AppID / AppSecret

素材的最原始来源

素材分三层,从源头到本仓库:

第一层:官方原作

角色「昔涟」及《崩坏:星穹铁道》的名称、形象、服装与官方美术,著作权归 HoYoverse / 米哈游(miHoYo) 所有。本仓库与米哈游、HoYoverse 没有任何隶属、授权或合作关系。

第二层:Cyrene 客户端资源包

立绘、表情、状态面板头像等素材取自 Cyrene 客户端自带的「昔涟 · 桌面桌宠」资源包(resources/app.asar 内):

  • assets/ui/cyrene-thinking-loop/:情绪特写与状态面板立绘
  • dist/renderer/stickers/:44 张小表情
  • dist/renderer/icons/mimi.png:状态面板头像
  • pet/assets/live2d/cyrene/:Live2D 模型(model.moc3、model.physics3.json、12 个表情、5 组动作、texture_0.png);公开包不含此目录

Live2D 模型由 B 站 UP 主 @是依七哒 制作,经 Cyrene 资源包引入。本仓库不主张该模型的著作权。

官方背景插画

assets/backgrounds/builtin-cyrene-01 ~ 07 是《崩坏:星穹铁道》官方宣传插画,著作权归 HoYoverse / miHoYo 所有,由项目作者收集后随包内置,仅作桌面背景使用。使用性质为非官方二创,禁止商用、转售、付费分发;公开分发前请自行确认授权范围。逐张来源说明见 assets/backgrounds/CREDITS.md。

第三层:本仓库的处理

本仓库只做了搬运、去白底、缩放、透明化与目录整理,没有重新绘制角色形象。逐项对照与处理记录见 cyrene-balance 的 MATERIALS.md。

素材与代码的授权范围不同:代码是 MIT,assets/ 与 pet/assets/ 不在 MIT 范围内,详见 LICENSE 的「素材例外(Assets Exception)」。

免责声明

  1. 非官方作品。 本项目是个人制作的第三方插件,与 DeepSeek、Live2D Inc.、miHoYo / HoYoverse 均无隶属、授权、赞助或合作关系。
  2. 素材版权归原权利人。 立绘、Live2D 模型、表情、头像等素材的著作权归 HoYoverse / 米哈游及 Live2D 模型制作者所有。本项目仅在个人学习与本机使用范围内引用,禁止商用、转售、付费分发或二次分发素材。
  3. 代码许可不等于素材许可。 源代码按 MIT 发布;assets/、pet/assets/ 中的素材不受 MIT 授权,见 LICENSE 的素材例外条款。
  4. 使用风险自负。 桌宠会创建透明置顶窗口、改写 resources/app 链接、启动独立 Electron 进程。由此产生的窗口异常、桌面操作受阻、系统资源占用等问题,作者不承担赔偿责任。
  5. 数据仅供参考。 余额、今日消费、今日充值由 DeepSeek 接口与本地账本推算,可能有延迟或误差,请以 DeepSeek 官方账单为准。
  6. API Key 由你保管。 Key 加密保存在本机 ~/.dsh/storages/cyrene-pet/secret.vault.json,不会上传到本项目;因本机泄露、共享电脑或第三方插件读取造成的损失,作者不承担责任。
  7. 审批授权后果自负。 在桌宠上点「允许一次」等于授权 Agent 越权执行对应操作,可能修改文件、访问网络或执行命令。请确认工具名和理由后再点。
  8. 提问接管可能漏答。 桌宠只接管「带选项、无 intent」的批次;超时、桌宠未运行或已有挂起请求时,会交还网页卡片,不保证每次都弹在桌宠。
  9. 任务进度只读展示。 任务进程读取 dsh 的 todos 投影,不修改任务状态,也不保证与实际执行进度完全同步。
  10. 升级兼容性不承诺。 dsh 升级、Electron 主版本变化、插件 API 调整都可能导致桌宠失效,详见「Agent(dsh)升级后可能产生的后果」。
  11. 无担保。 本项目按「现状」提供,不附带任何明示或暗示的担保,包括适销性、特定用途适用性和不侵权担保。
  12. 责任上限。 在适用法律允许的范围内,作者对因使用或无法使用本项目产生的任何直接、间接、附带或后果性损失不承担责任。
  13. 第三方冲突。 同时安装其他桌宠、窗口管理或自动化插件可能产生快捷键、托盘、窗口层级冲突,请自行排查。
  14. 删除不自动清理数据。 卸载插件不会自动删除 ~/.dsh/storages/cyrene-pet/,需要手动清理。
  15. 作者保留权利。 作者可随时修改、停止分发或调整授权范围;已分发的副本仍受当时条款约束。

目录

dsh-cyrene-pet/
├─ lib/                        宿主半(在 dsh 进程里跑)
│  ├─ index.js                 设置、余额、系统状态、提问、审批、任务、桌宠进程管理
│  ├─ client.js                dsh 设置页「昔涟 · 桌宠」卡片
│  ├─ companion-runtime.mjs    好感 / 记忆 / 身体 / 念头 / 亲密层 / 开口账本
│  ├─ persona.mjs              人格与台词
│  ├─ ability.mjs              小游戏战绩
│  ├─ session-bridge.js        会话只读桥(列表、历史、SSE)
│  ├─ qq-host.mjs              QQ 官方机器人回调、签名校验、远程拍板
│  ├─ sync-bridge.mjs          陪伴数据多端同步
│  ├─ state-merge.mjs          两份写入口的设置合并
│  └─ vault/                   加密仓库与同步引擎(hlc / syncEngine / contracts)
├─ pet/                        Electron 渲染半
│  ├─ main.js                  透明窗口、拖拽、贴边、托盘、背景落盘、诊断截图
│  ├─ preload.js               IPC 桥
│  ├─ index.html               气泡 / 状态面板 / 菜单 / 设置
│  ├─ renderer.js              形象渲染、命中检测、交互、背景
│  ├─ style.css                气泡、面板与设置样式
│  ├─ model-pack.mjs           自备模型的清单解析
│  ├─ outline.js               描边处理
│  └─ assets/live2d/           渲染库与 Live2D 模型(公开包不含)
├─ assets/                     默认形象、表情、气泡、音效、内置背景
│  ├─ backgrounds/             builtin-cyrene-01~07 / night / sakura + CREDITS.md
│  ├─ emoji/                   44 张小表情
│  └─ sound/                   问候、任务结束、费用等音效
├─ cordis.patch.yml            插件注入声明
├─ LICENSE                     MIT + 素材例外
└─ package.json

许可与作者

  • 代码:MIT
  • 素材:不在 MIT 范围内,著作权归原权利人
  • 作者:bestlike093
  • 问题反馈:GitHub Issues

表情 / 动作框架的出处与依赖

渲染层表情、动作框架的部分能力(中文动作名映射、emoji → 表情映射、七段触摸分区、临时表情墙钟回落、能力识别成文)出自遐蝶桌宠驱动 live2d-driver(2026-11-10 定版),原驱动自述「代码本仓自写,形态参考鲸语 jingyu-live2d(MIT)」。接入文件均保留出处署名,映射表与降级策略沿用原样,台词已按本桌宠角色改写。

相关依赖许可:

  • pixi.js:MIT
  • pixi-live2d-display:MIT
  • Live2D Cubism Core / Cubism Web Framework:Live2D Inc. 授权(仅限本地个人使用;随包不含任何 Live2D SDK 文件,使用时请遵守 Live2D 发行许可条款)
  • 模型素材(.moc3 等):不属于本仓库,著作权归各模型原权利人;本仓库不收录、不随发行包分发
—/ 5

No ratings yet

Verified DSH bundle

Commit 18124f7abe86

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout