Skip to content

Commit f121bd3

Browse files
fix(voice): retain STT environment configuration
1 parent 20b35a7 commit f121bd3

6 files changed

Lines changed: 35 additions & 10 deletions

File tree

src-tauri/src/commands/openai_audio.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ enum OpenAiStreamCommand {
113113
pub struct OpenAiVoiceStatus {
114114
stt_configured: bool,
115115
tts_configured: bool,
116+
stt_configuration_source: OpenAiVoiceConfigurationSource,
116117
tts_configuration_source: OpenAiVoiceConfigurationSource,
117118
stt_unavailable_reason: Option<String>,
118119
tts_unavailable_reason: Option<String>,
@@ -254,6 +255,17 @@ fn tts_configuration_source() -> OpenAiVoiceConfigurationSource {
254255
}
255256
}
256257

258+
fn stt_configuration_source() -> OpenAiVoiceConfigurationSource {
259+
if [BASE_URL_ENV, STT_MODEL_ENV]
260+
.iter()
261+
.any(|name| env_trimmed(name).is_some())
262+
{
263+
OpenAiVoiceConfigurationSource::Environment
264+
} else {
265+
OpenAiVoiceConfigurationSource::Default
266+
}
267+
}
268+
257269
fn endpoint(path: &str) -> Result<String, String> {
258270
endpoint_for_base_url(&base_url()?, path)
259271
}
@@ -343,6 +355,7 @@ pub async fn get_openai_voice_status(
343355
Ok(OpenAiVoiceStatus {
344356
stt_configured,
345357
tts_configured,
358+
stt_configuration_source: stt_configuration_source(),
346359
tts_configuration_source: tts_configuration_source(),
347360
stt_unavailable_reason: stt_error,
348361
tts_unavailable_reason: tts_error,
@@ -1302,6 +1315,7 @@ mod tests {
13021315
#[test]
13031316
fn voice_configuration_uses_berd_scoped_environment_names() {
13041317
assert_eq!(BASE_URL_ENV, "BERD_OPENAI_VOICE_BASE_URL");
1318+
assert_eq!(STT_MODEL_ENV, "BERD_OPENAI_STT_MODEL");
13051319
assert_eq!(TTS_MODEL_ENV, "BERD_OPENAI_TTS_MODEL");
13061320
assert_eq!(TTS_VOICE_ENV, "BERD_OPENAI_TTS_VOICE");
13071321
}

src-tauri/src/commands/openai_voice_credentials.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ pub(crate) fn clear(credential: OpenAiVoiceCredential) -> Result<(), String> {
9595
|| clear_account(LEGACY_TTS_KEYCHAIN_ACCOUNT),
9696
)
9797
}
98+
9899
pub(crate) fn require(credential: OpenAiVoiceCredential) -> Result<String, String> {
99100
read(credential)?.ok_or_else(|| credential.missing_message().to_string())
100101
}

src/features/voice-conversation/api/openAiVoice.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import type {
99
export interface OpenAiVoiceStatus {
1010
sttConfigured: boolean;
1111
ttsConfigured: boolean;
12+
sttConfigurationSource: "default" | "environment";
1213
ttsConfigurationSource: "default" | "environment";
1314
sttUnavailableReason: string | null;
1415
ttsUnavailableReason: string | null;

src/features/voice-conversation/hooks/useOpenAiVoiceSetup.test.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ function status(configured: boolean): OpenAiVoiceStatus {
3535
return {
3636
sttConfigured: configured,
3737
ttsConfigured: configured,
38+
sttConfigurationSource: "default",
3839
ttsConfigurationSource: "default",
3940
sttUnavailableReason: null,
4041
ttsUnavailableReason: null,

src/features/voice-conversation/ui/VoiceSettings.test.tsx

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ const openAiStatusState = vi.hoisted(() => ({
5454
current: {
5555
sttConfigured: true,
5656
ttsConfigured: true,
57+
sttConfigurationSource: "default" as "default" | "environment",
5758
ttsConfigurationSource: "default" as "default" | "environment",
5859
sttUnavailableReason: null,
5960
ttsUnavailableReason: null,
@@ -228,6 +229,7 @@ describe("VoiceSettings", () => {
228229
openAiStatusState.current = {
229230
sttConfigured: true,
230231
ttsConfigured: true,
232+
sttConfigurationSource: "default",
231233
ttsConfigurationSource: "default",
232234
sttUnavailableReason: null,
233235
ttsUnavailableReason: null,
@@ -295,19 +297,20 @@ describe("VoiceSettings", () => {
295297
).toBeInTheDocument();
296298
});
297299

298-
it("saves a dedicated OpenAI speech-to-text API key", async () => {
300+
it("labels speech-to-text environment overrides", async () => {
299301
inputState.backend = "openai";
300-
setupState.current = setup(pocketStatus({ pocketInstalled: true }));
302+
openAiStatusState.current = {
303+
...openAiStatusState.current,
304+
sttConfigurationSource: "environment",
305+
};
306+
setupState.current = setup(pocketStatus());
301307
renderWithProviders(<VoiceSettings />);
302308

303-
const user = userEvent.setup();
304-
await user.type(
305-
screen.getByLabelText("OpenAI speech-to-text API key"),
306-
"stt-secret",
307-
);
308-
await user.click(screen.getAllByRole("button", { name: "Save key" })[0]);
309-
310-
expect(openAiApiMocks.setSttApiKey).toHaveBeenCalledWith("stt-secret");
309+
expect(
310+
await screen.findByText(
311+
"Development configuration is overridden by the Berd process environment.",
312+
),
313+
).toBeInTheDocument();
311314
});
312315

313316
it("saves the shared OpenAI voice key from the text-to-speech settings", async () => {

src/features/voice-conversation/ui/VoiceSettings.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,11 @@ export function VoiceSettings() {
247247
: t("voice.openAiSttNotConfigured")
248248
: t("voice.openAiChecking"))}
249249
</p>
250+
{openAiStatus?.sttConfigurationSource === "environment" ? (
251+
<p className="text-xs text-muted-foreground">
252+
{t("voice.openAiEnvironmentOverride")}
253+
</p>
254+
) : null}
250255
</div>
251256
) : input.backend === "macos" ? (
252257
<MacSpeechSettings setup={macSpeechSetup} />

0 commit comments

Comments
 (0)