fix(ci): resolve type regressions on main

This commit is contained in:
Peter Steinberger
2026-03-08 03:11:14 +00:00
parent 9c8e34da9d
commit f72114173c
3 changed files with 88 additions and 6 deletions

View File

@@ -189,4 +189,30 @@ describe("normalizeVoiceCallConfig", () => {
expect(normalized.tunnel.provider).toBe("none");
expect(normalized.webhookSecurity.allowedHosts).toEqual([]);
});
it("accepts partial nested TTS overrides and preserves nested objects", () => {
const normalized = normalizeVoiceCallConfig({
tts: {
provider: "elevenlabs",
elevenlabs: {
apiKey: {
source: "env",
provider: "elevenlabs",
id: "ELEVENLABS_API_KEY",
},
voiceSettings: {
speed: 1.1,
},
},
},
});
expect(normalized.tts?.provider).toBe("elevenlabs");
expect(normalized.tts?.elevenlabs?.apiKey).toEqual({
source: "env",
provider: "elevenlabs",
id: "ELEVENLABS_API_KEY",
});
expect(normalized.tts?.elevenlabs?.voiceSettings).toEqual({ speed: 1.1 });
});
});

View File

@@ -368,6 +368,55 @@ function cloneDefaultVoiceCallConfig(): VoiceCallConfig {
return structuredClone(DEFAULT_VOICE_CALL_CONFIG);
}
function normalizeVoiceCallTtsConfig(
defaults: VoiceCallTtsConfig,
overrides: DeepPartial<NonNullable<VoiceCallTtsConfig>> | undefined,
): VoiceCallTtsConfig {
if (!defaults && !overrides) {
return undefined;
}
return TtsConfigSchema.parse({
...(defaults ?? {}),
...(overrides ?? {}),
modelOverrides:
defaults?.modelOverrides || overrides?.modelOverrides
? {
...(defaults?.modelOverrides ?? {}),
...(overrides?.modelOverrides ?? {}),
}
: undefined,
elevenlabs:
defaults?.elevenlabs || overrides?.elevenlabs
? {
...(defaults?.elevenlabs ?? {}),
...(overrides?.elevenlabs ?? {}),
voiceSettings:
defaults?.elevenlabs?.voiceSettings || overrides?.elevenlabs?.voiceSettings
? {
...(defaults?.elevenlabs?.voiceSettings ?? {}),
...(overrides?.elevenlabs?.voiceSettings ?? {}),
}
: undefined,
}
: undefined,
openai:
defaults?.openai || overrides?.openai
? {
...(defaults?.openai ?? {}),
...(overrides?.openai ?? {}),
}
: undefined,
edge:
defaults?.edge || overrides?.edge
? {
...(defaults?.edge ?? {}),
...(overrides?.edge ?? {}),
}
: undefined,
});
}
export function normalizeVoiceCallConfig(config: VoiceCallConfigInput): VoiceCallConfig {
const defaults = cloneDefaultVoiceCallConfig();
return {
@@ -387,7 +436,7 @@ export function normalizeVoiceCallConfig(config: VoiceCallConfigInput): VoiceCal
},
streaming: { ...defaults.streaming, ...config.streaming },
stt: { ...defaults.stt, ...config.stt },
tts: config.tts ?? defaults.tts,
tts: normalizeVoiceCallTtsConfig(defaults.tts, config.tts),
};
}

View File

@@ -64,7 +64,9 @@ export type GatewayService = {
readRuntime: (env: GatewayServiceEnv) => Promise<GatewayServiceRuntime>;
};
const GATEWAY_SERVICE_REGISTRY = {
type SupportedGatewayServicePlatform = "darwin" | "linux" | "win32";
const GATEWAY_SERVICE_REGISTRY: Record<SupportedGatewayServicePlatform, GatewayService> = {
darwin: {
label: "LaunchAgent",
loadedText: "loaded",
@@ -101,12 +103,17 @@ const GATEWAY_SERVICE_REGISTRY = {
readCommand: readScheduledTaskCommand,
readRuntime: readScheduledTaskRuntime,
},
} satisfies Partial<Record<NodeJS.Platform, GatewayService>>;
};
function isSupportedGatewayServicePlatform(
platform: NodeJS.Platform,
): platform is SupportedGatewayServicePlatform {
return Object.hasOwn(GATEWAY_SERVICE_REGISTRY, platform);
}
export function resolveGatewayService(): GatewayService {
const service = GATEWAY_SERVICE_REGISTRY[process.platform];
if (service) {
return service;
if (isSupportedGatewayServicePlatform(process.platform)) {
return GATEWAY_SERVICE_REGISTRY[process.platform];
}
throw new Error(`Gateway service install not supported on ${process.platform}`);
}