🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

VRM 3D 桌宠 drliuhuan/dsh-plugin-vrmpet3d

DeepSeek Harnessv0.1.4
drliuhuan7 天前有提交已提供中文文档扫描:含敏感能力

DeepSeek Harness 的 VRM 3D 桌宠插件:任务状态联动、独立悬浮窗、模型动作、部位互动与 AI…

34.9/100
综合分
7
GitHub 星标
781
npm 周下载
—/5
用户评分

数据截至 2026/10/27 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add dsh-plugin-vrmpet3d
npm 源 · dsh-plugin-vrmpet3d 的发布者账号已校验与本仓库一致

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · desktop
装得上吗
本站已在 dsh 0.2.1-rc.2 下真实安装成功
非静态推断
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 7 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查✓ 自动检查通过
展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✓npm 包dsh-plugin-vrmpet3d @ 0.1.4
✓Node 引擎要求 >=22 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/11/1 02:40:32

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件发起外部网络请求
查看扫描证据(共 154 处,展示前 74 条)
  • 读取本地文件
    lib/index.js:411
    if (existsSync(file)) return file;
  • 读取本地文件
    lib/index.js:413
    return legacy && existsSync(legacy) ? legacy : file;
  • 读取本地文件
    lib/index.js:426
    const parsed = JSON.parse(readFileSync(file, 'utf8'));
  • 写入本地文件
    lib/index.js:444
    mkdirSync(dirname(file), { recursive: true });
  • 写入本地文件
    lib/index.js:445
    writeFileSync(file, JSON.stringify({ modelDirs: dirs }, null, 2) + '\n');
  • 读取本地文件
    lib/index.js:508
    const parsed = JSON.parse(readFileSync(file, 'utf8'));
  • 写入本地文件
    lib/index.js:532
    mkdirSync(dirname(file), { recursive: true });
  • 写入本地文件
    lib/index.js:533
    writeFileSync(file, JSON.stringify({ models }, null, 2) + '\n');
  • 读取本地文件
    lib/index.js:543
    const parsed = JSON.parse(readFileSync(file, 'utf8'));
  • 写入本地文件
    lib/index.js:568
    mkdirSync(dirname(file), { recursive: true });
  • 写入本地文件
    lib/index.js:569
    writeFileSync(file, JSON.stringify({ imports }, null, 2) + '\n');
  • 读取本地文件
    lib/index.js:581
    for (let n = 2; existsSync(candidate) && n < 1000; n += 1) candidate = join(dir, `${stem}-${n}${ext}`);
  • 删除本地文件
    lib/index.js:670
    rmSync(absolute, { force: true });
  • 删除本地文件递归
    lib/index.js:777
    rmSync(absolute, { recursive: true, force: true });
  • 发起网络请求
    lib/index.js:3713
    const response = await fetch(`${speech.ai.baseUrl.replace(/ +$/, '')}/chat/completions`, {
  • 发起网络请求
    lib/client.js:1675
    fetch('/vrmpet3d/desktop', { method: 'POST', credentials: 'same-origin',
  • 发起网络请求
    lib/client.js:1705
    fetch('/vrmpet3d/desktop', {
  • 发起网络请求
    lib/client.js:1742
    return fetch('/vrmpet3d/setup-state', {
  • 发起网络请求
    lib/client.js:1749
    return fetch('/vrmpet3d/setup-state', { credentials: 'same-origin' })
  • 发起网络请求
    lib/client.js:1755
    return fetch('/vrmpet3d/desktop', {
  • 发起网络请求
    lib/client.js:2274
    return fetch('/vrmpet3d/desktop', {
  • 读取本地文件
    lib/settings.js:33
    if (!existsSync(file)) return null;
  • 读取本地文件
    lib/settings.js:34
    const parsed = JSON.parse(readFileSync(file, 'utf8'));
  • 写入本地文件
    lib/settings.js:44
    mkdirSync(dirname(file), { recursive: true });
  • 写入本地文件
    lib/settings.js:46
    writeFileSync(temporary, JSON.stringify(payload, null, 2), 'utf8');
  • 写入本地文件
    lib/settings.js:47
    renameSync(temporary, file);
  • 读取本地文件
    lib/mini-game-level-store.js:9
    const bundled = api.normalizeLevels(JSON.parse(readFileSync(new URL('../assets/game/levels.json', import.meta.url), 'utf8')));
  • 读取本地文件
    lib/desktop.js:168
    if (existsSync(join(current, 'resources')) && findExecutable(current)) return current;
  • 读取本地文件
    lib/desktop.js:180
    if (existsSync(candidate) && statSync(candidate).isFile()) return candidate;
  • 读取本地文件
    lib/desktop.js:180
    if (existsSync(candidate) && statSync(candidate).isFile()) return candidate;
  • 读取本地文件
    lib/desktop.js:197
    if (!existsSync(from)) { missing.push(name); continue; }
  • 读取本地文件
    lib/desktop.js:204
    kind: existsSync(localesFrom) ? 'dir' : 'skip',
  • 读取本地文件
    lib/desktop.js:232
    const usable = existsSync(targetExe)
  • 写入本地文件
    lib/desktop.js:238
    mkdirSync(plan.resources, { recursive: true });
  • 写入本地文件
    lib/desktop.js:254
    mkdirSync(to, { recursive: true });
  • 写入本地文件
    lib/desktop.js:255
    for (const entry of readdirSync(from)) copyFileSync(join(from, entry), join(to, entry));
  • 写入本地文件
    lib/desktop.js:257
    copyFileSync(from, to);
  • 删除本地文件递归
    lib/desktop.js:296
    rmSync(dir, { recursive: true, force: true });
  • 写入本地文件
    lib/whale.js:143
    mkdirSync(dirname(file), { recursive: true });
  • 写入本地文件
    lib/whale.js:144
    writeFileSync(file, bytes);
  • 读取本地文件
    lib/whale.js:155
    return { bytes: readFileSync(file) };
  • 读取本地文件
    lib/whale.js:174
    if (!existsSync(bundle)) { tried.push(`${bundle} (absent)`); continue; }
  • 读取本地文件
    lib/vrm-info.js:82
    const bytes = readFileSync(path);
  • 读取本地文件
    lib/vrm-info.js:734
    current = statSync(absolute);
  • 发起网络请求
    desktop/game-visibility.cjs:39
    const response = await session.fetch(url.href, {
  • 写入本地文件
    desktop/main.js:200
    fs.mkdirSync(ownProfile, { recursive: true });
  • 写入本地文件
    desktop/main.js:222
    fs.writeFileSync(options.selfTest, JSON.stringify(report, null, 2));
  • 写入本地文件
    desktop/main.js:248
    fs.writeFileSync(options.selfTest, JSON.stringify(report, null, 2));
  • 写入本地文件
    desktop/main.js:968
    fs.writeFileSync(pngPath, image.toPNG());
  • 写入本地文件
    desktop/main.js:999
    fs.writeFileSync(pngPath, Buffer.from(String(shot.png).split(',')[1], 'base64'));
  • 写入本地文件
    desktop/main.js:1021
    if (shot.png) fs.writeFileSync(pngPath, Buffer.from(String(shot.png).split(',')[1], 'base64'));
  • 读取本地文件
    desktop/main.js:1192
    const script = fs.readFileSync(path.join(__dirname, 'probe-parts-editor.js'), 'utf8');
  • 读取本地文件
    desktop/main.js:1209
    const script = fs.readFileSync(path.join(__dirname, 'probe-motion-picker.js'), 'utf8');
  • 发起网络请求
    lib/config-page.js:1084
    return fetch('/vrmpet3d/catalog', { credentials: 'same-origin' })
  • 发起网络请求
    lib/config-page.js:1186
    return fetch('/vrmpet3d/models', { credentials: 'same-origin' })
  • 发起网络请求
    lib/config-page.js:1210
    return fetch('/vrmpet3d/models', {
  • 发起网络请求
    lib/config-page.js:1344
    return fetch('/vrmpet3d/motions', { credentials: 'same-origin' })
  • 发起网络请求
    lib/config-page.js:1364
    return fetch('/vrmpet3d/motions', {
  • 发起网络请求
    lib/config-page.js:1506
    var promise = fetch('/vrmpet3d/model-info?m=' + encodeURIComponent(id), { credentials: 'same-origin' })
  • 发起网络请求
    lib/desktop-page.js:763
    return fetch('/vrmpet3d/settings', {
  • 发起网络请求
    lib/desktop-page.js:771
    return fetch('/vrmpet3d/desktop', {
  • 发起网络请求
    lib/desktop-page.js:1156
    fetch('/vrmpet3d/desktop', {
  • 发起网络请求
    lib/desktop-page.js:1229
    fetch('/vrmpet3d/desktop', {
  • 发起网络请求
    lib/desktop-page.js:1374
    fetch('/vrmpet3d/say', {
  • 发起网络请求
    lib/desktop-page.js:1697
    return fetch('/vrmpet3d/catalog', { credentials: 'same-origin' })
  • 发起网络请求
    lib/mini-game-page.js:42
    return fetch('/vrmpet3d/desktop', { method: 'POST', credentials: 'same-origin', keepalive: keepalive === true,
  • 发起网络请求
    lib/mini-game-page.js:244
    fetch('/vrmpet3d/desktop', { method: 'POST', headers: { 'content-type': 'application/json' },
  • 发起网络请求
    lib/mini-game-page.js:253
    fetch('/vrmpet3d/state', { credentials: 'same-origin', cache: 'no-store', signal: statusRequest.signal }).then(function (r) {
  • 发起网络请求
    lib/mini-game-page.js:560
    fetch('/vrmpet3d/settings', { credentials: 'same-origin' }).then(function (r) { if (!r.ok) throw new Error('无法读取模型设置'); return r.json(); }),
  • 发起网络请求
    lib/mini-game-page.js:561
    fetch('/vrmpet3d/catalog', { credentials: 'same-origin' }).then(function (r) { if (!r.ok) throw new Error('无法读取模型列表'); return r.json(); }),
  • 发起网络请求
    lib/mini-game-page.js:562
    fetch('/vrmpet3d/motions', { credentials: 'same-origin' }).then(function (r) { if (!r.ok) throw new Error('无法读取分发的弹簧骨默认参数'); return r.json(); }),
  • 发起网络请求
    lib/setup-page.js:302
    return fetch(path, {
  • 发起网络请求
    lib/setup-page.js:318
    return fetch(path, { credentials: 'same-origin' })
  • 发起网络请求
    lib/setup-page.js:520
    fetch('/vrmpet3d/desktop', { credentials: 'same-origin' })
扫描于 2026/11/2(1 天前) · 范围 入口闭包 + 全包扫描 · 来源 npm 发布包

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

README

由 DeepSeek 最新模型翻译生成
桌宠 3D · VRM Pet 3D 为 DeepSeek Harness(DSH) 添加一只 3D 桌宠,随任务状态活动。支持应用内显示,也支持 DSH Desktop 上独立的透明悬浮窗;任务进行、等待确认、完成或出错时,宠物会显示对应状态,播放配置的动作。 自带两款模型和 VRMA 动作包,安装后即可使用。可导入自己的模型,设置动作、表情、视线和物理效果,也可以让宠物说预设台词,或用 AI 生成碎碎念。 安装与使用 · 问题反馈 · MIT 许可证 当前为早期版本,仍在修复和完善。3D 渲染会占用 GPU 与内存;遇到异常时,请附上 DSH 版本、显示方式和复现步骤反馈。 no runtime dependencies · works offline 效果展示 空闲、工作中、等待确认与任务完成的状态展示合成图: 桌宠空闲、工作中、等待确认与任务完成 碎碎念与鼠标凝视的实机演示: 碎碎念与鼠标凝视演示 展示模型为 BlueFatFish / 蓝色小肥鱼Deepseek,作者 木子恶魔,原始发布页。经作者授权随本插件分发,需注明来源与作者。 模型版权归原作者,其授权独立于插件代码的 MIT 许可证。模型选择页及首次引导的模型步骤也展示相同署名、授权与来源。 市场截图顺序由根目录 screenshots.json 声明,包含合成展示图和四张原始截图。
展开完整文档(README 剩余 1 节)
桌宠 3D · VRM Pet 3D

为 DeepSeek Harness(DSH) 添加一只 3D 桌宠,随任务状态活动。支持应用内显示,也支持 DSH Desktop 上独立的透明悬浮窗;任务进行、等待确认、完成或出错时,宠物会显示对应状态,播放配置的动作。

自带两款模型和 VRMA 动作包,安装后即可使用。可导入自己的模型,设置动作、表情、视线和物理效果,也可以让宠物说预设台词,或用 AI 生成碎碎念。

安装与使用 · 问题反馈 · MIT 许可证

当前为早期版本,仍在修复和完善。3D 渲染会占用 GPU 与内存;遇到异常时,请附上 DSH 版本、显示方式和复现步骤反馈。

no runtime dependencies · works offline

效果展示

空闲、工作中、等待确认与任务完成的状态展示合成图:

桌宠空闲、工作中、等待确认与任务完成

碎碎念与鼠标凝视的实机演示:

碎碎念与鼠标凝视演示

展示模型为 BlueFatFish / 蓝色小肥鱼Deepseek,作者 木子恶魔,原始发布页。经作者授权随本插件分发,需注明来源与作者。
模型版权归原作者,其授权独立于插件代码的 MIT 许可证。模型选择页及首次引导的模型步骤也展示相同署名、授权与来源。

市场截图顺序由根目录 screenshots.json 声明,包含合成展示图和四张原始截图。

功能

| 功能 | 说明 |
| 两种显示方式 | 应用内宠物;Desktop 端自动开启独立悬浮窗,支持置顶和透明区域鼠标穿透 |
| 任务状态联动 | 空闲、工作中、等待确认、完成、出错与离线;空闲保持 idle,不自动进入休眠 |
| 模型 | VRM 1.0 / 0.x,兼容普通 glTF/GLB;人体动作播放需要 VRM 骨架 |
| 动作 | 自带 VRMA 动作包,可按状态配置循环、单次、速度、表情、口型和凝视 |
| 跳支舞 | 右键随机播放一支舞蹈;播完、双击或开始工作时结束 |
| 吃白饭小游戏 | 右键进入桌宠弹球,吃完米饭通关;自动保存、暂停恢复倒计时、任务消息提醒,内置两关并静默更新关卡 |
| 互动 | 点击与长按部位触发表情和碎碎念;拖动、缩放、旋转视角、视线跟随和弹簧骨物理 |
| 碎碎念 | 内置台词、自定义台词,或使用 DSH 模型 / OpenAI 兼容接口生成 AI 台词 |
| 导入 | 模型以文件导入、动作包以文件夹导入,复制到插件存储后不依赖原路径 |
| 界面语言 | 全部界面中英双语,默认跟随系统 / DSH 自动识别;「通用设置 → 显示与外观」和初次引导欢迎页各有一个语言选择(自动 / 中文 / English) |

运行要求

- 已在 DeepSeek Harness 0.2.0-rc.2 上验证;其他版本尚未验证,不代表无法使用。本项目是 DSH 插件,不能作为独立应用运行。
- 支持 WebGL2 的图形环境。独立悬浮窗需可用的 Electron 运行时,由启动器从 DSH 安装目录复用;无法启动时回退到应用内显示。
- 无需安装运行时 npm 依赖。默认台词和模型动画可离线使用;AI 碎碎念取决于所选服务的网络与额度。

安装

请使用本仓库的 main 分支安装。项目尚未发布到 npm。

1. 在 DSH 插件管理器中添加本仓库;支持 GitHub 包来源时,使用:

github:drliuhuan/dsh-plugin-vrmpet3d#main

2. 也可以下载 main 分支 ZIP,解压后在插件管理器中添加包含 package.json 的文件夹,或填写 link:<插件文件夹的绝对路径>。
3. 确认插件已启用,然后重启 DSH。更新插件后也请重启,确保宿主代码和页面代码使用同一版本。

请先停用其他占用同一桌宠显示位置的插件,例如 dsh-plugin-fatfish-pet、dsh-plugin-whale-pet。卸载时从插件管理器移除本插件。

首次使用

首次引导会依次配置偏好模型、桌宠界面和 AI 碎碎念。可稍后配置,也可在 通用设置 → 其他 → 重新运行引导 再次打开。

- 切换显示方式:Desktop 的通用设置最上方可选「内置宠物」或「自动」;自动优先使用独立悬浮窗。右键菜单也可以切换。
- 切换模型:右键 → 切换模型,点击缩略图;可拖入自己的模型文件,加载进度结束后再继续切换。
- 设置动作:通用设置 → 状态与动作。默认映射、表情和播放方式已随动作包提供,可以自行修改。
- 设置台词:通用设置 → 碎碎念。选择内置、自定义或 AI 来源;AI 模式需要先选择可用服务和模型。
- 设置表情与部位:右键 → 当前模型参数设置。模型结构不同,可用表情、部位和弹簧骨链也会不同。

鼠标操作

| 操作 | 效果 |
| 点击 / 原地长按 | 触发部位互动与碎碎念,保留正在播放的动作 |
| 左键拖动 | 移动宠物;开启对应界面的重力后,松开可触发抛掷和落地 |
| 滚轮经过宠物 | 调整宠物及其文字大小 |
| 滚轮经过文字 | 单独调整文字大小 |
| 右键拖动 | 旋转观察视角 |
| 右键点击 | 打开菜单:显示切换、模型切换、跳舞、重载、设置、重力和隐藏等 |
| 双击 | 结束当前跳舞 |

模型、动作与数据

自带默认模型 蓝色小肥鱼Deepseek(木子恶魔),以及备用模型 ヴィータ(VRoid プロジェクト)。来源和授权见下方许可证说明及模型说明。

BlueFatFish 模型署名与授权

| 项目 | 信息 |
| 模型文件 | BlueFatFish.vrm.br(加载时解压为 VRM) |
| 模型名称 | 蓝色小肥鱼Deepseek |
| 作者 | 木子恶魔 |
| 来源 | Aplaybox 原始发布页 |
| 分发授权 | 经作者授权随本插件分发,需注明来源与作者 |

本项目的 MIT 许可证不替代模型作者的授权;其他用途仍以作者原始发布页的条款和另行授权为准。

模型支持 .vrm、.glb、.gltf,动作支持 .vrma;不支持 PMX/PMD 或 VMD。普通 glTF/GLB 没有 VRM 人体骨架时,不能播放 VRMA 人体动作。自带模型与动作使用 Brotli 压缩存储,加载时自动解压。

导入内容与配置保存在 DSH profile 的插件存储目录中。移除导入只删除插件持有的副本,不删除原文件。随包动作的默认设置按文件名解析,不依赖其他机器上的模型或动作 ID。

AI 与隐私

宠物通过任务状态、会话标识和计时信息判断当前状态,不需要读取会话正文、工具参数或附件。启用 AI 碎碎念后,所配置的人格、状态提示词和部位信息会发送给你选择的 AI 服务;费用与数据处理规则由该服务决定。

常见问题与反馈

- 没有宠物:检查插件管理器里是否仍已启用,重启 DSH,并确认未被其他桌宠插件占用显示位置。
- 没有独立窗口:在通用设置中选择「自动」;若运行时不可用,仍可使用内置宠物。
- 模型不播放动作:确认使用 VRM 模型,状态下选有动作,并开启模型动作。反馈时请附上完整错误提示。
- AI 不说话:检查台词来源、服务、模型和访问额度;可以先切回内置台词确认气泡显示正常。

请通过 GitHub Issues 提交问题,附上 DSH 版本、操作系统、内置/外置显示方式、复现顺序与预期结果。请勿上传 API Key 或私人会话内容。

给 DeepSeek Harness(DSH) 加一只 3D 桌宠。宠物跟随任务状态变化,可以显示在应用内,也可以在 DSH Desktop 上单独开一个透明悬浮窗。任务运行中、等待确认、已完成或已失败时,它会显示当前状态,并播放对应的动作。

内置两个模型和一套 VRMA 动作包。你也可以导入自己的模型,配置动作、表情、视线和物理,让宠物说预设台词,或者生成 AI 碎碎念。

安装与使用 · 反馈问题 · MIT 许可证

这是早期版本,仍在持续改进。3D 渲染会占用 GPU 和内存。反馈问题时,请附上 DSH 版本、显示方式和复现步骤。

截图与演示

合成图展示了空闲、工作中、等待确认和任务完成四种状态:

宠物处于空闲、工作中、等待确认和已完成状态

碎碎念与鼠标视线跟随的实时演示:

碎碎念与鼠标视线跟随演示

图中模型为 BlueFatFish / 蓝色小肥鱼Deepseek,作者 木子恶魔。见原始发布页。作者授权随本插件分发,需注明来源与作者。 模型仍属作者作品,授权独立于本插件的 MIT 许可证。模型选择器和首次运行引导中同样标注了来源、授权与作者信息。

应用市场的截图顺序在根目录 screenshots.json 中声明,其中列出了合成图和四张原始截图。

功能

| 功能 | 说明 |
| 两种显示方式 | 应用内宠物;或在 Desktop 上自动打开悬浮窗,支持置顶和透明区域点击穿透 |
| 任务状态跟踪 | 空闲、工作中、等待确认、已完成、失败和离线;空闲时保持空闲状态,不会自动休眠 |
| 模型 | VRM 1.0 / 0.x 和普通 glTF/GLB;角色动作需要 humanoid VRM 骨骼 |
| 动作 | 内置 VRMA 动作包,支持按状态设置循环、单次播放、速度、表情、口型同步和视线 |
| 跳舞 | 右键播放随机舞蹈;动作结束、双击或开始工作时停止 |
| 交互 | 点击或按住身体部位触发表情和闲聊;拖动、缩放、旋转视图,跟随指针,支持弹簧骨骼物理 |
| 闲聊 | 内置台词或自定义台词,也可以用 DSH 模型或 OpenAI 兼容服务生成 AI 台词 |
| 导入 | 模型按文件导入,动作包按文件夹导入。导入的文件会复制到插件存储中,不再依赖原始路径 |
| 语言 | 整个界面支持中文和英文,默认从系统或 DSH 自动检测;通用设置 → 显示里有选择器(自动 / 中文 / English),首次运行引导的欢迎页也有 |

环境要求

- 已在 DeepSeek Harness 0.2.0-rc.2 上验证。其他版本未验证,但这不代表不能用。这是 DSH 插件,不能作为独立应用运行。
- 需要支持 WebGL2 的图形环境。浮动窗口需要可用的 Electron 运行时,启动器会复用 DSH 安装中的运行时。如果启动失败,宠物会退回应用内显示。
- 不需要运行时 npm 依赖。内置台词和模型动作可离线使用。AI 闲聊依赖所选服务的网络访问和使用配额。

安装

从本仓库的 main 分支安装。项目尚未发布到 npm。

1. 在 DSH 插件管理器中添加本仓库。如果支持 GitHub 包源,使用:

github:drliuhuan/dsh-plugin-vrmpet3d#main

2. 也可以下载 main 分支 ZIP,解压后在插件管理器中添加包含 package.json 的文件夹,或输入 link:<插件文件夹的绝对路径>。
3. 确认插件已启用,然后重启 DSH。更新后也要重启,让宿主和页面代码使用同一版本。

先禁用其他使用相同宠物显示位置的插件,比如 dsh-plugin-fatfish-pet 和 dsh-plugin-whale-pet。通过插件管理器卸载本插件。

首次运行

首次运行引导会配置你偏好的模型、宠物显示和 AI 闲聊。你可以稍后完成设置,也可以从通用设置 → 其他 → 再次运行设置引导重新打开。

- 选择显示模式: 在桌面端,于通用设置顶部选择「内置宠物」或「自动」。自动模式优先使用独立的浮动窗口。也可以从右键菜单切换模式。
- 选择模型: 右键 → 切换模型,然后选择缩略图。也可以拖入模型文件;等加载完成后再切换。
- 配置动作: 通用设置 → 状态与动作。默认状态映射、表情和播放设置都已内置,可以修改。
- 配置台词: 通用设置 → 闲聊。可选内置台词、自定义台词或 AI 台词。AI 模式需要可用的服务商和模型。
- 配置表情和身体部位: 右键 → 当前模型设置。可用的表情、身体部位和弹簧骨链取决于模型。

鼠标操作

| 操作 | 结果 |
| 单击 / 原地按住 | 触发身体部位互动和闲聊,同时保持当前动作 |
| 左键拖动 | 移动宠物;如果该显示器启用了重力,松开后会把它抛出去并落地 |
| 在宠物上滚动 | 缩放宠物和文字 |
| 在文字上滚动 | 只缩放文字 |
| 右键拖动 | 旋转视角 |
| 右键单击 | 打开菜单,可切换显示器和模型、跳舞、重新加载、设置、重力、隐藏等 |
| 双击 | 结束当前舞蹈 |

模型、动作和数据

内置默认模型是 蓝色小肥鱼Deepseek by 木子恶魔。备用模型是 ヴィータ by VRoid プロジェクト。来源和条款见下方许可说明以及模型文档。

BlueFatFish 模型署名与授权

| 项目 | 信息 |
| 模型文件 | BlueFatFish.vrm.br(加载时解压为 VRM) |
| 模型名称 | 蓝色小肥鱼Deepseek |
| 作者 | 木子恶魔 |
| 来源 | Aplaybox 原始发布页 |
| 分发授权 | 作者授权随本插件分发,前提是注明来源和作者 |

本项目的 MIT 许可证不能替代模型作者的授权。其他用途仍受原始发布页条款和作者另行授权的约束。

模型支持 .vrm、.glb 和 .gltf;动作支持 .vrma。不支持 PMX/PMD 和 VMD。普通 glTF/GLB 文件没有 VRM humanoid 骨架,无法播放 VRMA 角色动作。内置模型和动作以 Brotli 压缩存储,加载时自动解压。

导入的文件和设置存放在 DSH 配置档中的插件存储目录。删除导入只删除插件内的副本,不会删除原始文件。内置动作的默认设置按文件名解析,不依赖另一台机器上的模型或动作 ID。

AI 与隐私

宠物使用任务状态、会话标识和时间信息判断当前状态。它不需要读取对话文本、工具参数或附件。启用 AI 闲聊后,配置的人设、状态提示词和身体部位信息会发送到你选择的 AI 服务商。该服务商自行决定收费和数据处理的规则。

故障排查与反馈

- 宠物不见了: 检查插件是否已启用,重启 DSH,并确认没有其他宠物插件占用同一个显示位置。
- 悬浮窗不见了: 在常规设置里选择「自动」。如果运行时无法启动,应用内宠物仍然可用。
- 模型不动: 确认你用的是 VRM 模型,当前状态已分配动作,且模型动作已开启。反馈问题时请附上完整错误信息。
- AI 不说话: 检查台词来源、服务、模型和用量配额。切换到内置台词,确认气泡能正常工作。

请通过 GitHub Issues 反馈问题。请附上你的 DSH 版本、操作系统、显示模式、复现步骤和预期结果。不要上传 API 密钥或私密对话内容。

License

插件代码与本项目原创动作采用 MIT 许可证。模型资源仍遵守各自作者的授权,不因随本仓库分发而自动改为 MIT。

MIT — see LICENSE. It bundles other MIT-licensed software as one generated file (lib/client.vendor.js): three.js, @pixiv/three-vrm and @pixiv/three-vrm-animation. It ships exactly two 3D model files, and both may be redistributed with it:

| file | model | author | source | terms |
| assets/models/BlueFatFish.vrm.br | 蓝色小肥鱼Deepseek | 木子恶魔 | <https://www.aplaybox.com/details/model/ayXkRzVflmnd> | 经作者授权分发 — credited here as the author asks |
| assets/models/SampleModel.vrm.br | ヴィータ | VRoid プロジェクト | <https://vroid.com/en/studio> | its own embedded licence: redistribution, modification and commercial use allowed, no attribution required |

The first is what a fresh profile resolves to; the second is the fallback. Every other model is the user's and stays
under its own author's terms.
预览分享卡片长什么样 ↓drliuhuan/dsh-plugin-vrmpet3d
分享 · DeepSeek Harness Hub
drliuhuan/dsh-plugin-vrmpet3d

DeepSeek Harness 的 VRM 3D 桌宠插件:任务状态联动、独立悬浮窗、模型动作、部位互动与 AI…

回到顶部