Skip to content

Conversation

@lorenjphillips
Copy link

@lorenjphillips lorenjphillips commented Dec 7, 2025

Hey! Noticed the real-time-voicebot project had hardcoded API keys in the code which isn't great for security or usability.

Made a few changes:

  • Moved API keys to env vars using python-dotenv
  • Added .env.example so poeple know what keys they need
  • Updated the README with setup steps

Follows the same pattern as rag-voice-agent and other projects in the repo. Let me know if you want any changes!

Summary by CodeRabbit

  • New Features

    • Environment-based API key configuration via .env for simpler, more secure setup.
  • Improvements

    • Startup now validates presence of required API keys and surfaces errors early.
    • Minor runtime behavior and message formatting tweaks for more consistent transcripts and responses.
  • Documentation

    • Updated setup and run instructions to include copying .env and installing dependencies.
  • Chores

    • Added an example .env file with placeholder API keys.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 7, 2025

Walkthrough

Adds a .env.example, updates README to use dotenv workflow and install dependencies, and refactors app.py to load ASSEMBLYAI, OPENAI, and ELEVENLABS API keys from environment variables while adjusting transcription lifecycle and message/audio handling.

Changes

Cohort / File(s) Summary
Configuration & Documentation
real-time-voicebot/.env.example, real-time-voicebot/README.md
New .env.example with placeholders for ASSEMBLYAI_API_KEY, OPENAI_API_KEY, ELEVENLABS_API_KEY. README updated to instruct copying .env.example.env, adding keys, and installing dependencies (assemblyai, openai, elevenlabs, python-dotenv).
Runtime / Application Logic
real-time-voicebot/app.py
Loads environment via python-dotenv and reads the three API keys; validates presence and raises on missing keys. Replaces hard-coded API keys with env-driven clients. Adjusts transcription lifecycle callbacks (removed early returns in open/error/close), refines on_data handling for interim vs final transcripts, updates start_transcription param formatting, and changes generate_ai_response / generate_audio message formatting and parameter usage.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Areas to focus on:
    • Env loading and key validation paths in app.py
    • Transcription lifecycle: on_open, on_error, on_close, and on_data changes
    • Message construction passed to OpenAI and text passed to ElevenLabs
    • Any runtime startup ordering changes (greeting vs transcription start)

Poem

🐰 I found a dotfile in the glade,
Keys tucked softly in a shade,
Env whispers wake the speaking bot,
Voices bloom where secrets slot,
Hopping code — a springtime serenade! 🌿🎙️

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and clearly describes the main change: moving API key configuration from hardcoded values to environment variables, which is the central objective of the changeset across all modified files.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4ce9513 and 43023d6.

📒 Files selected for processing (3)
  • real-time-voicebot/.env.example (1 hunks)
  • real-time-voicebot/README.md (1 hunks)
  • real-time-voicebot/app.py (2 hunks)
🧰 Additional context used
🪛 dotenv-linter (4.0.0)
real-time-voicebot/.env.example

[warning] 3-3: [UnorderedKey] The ELEVENLABS_API_KEY key should go before the OPENAI_API_KEY key

(UnorderedKey)

🪛 Ruff (0.14.7)
real-time-voicebot/app.py

67-67: f-string without any placeholders

Remove extraneous f prefix

(F541)

🔇 Additional comments (6)
real-time-voicebot/.env.example (1)

1-3: LGTM!

The .env.example file correctly documents all required API keys with clear placeholder values. The key ordering matches the initialization order in app.py, which is more intuitive than alphabetical ordering.

real-time-voicebot/app.py (4)

1-2: LGTM!

The dotenv integration is correctly implemented with proper imports and initialization at module load time.

Also applies to: 8-9


44-49: LGTM!

The normalized parameter formatting (no spaces around equals) improves code consistency and readability.


57-57: LGTM!

Using explicit dictionary keys for role and content makes the message structure clearer and more maintainable.

Also applies to: 70-70


72-76: LGTM!

Using explicit parameter names for the ElevenLabs generate call improves code clarity.

real-time-voicebot/README.md (1)

23-27: LGTM!

The README updates provide clear, actionable setup instructions that align with the environment-based configuration. The dependency list correctly includes python-dotenv.

Also applies to: 32-32

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
real-time-voicebot/app.py (3)

12-24: Env var validation is solid; consider taming the long error message (TRY003)

Nice job reading all three API keys and validating them before initializing the clients; this cleanly addresses the earlier review about missing-key failures. To satisfy Ruff’s TRY003 and keep the constructor a bit leaner, you might move the long error string into a small custom exception or module-level constant and raise that instead—purely an optional polish.

Also applies to: 27-27


27-27: Bound the size of self.interaction to avoid unbounded growth

self.interaction accumulates every user and assistant turn (Lines 27, 67, 80). For long calls this list can grow large, increasing memory usage and token costs when passed to chat.completions. Consider capping the history (e.g., keep last N turns) or periodically summarizing older context into a single message.

-        self.interaction.append({"role": "user", "content": transcript.text})
+        self.interaction.append({"role": "user", "content": transcript.text})
+        # Optionally trim history to last N turns to keep memory/token usage bounded.
+        MAX_TURNS = 20
+        if len(self.interaction) > MAX_TURNS + 1:  # +1 for system prompt
+            self.interaction = [self.interaction[0]] + self.interaction[-MAX_TURNS:]

Also applies to: 67-67, 80-80, 83-85


90-93: Wrap script startup logic in an if __name__ == "__main__": guard

Right now, importing this module will immediately create an assistant, play the greeting, and start transcription. If you ever want to reuse AI_Assistant from other modules or tests, guarding the startup code will prevent those side effects on import.

-greeting = "Thank you for calling London Travel Guide. My name is Rachel, how may I assist you?"
-ai_assistant = AI_Assistant()
-ai_assistant.generate_audio(greeting)
-ai_assistant.start_transcription()
+if __name__ == "__main__":
+    greeting = (
+        "Thank you for calling London Travel Guide. "
+        "My name is Rachel, how may I assist you?"
+    )
+    ai_assistant = AI_Assistant()
+    ai_assistant.generate_audio(greeting)
+    ai_assistant.start_transcription()
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 43023d6 and 1e55c7b.

📒 Files selected for processing (1)
  • real-time-voicebot/app.py (2 hunks)
🧰 Additional context used
🪛 Ruff (0.14.7)
real-time-voicebot/app.py

17-20: Avoid specifying long messages outside the exception class

(TRY003)

🔇 Additional comments (2)
real-time-voicebot/app.py (2)

1-2: Environment loading pattern looks good for this script-style module

Importing load_dotenv and calling it once at module import is appropriate here given that the module immediately runs the assistant as a script; no issues from a correctness or security standpoint.

Also applies to: 8-8


54-60: RealtimeTranscriber configuration is clear and explicit

Using keyword arguments for callbacks and end_utterance_silence_threshold makes the transcription setup readable and easy to tweak; no issues spotted in this block.

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