dsh-realtime-audio-ws 0.2.4 → 0.2.6
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/lib/index.d.ts.map +1 -1
- package/lib/index.js +35 -5
- package/lib/index.js.map +1 -1
- package/package.json +3 -3
- package/src/index.ts +34 -5
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,MAAM,MAAM,0BAA0B,CAAA;AAC7C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAkBlD,OAAO,EAOL,KAAK,qBAAqB,EAC3B,MAAM,YAAY,CAAA;AAEnB,cAAc,YAAY,CAAA;AAC1B;;;;;;GAMG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAC5F,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,WAAW,GACjB,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAA;AACzF,OAAO,EAAE,gBAAgB,EAAE,KAAK,eAAe,EAAE,KAAK,kBAAkB,EAAE,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AACzH,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AACrF,YAAY,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAIpE,mBAAmB;AACnB,eAAO,MAAM,IAAI,sBAAsB,CAAA;AAEvC,eAAO,MAAM,MAAM;;;;;;;;;;;;;;aAajB,CAAA;AAqCF,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,qBAAqB,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,MAAM,MAAM,0BAA0B,CAAA;AAC7C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAkBlD,OAAO,EAOL,KAAK,qBAAqB,EAC3B,MAAM,YAAY,CAAA;AAEnB,cAAc,YAAY,CAAA;AAC1B;;;;;;GAMG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAC5F,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,WAAW,GACjB,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAA;AACzF,OAAO,EAAE,gBAAgB,EAAE,KAAK,eAAe,EAAE,KAAK,kBAAkB,EAAE,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AACzH,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AACrF,YAAY,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAIpE,mBAAmB;AACnB,eAAO,MAAM,IAAI,sBAAsB,CAAA;AAEvC,eAAO,MAAM,MAAM;;;;;;;;;;;;;;aAajB,CAAA;AAqCF,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,qBAAqB,GAAG,IAAI,CAyMvE"}
|
package/lib/index.js
CHANGED
|
@@ -69,12 +69,32 @@ export function apply(ctx, config) {
|
|
|
69
69
|
// constructor argument: the plugin that mints the token is the only one that can name it, and it
|
|
70
70
|
// mints it here, after the journal already exists.
|
|
71
71
|
journal.addSecrets([token]);
|
|
72
|
+
// What this plugin resolved, so the journal can be read without the profile beside it. Values only, and
|
|
73
|
+
// no field that could carry a secret: `journalPath` names a file, and the token went in on the line above
|
|
74
|
+
// so that it can never reach a record in the first place.
|
|
75
|
+
journal.record('config.resolved', {
|
|
76
|
+
plugin: 'dsh-realtime-audio-ws',
|
|
77
|
+
path: config.path,
|
|
78
|
+
openSessionOnConnect: String(config.openSessionOnConnect),
|
|
79
|
+
maxConnections: String(config.maxConnections),
|
|
80
|
+
maxFrameBytes: String(config.maxFrameBytes),
|
|
81
|
+
journalPath: config.journalPath,
|
|
82
|
+
});
|
|
72
83
|
// The record leaves the process when a path is named. Registered *after* the token, so that every entry
|
|
73
84
|
// the file receives has already been through the redaction that knows about it — a sink is handed
|
|
74
85
|
// entries after `record` has redacted them, and that ordering is the reason this is a sink rather than a
|
|
75
86
|
// second writer with its own idea of what a secret looks like.
|
|
76
87
|
if (config.journalPath.length > 0) {
|
|
77
|
-
|
|
88
|
+
const sink = createJournalFileSink(config.journalPath);
|
|
89
|
+
// Everything recorded before this sink existed — every plugin's boot record, in whatever order the
|
|
90
|
+
// plugins happened to load — reaches the file here, or it reaches it never. The file is the record
|
|
91
|
+
// meant to be read without the profile beside it, so an entry that depends on load order is an entry
|
|
92
|
+
// that lies by omission. This plugin's own `config.resolved` is written above this line, which is
|
|
93
|
+
// exactly why the replay is here: the first version of that record never reached the file at all, and
|
|
94
|
+
// the file's silence looked like a plugin that had failed to load.
|
|
95
|
+
for (const entry of journal.snapshot())
|
|
96
|
+
sink(entry);
|
|
97
|
+
journal.onEntry(sink);
|
|
78
98
|
}
|
|
79
99
|
// The injection event is declared by `@deepseek-ai/dsh-host-webserver`, which this package deliberately
|
|
80
100
|
// does not import: importing it would augment `Context` with a second declaration of `webServer` and
|
|
@@ -94,9 +114,14 @@ export function apply(ctx, config) {
|
|
|
94
114
|
path: config.path,
|
|
95
115
|
clients: () => clients.size,
|
|
96
116
|
voice: () => ctx.serial('realtime-agent/status'),
|
|
97
|
-
request: (verb) =>
|
|
98
|
-
|
|
99
|
-
|
|
117
|
+
request: (verb) => {
|
|
118
|
+
// Only a start asks for a session; a stop is answered by the close entry that already follows it.
|
|
119
|
+
if (verb === 'start')
|
|
120
|
+
journal.record('session.requested', { trigger: 'strip' });
|
|
121
|
+
return verb === 'start'
|
|
122
|
+
? ctx.serial('realtime-agent/start')
|
|
123
|
+
: ctx.serial('realtime-agent/stop');
|
|
124
|
+
},
|
|
100
125
|
});
|
|
101
126
|
/**
|
|
102
127
|
* The tail of the control-reply queue.
|
|
@@ -179,8 +204,13 @@ export function apply(ctx, config) {
|
|
|
179
204
|
journal.record('socket.accepted', { clients: String(clients.size), url: target });
|
|
180
205
|
// Ask for the session before the bridge goes in, so the first frames are written into a session
|
|
181
206
|
// that is being opened rather than dropped by the mic seam's no-session rule.
|
|
182
|
-
if (live.openSessionOnConnect)
|
|
207
|
+
if (live.openSessionOnConnect) {
|
|
208
|
+
// Recorded on the side that asks. The opener records what came of the request, and the distance
|
|
209
|
+
// between the two entries is the only thing that separates a listener which never ran from a
|
|
210
|
+
// session nobody asked for — both of which are otherwise the same silence.
|
|
211
|
+
journal.record('session.requested', { trigger: 'connect', clients: String(clients.size) });
|
|
183
212
|
ctx.emit('realtime-agent/start');
|
|
213
|
+
}
|
|
184
214
|
attachAudioSocket(client, {
|
|
185
215
|
emitMic: (pcm16) => { ctx.emit('realtime-agent/mic', pcm16); },
|
|
186
216
|
subscribeAudio: (listener) => ctx.on('realtime-agent/audio', listener),
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-realtime-audio-ws",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.6",
|
|
4
4
|
"description": "The host end of the client half's transport: a WebSocket upgrade route that bridges microphone audio in and agent speech out.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -52,8 +52,8 @@
|
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"ws": "^8.22.0",
|
|
55
|
-
"dsh-realtime-agent": "^0.2.
|
|
56
|
-
"dsh-realtime": "^0.2.
|
|
55
|
+
"dsh-realtime-agent": "^0.2.10",
|
|
56
|
+
"dsh-realtime": "^0.2.6"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
59
|
"@deepseek-ai/cordis": "^4.0.3",
|
package/src/index.ts
CHANGED
|
@@ -143,12 +143,31 @@ export function apply(ctx: Context, config: RealtimeAudioWsConfig): void {
|
|
|
143
143
|
// constructor argument: the plugin that mints the token is the only one that can name it, and it
|
|
144
144
|
// mints it here, after the journal already exists.
|
|
145
145
|
journal.addSecrets([token])
|
|
146
|
+
// What this plugin resolved, so the journal can be read without the profile beside it. Values only, and
|
|
147
|
+
// no field that could carry a secret: `journalPath` names a file, and the token went in on the line above
|
|
148
|
+
// so that it can never reach a record in the first place.
|
|
149
|
+
journal.record('config.resolved', {
|
|
150
|
+
plugin: 'dsh-realtime-audio-ws',
|
|
151
|
+
path: config.path,
|
|
152
|
+
openSessionOnConnect: String(config.openSessionOnConnect),
|
|
153
|
+
maxConnections: String(config.maxConnections),
|
|
154
|
+
maxFrameBytes: String(config.maxFrameBytes),
|
|
155
|
+
journalPath: config.journalPath,
|
|
156
|
+
})
|
|
146
157
|
// The record leaves the process when a path is named. Registered *after* the token, so that every entry
|
|
147
158
|
// the file receives has already been through the redaction that knows about it — a sink is handed
|
|
148
159
|
// entries after `record` has redacted them, and that ordering is the reason this is a sink rather than a
|
|
149
160
|
// second writer with its own idea of what a secret looks like.
|
|
150
161
|
if (config.journalPath.length > 0) {
|
|
151
|
-
|
|
162
|
+
const sink = createJournalFileSink(config.journalPath)
|
|
163
|
+
// Everything recorded before this sink existed — every plugin's boot record, in whatever order the
|
|
164
|
+
// plugins happened to load — reaches the file here, or it reaches it never. The file is the record
|
|
165
|
+
// meant to be read without the profile beside it, so an entry that depends on load order is an entry
|
|
166
|
+
// that lies by omission. This plugin's own `config.resolved` is written above this line, which is
|
|
167
|
+
// exactly why the replay is here: the first version of that record never reached the file at all, and
|
|
168
|
+
// the file's silence looked like a plugin that had failed to load.
|
|
169
|
+
for (const entry of journal.snapshot()) sink(entry)
|
|
170
|
+
journal.onEntry(sink)
|
|
152
171
|
}
|
|
153
172
|
// The injection event is declared by `@deepseek-ai/dsh-host-webserver`, which this package deliberately
|
|
154
173
|
// does not import: importing it would augment `Context` with a second declaration of `webServer` and
|
|
@@ -172,9 +191,13 @@ export function apply(ctx: Context, config: RealtimeAudioWsConfig): void {
|
|
|
172
191
|
path: config.path,
|
|
173
192
|
clients: () => clients.size,
|
|
174
193
|
voice: () => ctx.serial('realtime-agent/status'),
|
|
175
|
-
request: (verb) =>
|
|
176
|
-
|
|
177
|
-
|
|
194
|
+
request: (verb) => {
|
|
195
|
+
// Only a start asks for a session; a stop is answered by the close entry that already follows it.
|
|
196
|
+
if (verb === 'start') journal.record('session.requested', { trigger: 'strip' })
|
|
197
|
+
return verb === 'start'
|
|
198
|
+
? ctx.serial('realtime-agent/start')
|
|
199
|
+
: ctx.serial('realtime-agent/stop')
|
|
200
|
+
},
|
|
178
201
|
})
|
|
179
202
|
|
|
180
203
|
/**
|
|
@@ -268,7 +291,13 @@ export function apply(ctx: Context, config: RealtimeAudioWsConfig): void {
|
|
|
268
291
|
journal.record('socket.accepted', { clients: String(clients.size), url: target })
|
|
269
292
|
// Ask for the session before the bridge goes in, so the first frames are written into a session
|
|
270
293
|
// that is being opened rather than dropped by the mic seam's no-session rule.
|
|
271
|
-
if (live.openSessionOnConnect)
|
|
294
|
+
if (live.openSessionOnConnect) {
|
|
295
|
+
// Recorded on the side that asks. The opener records what came of the request, and the distance
|
|
296
|
+
// between the two entries is the only thing that separates a listener which never ran from a
|
|
297
|
+
// session nobody asked for — both of which are otherwise the same silence.
|
|
298
|
+
journal.record('session.requested', { trigger: 'connect', clients: String(clients.size) })
|
|
299
|
+
ctx.emit('realtime-agent/start')
|
|
300
|
+
}
|
|
272
301
|
attachAudioSocket(client, {
|
|
273
302
|
emitMic: (pcm16) => { ctx.emit('realtime-agent/mic', pcm16) },
|
|
274
303
|
subscribeAudio: (listener) => ctx.on('realtime-agent/audio', listener),
|