@linxin666/dsh-pet 0.3.4 → 0.3.5

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.
@@ -360,14 +360,14 @@ export function PetSprite(props) {
360
360
  const statusBubble = feedback === null && sessionBubbles.length === 0
361
361
  ? snapshot?.bubble
362
362
  : undefined;
363
- // The display session's inner whisper (碎碎念) — short inner-voice copy
364
- // woken by the model's output. Instead of a second bubble of its own, a
365
- // fresh whisper takes over the display session's bubble (the stack top, or
366
- // the single status bubble) and re-tints it, so the pet never wears two
367
- // voices at once. Interaction feedback takes over the whole bubble area
368
- // while it plays, so whispers yield to it like status copy.
369
- const whisper = feedback === null ? snapshot?.whisper : undefined;
370
- const bubblePresent = feedback !== null || sessionBubbles.length > 0 || statusBubble !== undefined || whisper !== undefined;
363
+ // Each session's inner whisper (碎碎念) rides its own bubble — short
364
+ // inner-voice copy woken by that session's activity, never the model's or
365
+ // another session's. Instead of a second bubble of its own, a fresh
366
+ // whisper takes over its session's bubble and re-tints it, so the pet
367
+ // never wears two voices at once. Interaction feedback takes over the
368
+ // whole bubble area while it plays, so whispers yield to it like status
369
+ // copy.
370
+ const bubblePresent = feedback !== null || sessionBubbles.length > 0 || statusBubble !== undefined;
371
371
  const displayName = snapshot?.name ?? definition.displayName;
372
372
  // The host-served status decoration (M5, #567); absent = text-only bubbles.
373
373
  const decoration = snapshot?.decoration;
@@ -447,14 +447,13 @@ export function PetSprite(props) {
447
447
  }
448
448
  }
449
449
  props.onPet();
450
- }, role: "button", "aria-label": definition.displayName, children: props.visual }) }), props.hud, feedback !== null && (_jsx("div", { ref: bubbleRef, className: clsx(styles.bubble, feedback.kind === 'feed' ? styles.bubbleFeed : styles.bubblePet), children: feedback.text }, feedback.at)), feedback === null && (sessionBubbles.length > 0 || statusBubble !== undefined || whisper !== undefined) && (_jsxs("div", { ref: bubbleRef, className: styles.bubbleStack, onPointerEnter: () => setStackPeek(true), onPointerLeave: () => setStackPeek(false), children: [visibleSessions.map((session, index) => {
451
- // The whisper rides the display session's bubble the stack's
452
- // primary entry (DOM-first, rendered bottom-most by the reversed
453
- // column so it stays glued to the sprite when extras open above).
454
- // The key swap restarts the entrance animation so the mood change
455
- // reads as the bubble re-speaking.
456
- const speaksWhisper = index === 0 && whisper !== undefined;
457
- const bubble = (_jsxs("button", { type: "button", className: clsx(styles.bubble, styles.bubbleStatus, styles.bubbleClickable, speaksWhisper && styles.bubbleWhisper), title: props.t('pet.openSessionHint'), onClick: () => { props.onOpenSession(session.sessionId); }, children: [index === 0 && !speaksWhisper && decoration !== undefined && (_jsx(StatusOrnament, { decoration: decoration, phase: phase })), speaksWhisper ? whisper : session.bubble] }, speaksWhisper ? 'whisper:' + whisper : session.sessionId));
450
+ }, role: "button", "aria-label": definition.displayName, children: props.visual }) }), props.hud, feedback !== null && (_jsx("div", { ref: bubbleRef, className: clsx(styles.bubble, feedback.kind === 'feed' ? styles.bubbleFeed : styles.bubblePet), children: feedback.text }, feedback.at)), feedback === null && (sessionBubbles.length > 0 || statusBubble !== undefined) && (_jsxs("div", { ref: bubbleRef, className: styles.bubbleStack, onPointerEnter: () => setStackPeek(true), onPointerLeave: () => setStackPeek(false), children: [visibleSessions.map((session, index) => {
451
+ // A session's whisper rides ITS OWN bubble (the stack lead when
452
+ // the current session has one, any bubble when the stack is
453
+ // expanded). The key swap restarts the entrance animation so the
454
+ // mood change reads as the bubble re-speaking.
455
+ const speaksWhisper = session.whisper !== undefined;
456
+ const bubble = (_jsxs("button", { type: "button", className: clsx(styles.bubble, styles.bubbleStatus, styles.bubbleClickable, speaksWhisper && styles.bubbleWhisper), title: props.t('pet.openSessionHint'), onClick: () => { props.onOpenSession(session.sessionId); }, children: [index === 0 && !speaksWhisper && decoration !== undefined && (_jsx(StatusOrnament, { decoration: decoration, phase: phase })), session.whisper ?? session.bubble] }, speaksWhisper ? 'whisper:' + session.whisper : session.sessionId));
458
457
  // The primary bubble carries the '+N' badge while other sessions
459
458
  // hide behind it; the badge toggles the pinned (touch) expansion.
460
459
  if (index !== 0 || sessionBubbles.length <= 1)
@@ -467,7 +466,7 @@ export function PetSprite(props) {
467
466
  e.stopPropagation();
468
467
  setStackPinned(open => !open);
469
468
  }, children: stackOpen ? '×' : '+' + String(sessionBubbles.length - 1) })] }, "primary"));
470
- }), sessionBubbles.length === 0 && (statusBubble !== undefined || whisper !== undefined) && (_jsxs("div", { className: clsx(styles.bubble, styles.bubbleStatus, whisper !== undefined && styles.bubbleWhisper), role: "status", "aria-live": "polite", children: [whisper === undefined && decoration !== undefined && (_jsx(StatusOrnament, { decoration: decoration, phase: phase })), whisper ?? statusBubble] }, whisper === undefined ? 'status' : 'whisper:' + whisper))] })), hovered && dragRef.current === null && (_jsx("div", { ref: panelRef, className: clsx(styles.panel, panelAbove && styles.panelAbove), "data-placement": panelAbove ? 'above' : 'below', style: panelAbove && panelLift > 0
469
+ }), sessionBubbles.length === 0 && statusBubble !== undefined && (_jsxs("div", { className: clsx(styles.bubble, styles.bubbleStatus), role: "status", "aria-live": "polite", children: [decoration !== undefined && (_jsx(StatusOrnament, { decoration: decoration, phase: phase })), statusBubble] }, "status"))] })), hovered && dragRef.current === null && (_jsx("div", { ref: panelRef, className: clsx(styles.panel, panelAbove && styles.panelAbove), "data-placement": panelAbove ? 'above' : 'below', style: panelAbove && panelLift > 0
471
470
  ? { marginBottom: panelLift }
472
471
  : undefined, onPointerEnter: () => {
473
472
  // Reaching the panel (or its bridge) must cancel any hide timer
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAwB,aAAa,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAA;AA0EnI,wEAAwE;AACxE,eAAO,MAAM,MAAM,UAA2E,CAAA;AAE9F,qEAAqE;AACrE,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AACxE,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AACrD,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC7D,YAAY,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AACtF,YAAY,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AACpE,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAEnD,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,OAAO;QACf;;;;WAIG;QACH,aAAa,CAAC,EAAE;YAAE,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAAA;SAAE,CAAA;KAC1E;CACF;AAED;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CA+R9C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAwB,aAAa,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAA;AA4EnI,wEAAwE;AACxE,eAAO,MAAM,MAAM,UAA2E,CAAA;AAE9F,qEAAqE;AACrE,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AACxE,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AACrD,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC7D,YAAY,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AACtF,YAAY,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AACpE,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAEnD,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,OAAO;QACf;;;;WAIG;QACH,aAAa,CAAC,EAAE;YAAE,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAAA;SAAE,CAAA;KAC1E;CACF;AAED;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAgT9C"}
@@ -37,7 +37,8 @@ async function petFetch(path, body) {
37
37
  }
38
38
  /** The live host API instance (always defined; failures surface per call). */
39
39
  const petApi = {
40
- state: () => petFetch('/api/pet/state'),
40
+ state: (currentSessionId) => petFetch('/api/pet/state'
41
+ + (currentSessionId === undefined ? '' : '?current=' + encodeURIComponent(currentSessionId))),
41
42
  pets: () => petFetch('/api/pet/pets'),
42
43
  interact: (kind) => petFetch('/api/pet/interact', { kind }),
43
44
  setVisible: (visible) => petFetch('/api/pet/set-visible', { visible }),
@@ -142,6 +143,19 @@ export function apply(ctx) {
142
143
  const setPets = petStore.actions.setPets;
143
144
  const setState = petStore.actions.setState;
144
145
  const setFeedback = petStore.actions.setFeedback;
146
+ // Clicking a session bubble jumps the GUI to that session; the same
147
+ // sessions face reports which session the user is currently on, so the
148
+ // host can lead the bubble stack with it. A bubble can outlive its
149
+ // disposed session by one poll tick, and the sessions service fails
150
+ // loud on unknown ids, so consult the live list first. The pet's type
151
+ // program also loads the host-side dsh-session package through the
152
+ // service types, whose Context merge declares a different 'sessions'
153
+ // face; pin the browser runtime's outward face here.
154
+ const sessions = ctx.sessions;
155
+ const currentSessionId = () => {
156
+ const current = sessions.list.getSnapshot().current;
157
+ return current === undefined ? undefined : String(current);
158
+ };
145
159
  // The registry list is fetched lazily with retries baked into the poll
146
160
  // cycle: until it lands, the dock entry renders nothing and every 2s
147
161
  // tick tries again. After it lands, one list feeds both the sprite and
@@ -163,7 +177,7 @@ export function apply(ctx) {
163
177
  }
164
178
  const seq = stateSeq + 1;
165
179
  stateSeq = seq;
166
- petApi.state().then((snapshot) => {
180
+ petApi.state(currentSessionId()).then((snapshot) => {
167
181
  if (seq !== stateSeq)
168
182
  return;
169
183
  setSnapshot(snapshot);
@@ -207,13 +221,16 @@ export function apply(ctx) {
207
221
  document.removeEventListener('visibilitychange', onVisibility);
208
222
  };
209
223
  }, 'pet: poll');
210
- // Clicking a session bubble jumps the GUI to that session. A bubble
211
- // can outlive its disposed session by one poll tick, and the sessions
212
- // service fails loud on unknown ids, so consult the live list first.
213
- // The pet's type program also loads the host-side dsh-session package
214
- // through the service types, whose Context merge declares a different
215
- // 'sessions' face; pin the browser runtime's outward face here.
216
- const sessions = ctx.sessions;
224
+ // A current-session switch should re-order the bubble stack right away,
225
+ // not on the next 2s tick. Poll only while the tab is visible, as the
226
+ // poll loop itself does.
227
+ const disposeSessionWatch = ctx.effect(() => {
228
+ const unsubscribe = sessions.list.subscribe(() => {
229
+ if (document.visibilityState === 'visible')
230
+ pollNow();
231
+ });
232
+ return unsubscribe;
233
+ }, 'pet: current-session watch');
217
234
  const openSession = (sessionId) => {
218
235
  const list = sessions.list.getSnapshot();
219
236
  if (list.byId[sessionId] === undefined)
@@ -5,8 +5,11 @@
5
5
  * {@link ProjectionRuntime} per session and feed events in arrival order.
6
6
  *
7
7
  * Status copy comes from the chatter voice (big rotating pools, per-tool
8
- * families, real-argument hints), and streamed model output feeds the murmur
9
- * engine so the pet can whisper its inner voice (碎碎念). The wall clock is
8
+ * families, real-argument hints), and the projection feeds the murmur engine
9
+ * (碎碎念) with the SITUATION thinking/writing during the stream, the
10
+ * running tool family on tool calls, and the STRUCTURED outcome on
11
+ * tool/result and turn/end — so the pet's inner voice always roughly knows
12
+ * what is going on and never mis-fires on output text. The wall clock is
10
13
  * injected by the caller, keeping every projection reproducible.
11
14
  * @module @linxin666/dsh-pet/event-projection
12
15
  */
@@ -22,18 +25,20 @@ export interface ActivityStatusEventLike {
22
25
  /** Per-session facts needed to project the official event stream. */
23
26
  export interface ProjectionRuntime {
24
27
  activeTools: Set<string>;
28
+ /** callIds whose tool looked like a test run, marked at tool/call (pet M6). */
29
+ testCalls: Set<string>;
25
30
  officialEventsSeen: boolean;
26
31
  stepHadFailure: boolean;
27
32
  /** Round-robin status copy voice (scene-stable, cadence-rotated). */
28
33
  voice: StatusVoice;
29
- /** Inner-whisper engine fed by the model's own streamed output. */
34
+ /** Inner-whisper engine fed by the projection's situation and outcomes. */
30
35
  whispers: WhisperEngine;
31
36
  }
32
37
  /** One official event projection, optionally carrying a completed turn reward. */
33
38
  export interface PetActivityTransition {
34
39
  input: PetStateInput;
35
40
  completedTurn?: number;
36
- /** A fresh inner whisper woken by this event's model output, when any. */
41
+ /** A fresh inner whisper woken by this event, when any. */
37
42
  whisper?: string;
38
43
  }
39
44
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"event-projection.d.ts","sourceRoot":"","sources":["../../src/event-projection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC/C,OAAO,EAAE,WAAW,EAAe,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAE/F,2DAA2D;AAC3D,MAAM,WAAW,uBAAuB;IACtC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,qEAAqE;AACrE,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACxB,kBAAkB,EAAE,OAAO,CAAA;IAC3B,cAAc,EAAE,OAAO,CAAA;IACvB,qEAAqE;IACrE,KAAK,EAAE,WAAW,CAAA;IAClB,mEAAmE;IACnE,QAAQ,EAAE,aAAa,CAAA;CACxB;AAED,kFAAkF;AAClF,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,aAAa,CAAA;IACpB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,0EAA0E;IAC1E,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,CAAC,EAAE,kBAAkB,GAAG,iBAAiB,CAQpF;AAQD,wEAAwE;AACxE,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,aAAa,CAAC,OAAO,CAAC,CAE9E;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,YAAY,EACnB,OAAO,EAAE,iBAAiB,EAC1B,KAAK,GAAE,MAAmB,GACzB,qBAAqB,GAAG,SAAS,CAwFnC"}
1
+ {"version":3,"file":"event-projection.d.ts","sourceRoot":"","sources":["../../src/event-projection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC/C,OAAO,EACL,WAAW,EAGX,aAAa,EAGb,KAAK,kBAAkB,EACxB,MAAM,cAAc,CAAA;AAErB,2DAA2D;AAC3D,MAAM,WAAW,uBAAuB;IACtC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,qEAAqE;AACrE,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACxB,+EAA+E;IAC/E,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACtB,kBAAkB,EAAE,OAAO,CAAA;IAC3B,cAAc,EAAE,OAAO,CAAA;IACvB,qEAAqE;IACrE,KAAK,EAAE,WAAW,CAAA;IAClB,2EAA2E;IAC3E,QAAQ,EAAE,aAAa,CAAA;CACxB;AAED,kFAAkF;AAClF,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,aAAa,CAAA;IACpB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,CAAC,EAAE,kBAAkB,GAAG,iBAAiB,CASpF;AAQD,wEAAwE;AACxE,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,aAAa,CAAC,OAAO,CAAC,CAE9E;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,YAAY,EACnB,OAAO,EAAE,iBAAiB,EAC1B,KAAK,GAAE,MAAmB,GACzB,qBAAqB,GAAG,SAAS,CAmHnC"}
@@ -5,12 +5,15 @@
5
5
  * {@link ProjectionRuntime} per session and feed events in arrival order.
6
6
  *
7
7
  * Status copy comes from the chatter voice (big rotating pools, per-tool
8
- * families, real-argument hints), and streamed model output feeds the murmur
9
- * engine so the pet can whisper its inner voice (碎碎念). The wall clock is
8
+ * families, real-argument hints), and the projection feeds the murmur engine
9
+ * (碎碎念) with the SITUATION thinking/writing during the stream, the
10
+ * running tool family on tool calls, and the STRUCTURED outcome on
11
+ * tool/result and turn/end — so the pet's inner voice always roughly knows
12
+ * what is going on and never mis-fires on output text. The wall clock is
10
13
  * injected by the caller, keeping every projection reproducible.
11
14
  * @module @linxin666/dsh-pet/event-projection
12
15
  */
13
- import { StatusVoice, toolArgHint, WhisperEngine } from "./chatter.js";
16
+ import { StatusVoice, toolArgHint, toolCategory, WhisperEngine, whisperCategoryOf, looksLikeTestTool, } from "./chatter.js";
14
17
  /**
15
18
  * Fresh projection runtime for a newly seen session. The optional voice-pack
16
19
  * provider (pet-center M4, issue #677) hands both chatter engines their
@@ -20,6 +23,7 @@ import { StatusVoice, toolArgHint, WhisperEngine } from "./chatter.js";
20
23
  export function emptyProjectionRuntime(pools) {
21
24
  return {
22
25
  activeTools: new Set(),
26
+ testCalls: new Set(),
23
27
  officialEventsSeen: false,
24
28
  stepHadFailure: false,
25
29
  voice: new StatusVoice(pools),
@@ -44,6 +48,7 @@ export function projectOfficialEvent(event, runtime, nowMs = Date.now()) {
44
48
  switch (event.type) {
45
49
  case 'turn/start':
46
50
  runtime.activeTools.clear();
51
+ runtime.testCalls.clear();
47
52
  runtime.stepHadFailure = false;
48
53
  return { input: { phase: 'waiting', line: runtime.voice.scene('prepare', nowMs) } };
49
54
  case 'step/start':
@@ -53,14 +58,14 @@ export function projectOfficialEvent(event, runtime, nowMs = Date.now()) {
53
58
  case 'assistant/chunk': {
54
59
  const { chunk } = event.data;
55
60
  if (chunk.type === 'reasoning-delta' && chunk.text.length > 0) {
56
- const whisper = runtime.whispers.feed(chunk.text, nowMs);
61
+ const whisper = runtime.whispers.feed('thinking', nowMs);
57
62
  return {
58
63
  input: { phase: 'thinking', line: runtime.voice.scene('thinking', nowMs) },
59
64
  ...(whisper === undefined ? {} : { whisper }),
60
65
  };
61
66
  }
62
67
  if (chunk.type === 'text-delta' && chunk.text.length > 0) {
63
- const whisper = runtime.whispers.feed(chunk.text, nowMs);
68
+ const whisper = runtime.whispers.feed('writing', nowMs);
64
69
  return {
65
70
  input: { phase: 'review', line: runtime.voice.scene('review', nowMs) },
66
71
  ...(whisper === undefined ? {} : { whisper }),
@@ -70,40 +75,67 @@ export function projectOfficialEvent(event, runtime, nowMs = Date.now()) {
70
75
  }
71
76
  case 'assistant/message':
72
77
  return { input: { phase: 'review', line: runtime.voice.scene('review', nowMs) } };
73
- case 'tool/call':
74
- runtime.activeTools.add(String(event.data.callId));
78
+ case 'tool/call': {
79
+ const callId = String(event.data.callId);
80
+ runtime.activeTools.add(callId);
81
+ // A test-looking call is remembered so its result (the only place the
82
+ // outcome is known) can wake the test-green mood later.
83
+ if (looksLikeTestTool(event.data.name, event.data.arguments))
84
+ runtime.testCalls.add(callId);
85
+ const whisper = runtime.whispers.feed(whisperCategoryOf(toolCategory(event.data.name)), nowMs);
75
86
  return {
76
87
  input: {
77
88
  phase: 'tool',
78
89
  line: runtime.voice.tool(event.data.name, displayToolName(event.data.name), toolArgHint(event.data.name, event.data.arguments), nowMs),
79
90
  },
91
+ ...(whisper === undefined ? {} : { whisper }),
80
92
  };
93
+ }
81
94
  case 'tool/result': {
82
95
  const block = event.data.message.content[0];
83
- runtime.activeTools.delete(String(event.data.message.source.callId));
84
- runtime.stepHadFailure ||= event.data.error !== undefined || block.isError === true;
96
+ const callId = String(event.data.message.source.callId);
97
+ const failed = event.data.error !== undefined || block.isError === true;
98
+ const wasTest = runtime.testCalls.delete(callId);
99
+ runtime.activeTools.delete(callId);
100
+ runtime.stepHadFailure ||= failed;
101
+ const whisper = failed
102
+ ? runtime.whispers.result('fail', nowMs)
103
+ : wasTest
104
+ ? runtime.whispers.result('pass', nowMs)
105
+ : undefined;
106
+ const whisperSpread = whisper === undefined ? {} : { whisper };
85
107
  if (runtime.activeTools.size > 0) {
86
108
  return {
87
109
  input: {
88
110
  phase: 'tool',
89
111
  line: runtime.voice.toolRemaining(runtime.activeTools.size, nowMs),
90
112
  },
113
+ ...whisperSpread,
91
114
  };
92
115
  }
93
116
  return runtime.stepHadFailure
94
- ? { input: { phase: 'failed', line: runtime.voice.scene('toolFailed', nowMs) } }
95
- : { input: { phase: 'thinking', line: runtime.voice.scene('toolResult', nowMs) } };
117
+ ? { input: { phase: 'failed', line: runtime.voice.scene('toolFailed', nowMs) }, ...whisperSpread }
118
+ : { input: { phase: 'thinking', line: runtime.voice.scene('toolResult', nowMs) }, ...whisperSpread };
96
119
  }
97
120
  case 'turn/end': {
98
121
  runtime.activeTools.clear();
122
+ runtime.testCalls.clear();
99
123
  switch (event.data.reason.kind) {
100
- case 'completed':
124
+ case 'completed': {
125
+ const whisper = runtime.whispers.result('done', nowMs);
101
126
  return {
102
127
  input: { phase: 'done', line: runtime.voice.scene('done', nowMs) },
103
128
  completedTurn: event.data.turn,
129
+ ...(whisper === undefined ? {} : { whisper }),
130
+ };
131
+ }
132
+ case 'error': {
133
+ const whisper = runtime.whispers.result('fail', nowMs);
134
+ return {
135
+ input: { phase: 'failed', line: runtime.voice.scene('failed', nowMs) },
136
+ ...(whisper === undefined ? {} : { whisper }),
104
137
  };
105
- case 'error':
106
- return { input: { phase: 'failed', line: runtime.voice.scene('failed', nowMs) } };
138
+ }
107
139
  case 'max-tokens':
108
140
  return { input: { phase: 'failed', line: runtime.voice.scene('maxTokens', nowMs) } };
109
141
  case 'interrupted':
@@ -1 +1 @@
1
- {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAA;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAO9C,+CAA+C;AAC/C,eAAO,MAAM,cAAc,aAAa,CAAA;AAExC,0EAA0E;AAC1E,eAAO,MAAM,gBAAgB,SAAS,CAAA;AAMtC;;;;GAIG;AACH,eAAO,MAAM,cAAc;IACzB,yBAAyB;;IAEzB,iDAAiD;;IAEjD,8EAA8E;;CAEtE,CAAA;AAEV,6DAA6D;AAC7D,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd;AAWD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAUrF;AAwND,4EAA4E;AAC5E,eAAO,MAAM,kBAAkB,QAA8B,CAAA;AAe7D,4EAA4E;AAC5E,eAAO,MAAM,eAAe,QAAmB,CAAA;AAE/C,6EAA6E;AAC7E,MAAM,WAAW,eAAe;IAC9B,+EAA+E;IAC/E,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAwMD,4EAA4E;AAC5E,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAAE,OAAO,EAAE,UAAU,CAAC;IAAC,GAAG,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,YAAY,CAAA;CAAE,GAAG,eAAe,GAAG,QAAQ,EAAE,CA2EjI;AAGD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA"}
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAA;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAO9C,+CAA+C;AAC/C,eAAO,MAAM,cAAc,aAAa,CAAA;AAExC,0EAA0E;AAC1E,eAAO,MAAM,gBAAgB,SAAS,CAAA;AAMtC;;;;GAIG;AACH,eAAO,MAAM,cAAc;IACzB,yBAAyB;;IAEzB,iDAAiD;;IAEjD,8EAA8E;;CAEtE,CAAA;AAEV,6DAA6D;AAC7D,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd;AAWD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAUrF;AAwND,4EAA4E;AAC5E,eAAO,MAAM,kBAAkB,QAA8B,CAAA;AAe7D,4EAA4E;AAC5E,eAAO,MAAM,eAAe,QAAmB,CAAA;AAE/C,6EAA6E;AAC7E,MAAM,WAAW,eAAe;IAC9B,+EAA+E;IAC/E,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAwMD,4EAA4E;AAC5E,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAAE,OAAO,EAAE,UAAU,CAAC;IAAC,GAAG,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,YAAY,CAAA;CAAE,GAAG,eAAe,GAAG,QAAQ,EAAE,CAgFjI;AAGD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA"}
@@ -91,7 +91,7 @@ function guard(ctx, req, res) {
91
91
  writeJson(res, 403, { ok: false, error: 'forbidden: loopback-only' });
92
92
  return false;
93
93
  }
94
- /** Wrap one async service call as a GET JSON route. */
94
+ /** Wrap one async service call as a GET JSON route (request passed through for query params). */
95
95
  function getRoute(ctx, path, run) {
96
96
  return {
97
97
  kind: 'exact',
@@ -101,7 +101,7 @@ function getRoute(ctx, path, run) {
101
101
  return;
102
102
  if (!requireMethod(req, res, 'GET'))
103
103
  return;
104
- run().then((value) => writeJson(res, 200, value), (error) => {
104
+ run(req).then((value) => writeJson(res, 200, value), (error) => {
105
105
  writeJson(res, 500, { ok: false, error: error instanceof Error ? error.message : String(error) });
106
106
  });
107
107
  },
@@ -506,7 +506,12 @@ function decorationHandler(ctx, registry, caps) {
506
506
  export function makePetRoutes(deps) {
507
507
  const { service, ctx } = deps;
508
508
  const apiRoutes = [
509
- getRoute(ctx, PET_API_PREFIX + '/state', () => service.state()),
509
+ getRoute(ctx, PET_API_PREFIX + '/state', (req) => {
510
+ // The browser half reports the GUI's current session id so the bubble
511
+ // stack can lead with the session the user is actually looking at.
512
+ const current = new URL(req.url ?? '/', 'http://pet.local').searchParams.get('current');
513
+ return service.state(current === null || current === '' ? undefined : current);
514
+ }),
510
515
  getRoute(ctx, PET_API_PREFIX + '/pets', () => service.pets()),
511
516
  getRoute(ctx, PET_API_PREFIX + '/diagnostics', () => service.diagnostics()),
512
517
  postRoute(ctx, PET_API_PREFIX + '/interact', (body) => {
@@ -83,6 +83,8 @@ export interface PetSessionView {
83
83
  bubble: string;
84
84
  /** This session's raw activity phase. */
85
85
  phase: PetStateSnapshot['phase'];
86
+ /** This session's fresh inner whisper (碎碎念), when one is within its TTL. */
87
+ whisper?: string;
86
88
  }
87
89
  /** Hard cap on simultaneously displayed session bubbles (most recent first). */
88
90
  export declare const MAX_SESSION_BUBBLES = 12;
@@ -93,10 +95,10 @@ export interface PetStateView {
93
95
  phase: PetStateSnapshot['phase'];
94
96
  sessionActive: boolean;
95
97
  /**
96
- * Per-session bubbles for every concurrently active TOP-LEVEL session,
97
- * most recent first; optional so older hosts without the multi-session
98
- * view stay consumable. The single 'bubble' above mirrors the display
99
- * session.
98
+ * Per-session bubbles for every concurrently active TOP-LEVEL session:
99
+ * the GUI's current session first when reported, the rest most recently
100
+ * active first; optional so older hosts without the multi-session view
101
+ * stay consumable. The single 'bubble' above mirrors the display session.
100
102
  */
101
103
  sessions?: PetSessionView[];
102
104
  /** Affinity ledger snapshot. */
@@ -121,12 +123,6 @@ export interface PetStateView {
121
123
  /** Stock cap. */
122
124
  max: number;
123
125
  };
124
- /**
125
- * The display session's fresh inner whisper (碎碎念), when one is within
126
- * its TTL — short inner-voice copy woken by the model's own output,
127
- * rendered by the client as a distinct whisper bubble.
128
- */
129
- whisper?: string;
130
126
  /**
131
127
  * The active status decoration (pet-center M5, #567), when the master
132
128
  * switch is on and the default decoration entry exists. Absent means the
@@ -218,7 +214,7 @@ export declare class PetService extends Service {
218
214
  /** Whether the pet service consumes session activity while enabled. */
219
215
  isEnabled(): boolean;
220
216
  /** RPC: current pet state snapshot. */
221
- state(): Promise<PetStateView>;
217
+ state(currentSessionId?: string): Promise<PetStateView>;
222
218
  /** Current persisted display config (read-only view). */
223
219
  display(): PetDisplayConfig;
224
220
  /** RPC: the registry entries the browser half renders and selects from. */
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/service.ts"],"names":[],"mappings":"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"}
@@ -114,8 +114,8 @@ export class PetService extends Service {
114
114
  return this.enabled;
115
115
  }
116
116
  /** RPC: current pet state snapshot. */
117
- async state() {
118
- return this.view();
117
+ async state(currentSessionId) {
118
+ return this.view(currentSessionId);
119
119
  }
120
120
  /** Current persisted display config (read-only view). */
121
121
  display() {
@@ -547,15 +547,17 @@ export class PetService extends Service {
547
547
  if (this.ledger.rewardLegacyTurn(Date.now()))
548
548
  this.flush();
549
549
  }
550
- view() {
550
+ view(currentSessionId) {
551
551
  const snapshot = this.machine.render();
552
552
  const entry = this.activeEntry();
553
- // One bubble per concurrently active TOP-LEVEL session, most recent
554
- // first. Subagent children render no bubble of their own (their activity
555
- // already shows through the spawning conversation's bubble/display, and
556
- // the bubble buttons navigate to GUI sessions, which subagents are not).
557
- // Sessions whose own machine has settled (no bubble copy) drop out, so a
558
- // finished turn does not leave a stale bubble behind.
553
+ // One bubble per concurrently active TOP-LEVEL session. The GUI's current
554
+ // session leads the stack when reported (the browser half passes its
555
+ // session list's 'current'); everything else keeps the most recent
556
+ // meaningful event order. Subagent children render no bubble of their own
557
+ // (their activity already shows through the spawning conversation's
558
+ // bubble/display, and the bubble buttons navigate to GUI sessions, which
559
+ // subagents are not). Sessions whose own machine has settled (no bubble
560
+ // copy) drop out, so a finished turn does not leave a stale bubble behind.
559
561
  const sessions = [];
560
562
  for (const [session, activity] of [...this.sessionActivity.entries()].reverse()) {
561
563
  if (sessions.length >= MAX_SESSION_BUBBLES)
@@ -565,22 +567,29 @@ export class PetService extends Service {
565
567
  const perSession = activity.machine.render();
566
568
  if (perSession.bubble === undefined)
567
569
  continue;
570
+ // Each session's whisper rides its own bubble while fresh; an expired
571
+ // whisper simply stops appearing (the client's 2 s poll drops it).
572
+ const whisper = activity.whisper;
573
+ const freshWhisper = whisper !== undefined && Date.now() - whisper.at < WHISPER_TTL_MS
574
+ ? whisper.text
575
+ : undefined;
568
576
  sessions.push({
569
577
  sessionId: String(session.id),
570
578
  animation: perSession.animation,
571
579
  bubble: perSession.bubble,
572
580
  phase: perSession.phase,
581
+ ...(freshWhisper === undefined ? {} : { whisper: freshWhisper }),
573
582
  });
574
583
  }
575
- // The display session's inner whisper rides the global view while fresh;
576
- // an expired whisper simply stops appearing (the client's 2s poll drops it).
577
- const displayActivity = this.displaySession === undefined
578
- ? undefined
579
- : this.sessionActivity.get(this.displaySession);
580
- const whisper = displayActivity?.whisper;
581
- const freshWhisper = whisper !== undefined && Date.now() - whisper.at < WHISPER_TTL_MS
582
- ? whisper.text
583
- : undefined;
584
+ // The browser half reports the session the user is currently on; that
585
+ // session's bubble leads the stack (its whisper then speaks on the
586
+ // collapsed single bubble). An unreported or absent session keeps the
587
+ // legacy most-recent-first order.
588
+ if (currentSessionId !== undefined) {
589
+ const index = sessions.findIndex(session => session.sessionId === currentSessionId);
590
+ if (index > 0)
591
+ sessions.unshift(sessions.splice(index, 1)[0]);
592
+ }
584
593
  const decoration = this.activeDecoration();
585
594
  // Gameplay view: a read-only projection. The settle runs on a copy, so
586
595
  // polling never writes pet.json (verbs settle and persist).
@@ -599,7 +608,6 @@ export class PetService extends Service {
599
608
  phase: snapshot.phase,
600
609
  sessionActive: snapshot.sessionActive,
601
610
  sessions,
602
- ...(freshWhisper === undefined ? {} : { whisper: freshWhisper }),
603
611
  ...(decoration === undefined ? {} : { decoration }),
604
612
  affinity: this.ledger.affinityView(Date.now()),
605
613
  display: { ...this.ledger.snapshot.display },
@@ -27,7 +27,7 @@
27
27
  * TypeScript mode: keep it erasable-syntax-only.
28
28
  * @module @linxin666/dsh-pet/voice-pack
29
29
  */
30
- import { type VoicePackOverrides, type WhisperRule } from './chatter.ts';
30
+ import { type VoicePackOverrides, type WhisperCategory, type WhisperResult } from './chatter.ts';
31
31
  /** Schema version this module normalizes (optional field; missing = 1). */
32
32
  export declare const VOICE_PACK_V1: 1;
33
33
  /** Hover-panel action buttons a pack can show or hide (canonical order). */
@@ -58,12 +58,9 @@ export interface VoicePack {
58
58
  /** Hard caps shared by every pool slot (mirrors the remarks discipline). */
59
59
  export declare const VOICE_POOL_LINES_MAX = 64;
60
60
  export declare const VOICE_LINE_MAX = 160;
61
- export declare const VOICE_KEYWORDS_PER_RULE_MAX = 16;
62
- export declare const VOICE_KEYWORD_MAX = 40;
63
- export declare const VOICE_RULES_MAX = 32;
64
61
  export declare const VOICE_LABEL_MAX = 40;
65
62
  export declare const VOICE_STAT_MAX = 80;
66
- type PoolKind = 'status' | 'tools' | 'toolRemaining' | 'whisperGeneric' | 'whisperRule' | 'label' | 'stat';
63
+ type PoolKind = 'status' | 'tools' | 'toolRemaining' | 'whisperCategory' | 'whisperResult' | 'label' | 'stat';
67
64
  /**
68
65
  * Normalize one pool slot. Accepts a single line or an array; non-string
69
66
  * entries warn and drop, empty lines drop silently, lines over the length
@@ -73,8 +70,10 @@ type PoolKind = 'status' | 'tools' | 'toolRemaining' | 'whisperGeneric' | 'whisp
73
70
  * undefined (the slot keeps the built-in pool).
74
71
  */
75
72
  export declare function normalizePool(raw: unknown, kind: PoolKind, onWarning?: (message: string) => void): string[] | undefined;
76
- /** Normalize the ordered keyword-rule list ([] disables the keyword channel). */
77
- export declare function normalizeWhisperRules(raw: unknown, onWarning?: (message: string) => void): WhisperRule[] | undefined;
73
+ /** Normalize whisper category pools; a key replaces that category's built-in pool (an explicit empty pool mutes it). */
74
+ export declare function normalizeWhisperCategories(raw: unknown, onWarning?: (message: string) => void): Partial<Record<WhisperCategory, readonly string[]>> | undefined;
75
+ /** Normalize whisper outcome pools; a key replaces that outcome's built-in pool (an explicit empty pool mutes it). */
76
+ export declare function normalizeWhisperResults(raw: unknown, onWarning?: (message: string) => void): Partial<Record<WhisperResult, readonly string[]>> | undefined;
78
77
  /** Normalize the panel block (labels / stats / actions; warn-and-drop). */
79
78
  export declare function normalizePanel(raw: unknown, onWarning?: (message: string) => void): PetPanelView | undefined;
80
79
  /** Voice-pack top-level fields ('$schema' mirrors the schema twin; drift-locked in tests). */
@@ -1 +1 @@
1
- {"version":3,"file":"voice-pack.d.ts","sourceRoot":"","sources":["../../src/voice-pack.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAGL,KAAK,kBAAkB,EACvB,KAAK,WAAW,EACjB,MAAM,cAAc,CAAA;AAErB,2EAA2E;AAC3E,eAAO,MAAM,aAAa,EAAG,CAAU,CAAA;AAEvC,4EAA4E;AAC5E,eAAO,MAAM,aAAa,qCAAsC,CAAA;AAChE,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAA;AAExD,8EAA8E;AAC9E,eAAO,MAAM,gBAAgB,gDAAiD,CAAA;AAC9E,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAA;AAE7D,0EAA0E;AAC1E,eAAO,MAAM,eAAe,uCAAwC,CAAA;AACpE,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAA;AAE3D,+DAA+D;AAC/D,MAAM,WAAW,YAAY;IAC3B,wEAAwE;IACxE,MAAM,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAA;IAC/C,oEAAoE;IACpE,KAAK,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAA;IAC7C,2EAA2E;IAC3E,OAAO,CAAC,EAAE,WAAW,EAAE,CAAA;CACxB;AAED,6EAA6E;AAC7E,MAAM,WAAW,SAAS;IACxB,yEAAyE;IACzE,SAAS,EAAE,kBAAkB,CAAA;IAC7B,sDAAsD;IACtD,KAAK,CAAC,EAAE,YAAY,CAAA;CACrB;AAED,4EAA4E;AAC5E,eAAO,MAAM,oBAAoB,KAAK,CAAA;AACtC,eAAO,MAAM,cAAc,MAAM,CAAA;AACjC,eAAO,MAAM,2BAA2B,KAAK,CAAA;AAC7C,eAAO,MAAM,iBAAiB,KAAK,CAAA;AACnC,eAAO,MAAM,eAAe,KAAK,CAAA;AACjC,eAAO,MAAM,eAAe,KAAK,CAAA;AACjC,eAAO,MAAM,cAAc,KAAK,CAAA;AAYhC,KAAK,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,eAAe,GAAG,gBAAgB,GAAG,aAAa,GAAG,OAAO,GAAG,MAAM,CAAA;AA8B1G;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,OAAO,EACZ,IAAI,EAAE,QAAQ,EACd,SAAS,GAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAe,GAC9C,MAAM,EAAE,GAAG,SAAS,CAoBtB;AAED,iFAAiF;AACjF,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,OAAO,EACZ,SAAS,GAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAe,GAC9C,WAAW,EAAE,GAAG,SAAS,CAyC3B;AAED,2EAA2E;AAC3E,wBAAgB,cAAc,CAC5B,GAAG,EAAE,OAAO,EACZ,SAAS,GAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAe,GAC9C,YAAY,GAAG,SAAS,CA+D1B;AAED,8FAA8F;AAC9F,eAAO,MAAM,eAAe,aAAoG,CAAA;AAEhI,8DAA8D;AAC9D,eAAO,MAAM,YAAY,aAAgC,CAAA;AAEzD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,OAAO,EACZ,SAAS,GAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAe,GAC9C,SAAS,GAAG,SAAS,CAmFvB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,MAAM,EAAE,CAAC,SAAS,GAAG,SAAS,CAAC,EAAE,GAAG,SAAS,GAAG,SAAS,CAsC3F"}
1
+ {"version":3,"file":"voice-pack.d.ts","sourceRoot":"","sources":["../../src/voice-pack.ts"],"names":[],"mappings":"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"}