refactor(server): centralize speech provider resolver typing
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import type pino from "pino";
|
||||
import type { SpeechToTextProvider, TranscriptionResult } from "../speech/speech-provider.js";
|
||||
import { toResolver, type Resolvable } from "../speech/provider-resolver.js";
|
||||
import { maybePersistDebugAudio } from "./stt-debug.js";
|
||||
import { parsePcm16MonoWav, parsePcmRateFromFormat } from "../speech/audio.js";
|
||||
import { Pcm16MonoResampler } from "./pcm16-resampler.js";
|
||||
@@ -44,11 +45,11 @@ export class STTManager {
|
||||
constructor(
|
||||
sessionId: string,
|
||||
logger: pino.Logger,
|
||||
stt: SpeechToTextProvider | null | (() => SpeechToTextProvider | null)
|
||||
stt: Resolvable<SpeechToTextProvider | null>
|
||||
) {
|
||||
this.sessionId = sessionId;
|
||||
this.logger = logger.child({ module: "agent", component: "stt-manager", sessionId });
|
||||
this.resolveStt = typeof stt === "function" ? stt : () => stt;
|
||||
this.resolveStt = toResolver(stt);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type pino from "pino";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import type { TextToSpeechProvider } from "../speech/speech-provider.js";
|
||||
import { toResolver, type Resolvable } from "../speech/provider-resolver.js";
|
||||
import type { SessionOutboundMessage } from "../messages.js";
|
||||
|
||||
interface PendingPlayback {
|
||||
@@ -100,10 +101,10 @@ export class TTSManager {
|
||||
constructor(
|
||||
sessionId: string,
|
||||
logger: pino.Logger,
|
||||
tts: TextToSpeechProvider | null | (() => TextToSpeechProvider | null)
|
||||
tts: Resolvable<TextToSpeechProvider | null>
|
||||
) {
|
||||
this.logger = logger.child({ module: "agent", component: "tts-manager", sessionId });
|
||||
this.resolveTts = typeof tts === "function" ? tts : () => tts;
|
||||
this.resolveTts = toResolver(tts);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,6 +11,7 @@ import type {
|
||||
SpeechToTextProvider,
|
||||
StreamingTranscriptionSession,
|
||||
} from "../speech/speech-provider.js";
|
||||
import { toResolver, type Resolvable } from "../speech/provider-resolver.js";
|
||||
import { parsePcmRateFromFormat, pcm16lePeakAbs } from "../speech/audio.js";
|
||||
|
||||
const PCM_CHANNELS = 1;
|
||||
@@ -126,19 +127,14 @@ export class DictationStreamManager {
|
||||
logger: pino.Logger;
|
||||
emit: (msg: DictationStreamOutboundMessage) => void;
|
||||
sessionId: string;
|
||||
stt: SpeechToTextProvider | null | (() => SpeechToTextProvider | null);
|
||||
stt: Resolvable<SpeechToTextProvider | null>;
|
||||
finalTimeoutMs?: number;
|
||||
autoCommitSeconds?: number;
|
||||
}) {
|
||||
this.logger = params.logger.child({ component: "dictation-stream-manager" });
|
||||
this.emit = params.emit;
|
||||
this.sessionId = params.sessionId;
|
||||
if (typeof params.stt === "function") {
|
||||
this.resolveStt = params.stt;
|
||||
} else {
|
||||
const sttProvider = params.stt;
|
||||
this.resolveStt = () => sttProvider;
|
||||
}
|
||||
this.resolveStt = toResolver(params.stt);
|
||||
this.finalTimeoutMs = params.finalTimeoutMs ?? DEFAULT_DICTATION_FINAL_TIMEOUT_MS;
|
||||
this.autoCommitSeconds =
|
||||
params.autoCommitSeconds ??
|
||||
|
||||
@@ -130,6 +130,7 @@ import {
|
||||
listLocalSpeechModels,
|
||||
type LocalSpeechModelId,
|
||||
} from "./speech/providers/local/models.js";
|
||||
import type { Resolvable } from "./speech/provider-resolver.js";
|
||||
import type { SpeechReadinessSnapshot } from "./speech/speech-runtime.js";
|
||||
import type pino from "pino";
|
||||
|
||||
@@ -324,8 +325,8 @@ export type SessionOptions = {
|
||||
agentManager: AgentManager;
|
||||
agentStorage: AgentStorage;
|
||||
createAgentMcpTransport: AgentMcpTransportFactory;
|
||||
stt: SpeechToTextProvider | null | (() => SpeechToTextProvider | null);
|
||||
tts: TextToSpeechProvider | null | (() => TextToSpeechProvider | null);
|
||||
stt: Resolvable<SpeechToTextProvider | null>;
|
||||
tts: Resolvable<TextToSpeechProvider | null>;
|
||||
terminalManager: TerminalManager | null;
|
||||
voice?: {
|
||||
voiceAgentMcpStdio?: VoiceMcpStdioConfig | null;
|
||||
@@ -340,7 +341,7 @@ export type SessionOptions = {
|
||||
};
|
||||
dictation?: {
|
||||
finalTimeoutMs?: number;
|
||||
stt?: SpeechToTextProvider | null | (() => SpeechToTextProvider | null);
|
||||
stt?: Resolvable<SpeechToTextProvider | null>;
|
||||
localModels?: {
|
||||
modelsDir: string;
|
||||
defaultModelIds: LocalSpeechModelId[];
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
export type Resolvable<T> = T | (() => T);
|
||||
|
||||
export function toResolver<T>(value: Resolvable<T>): () => T {
|
||||
if (typeof value === "function") {
|
||||
return value as () => T;
|
||||
}
|
||||
return () => value;
|
||||
}
|
||||
@@ -26,6 +26,7 @@ import type { AgentProviderRuntimeSettingsMap } from "./agent/provider-launch-co
|
||||
import { PushTokenStore } from "./push/token-store.js";
|
||||
import { PushService } from "./push/push-service.js";
|
||||
import type { SpeechToTextProvider, TextToSpeechProvider } from "./speech/speech-provider.js";
|
||||
import type { Resolvable } from "./speech/provider-resolver.js";
|
||||
import type { SpeechReadinessSnapshot } from "./speech/speech-runtime.js";
|
||||
import type { LocalSpeechModelId } from "./speech/providers/local/models.js";
|
||||
import type {
|
||||
@@ -94,18 +95,12 @@ export class VoiceAssistantWebSocketServer {
|
||||
private readonly pushTokenStore: PushTokenStore;
|
||||
private readonly pushService: PushService;
|
||||
private readonly createAgentMcpTransport: AgentMcpTransportFactory;
|
||||
private readonly stt:
|
||||
| SpeechToTextProvider
|
||||
| null
|
||||
| (() => SpeechToTextProvider | null);
|
||||
private readonly tts:
|
||||
| TextToSpeechProvider
|
||||
| null
|
||||
| (() => TextToSpeechProvider | null);
|
||||
private readonly stt: Resolvable<SpeechToTextProvider | null>;
|
||||
private readonly tts: Resolvable<TextToSpeechProvider | null>;
|
||||
private readonly terminalManager: TerminalManager | null;
|
||||
private readonly dictation: {
|
||||
finalTimeoutMs?: number;
|
||||
stt?: SpeechToTextProvider | null | (() => SpeechToTextProvider | null);
|
||||
stt?: Resolvable<SpeechToTextProvider | null>;
|
||||
localModels?: {
|
||||
modelsDir: string;
|
||||
defaultModelIds: LocalSpeechModelId[];
|
||||
@@ -135,8 +130,8 @@ export class VoiceAssistantWebSocketServer {
|
||||
createAgentMcpTransport: AgentMcpTransportFactory,
|
||||
wsConfig: WebSocketServerConfig,
|
||||
speech?: {
|
||||
stt: SpeechToTextProvider | null | (() => SpeechToTextProvider | null);
|
||||
tts: TextToSpeechProvider | null | (() => TextToSpeechProvider | null);
|
||||
stt: Resolvable<SpeechToTextProvider | null>;
|
||||
tts: Resolvable<TextToSpeechProvider | null>;
|
||||
},
|
||||
terminalManager?: TerminalManager | null,
|
||||
voice?: {
|
||||
@@ -146,7 +141,7 @@ export class VoiceAssistantWebSocketServer {
|
||||
},
|
||||
dictation?: {
|
||||
finalTimeoutMs?: number;
|
||||
stt?: SpeechToTextProvider | null | (() => SpeechToTextProvider | null);
|
||||
stt?: Resolvable<SpeechToTextProvider | null>;
|
||||
localModels?: {
|
||||
modelsDir: string;
|
||||
defaultModelIds: LocalSpeechModelId[];
|
||||
|
||||
Reference in New Issue
Block a user