@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.
- package/node_modules/@mycadet/ces-client/node_modules/@mycadet/service-contracts/src/__tests__/ingress.test.ts +2 -2
- package/node_modules/@mycadet/ces-client/node_modules/@mycadet/service-contracts/src/ingress.ts +2 -2
- package/node_modules/@mycadet/gateway-client/node_modules/@mycadet/service-contracts/src/__tests__/ingress.test.ts +2 -2
- package/node_modules/@mycadet/gateway-client/node_modules/@mycadet/service-contracts/src/ingress.ts +2 -2
- package/node_modules/@mycadet/gateway-client/src/gateway-ipc-contracts.ts +0 -20
- package/node_modules/@mycadet/service-contracts/src/__tests__/ingress.test.ts +2 -2
- package/node_modules/@mycadet/service-contracts/src/ingress.ts +2 -2
- package/openapi.yaml +2 -708
- package/package.json +2 -3
- package/scripts/sync-web-search-catalog.ts +1 -2
- package/src/__tests__/cloud-profile-guard.test.ts +2 -2
- package/src/__tests__/config-schema.test.ts +6 -38
- package/src/__tests__/conversation-queue.test.ts +45 -6
- package/src/__tests__/db-readiness-http-gate.test.ts +0 -6
- package/src/__tests__/persist-onboarding-artifacts.test.ts +0 -1
- package/src/__tests__/persona-resolver.test.ts +0 -51
- package/src/__tests__/provider-cloud-proxy-integration.test.ts +2 -110
- package/src/__tests__/run-due-schedules.test.ts +0 -4
- package/src/__tests__/schedule-store.test.ts +0 -12
- package/src/__tests__/stt-stream-session.test.ts +4 -4
- package/src/__tests__/telephony-tts-guard.test.ts +2 -50
- package/src/__tests__/voice-config-update.test.ts +12 -167
- package/src/__tests__/web-search-catalog-parity.test.ts +0 -2
- package/src/__tests__/workspace-migration-130-speech-mode-to-provider.test.ts +9 -7
- package/src/__tests__/workspace-migration-132-web-search-mode-to-provider.test.ts +6 -6
- package/src/calls/__tests__/voice-session-bridge.test.ts +1 -4
- package/src/calls/resolve-call-tts-provider.ts +6 -25
- package/src/calls/telephony-credential-preflight.ts +0 -10
- package/src/calls/telephony-tts-capability.ts +1 -17
- package/src/cli/commands/tts.ts +1 -2
- package/src/cli/index.help.ts +0 -2
- package/src/cli/program.ts +0 -2
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +4 -42
- package/src/config/schemas/__tests__/stt.test.ts +10 -14
- package/src/config/schemas/services.ts +5 -6
- package/src/config/schemas/stt.ts +1 -3
- package/src/config/schemas/tts.ts +1 -30
- package/src/daemon/daemon-readiness.ts +4 -29
- package/src/daemon/lifecycle.ts +0 -31
- package/src/daemon/providers-setup.ts +0 -8
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +0 -1
- package/src/heartbeat/heartbeat-service.ts +1 -66
- package/src/ipc/__tests__/db-readiness-ipc-gate.test.ts +1 -9
- package/src/live-voice/__tests__/live-voice-credential-preflight.test.ts +0 -44
- package/src/live-voice/__tests__/live-voice-flux-turn-end.test.ts +4 -6
- package/src/live-voice/__tests__/live-voice-stt.test.ts +1 -1
- package/src/live-voice/live-voice-credential-preflight.ts +9 -33
- package/src/live-voice/live-voice-session.ts +10 -6
- package/src/live-voice/live-voice-tts.ts +1 -8
- package/src/plugins/defaults/memory/worker.ts +3 -3
- package/src/prompts/persona-resolver.ts +0 -35
- package/src/providers/__tests__/search-provider-catalog.test.ts +5 -8
- package/src/providers/__tests__/voice-error-copy.test.ts +9 -10
- package/src/providers/search-provider-catalog.ts +7 -39
- package/src/providers/speech-to-text/__tests__/provider-catalog.test.ts +3 -47
- package/src/providers/speech-to-text/__tests__/resolve.test.ts +6 -372
- package/src/providers/speech-to-text/provider-catalog.ts +2 -73
- package/src/providers/speech-to-text/resolve.ts +3 -120
- package/src/runtime/http-router-types.ts +1 -3
- package/src/runtime/http-server.ts +1 -1
- package/src/runtime/routes/__tests__/tts-routes.test.ts +2 -6
- package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +7 -7
- package/src/runtime/routes/index.ts +0 -4
- package/src/runtime/routes/live-voice-routes.test.ts +4 -11
- package/src/runtime/routes/live-voice-routes.ts +8 -11
- package/src/runtime/routes/secret-routes.ts +0 -6
- package/src/runtime/routes/tts-routes.ts +0 -38
- package/src/schedule/__tests__/plugin-schedule-reconciler.test.ts +1 -7
- package/src/schedule/__tests__/worker-mcp-readiness.test.ts +0 -4
- package/src/schedule/schedule-store.ts +0 -7
- package/src/schedule/scheduler.ts +0 -5
- package/src/schedule/worker.ts +1 -1
- package/src/stt/__tests__/daemon-batch-transcriber.test.ts +2 -10
- package/src/stt/daemon-batch-transcriber.ts +4 -38
- package/src/stt/types.ts +1 -9
- package/src/tools/network/__tests__/web-search.test.ts +3 -250
- package/src/tools/network/web-search.ts +4 -165
- package/src/tts/__tests__/provider-resolution.test.ts +0 -5
- package/src/tts/provider-catalog.ts +0 -4
- package/src/tts/types.ts +0 -1
- package/src/__tests__/cloud-speech-defaults.test.ts +0 -330
- package/src/__tests__/migration-cross-version-compatibility.test.ts +0 -1708
- package/src/__tests__/migration-export-http.test.ts +0 -557
- package/src/__tests__/migration-export-streaming.test.ts +0 -350
- package/src/__tests__/migration-export-to-gcs.test.ts +0 -706
- package/src/__tests__/migration-import-commit-http.test.ts +0 -1176
- package/src/__tests__/migration-import-from-gcs.test.ts +0 -534
- package/src/__tests__/migration-import-from-path.test.ts +0 -324
- package/src/__tests__/migration-import-from-url.test.ts +0 -588
- package/src/__tests__/migration-import-preflight-http.test.ts +0 -739
- package/src/__tests__/migration-jobs-status.test.ts +0 -139
- package/src/__tests__/migration-parity-persistence.test.ts +0 -1891
- package/src/__tests__/migration-transport.test.ts +0 -1089
- package/src/__tests__/migration-validate-http.test.ts +0 -634
- package/src/__tests__/migration-wizard.test.ts +0 -1395
- package/src/__tests__/rebind-secrets-screen.test.ts +0 -876
- package/src/__tests__/sanitize-config-for-transfer.test.ts +0 -259
- package/src/__tests__/transfer-progress-screen.test.ts +0 -1217
- package/src/__tests__/validation-results-screen.test.ts +0 -1130
- package/src/__tests__/vbundle-pax-and-symlink.test.ts +0 -147
- package/src/background-wake/background-wake-routes.test.ts +0 -906
- package/src/background-wake/cloud-client.test.ts +0 -328
- package/src/background-wake/cloud-client.ts +0 -196
- package/src/background-wake/next-wake.test.ts +0 -335
- package/src/background-wake/next-wake.ts +0 -188
- package/src/background-wake/publisher.ts +0 -93
- package/src/background-wake/wake-intent-hooks.test.ts +0 -234
- package/src/cli/commands/__tests__/backup.test.ts +0 -363
- package/src/cli/commands/backup.help.ts +0 -180
- package/src/cli/commands/backup.ts +0 -398
- package/src/cloud/cloud-speech.test.ts +0 -335
- package/src/cloud/cloud-speech.ts +0 -300
- package/src/config/cloud-speech-defaults.ts +0 -300
- package/src/config/sanitize-for-transfer.ts +0 -111
- package/src/live-voice/__tests__/live-voice-cloud-speech-fallback.test.ts +0 -250
- package/src/providers/speech-to-text/__tests__/cadet-cloud-realtime.test.ts +0 -457
- package/src/providers/speech-to-text/__tests__/cadet-cloud.test.ts +0 -271
- package/src/providers/speech-to-text/__tests__/cadet-speech-relay-connection.test.ts +0 -126
- package/src/providers/speech-to-text/cadet-cloud-flux-realtime.ts +0 -309
- package/src/providers/speech-to-text/cadet-cloud-realtime.ts +0 -315
- package/src/providers/speech-to-text/cadet-cloud.ts +0 -108
- package/src/providers/speech-to-text/cadet-speech-relay-connection.ts +0 -176
- package/src/runtime/migrations/__tests__/gcs-signed-url.test.ts +0 -254
- package/src/runtime/migrations/__tests__/job-registry.test.ts +0 -346
- package/src/runtime/migrations/__tests__/origin-mode.test.ts +0 -62
- package/src/runtime/migrations/__tests__/rebind-secrets-credentials.test.ts +0 -184
- package/src/runtime/migrations/__tests__/staged-import-path.test.ts +0 -110
- package/src/runtime/migrations/__tests__/v1-test-helpers.ts +0 -112
- package/src/runtime/migrations/__tests__/vbundle-builder-credentials.test.ts +0 -285
- package/src/runtime/migrations/__tests__/vbundle-builder-fd-leak.test.ts +0 -126
- package/src/runtime/migrations/__tests__/vbundle-builder-v1-shape.test.ts +0 -253
- package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +0 -208
- package/src/runtime/migrations/__tests__/vbundle-import-parity.test.ts +0 -485
- package/src/runtime/migrations/__tests__/vbundle-import-policy.test.ts +0 -349
- package/src/runtime/migrations/__tests__/vbundle-import-version-compat.test.ts +0 -196
- package/src/runtime/migrations/__tests__/vbundle-legacy-user-md.test.ts +0 -551
- package/src/runtime/migrations/__tests__/vbundle-metadata-merge-integration.test.ts +0 -428
- package/src/runtime/migrations/__tests__/vbundle-metadata-merge.test.ts +0 -220
- package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +0 -1823
- package/src/runtime/migrations/__tests__/vbundle-streaming-validator.test.ts +0 -598
- package/src/runtime/migrations/__tests__/vbundle-symlink-importer.test.ts +0 -463
- package/src/runtime/migrations/__tests__/vbundle-symlink-streaming-importer.test.ts +0 -538
- package/src/runtime/migrations/__tests__/vbundle-symlink-streaming.test.ts +0 -515
- package/src/runtime/migrations/__tests__/vbundle-symlink-tar.test.ts +0 -453
- package/src/runtime/migrations/__tests__/vbundle-symlink-walker.test.ts +0 -319
- package/src/runtime/migrations/__tests__/vbundle-tar-stream.test.ts +0 -240
- package/src/runtime/migrations/__tests__/vbundle-validator-v1-schema.test.ts +0 -473
- package/src/runtime/migrations/gcs-signed-url.ts +0 -190
- package/src/runtime/migrations/job-registry.ts +0 -297
- package/src/runtime/migrations/migration-transport.ts +0 -612
- package/src/runtime/migrations/migration-wizard.ts +0 -747
- package/src/runtime/migrations/origin-mode.ts +0 -42
- package/src/runtime/migrations/rebind-secrets-screen.ts +0 -412
- package/src/runtime/migrations/staged-import-path.ts +0 -116
- package/src/runtime/migrations/transfer-progress-screen.ts +0 -323
- package/src/runtime/migrations/validation-results-screen.ts +0 -469
- package/src/runtime/migrations/vbundle-builder.ts +0 -1382
- package/src/runtime/migrations/vbundle-import-analyzer.ts +0 -405
- package/src/runtime/migrations/vbundle-import-policy.ts +0 -241
- package/src/runtime/migrations/vbundle-importer.ts +0 -826
- package/src/runtime/migrations/vbundle-metadata-merge.ts +0 -113
- package/src/runtime/migrations/vbundle-streaming-importer.ts +0 -2844
- package/src/runtime/migrations/vbundle-streaming-validator.ts +0 -426
- package/src/runtime/migrations/vbundle-tar-stream.ts +0 -244
- package/src/runtime/migrations/vbundle-validator.ts +0 -724
- package/src/runtime/routes/__tests__/migration-cadet-metadata-reconcile.test.ts +0 -227
- package/src/runtime/routes/__tests__/migration-export-secrets-redacted.test.ts +0 -54
- package/src/runtime/routes/__tests__/migration-import-allowed-hosts-env.test.ts +0 -70
- package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +0 -257
- package/src/runtime/routes/background-wake-routes.ts +0 -387
- package/src/runtime/routes/migration-routes.ts +0 -2584
- package/src/tools/network/__tests__/cloud-search-proxy.test.ts +0 -282
- package/src/tools/network/cloud-search-proxy.ts +0 -211
- package/src/tts/__tests__/cadet-provider.test.ts +0 -253
- package/src/tts/providers/cadet-provider.ts +0 -244
- 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
|
-
|
|
519
|
-
|
|
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
|
|
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
|
|
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
|
|
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/
|
|
131
|
-
expect(ROUTES).toHaveLength(
|
|
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("
|
|
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: "
|
|
209
|
+
providerId: "deepgram",
|
|
210
210
|
boundaryId: "daemon-batch",
|
|
211
211
|
transcribe: async () => {
|
|
212
|
-
//
|
|
213
|
-
//
|
|
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
|
-
//
|
|
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("
|
|
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: "
|
|
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
|
|
5
|
-
*
|
|
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("
|
|
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(["
|
|
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 —
|
|
5
|
-
*
|
|
6
|
-
*
|
|
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:
|
|
55
|
-
//
|
|
56
|
-
//
|
|
57
|
-
//
|
|
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
|
-
"
|
|
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
|
|
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
|
|
package/src/schedule/worker.ts
CHANGED
|
@@ -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
|
|
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
|
-
|
|
614
|
-
|
|
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)
|
|
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)
|
|
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.
|
|
280
|
-
//
|
|
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.
|