dsh-dfy-pet 2.6.1 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -11,6 +11,8 @@
11
11
  - **会自己冒泡。** 没有其他交互时,每 9–16 秒挥手一次。
12
12
  - **点击 / 轻触 / <kbd>Enter</kbd> / <kbd>Space</kbd>:** 她蹦一下(或挥手),
13
13
  飘起三颗爱心,并随机说一句六句本地化短句之一。
14
+ - **双击(或聚焦后按 <kbd>Enter</kbd>/<kbd>Space</kbd>):** 在她旁边弹出对话面板,
15
+ 输入框可直接打字,见下方「双击对话」一节。
14
16
  - **拖动:** 拎起来放到任意位置;位置记在 `localStorage` 里,窗口尺寸变化时会重新
15
17
  夹取边界,保证她不会跑到屏幕外找不回来。
16
18
  - **首次加载:** 说一句欢迎气泡,每个浏览器只出现一次(v2 键)。
@@ -18,6 +20,83 @@
18
20
  下面两节分别说明。
19
21
  - 尊重 `prefers-reduced-motion`:关闭帧动画、爱心与气泡弹跳,角色和交互仍然保留。
20
22
 
23
+ ## 双击对话(交互版)
24
+
25
+ 双击宠物会弹出一个贴着她的对话面板:她在右边放得下就弹在右侧,否则落到上方,
26
+ 都不够就移到下方,且始终夹在视口内。
27
+
28
+ | 操作 | 效果 |
29
+ |---|---|
30
+ | 双击宠物 / 聚焦后按 <kbd>Enter</kbd>、<kbd>Space</kbd> | 打开面板,她挥手并冒出一句问候 |
31
+ | <kbd>Enter</kbd> 或点 **发送** | 发送当前输入;发送中按钮禁用,不会重复提交 |
32
+ | <kbd>Shift</kbd>+<kbd>Enter</kbd> | 换行,不发送 |
33
+ | 输入法候选中的 <kbd>Enter</kbd> | 只上屏文字,不发送(检查 `isComposing`) |
34
+ | <kbd>Esc</kbd> / 点面板外 / 点宠物本人 / 点 × | 关闭面板,已聊的消息保留 |
35
+ | 标题栏 **垃圾桶按钮** | 清空对话:点一下变红进入确认,再点一次才执行;发送中禁用,失焦自动取消 |
36
+
37
+ **清空会连同模型侧上下文一起丢弃**:除了把消息重置成开场问候,还会清掉
38
+ `localStorage` 里的会话身份,下次发送会新建一个会话,所以她不会记得清空前的对话。
39
+
40
+ ### 选择模型
41
+
42
+ 对话面板标题栏、**关闭按钮左边**有一个模型按钮,显示当前模型名(过长省略)。点击它
43
+ 弹出**模型选择弹窗**:顶部是检索框,下面是两级级联。
44
+
45
+ | 位置 | 内容 |
46
+ |---|---|
47
+ | 检索框 | 输入关键词即**跨所有供应商**过滤模型;大小写不敏感,匹配模型 ID 与显示名 |
48
+ | 左列:供应商 | DeepSeek 官方账号 / 官方 API / 其余供应商,按同一规则排序;带 `›` 表示可展开 |
49
+ | 右列:模型 | 选中供应商下的全部可用模型,当前选择带 `✓` |
50
+
51
+ - 检索时左列收起,右列变成**一列匹配结果**并标出来源;清空关键词后恢复级联,
52
+ 回到上次展开的供应商。
53
+ - 检索框中 <kbd>Enter</kbd> 选中第一条匹配;<kbd>Esc</kbd> 先清空关键词,
54
+ 再按一次才关闭弹窗;无匹配时显示「没有匹配的模型」和模型总数。
55
+ - 左列切换只改右列内容,不影响已选;**点右列某个模型即选中并关闭弹窗**。
56
+ - 打开弹窗时自动聚焦检索框,并定位到当前模型所在的供应商;点弹窗外部只收起弹窗,
57
+ 对话面板保留。
58
+ - 数据来自客户端远端 `ctx.remote.session.modelCatalog()`;`routableProviders` 之外、
59
+ 暂时没有可用模型的供应商不会出现,单个供应商加载失败也不影响其他项。
60
+ - 选择记在 `localStorage`(`dsh.deepseek-pet.chat.model`,键为 `provider::model`)。
61
+ 重开面板会重新拉一次目录;记住的模型不在目录里时自动回退到第一个并写回存储。
62
+ - 目录读取中 / 失败 / 为空时按钮禁用;**没有可选模型时发送会被拦下**并给出提示,
63
+ 而不把消息挂住。
64
+
65
+ **回复已接通。** 发送走 `ctx.remote.session` 的四个方法:
66
+
67
+ 1. `create({ sessionId, agentPreset: 'pet' })`:第一次发送时建一个**专供宠物对话的会话**,
68
+ 身份是随机生成的 `pet-chat-*`,记在 `localStorage`(`dsh.deepseek-pet.chat.sessionId`)。
69
+ 同一身份下已有空白会话会被 Host 复用,所以刷新页面后还能接着聊,也不会每句话新建会话。
70
+ 人设标记记在 `dsh.deepseek-pet.chat.preset`,**人设版本变了会自动换新会话**,
71
+ 不会接着旧上下文人设聊。
72
+ 2. `selectModel({ sessionId, provider, model })`:把该会话固定到弹窗里选的模型。
73
+ 3. `state({ sessionId })`:读当前游标 `cursor`,作为本轮回复的起点。
74
+ 4. `prompt({ requestId, sessionId, mode: 'queue', content: [{ type: 'text', text }] })`
75
+ 发消息,再 `wait({ sessionId, afterSeq, maxMessages: 1, timeoutMs })` 等本轮静默,
76
+ 从返回的 `output.records` 里挑 `assistant/message` 事件,取
77
+ `event.data.message.content` 中 `type === 'text'` 的块拼出回复。
78
+
79
+ 失败时面板会显示具体原因:发送被拒、等太久(`chatErrTimeout`,默认 120 秒)、
80
+ 模型在等你在应用里确认(`chatErrPending`)、模型没给文字(`chatErrEmptyReply`)。
81
+ 失败时输入框原文会被放回,方便重试。
82
+
83
+ 消息本身不落盘,刷新页面后清空;问候语只在会话里显示,不会作为上下文发给模型。
84
+ 会话建好后第二轮起不再重复 `create`,也不再重新 `selectModel`。
85
+
86
+ **宠物会话和一个普通会话一样出现在左侧列表。** 这是刻意的:侧栏的删除类插件
87
+ (如 `dsh-session-clean`)只能操作侧栏里看得见的会话,藏起来就等于删不掉。配合要点:
88
+
89
+ - 会话 id 用 `session-<uuid>` 格式,与 Host 自己生成的一致,格式校验类插件才认;
90
+ - 每轮回复读完**之后**调一次 `session.rename({ sessionId, title })`,把标题改成
91
+ 「大肥鱼对话」,在侧栏里一眼能认出来并随时删除;
92
+ - 同一会话只改名一次,失败(返回 `ok: false` 或抛错)会清标记,下一轮重试;
93
+ - 改名失败不影响聊天本身。
94
+
95
+ **不要再给宠物会话做归档。** 实测 Host 的 `session/create` 只复用「空白」会话,
96
+ 而 `reusable` 判定还把已归档的会话排除在外;一旦归档,刷新页面后 `create` 会另起新会话,
97
+ 之前的上下文就丢了。所以现在只在**没有历史身份**时才 `create`,已有身份直接
98
+ `selectModel` + `prompt`——这两者都会由 Host 自动恢复会话并带上完整历史。
99
+
21
100
  ## 右键菜单:AI 中转站配置
22
101
 
23
102
  右键宠物(浏览器原生菜单已被屏蔽),选择 **模型与供应商配置**。这个对话框会把
@@ -142,10 +221,10 @@ Host 半区通过 `ctx.connection.fetch.register` 注册了三个认证路由
142
221
  | 文件 | 用途 |
143
222
  |---|---|
144
223
  | `package.json` | bundle 清单:补丁、客户端入口、语言包与图标导出 |
145
- | `cordis.patch.yml` | 插入 `deepseek-pet` 的 Host 条目 |
224
+ | `cordis.patch.yml` | 插入 `deepseek-pet` 的 Host 条目,以及桌宠对话人设预设 `preset-pet` |
146
225
  | `index.js` | Host 半区:OpenCode 监控认证路由与只写密钥存储 |
147
226
  | `monitor.js` | Host 监控核心:抓取模型、解析文档/配额、差异引擎、原子快照 |
148
- | `client.js` | 客户端模块:插槽注册、精灵动画、拖动/摸头、右键中转站配置与 OpenCode 监控界面、文案 |
227
+ | `client.js` | 客户端模块:插槽注册、精灵动画、拖动/摸头、双击对话面板、右键中转站配置与 OpenCode 监控界面、文案 |
149
228
  | `assets/pet-sheet.webp` | 6×3 打包精灵图集(待机 / 挥手 / 蹦跳) |
150
229
  | `locale/en.json`、`locale/zh.json` | 插件清单里显示的标题与描述(英文 / 中文) |
151
230
  | `icon.png` | 插件图标,取自同一套角色画稿 |