@alexkroman1/aai 1.4.2 → 1.4.3

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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @alexkroman1/aai@1.4.2 build /home/runner/work/agent/agent/packages/aai
2
+ > @alexkroman1/aai@1.4.3 build /home/runner/work/agent/agent/packages/aai
3
3
  > tsdown && tsc -p tsconfig.build.json
4
4
 
5
5
  ℹ tsdown v0.21.7 powered by rolldown v1.0.0-rc.12
@@ -8,7 +8,7 @@
8
8
  ℹ target: node22
9
9
  ℹ tsconfig: tsconfig.json
10
10
  ℹ Build start
11
- ℹ dist/host/runtime-barrel.js 75.92 kB │ gzip: 22.48 kB
11
+ ℹ dist/host/runtime-barrel.js 75.94 kB │ gzip: 22.51 kB
12
12
  ℹ dist/sdk/protocol.js  4.75 kB │ gzip: 1.76 kB
13
13
  ℹ dist/index.js  2.88 kB │ gzip: 1.24 kB
14
14
  ℹ dist/sdk/manifest-barrel.js  0.36 kB │ gzip: 0.20 kB
@@ -22,5 +22,5 @@
22
22
  ℹ dist/assemblyai-Cxg9eobY.js  0.53 kB │ gzip: 0.35 kB
23
23
  ℹ dist/anthropic-BrUCPKUc.js  0.23 kB │ gzip: 0.18 kB
24
24
  ℹ dist/cartesia-DwDk2tEu.js  0.22 kB │ gzip: 0.17 kB
25
- ℹ 14 files, total: 100.74 kB
26
- ✔ Build complete in 48ms
25
+ ℹ 14 files, total: 100.76 kB
26
+ ✔ Build complete in 45ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @alexkroman1/aai
2
2
 
3
+ ## 1.4.3
4
+
5
+ ### Patch Changes
6
+
7
+ - 62d5a99: Fix pipeline mode: play greeting, emit a single agent_transcript per turn, open TTS at the client's playback sample rate, stop the Cartesia adapter from eagerly rotating its context (which was silently dropping in-flight audio chunks), and skip the wire `context.cancel()` when the context is already final on Cartesia's side (avoids a benign 400 that was killing the session).
8
+
3
9
  ## 1.4.2
4
10
 
5
11
  ### Patch Changes
@@ -1200,7 +1200,7 @@ function openCartesia(opts) {
1200
1200
  },
1201
1201
  cancel() {
1202
1202
  if (closed) return;
1203
- context.cancel().catch(ignoreRejection);
1203
+ if (!doneEmitted) context.cancel().catch(ignoreRejection);
1204
1204
  emitDoneOnce();
1205
1205
  rotatePending = true;
1206
1206
  },
@@ -217,4 +217,45 @@ describe("cartesia TTS adapter", () => {
217
217
  controller.abort();
218
218
  await session.close();
219
219
  });
220
+
221
+ test("cancel() after done is a no-op on the wire (avoids Cartesia's 'context ID does not exist' 400)", async () => {
222
+ const { session, controller } = await openSession();
223
+ const turn1 = session._currentContextId();
224
+
225
+ session.sendText("hello");
226
+ session.flush();
227
+ await flush();
228
+
229
+ // Cartesia finishes synthesizing and emits `done` for the flushed context.
230
+ const ws = session._ws as unknown as { _fire(event: string, payload: unknown): void };
231
+ ws._fire("done", { context_id: turn1 });
232
+
233
+ // A late cancel (e.g. client `cancel` event after the turn completed
234
+ // normally) must not re-send `context.cancel()` — doing so would trip
235
+ // Cartesia's 400 and kill the session via onTtsError → terminate.
236
+ session.cancel();
237
+ await flush();
238
+
239
+ const cancels = sends.filter((s) => s.kind === "cancel");
240
+ expect(cancels).toEqual([]);
241
+
242
+ controller.abort();
243
+ await session.close();
244
+ });
245
+
246
+ test("double cancel() only sends one wire cancel", async () => {
247
+ const { session, controller } = await openSession();
248
+ const turn1 = session._currentContextId();
249
+
250
+ session.sendText("hello");
251
+ session.cancel();
252
+ session.cancel();
253
+ await flush();
254
+
255
+ const cancels = sends.filter((s) => s.kind === "cancel");
256
+ expect(cancels).toEqual([{ kind: "cancel", contextId: turn1 }]);
257
+
258
+ controller.abort();
259
+ await session.close();
260
+ });
220
261
  });
@@ -213,7 +213,15 @@ export function openCartesia(opts: CartesiaOptions): TtsOpener {
213
213
  },
214
214
  cancel() {
215
215
  if (closed) return;
216
- void context.cancel().catch(ignoreRejection);
216
+ // Skip the wire cancel if the context is already final on
217
+ // Cartesia's side (natural `done` after flush, or a prior
218
+ // cancel). Cartesia responds to cancel on a retired context
219
+ // with a 400 "context ID does not exist", which our error
220
+ // listener surfaces as `tts_stream_error` and the pipeline
221
+ // treats as fatal — killing the session for a benign race.
222
+ if (!doneEmitted) {
223
+ void context.cancel().catch(ignoreRejection);
224
+ }
217
225
  // Emit synchronously: barge-in advances the orchestrator's
218
226
  // state machine on `done`, and delaying it would audibly
219
227
  // stall subsequent turns. Cartesia stops producing audio
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alexkroman1/aai",
3
- "version": "1.4.2",
3
+ "version": "1.4.3",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {