Skip to content

berd-call: read a separate OpenAI API key per service - #415

Closed
johnmatthewtennant wants to merge 1 commit into
mainfrom
jtennant/berd-call-service-keys
Closed

johnmatthewtennant wants to merge 1 commit into
mainfrom
jtennant/berd-call-service-keys

Conversation

@johnmatthewtennant

@johnmatthewtennant johnmatthewtennant commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Summary

The Buzz Berd Call plugin is adding per-service OpenAI endpoint settings (URL plus its own key for realtime, speech to text and text to speech). berd-call read only OPENAI_API_KEY for all three, so a per-service key could not be passed.

Each service now reads its own variable and falls back to OPENAI_API_KEY when it is unset or blank, so existing setups are unchanged:

Service Flag Variable
Realtime and Expert-Spokesperson --realtime-url OPENAI_REALTIME_API_KEY
Speech to text --stt-url OPENAI_STT_API_KEY
Text to speech --tts-url OPENAI_TTS_API_KEY
  • One helper, berd_call::openai::openai_key(kind_var), replaces the four inline OPENAI_API_KEY reads. openai_key_var reports which variable supplied the key.
  • Missing-key errors, the public TTS and STT startup errors, and the STT benchmark credential_source name the variable that applies. Missing-key messages still contain OPENAI_API_KEY is required.
  • The README documents the new variables.

Related issue

N/A. none found.

Testing

Unit tests in openai.rs cover a service key winning over OPENAI_API_KEY, fallback when the service key is unset, and fallback when it is blank. Before the change the winning-key test fails (left: Some(("OPENAI_API_KEY", "shared")), right: Some(("OPENAI_TTS_API_KEY", "tts"))); after it, it passes.

End to end, berd-call synthesize --tts-backend openai ... --allow-paid-openai against a local server that logs the Authorization header (OPENAI_BASE_URL pointed at it):

Environment Header the server saw
OPENAI_API_KEY=shared-key Bearer shared-key
OPENAI_API_KEY=shared-key OPENAI_TTS_API_KEY=tts-key Bearer tts-key
OPENAI_API_KEY=shared-key OPENAI_TTS_API_KEY= (blank) Bearer shared-key
neither OPENAI_TTS_API_KEY or OPENAI_API_KEY is required

The realtime and STT paths share the same helper and are covered by the unit tests, not by a live connection. No UI change.

🤖 Generated with Claude Code

Realtime, speech to text and text to speech each read their own key
(OPENAI_REALTIME_API_KEY, OPENAI_STT_API_KEY, OPENAI_TTS_API_KEY) and
fall back to OPENAI_API_KEY when it is unset or blank. Error messages,
public startup errors and the STT benchmark credential_source name the
variable that applies.

Signed-off-by: John Tennant <jtennant@block.xyz>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@johnmatthewtennant

Copy link
Copy Markdown
Contributor Author

🤖 Folded into #416 for review and merge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant