@flowingspring/dsh-voco 0.3.7 → 0.3.8

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.
@@ -72,6 +72,9 @@ var LocalSession = class {
72
72
  async start() {
73
73
  await this.backend.start((event) => this.receive(event));
74
74
  }
75
+ beginManualUtterance() {
76
+ this.backend.beginManualUtterance();
77
+ }
75
78
  appendAudio(audio) {
76
79
  this.backend.appendAudio(audio);
77
80
  }
@@ -314,6 +317,8 @@ var NodeSpeechBackend = class {
314
317
  preRoll = [];
315
318
  preRollBytes = 0;
316
319
  active;
320
+ manual = false;
321
+ manualMaxed = false;
317
322
  recognitionQueue = Promise.resolve();
318
323
  synthesisQueue = Promise.resolve();
319
324
  synthesisGeneration = 0;
@@ -345,8 +350,16 @@ var NodeSpeechBackend = class {
345
350
  emit({ type: "ready" });
346
351
  return Promise.resolve();
347
352
  }
353
+ beginManualUtterance() {
354
+ if (this.closed) return;
355
+ this.active = void 0;
356
+ this.preRoll.splice(0);
357
+ this.preRollBytes = 0;
358
+ this.manual = true;
359
+ this.manualMaxed = false;
360
+ }
348
361
  appendAudio(audio) {
349
- if (this.closed || audio.byteLength === 0) return;
362
+ if (this.closed || audio.byteLength === 0 || this.manualMaxed) return;
350
363
  if (audio.byteLength % 2 !== 0) {
351
364
  this.emit?.({
352
365
  type: "error",
@@ -369,14 +382,19 @@ var NodeSpeechBackend = class {
369
382
  this.active.silenceBytes = 0;
370
383
  if (!this.active.confirmed && this.active.voicedBytes >= this.bytesFor(this.config.minSpeechDurationMs ?? 250)) this.confirmUtterance();
371
384
  } else this.active.silenceBytes += frame.byteLength;
372
- if (!this.active.confirmed && this.active.silenceBytes >= this.bytesFor(this.config.minSpeechDurationMs ?? 250)) {
385
+ if (!this.manual && !this.active.confirmed && this.active.silenceBytes >= this.bytesFor(this.config.minSpeechDurationMs ?? 250)) {
373
386
  this.active = void 0;
374
387
  return;
375
388
  }
376
- if (this.active.silenceBytes >= this.bytesFor(this.config.silenceDurationMs) || this.active.totalBytes >= this.bytesFor(this.config.maxUtteranceMs)) this.finishUtterance();
389
+ if (!this.manual && this.active.silenceBytes >= this.bytesFor(this.config.silenceDurationMs) || this.active.totalBytes >= this.bytesFor(this.config.maxUtteranceMs)) {
390
+ this.finishUtterance();
391
+ if (this.manual) this.manualMaxed = true;
392
+ }
377
393
  }
378
394
  commitAudio() {
379
395
  this.finishUtterance();
396
+ this.manual = false;
397
+ this.manualMaxed = false;
380
398
  }
381
399
  synthesize(responseId, text) {
382
400
  const generation = this.synthesisGeneration;
@@ -435,6 +453,8 @@ var NodeSpeechBackend = class {
435
453
  this.synthesisGeneration += 1;
436
454
  this.synthesisResponses.clear();
437
455
  this.active = void 0;
456
+ this.manual = false;
457
+ this.manualMaxed = false;
438
458
  this.preRoll.splice(0);
439
459
  await Promise.allSettled([this.recognitionQueue, this.synthesisQueue]);
440
460
  this.emit?.({
@@ -213,7 +213,8 @@ async function attach(ctx, socket, rawUrl) {
213
213
  return;
214
214
  }
215
215
  const type = control.type;
216
- if (type === "audio.commit") voice.commitAudio(session.id);
216
+ if (type === "audio.push-to-talk.start") voice.beginManualUtterance(session.id);
217
+ else if (type === "audio.commit") voice.commitAudio(session.id);
217
218
  else if (type === "response.interrupt") voice.interruptResponse(session.id);
218
219
  else if (type === "playback.ended") voice.playbackEnded(session.id);
219
220
  else if (type === "task.cancel") {
@@ -169,6 +169,10 @@ var VoiceRuntime = class extends Service {
169
169
  appendAudio(id, audio) {
170
170
  this.requireAttachedSession(id).provider.appendAudio(audio);
171
171
  }
172
+ /** Begin a manually committed push-to-talk utterance. */
173
+ beginManualUtterance(id) {
174
+ this.requireAttachedSession(id).provider.beginManualUtterance();
175
+ }
172
176
  /**
173
177
  * Commit current microphone input.
174
178
  * @param id - voice session.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
- {
1
+ {
2
2
  "name": "@flowingspring/dsh-voco",
3
3
  "description": "Persistent voice conversations for DSH with cloud speech recognition, Edge TTS, and background Agent delegation",
4
- "version": "0.3.7",
4
+ "version": "0.3.8",
5
5
  "keywords": [
6
6
  "deepseek-harness",
7
7
  "dsh",
@@ -15,18 +15,18 @@
15
15
  "bugs": {
16
16
  "url": "https://github.com/lgquan/dsh-voco/issues"
17
17
  },
18
- "publishConfig": {
19
- "access": "public"
20
- },
21
- "repository": {
22
- "type": "git",
23
- "url": "git+https://github.com/lgquan/dsh-voco.git",
24
- "directory": "packages/voice-app"
25
- },
26
- "type": "module",
27
- "main": "lib/index.js",
28
- "types": "lib/types/index.d.ts",
29
- "exports": {
18
+ "publishConfig": {
19
+ "access": "public"
20
+ },
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "git+https://github.com/lgquan/dsh-voco.git",
24
+ "directory": "packages/voice-app"
25
+ },
26
+ "type": "module",
27
+ "main": "lib/index.js",
28
+ "types": "lib/types/index.d.ts",
29
+ "exports": {
30
30
  ".": {
31
31
  "types": "./lib/types/index.d.ts",
32
32
  "default": "./lib/index.js"
@@ -45,17 +45,17 @@
45
45
  "./voice-web": "./lib/plugins/voice-web.js",
46
46
  "./cordis.patch.yml": "./cordis.patch.yml",
47
47
  "./package.json": "./package.json"
48
- },
49
- "files": [
48
+ },
49
+ "files": [
50
50
  "lib/index.js",
51
51
  "lib/invariant.js",
52
52
  "lib/client.js",
53
53
  "lib/client.js.map",
54
54
  "lib/plugins/*.js",
55
55
  "cordis.patch.yml",
56
- "lib/types/**/*.d.ts"
57
- ],
58
- "license": "MIT",
56
+ "lib/types/**/*.d.ts"
57
+ ],
58
+ "license": "MIT",
59
59
  "dsh": {
60
60
  "bundle": {
61
61
  "patch": "./cordis.patch.yml"
@@ -131,15 +131,15 @@
131
131
  "@deepseek-ai/dsh-system-prompt": "^0.1.1-rc.1",
132
132
  "@deepseek-ai/dsh-tools": "^0.1.1-rc.1",
133
133
  "@deepseek-ai/dsh-workspace": "^0.1.1-rc.1",
134
- "@flowingspring/dsh-client-ui-voice": "workspace:*",
135
- "@flowingspring/dsh-llm-tool-call-compat": "workspace:*",
136
- "@flowingspring/dsh-voice": "workspace:*",
137
- "@flowingspring/dsh-voice-assistant": "workspace:*",
138
- "@flowingspring/dsh-voice-local": "workspace:*",
139
- "@flowingspring/dsh-voice-web": "workspace:*",
140
134
  "@types/react": "~18.3.1",
141
135
  "@types/ws": "^8.18.1",
142
136
  "react": "^18.2.0",
143
- "react-dom": "^18.2.0"
137
+ "react-dom": "^18.2.0",
138
+ "@flowingspring/dsh-voice": "0.1.2",
139
+ "@flowingspring/dsh-voice-local": "0.1.0",
140
+ "@flowingspring/dsh-llm-tool-call-compat": "0.1.0",
141
+ "@flowingspring/dsh-voice-web": "0.1.2",
142
+ "@flowingspring/dsh-client-ui-voice": "0.1.2",
143
+ "@flowingspring/dsh-voice-assistant": "0.1.2"
144
144
  }
145
- }
145
+ }