@mycadet/assistant 0.12.11 → 0.13.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.
Files changed (176) hide show
  1. package/node_modules/@mycadet/ces-client/node_modules/@mycadet/service-contracts/src/__tests__/ingress.test.ts +2 -2
  2. package/node_modules/@mycadet/ces-client/node_modules/@mycadet/service-contracts/src/ingress.ts +2 -2
  3. package/node_modules/@mycadet/gateway-client/node_modules/@mycadet/service-contracts/src/__tests__/ingress.test.ts +2 -2
  4. package/node_modules/@mycadet/gateway-client/node_modules/@mycadet/service-contracts/src/ingress.ts +2 -2
  5. package/node_modules/@mycadet/gateway-client/src/gateway-ipc-contracts.ts +0 -20
  6. package/node_modules/@mycadet/service-contracts/src/__tests__/ingress.test.ts +2 -2
  7. package/node_modules/@mycadet/service-contracts/src/ingress.ts +2 -2
  8. package/openapi.yaml +2 -708
  9. package/package.json +2 -3
  10. package/scripts/sync-web-search-catalog.ts +1 -2
  11. package/src/__tests__/cloud-profile-guard.test.ts +2 -2
  12. package/src/__tests__/config-schema.test.ts +6 -38
  13. package/src/__tests__/conversation-queue.test.ts +45 -6
  14. package/src/__tests__/db-readiness-http-gate.test.ts +0 -6
  15. package/src/__tests__/persist-onboarding-artifacts.test.ts +0 -1
  16. package/src/__tests__/persona-resolver.test.ts +0 -51
  17. package/src/__tests__/provider-cloud-proxy-integration.test.ts +2 -110
  18. package/src/__tests__/run-due-schedules.test.ts +0 -4
  19. package/src/__tests__/schedule-store.test.ts +0 -12
  20. package/src/__tests__/stt-stream-session.test.ts +4 -4
  21. package/src/__tests__/telephony-tts-guard.test.ts +2 -50
  22. package/src/__tests__/voice-config-update.test.ts +12 -167
  23. package/src/__tests__/web-search-catalog-parity.test.ts +0 -2
  24. package/src/__tests__/workspace-migration-130-speech-mode-to-provider.test.ts +9 -7
  25. package/src/__tests__/workspace-migration-132-web-search-mode-to-provider.test.ts +6 -6
  26. package/src/calls/__tests__/voice-session-bridge.test.ts +1 -4
  27. package/src/calls/resolve-call-tts-provider.ts +6 -25
  28. package/src/calls/telephony-credential-preflight.ts +0 -10
  29. package/src/calls/telephony-tts-capability.ts +1 -17
  30. package/src/cli/commands/tts.ts +1 -2
  31. package/src/cli/index.help.ts +0 -2
  32. package/src/cli/program.ts +0 -2
  33. package/src/config/bundled-skills/settings/tools/voice-config-update.ts +4 -42
  34. package/src/config/schemas/__tests__/stt.test.ts +10 -14
  35. package/src/config/schemas/services.ts +5 -6
  36. package/src/config/schemas/stt.ts +1 -3
  37. package/src/config/schemas/tts.ts +1 -30
  38. package/src/daemon/daemon-readiness.ts +4 -29
  39. package/src/daemon/lifecycle.ts +0 -31
  40. package/src/daemon/providers-setup.ts +0 -8
  41. package/src/heartbeat/__tests__/heartbeat-service.test.ts +0 -1
  42. package/src/heartbeat/heartbeat-service.ts +1 -66
  43. package/src/ipc/__tests__/db-readiness-ipc-gate.test.ts +1 -9
  44. package/src/live-voice/__tests__/live-voice-credential-preflight.test.ts +0 -44
  45. package/src/live-voice/__tests__/live-voice-flux-turn-end.test.ts +4 -6
  46. package/src/live-voice/__tests__/live-voice-stt.test.ts +1 -1
  47. package/src/live-voice/live-voice-credential-preflight.ts +9 -33
  48. package/src/live-voice/live-voice-session.ts +10 -6
  49. package/src/live-voice/live-voice-tts.ts +1 -8
  50. package/src/plugins/defaults/memory/worker.ts +3 -3
  51. package/src/prompts/persona-resolver.ts +0 -35
  52. package/src/providers/__tests__/search-provider-catalog.test.ts +5 -8
  53. package/src/providers/__tests__/voice-error-copy.test.ts +9 -10
  54. package/src/providers/search-provider-catalog.ts +7 -39
  55. package/src/providers/speech-to-text/__tests__/provider-catalog.test.ts +3 -47
  56. package/src/providers/speech-to-text/__tests__/resolve.test.ts +6 -372
  57. package/src/providers/speech-to-text/provider-catalog.ts +2 -73
  58. package/src/providers/speech-to-text/resolve.ts +3 -120
  59. package/src/runtime/http-router-types.ts +1 -3
  60. package/src/runtime/http-server.ts +1 -1
  61. package/src/runtime/routes/__tests__/tts-routes.test.ts +2 -6
  62. package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +7 -7
  63. package/src/runtime/routes/index.ts +0 -4
  64. package/src/runtime/routes/live-voice-routes.test.ts +4 -11
  65. package/src/runtime/routes/live-voice-routes.ts +8 -11
  66. package/src/runtime/routes/secret-routes.ts +0 -6
  67. package/src/runtime/routes/tts-routes.ts +0 -38
  68. package/src/schedule/__tests__/plugin-schedule-reconciler.test.ts +1 -7
  69. package/src/schedule/__tests__/worker-mcp-readiness.test.ts +0 -4
  70. package/src/schedule/schedule-store.ts +0 -7
  71. package/src/schedule/scheduler.ts +0 -5
  72. package/src/schedule/worker.ts +1 -1
  73. package/src/stt/__tests__/daemon-batch-transcriber.test.ts +2 -10
  74. package/src/stt/daemon-batch-transcriber.ts +4 -38
  75. package/src/stt/types.ts +1 -9
  76. package/src/tools/network/__tests__/web-search.test.ts +3 -250
  77. package/src/tools/network/web-search.ts +4 -165
  78. package/src/tts/__tests__/provider-resolution.test.ts +0 -5
  79. package/src/tts/provider-catalog.ts +0 -4
  80. package/src/tts/types.ts +0 -1
  81. package/src/__tests__/cloud-speech-defaults.test.ts +0 -330
  82. package/src/__tests__/migration-cross-version-compatibility.test.ts +0 -1708
  83. package/src/__tests__/migration-export-http.test.ts +0 -557
  84. package/src/__tests__/migration-export-streaming.test.ts +0 -350
  85. package/src/__tests__/migration-export-to-gcs.test.ts +0 -706
  86. package/src/__tests__/migration-import-commit-http.test.ts +0 -1176
  87. package/src/__tests__/migration-import-from-gcs.test.ts +0 -534
  88. package/src/__tests__/migration-import-from-path.test.ts +0 -324
  89. package/src/__tests__/migration-import-from-url.test.ts +0 -588
  90. package/src/__tests__/migration-import-preflight-http.test.ts +0 -739
  91. package/src/__tests__/migration-jobs-status.test.ts +0 -139
  92. package/src/__tests__/migration-parity-persistence.test.ts +0 -1891
  93. package/src/__tests__/migration-transport.test.ts +0 -1089
  94. package/src/__tests__/migration-validate-http.test.ts +0 -634
  95. package/src/__tests__/migration-wizard.test.ts +0 -1395
  96. package/src/__tests__/rebind-secrets-screen.test.ts +0 -876
  97. package/src/__tests__/sanitize-config-for-transfer.test.ts +0 -259
  98. package/src/__tests__/transfer-progress-screen.test.ts +0 -1217
  99. package/src/__tests__/validation-results-screen.test.ts +0 -1130
  100. package/src/__tests__/vbundle-pax-and-symlink.test.ts +0 -147
  101. package/src/background-wake/background-wake-routes.test.ts +0 -906
  102. package/src/background-wake/cloud-client.test.ts +0 -328
  103. package/src/background-wake/cloud-client.ts +0 -196
  104. package/src/background-wake/next-wake.test.ts +0 -335
  105. package/src/background-wake/next-wake.ts +0 -188
  106. package/src/background-wake/publisher.ts +0 -93
  107. package/src/background-wake/wake-intent-hooks.test.ts +0 -234
  108. package/src/cli/commands/__tests__/backup.test.ts +0 -363
  109. package/src/cli/commands/backup.help.ts +0 -180
  110. package/src/cli/commands/backup.ts +0 -398
  111. package/src/cloud/cloud-speech.test.ts +0 -335
  112. package/src/cloud/cloud-speech.ts +0 -300
  113. package/src/config/cloud-speech-defaults.ts +0 -300
  114. package/src/config/sanitize-for-transfer.ts +0 -111
  115. package/src/live-voice/__tests__/live-voice-cloud-speech-fallback.test.ts +0 -250
  116. package/src/providers/speech-to-text/__tests__/cadet-cloud-realtime.test.ts +0 -457
  117. package/src/providers/speech-to-text/__tests__/cadet-cloud.test.ts +0 -271
  118. package/src/providers/speech-to-text/__tests__/cadet-speech-relay-connection.test.ts +0 -126
  119. package/src/providers/speech-to-text/cadet-cloud-flux-realtime.ts +0 -309
  120. package/src/providers/speech-to-text/cadet-cloud-realtime.ts +0 -315
  121. package/src/providers/speech-to-text/cadet-cloud.ts +0 -108
  122. package/src/providers/speech-to-text/cadet-speech-relay-connection.ts +0 -176
  123. package/src/runtime/migrations/__tests__/gcs-signed-url.test.ts +0 -254
  124. package/src/runtime/migrations/__tests__/job-registry.test.ts +0 -346
  125. package/src/runtime/migrations/__tests__/origin-mode.test.ts +0 -62
  126. package/src/runtime/migrations/__tests__/rebind-secrets-credentials.test.ts +0 -184
  127. package/src/runtime/migrations/__tests__/staged-import-path.test.ts +0 -110
  128. package/src/runtime/migrations/__tests__/v1-test-helpers.ts +0 -112
  129. package/src/runtime/migrations/__tests__/vbundle-builder-credentials.test.ts +0 -285
  130. package/src/runtime/migrations/__tests__/vbundle-builder-fd-leak.test.ts +0 -126
  131. package/src/runtime/migrations/__tests__/vbundle-builder-v1-shape.test.ts +0 -253
  132. package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +0 -208
  133. package/src/runtime/migrations/__tests__/vbundle-import-parity.test.ts +0 -485
  134. package/src/runtime/migrations/__tests__/vbundle-import-policy.test.ts +0 -349
  135. package/src/runtime/migrations/__tests__/vbundle-import-version-compat.test.ts +0 -196
  136. package/src/runtime/migrations/__tests__/vbundle-legacy-user-md.test.ts +0 -551
  137. package/src/runtime/migrations/__tests__/vbundle-metadata-merge-integration.test.ts +0 -428
  138. package/src/runtime/migrations/__tests__/vbundle-metadata-merge.test.ts +0 -220
  139. package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +0 -1823
  140. package/src/runtime/migrations/__tests__/vbundle-streaming-validator.test.ts +0 -598
  141. package/src/runtime/migrations/__tests__/vbundle-symlink-importer.test.ts +0 -463
  142. package/src/runtime/migrations/__tests__/vbundle-symlink-streaming-importer.test.ts +0 -538
  143. package/src/runtime/migrations/__tests__/vbundle-symlink-streaming.test.ts +0 -515
  144. package/src/runtime/migrations/__tests__/vbundle-symlink-tar.test.ts +0 -453
  145. package/src/runtime/migrations/__tests__/vbundle-symlink-walker.test.ts +0 -319
  146. package/src/runtime/migrations/__tests__/vbundle-tar-stream.test.ts +0 -240
  147. package/src/runtime/migrations/__tests__/vbundle-validator-v1-schema.test.ts +0 -473
  148. package/src/runtime/migrations/gcs-signed-url.ts +0 -190
  149. package/src/runtime/migrations/job-registry.ts +0 -297
  150. package/src/runtime/migrations/migration-transport.ts +0 -612
  151. package/src/runtime/migrations/migration-wizard.ts +0 -747
  152. package/src/runtime/migrations/origin-mode.ts +0 -42
  153. package/src/runtime/migrations/rebind-secrets-screen.ts +0 -412
  154. package/src/runtime/migrations/staged-import-path.ts +0 -116
  155. package/src/runtime/migrations/transfer-progress-screen.ts +0 -323
  156. package/src/runtime/migrations/validation-results-screen.ts +0 -469
  157. package/src/runtime/migrations/vbundle-builder.ts +0 -1382
  158. package/src/runtime/migrations/vbundle-import-analyzer.ts +0 -405
  159. package/src/runtime/migrations/vbundle-import-policy.ts +0 -241
  160. package/src/runtime/migrations/vbundle-importer.ts +0 -826
  161. package/src/runtime/migrations/vbundle-metadata-merge.ts +0 -113
  162. package/src/runtime/migrations/vbundle-streaming-importer.ts +0 -2844
  163. package/src/runtime/migrations/vbundle-streaming-validator.ts +0 -426
  164. package/src/runtime/migrations/vbundle-tar-stream.ts +0 -244
  165. package/src/runtime/migrations/vbundle-validator.ts +0 -724
  166. package/src/runtime/routes/__tests__/migration-cadet-metadata-reconcile.test.ts +0 -227
  167. package/src/runtime/routes/__tests__/migration-export-secrets-redacted.test.ts +0 -54
  168. package/src/runtime/routes/__tests__/migration-import-allowed-hosts-env.test.ts +0 -70
  169. package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +0 -257
  170. package/src/runtime/routes/background-wake-routes.ts +0 -387
  171. package/src/runtime/routes/migration-routes.ts +0 -2584
  172. package/src/tools/network/__tests__/cloud-search-proxy.test.ts +0 -282
  173. package/src/tools/network/cloud-search-proxy.ts +0 -211
  174. package/src/tts/__tests__/cadet-provider.test.ts +0 -253
  175. package/src/tts/providers/cadet-provider.ts +0 -244
  176. package/src/types/tar-stream.d.ts +0 -66
@@ -13,7 +13,6 @@ import {
13
13
  batchBoundaryGapReason,
14
14
  getCredentialProvider,
15
15
  getProviderEntry,
16
- isCloudSttProvider,
17
16
  resolveSttCatalogKey,
18
17
  supportsBoundary,
19
18
  supportsDiarization,
@@ -37,11 +36,6 @@ const log = getLogger("stt-resolver");
37
36
  */
38
37
  const MULTILINGUAL_DEFAULT_PROVIDERS: ReadonlySet<SttProviderId> = new Set([
39
38
  "deepgram",
40
- "cadet",
41
- // Cloud Flux resolves an absent language to `flux-general-en` relay-side,
42
- // so unset is an English pin here too. With "multi" the relay selects
43
- // `flux-general-multi` and lets Flux detect and code-switch.
44
- "cadet-flux",
45
39
  ] as SttProviderId[]);
46
40
 
47
41
  /**
@@ -156,16 +150,6 @@ export async function resolveBatchTranscriber(
156
150
  throw new SttError("provider-error", reason, { userFacing: true });
157
151
  }
158
152
 
159
- if (provider === "cadet") {
160
- // Managed batch rides the cloud's speech proxy, which forwards the
161
- // language to Deepgram server-side. A platform build predating that
162
- // field ignores it rather than failing, so the daemon can send one
163
- // before the cloud side deploys.
164
- return (await sttProviderKeyResolves("cadet"))
165
- ? createDaemonBatchTranscriber(null, "cadet", language)
166
- : null;
167
- }
168
-
169
153
  const apiKey = await getProviderKeyAsync(credentialProviderName);
170
154
  return createDaemonBatchTranscriber(
171
155
  apiKey,
@@ -515,18 +499,8 @@ export async function resolveStreamingTranscriber(
515
499
  (diarizePreference === "preferred" || diarizePreference === "required") &&
516
500
  providerSupportsDiarization;
517
501
 
518
- // Both managed entries authenticate with the cloud connection, not a
519
- // stored API key: there is no key to fetch, and readiness is whether the
520
- // connection resolves.
521
- const managed = isCloudSttProvider(provider);
522
- const apiKey = managed
523
- ? null
524
- : await getProviderKeyAsync(credentialProviderName);
525
- if (managed) {
526
- if (!(await sttProviderKeyResolves("cadet"))) {
527
- return null;
528
- }
529
- } else if (!apiKey) {
502
+ const apiKey = await getProviderKeyAsync(credentialProviderName);
503
+ if (!apiKey) {
530
504
  return null;
531
505
  }
532
506
 
@@ -656,82 +630,6 @@ async function createStreamingTranscriber(
656
630
  ...(options.diarize ? { diarize: true } : {}),
657
631
  });
658
632
  }
659
- case "cadet": {
660
- // Cloud speech dials the GATEWAY's speech relay (tunnel contact is
661
- // gateway-only); the apiKey argument is unused. Diarization is
662
- // unsupported (not in the relay's param allowlist) and silently
663
- // ignored, matching Gemini/Whisper — as is utteranceEndMs (the relay
664
- // allowlist has no utterance_end_ms; boundary finals ride on
665
- // endpointing alone).
666
- // The gateway is the credential authority, but the cloud
667
- // connection (API key + assistant ID) is checkable locally — gate
668
- // here so preflight reports "connect your account" instead of
669
- // resolving a transcriber whose dial is doomed.
670
- const { cadetCloudSpeechAvailable } = await import("./cadet-cloud.js");
671
- if (!(await cadetCloudSpeechAvailable())) {
672
- return null;
673
- }
674
- const { resolveSpeechRelayConnection } =
675
- await import("./cadet-speech-relay-connection.js");
676
- const connection = await resolveSpeechRelayConnection();
677
- if (!connection) {
678
- return null;
679
- }
680
- const { CadetManagedRealtimeTranscriber } =
681
- await import("./cadet-cloud-realtime.js");
682
- return new CadetManagedRealtimeTranscriber(connection, {
683
- sampleRate: options.sampleRate,
684
- // `language` IS in the relay's param allowlist, and the relay pins
685
- // the STT model to nova-3 server-side, so "multi" code-switching
686
- // needs nothing from the cloud, only this forward. Source:
687
- // mycadet-platform: tunnel/internal/tunnel/deepgram.go
688
- // (deepgramSTTParams allowlist; deepgramSTTModel pin).
689
- ...(options.language ? { language: options.language } : {}),
690
- ...(options.utteranceBoundaryFinals
691
- ? { utteranceBoundaryFinals: true }
692
- : {}),
693
- });
694
- }
695
- case "cadet-flux": {
696
- // Cloud Flux: same relay as `cadet`, but the STT v2 endpoint with
697
- // `contract=flux` so the turn events arrive intact instead of being
698
- // translated into the released v1 Deepgram dialect. Gated on the local
699
- // cloud connection for the same reason as `cadet` above.
700
- const { cadetCloudSpeechAvailable } = await import("./cadet-cloud.js");
701
- if (!(await cadetCloudSpeechAvailable())) {
702
- return null;
703
- }
704
- // The relay maps the language onto a Flux model and refuses the dial
705
- // when there is none, so a language outside Flux's roster fails as a
706
- // relay param error the caller cannot explain. Refuse here instead, on
707
- // the same rule the BYOK twin above applies, so the reason is named
708
- // where it can be read.
709
- const { fluxModelForLanguage: managedFluxModelForLanguage } =
710
- await import("./deepgram-flux-frames.js");
711
- if (managedFluxModelForLanguage(options.language) === null) {
712
- log.warn(
713
- { providerId, language: options.language },
714
- "Cloud Flux has no model for the configured language; refusing rather than transcribing it as another",
715
- );
716
- return null;
717
- }
718
- const { resolveSpeechRelayConnection } =
719
- await import("./cadet-speech-relay-connection.js");
720
- const connection = await resolveSpeechRelayConnection();
721
- if (!connection) {
722
- return null;
723
- }
724
- const { CadetManagedFluxRealtimeTranscriber } =
725
- await import("./cadet-cloud-flux-realtime.js");
726
- return new CadetManagedFluxRealtimeTranscriber(connection, {
727
- sampleRate: options.sampleRate,
728
- // The relay picks `flux-general-en` or `flux-general-multi` from
729
- // this, so it is the only lever over the Flux model from here.
730
- // `utteranceBoundaryFinals` is a nova-3 concept and the catalog
731
- // keeps this provider off telephony, so it never arrives.
732
- ...(options.language ? { language: options.language } : {}),
733
- });
734
- }
735
633
  case "deepgram-flux": {
736
634
  // Flux is streaming-only and dials Deepgram's /v2/listen conversational
737
635
  // endpoint. Turn-detection tuning comes from `liveVoice.flux`, which the
@@ -775,29 +673,14 @@ async function createStreamingTranscriber(
775
673
  * need a key-existence check don't import secure-keys directly.
776
674
  */
777
675
  /**
778
- * Human-readable reason for a credential gap, aware that connection-based
779
- * providers (cadet) are fixed by connecting the cloud account, not by
780
- * entering an API key.
676
+ * Human-readable reason for a credential gap.
781
677
  */
782
678
  export function sttCredentialGapReason(credentialProviderName: string): string {
783
- // Called with either the catalog id ("cadet") or its credential-service
784
- // key ("cadet", the persisted identity family) — both mean cloud speech.
785
- if (
786
- credentialProviderName === "cadet" ||
787
- credentialProviderName === "cadet"
788
- ) {
789
- return "No Cadet Cloud connection for cloud speech — run 'assistant cloud connect'";
790
- }
791
679
  return `No API key configured for credential provider "${credentialProviderName}"`;
792
680
  }
793
681
 
794
682
  export async function sttProviderKeyResolves(
795
683
  credentialProviderName: string,
796
684
  ): Promise<boolean> {
797
- // cadet has no stored API key — the cloud connection is the credential.
798
- if (credentialProviderName === "cadet") {
799
- const { cadetCloudSpeechAvailable } = await import("./cadet-cloud.js");
800
- return cadetCloudSpeechAvailable();
801
- }
802
685
  return (await getProviderKeyAsync(credentialProviderName)) !== undefined;
803
686
  }
@@ -45,9 +45,7 @@ export type RouteBodySchema = z.ZodType;
45
45
 
46
46
  /**
47
47
  * Description for a non-200 response variant. Used when an endpoint has
48
- * meaningful alternate response shapes that clients should handle (e.g.
49
- * 502 `fetch_failed` on POST /v1/migrations/import when the URL body path
50
- * can't reach the upstream bundle host).
48
+ * meaningful alternate response shapes that clients should handle.
51
49
  */
52
50
  export interface RouteAdditionalResponse {
53
51
  description: string;
@@ -122,7 +122,7 @@ const log = getLogger("runtime-http");
122
122
  const DEFAULT_PORT = 7821;
123
123
  const DEFAULT_HOSTNAME = "127.0.0.1";
124
124
 
125
- /** Global hard cap on request body size (512 MB — accommodates large .vbundle backup imports). */
125
+ /** Global hard cap on request body size (512 MB, accommodates app package uploads). */
126
126
  const MAX_REQUEST_BODY_BYTES = 512 * 1024 * 1024;
127
127
 
128
128
  function dbMigrationUnavailableForEndpoint(endpoint: string): Response | null {
@@ -127,17 +127,13 @@ afterEach(() => {
127
127
  // ---------------------------------------------------------------------------
128
128
 
129
129
  describe("tts-routes", () => {
130
- test("exports route definitions for tts/providers, tts/managed-voices, tts/synthesize, and tts/synthesize-cli", () => {
131
- expect(ROUTES).toHaveLength(4);
130
+ test("exports route definitions for tts/providers, tts/synthesize, and tts/synthesize-cli", () => {
131
+ expect(ROUTES).toHaveLength(3);
132
132
 
133
133
  const providers = getRoute("tts/providers");
134
134
  expect(providers.method).toBe("GET");
135
135
  expect(providers.policy?.requiredScopes).toContain("settings.read");
136
136
 
137
- const managedVoices = getRoute("tts/managed-voices");
138
- expect(managedVoices.method).toBe("GET");
139
- expect(managedVoices.policy?.requiredScopes).toContain("settings.read");
140
-
141
137
  const synthesize = getRoute("tts/synthesize");
142
138
  expect(synthesize.method).toBe("POST");
143
139
  expect(synthesize.policy?.requiredScopes).toContain("chat.read");
@@ -200,17 +200,17 @@ describe("tryTranscribeAudioAttachments", () => {
200
200
  expect(reason).toContain("Deepgram");
201
201
  });
202
202
 
203
- test("managed auth failure surfaces its remediation, not the BYOK API-key rewrite", async () => {
203
+ test("a userFacing auth failure surfaces its remediation, not the BYOK API-key rewrite", async () => {
204
204
  const audio = makeAudioAttachment("a1");
205
205
  mockAttachments = [audio];
206
206
  const managedMessage =
207
207
  "Cloud speech needs a working Cadet Cloud connection — reconnect with 'assistant cloud connect'.";
208
208
  mockTranscriber = {
209
- providerId: "cadet",
209
+ providerId: "deepgram",
210
210
  boundaryId: "daemon-batch",
211
211
  transcribe: async () => {
212
- // Managed adapters flag their SttError userFacing so the friendly
213
- // copy layer passes the message through verbatim.
212
+ // Adapters flag their SttError userFacing so the friendly copy
213
+ // layer passes the message through verbatim.
214
214
  throw new SttError("auth", managedMessage, { userFacing: true });
215
215
  },
216
216
  };
@@ -220,18 +220,18 @@ describe("tryTranscribeAudioAttachments", () => {
220
220
  expect(result.status).toBe("error");
221
221
  const reason = (result as { reason: string }).reason;
222
222
  expect(reason).toBe(managedMessage);
223
- // Managed users have no STT key — the BYOK rewrite must not appear.
223
+ // The BYOK rewrite must not appear over a userFacing message.
224
224
  expect(reason).not.toContain("API key");
225
225
  expect(reason).not.toContain("Settings → Voice");
226
226
  });
227
227
 
228
- test("managed credits-exhausted failure is not hidden behind generic copy", async () => {
228
+ test("a credits-exhausted userFacing failure is not hidden behind generic copy", async () => {
229
229
  const audio = makeAudioAttachment("a1");
230
230
  mockAttachments = [audio];
231
231
  const creditsMessage =
232
232
  "Cadet credits are exhausted — add funds to your Cadet account to continue using managed transcription.";
233
233
  mockTranscriber = {
234
- providerId: "cadet",
234
+ providerId: "deepgram",
235
235
  boundaryId: "daemon-batch",
236
236
  transcribe: async () => {
237
237
  throw new SttError("provider-error", creditsMessage, {
@@ -27,7 +27,6 @@ import { ROUTES as AUDIT_ROUTES } from "./audit-routes.js";
27
27
  import { ROUTES as AUTH_ROUTES } from "./auth-routes.js";
28
28
  import { ROUTES as AVATAR_ROUTES } from "./avatar-routes.js";
29
29
  import { ROUTES as BACKGROUND_TOOL_ROUTES } from "./background-tool-routes.js";
30
- import { ROUTES as BACKGROUND_WAKE_ROUTES } from "./background-wake-routes.js";
31
30
  import { ROUTES as BOOKMARK_ROUTES } from "./bookmark-routes.js";
32
31
  import { ROUTES as BRAIN_GRAPH_ROUTES } from "./brain-graph-routes.js";
33
32
  import { ROUTES as BROWSER_ROUTES } from "./browser-routes.js";
@@ -114,7 +113,6 @@ import { ROUTES as LOG_EXPORT_ROUTES } from "./log-export-routes.js";
114
113
  import { ROUTES as MCP_AUTH_ROUTES } from "./mcp-auth-routes.js";
115
114
  import { ROUTES as MESSAGES_LEXICAL_ROUTES } from "./messages-lexical-routes.js";
116
115
  import { ROUTES as MIGRATION_ROLLBACK_ROUTES } from "./migration-rollback-routes.js";
117
- import { ROUTES as MIGRATION_ROUTES } from "./migration-routes.js";
118
116
  import { ROUTES as MONITORING_ROUTES } from "./monitoring-routes.js";
119
117
  import { ROUTES as NOTIFICATION_ROUTES } from "./notification-routes.js";
120
118
  import { ROUTES as OAUTH_APPS_ROUTES } from "./oauth-apps.js";
@@ -179,7 +177,6 @@ export const ROUTES: RouteDefinition[] = [
179
177
  ...AUDIT_ROUTES,
180
178
  ...AUTH_ROUTES,
181
179
  ...AVATAR_ROUTES,
182
- ...BACKGROUND_WAKE_ROUTES,
183
180
  ...BACKGROUND_TOOL_ROUTES,
184
181
  ...BOOKMARK_ROUTES,
185
182
  ...CACHE_ROUTES,
@@ -267,7 +264,6 @@ export const ROUTES: RouteDefinition[] = [
267
264
  ...MEMORY_WORKER_ROUTES,
268
265
  ...MESSAGES_LEXICAL_ROUTES,
269
266
  ...MIGRATION_ROLLBACK_ROUTES,
270
- ...MIGRATION_ROUTES,
271
267
  ...NOTIFICATION_ROUTES,
272
268
  ...OAUTH_APPS_ROUTES,
273
269
  ...OAUTH_LIFECYCLE_ROUTES,
@@ -1,11 +1,10 @@
1
1
  /**
2
2
  * Tests for the live-voice preflight and session-end routes.
3
3
  *
4
- * The handler must run cloud-speech defaulting first, then return the
5
- * live-voice credential readiness verdict verbatim:
4
+ * The preflight handler returns the live-voice credential readiness verdict
5
+ * verbatim:
6
6
  * - ready → { status: "ready" }
7
7
  * - not-ready → passes through the missing gaps + userMessage
8
- * - defaulting is invoked BEFORE readiness is resolved
9
8
  *
10
9
  * The session-end route is the out-of-band recovery path (LUM-3440): it
11
10
  * reports whether it actually reclaimed the daemon's single live-voice slot.
@@ -23,12 +22,6 @@ const calls: string[] = [];
23
22
  let readiness: LiveVoiceCredentialReadiness = { status: "ready" };
24
23
  let releaseResult: LiveVoiceSessionReleaseResult = { released: false };
25
24
 
26
- mock.module("../../config/cloud-speech-defaults.js", () => ({
27
- maybeDefaultSpeechToCloud: async () => {
28
- calls.push("default");
29
- },
30
- }));
31
-
32
25
  mock.module("../../live-voice/live-voice-credential-preflight.js", () => ({
33
26
  resolveLiveVoiceCredentialReadiness: async () => {
34
27
  calls.push("resolve");
@@ -80,13 +73,13 @@ describe("live_voice_preflight_post", () => {
80
73
  expect(result).toEqual(readiness);
81
74
  });
82
75
 
83
- test("runs cloud-speech defaulting before resolving readiness", async () => {
76
+ test("resolves readiness without touching persisted config", async () => {
84
77
  calls.length = 0;
85
78
  readiness = { status: "ready" };
86
79
 
87
80
  await preflightRoute.handler({});
88
81
 
89
- expect(calls).toEqual(["default", "resolve"]);
82
+ expect(calls).toEqual(["resolve"]);
90
83
  });
91
84
  });
92
85
 
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * Transport-agnostic route definitions for live-voice preflight.
3
3
  *
4
- * POST /v1/live-voice/preflight — ensure cloud-speech defaulting has run,
5
- * then report whether the daemon can run both audio legs of a live voice
6
- * session. Lets the web client verify voice is configured BEFORE opening the
4
+ * POST /v1/live-voice/preflight — report whether the daemon can run both
5
+ * audio legs of a live voice session. Lets the web client verify voice is
6
+ * configured BEFORE opening the
7
7
  * voice-room WebSocket, instead of opening it and reacting to an error frame.
8
8
  *
9
9
  * POST /v1/live-voice/session/end releases whatever session holds the
@@ -22,12 +22,9 @@ import type { RouteDefinition } from "./types.js";
22
22
  // ---------------------------------------------------------------------------
23
23
 
24
24
  async function handleLiveVoicePreflight() {
25
- const { maybeDefaultSpeechToCloud } =
26
- await import("../../config/cloud-speech-defaults.js");
27
25
  const { resolveLiveVoiceCredentialReadiness } =
28
26
  await import("../../live-voice/live-voice-credential-preflight.js");
29
27
 
30
- await maybeDefaultSpeechToCloud();
31
28
  return resolveLiveVoiceCredentialReadiness();
32
29
  }
33
30
 
@@ -51,17 +48,17 @@ export const ROUTES: RouteDefinition[] = [
51
48
  operationId: "live_voice_preflight_post",
52
49
  endpoint: "live-voice/preflight",
53
50
  method: "POST",
54
- // Requires settings.write, not a read scope: the handler runs
55
- // maybeDefaultSpeechToCloud(), which can persist config changes
56
- // (switching services.stt/tts.provider to "cadet"). This matches the
57
- // secret/settings config writers, which all require settings.write.
51
+ // Requires settings.write, not a read scope: preflight reports the
52
+ // assistant's speech credential state, which the caller may act on to
53
+ // rewrite speech config. This matches the secret/settings config
54
+ // writers, which all require settings.write.
58
55
  policy: {
59
56
  requiredScopes: ["settings.write"],
60
57
  allowedPrincipalTypes: ACTOR_PRINCIPALS,
61
58
  },
62
59
  summary: "Live voice preflight",
63
60
  description:
64
- "Ensure cloud speech defaulting has run, then report whether live voice can start.",
61
+ "Report whether live voice can start with the current speech credentials.",
65
62
  tags: ["live-voice"],
66
63
  responseBody: z.object({
67
64
  status: z.enum(["ready", "not-ready"]),
@@ -16,7 +16,6 @@ import {
16
16
  } from "../../acp/acp-credentials.js";
17
17
  import { syncAvatarToCloud } from "../../avatar/sync-avatar.js";
18
18
  import { syncWorkspaceIdentityToPlatform } from "../../cloud/sync-identity.js";
19
- import { maybeDefaultSpeechToCloud } from "../../config/cloud-speech-defaults.js";
20
19
  import { getCloudAssistantId } from "../../config/env.js";
21
20
  import { getConfig } from "../../config/loader.js";
22
21
  import { getCesClient } from "../../credential-execution/ces-runtime.js";
@@ -342,11 +341,6 @@ async function handleAddSecret({ body }: RouteHandlerArgs) {
342
341
  await refreshProvidersForRotatedCredential(service, field);
343
342
  }
344
343
  if (field === "assistant_api_key") {
345
- // Managed-speech availability needs the API key and the assistant
346
- // ID. Fire on each write that completes a piece of that set; the
347
- // hook no-ops until the connection is complete.
348
- // Detached, must not block the response.
349
- void maybeDefaultSpeechToCloud();
350
344
  // Same last-write-wins shape: the startup syncs no-op before live
351
345
  // registration, so re-enqueue them here. Both dedup and no-op until
352
346
  // the client and assistant id exist.
@@ -8,7 +8,6 @@
8
8
  import { z } from "zod";
9
9
 
10
10
  import { sanitizeForTts } from "../../calls/tts-text-sanitizer.js";
11
- import { managedSpeechVoices } from "../../cloud/cloud-speech.js";
12
11
  import { getConfig } from "../../config/loader.js";
13
12
  import { listCatalogProvidersForDisplay } from "../../tts/provider-catalog.js";
14
13
  import {
@@ -132,17 +131,6 @@ function handleListTtsProviders() {
132
131
  return { providers: listCatalogProvidersForDisplay() };
133
132
  }
134
133
 
135
- async function handleListCloudVoices() {
136
- const result = await managedSpeechVoices();
137
- if (!result.ok) {
138
- if (result.kind === "unavailable") {
139
- throw new ServiceUnavailableError(result.message);
140
- }
141
- throw new BadGatewayError(result.message);
142
- }
143
- return result.value;
144
- }
145
-
146
134
  async function handleSynthesizeTts({ body }: RouteHandlerArgs) {
147
135
  if (!body?.text || typeof body.text !== "string") {
148
136
  throw new BadRequestError("text is required");
@@ -234,32 +222,6 @@ export const ROUTES: RouteDefinition[] = [
234
222
  }),
235
223
  handler: handleListTtsProviders,
236
224
  },
237
- {
238
- operationId: "tts_managed_voices",
239
- endpoint: "tts/managed-voices",
240
- method: "GET",
241
- policy: {
242
- requiredScopes: ["settings.read"],
243
- allowedPrincipalTypes: ACTOR_PRINCIPALS,
244
- },
245
- summary: "List managed TTS voices",
246
- description:
247
- "Return the voices offered by Cadet Cloud TTS, fetched live from the cloud. Only currently-usable voices are returned; defaultModel is always one of them (null when none are offered).",
248
- tags: ["tts"],
249
- responseBody: z.object({
250
- voices: z.array(
251
- z.object({
252
- model: z.string(),
253
- label: z.string(),
254
- description: z.string(),
255
- sampleUrl: z.string(),
256
- source: z.string(),
257
- }),
258
- ),
259
- defaultModel: z.string().nullable(),
260
- }),
261
- handler: handleListCloudVoices,
262
- },
263
225
  {
264
226
  operationId: "tts_synthesize",
265
227
  endpoint: "tts/synthesize",
@@ -3,19 +3,13 @@
3
3
  *
4
4
  * Fixture plugin directories are written under the (per-test-process)
5
5
  * workspace plugins dir and converged against the real schedule store; the
6
- * only stubs are the notification emitter (recorded for assertions) and the
7
- * background-wake publisher (kept out for hermeticity, mirroring
8
- * schedule-store.test.ts).
6
+ * only stub is the notification emitter (recorded for assertions).
9
7
  */
10
8
 
11
9
  import { mkdirSync, rmSync, writeFileSync } from "node:fs";
12
10
  import { dirname, join } from "node:path";
13
11
  import { beforeEach, describe, expect, mock, test } from "bun:test";
14
12
 
15
- mock.module("../../background-wake/publisher.js", () => ({
16
- refreshBackgroundWakeIntent: () => {},
17
- }));
18
-
19
13
  const emittedSignals: Array<Record<string, unknown>> = [];
20
14
 
21
15
  /** When set, merged into the next emit results (e.g. a failure reason). */
@@ -32,10 +32,6 @@ mock.module("../../daemon/process-message.js", () => ({
32
32
  processMessageInBackground: async () => {},
33
33
  }));
34
34
 
35
- mock.module("../../background-wake/publisher.js", () => ({
36
- refreshBackgroundWakeIntent: () => {},
37
- }));
38
-
39
35
  mock.module("../../daemon/disk-pressure-background-gate.js", () => ({
40
36
  checkDiskPressureBackgroundGate: () => ({
41
37
  action: "allow",
@@ -49,13 +49,6 @@ const logger = getLogger("schedule-store");
49
49
 
50
50
  function notifySchedulesChanged(): void {
51
51
  publishSchedulesChanged();
52
- void import("../background-wake/publisher.js")
53
- .then(({ refreshBackgroundWakeIntent }) =>
54
- refreshBackgroundWakeIntent("schedule-changed"),
55
- )
56
- .catch((err) =>
57
- logger.warn({ err }, "Failed to queue background wake refresh"),
58
- );
59
52
  }
60
53
 
61
54
  export type ScheduleMode =
@@ -1,4 +1,3 @@
1
- import { refreshBackgroundWakeIntent } from "../background-wake/publisher.js";
2
1
  import { resolveSingleRouteProfileKey } from "../config/llm-resolver.js";
3
2
  import { getConfig } from "../config/loader.js";
4
3
  import { findConversationOrSubagent } from "../daemon/conversation-registry.js";
@@ -556,10 +555,6 @@ export function startScheduler(): SchedulerHandle {
556
555
  },
557
556
  };
558
557
 
559
- // Publish the initial background wake intent now that the scheduler is live
560
- // and its schedules are visible to `computeNextBackgroundWakeIntent`.
561
- refreshBackgroundWakeIntent("daemon-startup");
562
-
563
558
  return instance;
564
559
  }
565
560
 
@@ -144,7 +144,7 @@ async function main(): Promise<void> {
144
144
  // standalone process must do it itself so getCloudBaseUrl() resolves to
145
145
  // the persisted platform environment instead of the CADET_ENVIRONMENT
146
146
  // default — otherwise valid credentials are sent to the wrong platform and
147
- // rejected for both inference and background-wake requests.
147
+ // rejected for inference requests.
148
148
  await ensureCloudIdentityIds();
149
149
 
150
150
  // This process is the sole runner of schedule execution and hosts real agent
@@ -610,16 +610,8 @@ describe("normalizeSttError", () => {
610
610
  });
611
611
  });
612
612
 
613
- describe("cadet factory case", () => {
614
- test("constructs the cloud transcriber with no API key", () => {
615
- const transcriber = createDaemonBatchTranscriber(null, "cadet");
616
- expect(transcriber?.providerId).toBe("cadet");
617
- expect(transcriber?.boundaryId).toBe("daemon-batch");
618
- });
619
-
620
- test("still returns null for key-based providers without a key", () => {
621
- expect(createDaemonBatchTranscriber(null, "deepgram")).toBeNull();
622
- });
613
+ test("still returns null for key-based providers without a key", () => {
614
+ expect(createDaemonBatchTranscriber(null, "deepgram")).toBeNull();
623
615
  });
624
616
 
625
617
  describe("deepgram-flux factory case", () => {
@@ -205,32 +205,6 @@ export function normalizeSttError(err: unknown): SttError {
205
205
  return new SttError("provider-error", message);
206
206
  }
207
207
 
208
- // ---------------------------------------------------------------------------
209
- // Cadet Cloud adapter — implements BatchTranscriber on top of the
210
- // platform's cloud speech endpoint. No API key: the cloud connection
211
- // is the credential.
212
- // ---------------------------------------------------------------------------
213
-
214
- class CadetManagedBatchTranscriber implements BatchTranscriber {
215
- readonly providerId = "cadet" as const;
216
- readonly boundaryId = "daemon-batch" as const;
217
-
218
- constructor(private readonly language: string | undefined) {}
219
-
220
- async transcribe(
221
- request: SttTranscribeRequest,
222
- ): Promise<SttTranscribeResult> {
223
- const { cadetCloudTranscribe } =
224
- await import("../providers/speech-to-text/cadet-cloud.js");
225
- return cadetCloudTranscribe(
226
- request.audio,
227
- request.mimeType,
228
- request.signal,
229
- this.language,
230
- );
231
- }
232
- }
233
-
234
208
  /**
235
209
  * Create a `BatchTranscriber` for the daemon-batch boundary.
236
210
  *
@@ -241,10 +215,9 @@ class CadetManagedBatchTranscriber implements BatchTranscriber {
241
215
  * is unavailable.
242
216
  *
243
217
  * `language` is the spoken language, forwarded to providers whose batch API
244
- * accepts one: Deepgram (where `"multi"` also pins nova-3), xAI (where
218
+ * accepts one: Deepgram (where `"multi"` also pins nova-3) and xAI (where
245
219
  * `"multi"` is dropped because it is a Deepgram-specific value, not a
246
- * language code), and the Cadet Cloud path, whose cloud proxy passes
247
- * it to Deepgram server-side. Whisper and Gemini auto-detect natively and
220
+ * language code). Whisper and Gemini auto-detect natively and
248
221
  * take no language parameter, so it is silently ignored for them.
249
222
  *
250
223
  * Throws an {@link SttError} for a provider with no batch endpoint at all,
@@ -255,11 +228,6 @@ export function createDaemonBatchTranscriber(
255
228
  providerId: SttProviderId,
256
229
  language?: string,
257
230
  ): BatchTranscriber | null {
258
- // Cloud speech authenticates via the cloud connection, not an API
259
- // key. Callers pass canonical ids; the resolver maps legacy ones first.
260
- if (providerId === "cadet") {
261
- return new CadetManagedBatchTranscriber(language);
262
- }
263
231
  if (!apiKey) {
264
232
  return null;
265
233
  }
@@ -274,11 +242,9 @@ export function createDaemonBatchTranscriber(
274
242
  case "xai":
275
243
  return new XAIBatchTranscriber(apiKey, language);
276
244
  case "deepgram-flux":
277
- case "cadet-flux":
278
245
  // Same copy the resolver raises, so a direct factory caller and a
279
- // config-driven one report the mismatch identically. Both Flux
280
- // variants are streaming-only: the model has no batch endpoint, BYOK
281
- // or managed.
246
+ // config-driven one report the mismatch identically. Flux is
247
+ // streaming-only: the model has no batch endpoint.
282
248
  throw new SttError("provider-error", batchBoundaryGapReason(providerId), {
283
249
  userFacing: true,
284
250
  });
package/src/stt/types.ts CHANGED
@@ -52,15 +52,7 @@ export type SttProviderId =
52
52
  */
53
53
  | "deepgram-flux"
54
54
  | "google-gemini"
55
- | "xai"
56
- | "cadet"
57
- /**
58
- * Cloud Flux: the same conversational model as `deepgram-flux`, reached
59
- * through the cloud's speech relay instead of a Deepgram key. Dials the
60
- * relay's STT v2 endpoint asking for native Flux frames, so it keeps the
61
- * turn events the relay's default v1-shaped translation drops.
62
- */
63
- | "cadet-flux";
55
+ | "xai";
64
56
 
65
57
  /**
66
58
  * Telephony-specific STT capability class.