dsh-pet-live2d 2.1.0 → 2.2.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/CHANGELOG.md +21 -0
- package/README.md +18 -2
- package/lib/index.js +76 -13
- package/package.json +1 -1
- package/pets/ds-whale-girl/pet.json +16 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# 更新日志
|
|
2
2
|
|
|
3
|
+
## 2.2.0
|
|
4
|
+
|
|
5
|
+
### 多接三个会话状态(对着 DSH 0.1.7 的事件表挑的)
|
|
6
|
+
|
|
7
|
+
0.1.7 里能订阅的事件有 100 个,但只有一部分能翻译成"宠物该演什么"。挑的标准是
|
|
8
|
+
**它填的是不是一个真实的空档**:
|
|
9
|
+
|
|
10
|
+
| 新相位 | 来自 | 以前的样子 |
|
|
11
|
+
|---|---|---|
|
|
12
|
+
| `asking` | `user-questions/request` | 它问你问题、等你回答的整段时间里,宠物还在演"干活" —— 最大的一个空档 |
|
|
13
|
+
| `helper` | `subagent/start` / `subagent/end` | 子代理是**长活**(几分钟),和一次普通工具调用混在一起看不出区别 |
|
|
14
|
+
| `queued` | `agent/inbox/inserted` | 你发的话在它忙的时候排队,宠物毫无反应 |
|
|
15
|
+
|
|
16
|
+
`asking` 挂的是 waterfall:链一直挂到你答完才 resume,所以这个相位**正好**等于"卡在等你"
|
|
17
|
+
的那一段,不用自己计时。`queued` 是短促反应(1.6 秒),回落到**排队前那个相位**而不是
|
|
18
|
+
一律回 idle —— 否则一个正在跑工具的回合看起来像停了。
|
|
19
|
+
|
|
20
|
+
**没接的**(评估过,理由写在 `lib/index.js` 的注释里):`fs/write-intent` / `edit-intent`
|
|
21
|
+
(tool 相位已经演「写本本」了,再拆一个 editing 和它重复)、`workflow/*`(工作流本身就是
|
|
22
|
+
工具调用,已被 tool 覆盖)、`agent/status`(只有 idle / running 两个值,给不出更细的)。
|
|
23
|
+
|
|
3
24
|
## 2.1.0
|
|
4
25
|
|
|
5
26
|
### 会话相位改成真正的"接管"
|
package/README.md
CHANGED
|
@@ -74,8 +74,24 @@ dsh plugin --profile web add "link:./dsh-pet-live2d/dsh-live2d-pet"
|
|
|
74
74
|
|
|
75
75
|
### 会话相位:同一套池子
|
|
76
76
|
|
|
77
|
-
|
|
78
|
-
|
|
77
|
+
每个会话相位下面是"槽位 → 条目表",机制和摸鱼一样。**宠物跟着 DSH 的真实事件换相位**:
|
|
78
|
+
|
|
79
|
+
| 相位 | 什么时候 | 这只宠物演什么 |
|
|
80
|
+
|---|---|---|
|
|
81
|
+
| `thinking` | 模型在想 / 刚开工 | 抬头看 |
|
|
82
|
+
| `tool` | 调工具(detail 带工具名) | 写本本 + 流汗 |
|
|
83
|
+
| `waiting` | 有操作**等你批准** | 问号 |
|
|
84
|
+
| `asking` | 它**问了你一个问题**、在等你回答 | 举手 + 问号 |
|
|
85
|
+
| `helper` | 起了**子代理**(一段长活) | 喵喵手 + 调皮 |
|
|
86
|
+
| `queued` | 你发的话**排队**了(它还在忙) | 感叹号(短促一下) |
|
|
87
|
+
| `done` | 这一轮说完(庆祝 3.5 秒) | 开心 + 情绪花花 |
|
|
88
|
+
| `failed` | 出错了 | 大哭 + 流汗 |
|
|
89
|
+
|
|
90
|
+
来源是 `agent/status`、`tools/pre-execute|post-execute`、`approval/request`、
|
|
91
|
+
`user-questions/request`、`subagent/start|end`、`agent/inbox/inserted`、
|
|
92
|
+
`agent/turn-stopping`、`agent/error` —— 按主题折成上面这几个相位。
|
|
93
|
+
|
|
94
|
+
相位表**一开始就列出全部相位**,显示的是**有效池子**:
|
|
79
95
|
|
|
80
96
|
| 行头标记 | 含义 | 那一行有什么 |
|
|
81
97
|
|---|---|---|
|
package/lib/index.js
CHANGED
|
@@ -803,11 +803,16 @@ function runtimeRoute() {
|
|
|
803
803
|
// comment frame.
|
|
804
804
|
|
|
805
805
|
/** The activity phases the browser half understands. */
|
|
806
|
-
export const ACTIVITY_PHASES = [
|
|
806
|
+
export const ACTIVITY_PHASES = [
|
|
807
|
+
'idle', 'thinking', 'waiting', 'asking', 'tool', 'helper', 'queued', 'done', 'failed',
|
|
808
|
+
]
|
|
807
809
|
|
|
808
810
|
/** How long the 'done' celebration is held before falling back to idle. */
|
|
809
811
|
const DONE_HOLD_MS = 3500
|
|
810
812
|
|
|
813
|
+
/** "你的消息排队了"给一个短促的收到反应,然后回到原来在演的东西。 */
|
|
814
|
+
const QUEUED_HOLD_MS = 1600
|
|
815
|
+
|
|
811
816
|
/** SSE keep-alive interval. */
|
|
812
817
|
const SSE_PING_MS = 30000
|
|
813
818
|
|
|
@@ -820,7 +825,7 @@ export class ActivityHub {
|
|
|
820
825
|
this.phase = 'idle'
|
|
821
826
|
this.detail = ''
|
|
822
827
|
this.listeners = new Set()
|
|
823
|
-
this.
|
|
828
|
+
this.holdTimer = undefined
|
|
824
829
|
}
|
|
825
830
|
|
|
826
831
|
/** Current snapshot (sent as the first frame of every stream). */
|
|
@@ -841,19 +846,30 @@ export class ActivityHub {
|
|
|
841
846
|
this.emit()
|
|
842
847
|
}
|
|
843
848
|
|
|
849
|
+
/**
|
|
850
|
+
* 演一个**短促反应**相位,过一会儿自动回落到 `fallback`。
|
|
851
|
+
*
|
|
852
|
+
* `done`(庆祝)和 `queued`(收到你排队的消息)都是这一类:宠物演一下,然后回到
|
|
853
|
+
* 它该在的地方。回落之前会确认相位没被别人接管 —— 这段时间里工具开始了、或者
|
|
854
|
+
* 新一轮说话了,就不要再把它拽回旧的 fallback。
|
|
855
|
+
*/
|
|
856
|
+
hold(phase, ms, fallback = 'idle') {
|
|
857
|
+
if (this.holdTimer !== undefined) clearTimeout(this.holdTimer)
|
|
858
|
+
this.set(phase, '')
|
|
859
|
+
this.holdTimer = setTimeout(() => {
|
|
860
|
+
this.holdTimer = undefined
|
|
861
|
+
if (this.phase === phase) this.set(fallback, '')
|
|
862
|
+
}, ms)
|
|
863
|
+
// Keep the process free to exit; the timer is purely cosmetic.
|
|
864
|
+
this.holdTimer?.unref?.()
|
|
865
|
+
}
|
|
866
|
+
|
|
844
867
|
/**
|
|
845
868
|
* Enter the 'done' celebration and fall back to idle after a hold, so the
|
|
846
869
|
* pet visibly finishes a turn instead of snapping straight back.
|
|
847
870
|
*/
|
|
848
871
|
celebrate() {
|
|
849
|
-
|
|
850
|
-
this.set('done', '')
|
|
851
|
-
this.doneTimer = setTimeout(() => {
|
|
852
|
-
this.doneTimer = undefined
|
|
853
|
-
this.set('idle', '')
|
|
854
|
-
}, DONE_HOLD_MS)
|
|
855
|
-
// Keep the process free to exit; the timer is purely cosmetic.
|
|
856
|
-
this.doneTimer?.unref?.()
|
|
872
|
+
this.hold('done', DONE_HOLD_MS, 'idle')
|
|
857
873
|
}
|
|
858
874
|
|
|
859
875
|
emit() {
|
|
@@ -868,9 +884,9 @@ export class ActivityHub {
|
|
|
868
884
|
}
|
|
869
885
|
|
|
870
886
|
dispose() {
|
|
871
|
-
if (this.
|
|
872
|
-
clearTimeout(this.
|
|
873
|
-
this.
|
|
887
|
+
if (this.holdTimer !== undefined) {
|
|
888
|
+
clearTimeout(this.holdTimer)
|
|
889
|
+
this.holdTimer = undefined
|
|
874
890
|
}
|
|
875
891
|
this.listeners.clear()
|
|
876
892
|
}
|
|
@@ -958,6 +974,53 @@ export function attachActivityEvents(ctx, hub) {
|
|
|
958
974
|
}, TOOL_IDLE_MS)
|
|
959
975
|
return next()
|
|
960
976
|
})
|
|
977
|
+
|
|
978
|
+
// ---- DSH 0.1.7 里另外三个值得接的状态 --------------------------------------
|
|
979
|
+
//
|
|
980
|
+
// 事件词汇表在 0.1.7 里已经不小(`*.d.ts` 里声明了 100 个可订阅事件),但只有一部分
|
|
981
|
+
// 能翻译成"宠物该演什么"。挑的标准是**它填的是不是一个真实的空档**:
|
|
982
|
+
//
|
|
983
|
+
// asking ← user-questions/request:以前"在等你回答问题"这段时间宠物还在演"干活",
|
|
984
|
+
// 看着像它没停过 ✗ —— 这是最大的一个空档;
|
|
985
|
+
// helper ← subagent/start|end:子代理是**长活**(几分钟),和一次普通工具调用
|
|
986
|
+
// 混在一起看不出区别;
|
|
987
|
+
// queued ← agent/inbox/inserted:你发的话在它忙的时候插进来,现在至少给个"收到"。
|
|
988
|
+
//
|
|
989
|
+
// 没接的(评估过,不值得):`fs/write-intent` / `edit-intent` —— 宠物在 tool 相位已经
|
|
990
|
+
// 演「写本本」了,再拆一个 editing 和它重复;`workflow/*` —— 工作流本身是工具调用,
|
|
991
|
+
// 已被 tool 覆盖(`workflow/phase` 的标题倒是可以当 detail,但宠物目前不显示 detail);
|
|
992
|
+
// `agent/status` 只有 idle / running 两个值,给不出更细的东西。
|
|
993
|
+
|
|
994
|
+
// `user-questions/request` 是 waterfall:链一直挂到**你把问题答完**才 resume,所以
|
|
995
|
+
// 这个相位正好等于"卡在等你"的那段,不用自己计时。
|
|
996
|
+
onWaterfall('user-questions/request', (_request, next) => {
|
|
997
|
+
hub.set('asking', '')
|
|
998
|
+
const answered = typeof next === 'function' ? next() : undefined
|
|
999
|
+
const back = () => {
|
|
1000
|
+
if (hub.phase === 'asking') hub.set('thinking', '')
|
|
1001
|
+
}
|
|
1002
|
+
if (answered !== null && typeof answered?.then === 'function') {
|
|
1003
|
+
answered.then(back, back)
|
|
1004
|
+
return answered
|
|
1005
|
+
}
|
|
1006
|
+
back()
|
|
1007
|
+
return answered
|
|
1008
|
+
})
|
|
1009
|
+
on('subagent/start', (info) => {
|
|
1010
|
+
const label = typeof info?.name === 'string'
|
|
1011
|
+
? info.name
|
|
1012
|
+
: (typeof info?.label === 'string' ? info.label : '')
|
|
1013
|
+
hub.set('helper', label)
|
|
1014
|
+
})
|
|
1015
|
+
on('subagent/end', () => {
|
|
1016
|
+
if (hub.phase === 'helper') hub.set('thinking', '')
|
|
1017
|
+
})
|
|
1018
|
+
on('agent/inbox/inserted', () => {
|
|
1019
|
+
// 回到"刚才在演的那个"(可能是 tool / asking,也可能是 idle)——不要一律回 idle,
|
|
1020
|
+
// 那会让一个正在跑工具的回合看起来停了。
|
|
1021
|
+
const previous = hub.phase
|
|
1022
|
+
hub.hold('queued', QUEUED_HOLD_MS, previous === 'queued' ? 'thinking' : previous)
|
|
1023
|
+
})
|
|
961
1024
|
}
|
|
962
1025
|
|
|
963
1026
|
/** The activity stream + snapshot route. */
|
package/package.json
CHANGED
|
@@ -568,6 +568,22 @@
|
|
|
568
568
|
"lhand": "橡皮",
|
|
569
569
|
"symbol": "问号"
|
|
570
570
|
},
|
|
571
|
+
"asking": {
|
|
572
|
+
"whale": "头顶鲸",
|
|
573
|
+
"rhand": "双手比耶",
|
|
574
|
+
"mood": "开心兴奋",
|
|
575
|
+
"symbol": "问号"
|
|
576
|
+
},
|
|
577
|
+
"helper": {
|
|
578
|
+
"whale": "头顶鲸",
|
|
579
|
+
"rhand": "喵喵手",
|
|
580
|
+
"mood": "调皮"
|
|
581
|
+
},
|
|
582
|
+
"queued": {
|
|
583
|
+
"whale": "头顶鲸",
|
|
584
|
+
"mood": "开心兴奋",
|
|
585
|
+
"symbol": "感叹号"
|
|
586
|
+
},
|
|
571
587
|
"done": {
|
|
572
588
|
"whale": "头顶鲸",
|
|
573
589
|
"lhand": "橡皮",
|