Skip to content

Stability improvements: V0.6 Maybe#772

Open
dustinwloring1988 wants to merge 18 commits into
jamiepine:mainfrom
voicebox-ai:v0.6
Open

Stability improvements: V0.6 Maybe#772
dustinwloring1988 wants to merge 18 commits into
jamiepine:mainfrom
voicebox-ai:v0.6

Conversation

@dustinwloring1988

@dustinwloring1988 dustinwloring1988 commented Jun 21, 2026

Copy link
Copy Markdown

I have been working on ironing out some of the bugs and errors for my own build but would like to share if you want any.

Summary by CodeRabbit

Release Notes

  • Bug Fixes
    • Resolved Linux crash when hiding the dictate pill
    • Enforced 10MB avatar upload limit with allowed extension validation
    • Fixed Personality LLM to use the configured model size
    • Improved CUDA downloads: unsupported platforms fail fast; real download errors stop retries
    • Enhanced long-form Whisper transcription on the PyTorch backend
    • Switched timestamps to timezone-aware UTC across tasks, profiles, stories, and generations
  • Documentation
    • Updated GPU acceleration guidance for Linux + NVIDIA
  • Tests
    • Added tests covering CUDA download support behavior

…-platforms

Fix CUDA downloads on unsupported platforms
fix: replace deprecated datetime.utcnow() with datetime.now(UTC) thro…
fix: enforce 10MB size limit and validate extensions for avatar uploads
fix: fail fast when model not downloaded instead of retrying infinitely
…ment

fix: personality LLM now respects the selected refinement model
fix(backend): enable long-form Whisper transcription on PyTorch path
fix(linux): avoid abort when hiding the dictate pill
@coderabbitai

coderabbitai Bot commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

A focused stability pass applying seven bug fixes: CUDA binary downloads are now gated to Windows only with fast-fail enforcement; personality and compose endpoints respect the configured LLM model; transcription endpoint respects the configured STT model; avatar uploads validate extensions and enforce a 10 MB cap; PyTorch Whisper enables long-form transcription; model generation fails fast when the model is absent; Linux dictate pill crash is prevented via a compile flag; and all datetime.utcnow() calls are replaced with datetime.now(UTC).

Changes

Stability Bug Fixes

Layer / File(s) Summary
CUDA Windows-only download gating
backend/services/cuda.py, backend/routes/cuda.py, app/src/lib/api/types.ts, backend/tests/test_cuda_download.py
New is_cuda_download_supported(), get_cuda_download_unsupported_reason(), and ensure_cuda_download_supported() helpers restrict CUDA binary downloads to Windows. get_cuda_status() gains download_supported and unsupported_reason fields; the download endpoint returns HTTP 409 on unsupported platforms; startup updater early-returns before update checks; CudaStatus TypeScript interface adds the new fields; tests verify platform gating and status shape across Windows and Linux.
Personality and compose endpoints respect configured LLM model
backend/routes/generations.py, backend/routes/profiles.py
Both the /generate personality-rewrite path and the profile /compose endpoint now import settings_service, load capture settings, and pass saved.llm_model as model_size to personality.rewrite_as_profile and personality.compose_as_profile respectively.
Transcription endpoint respects configured STT model
backend/routes/transcription.py
The /transcribe endpoint now injects a SQLAlchemy session and loads the default speech-to-text model from capture settings when no explicit model is provided, replacing previous non-database model selection logic.
Avatar upload size cap and extension validation
backend/routes/profiles.py
Constants AVATAR_MAX_FILE_SIZE (10 MB), AVATAR_UPLOAD_CHUNK_SIZE, and _ALLOWED_IMAGE_EXTS are defined; the upload handler now validates extensions (HTTP 400) and enforces the size cap via chunked reading with running total accounting (HTTP 413).
PyTorch Whisper long-form transcription
backend/backends/pytorch_backend.py
Processor call sets truncation=False, padding="longest", return_attention_mask=True; generation passes attention_mask and return_timestamps=True; language hint now uses language and task="transcribe" kwargs instead of forced_decoder_ids.
Model download fast-fail
backend/services/generation.py
run_generation() calls tts_model._is_model_cached(model_size) before loading; raises RuntimeError immediately when the model is absent, with graceful fallback if the check is unavailable.
Linux dictate pill crash prevention
tauri/src-tauri/src/main.rs
set_ignore_cursor_events(true) in the dictate:hide listener is now wrapped in #[cfg(not(target_os = "linux"))].
Timezone-aware timestamps across models and services
backend/database/models.py, backend/services/..., backend/routes/..., backend/utils/tasks.py
All datetime.utcnow() calls across SQLAlchemy model defaults and onupdate handlers, service timestamp writes (profiles, stories, generation, history, export_import, channels), route handlers (profiles, tasks), and task dataclass defaults are replaced with datetime.now(UTC) to use timezone-aware UTC.
Changelog and GPU documentation
CHANGELOG.md, docs/content/docs/overview/gpu-acceleration.mdx, docs/content/docs/overview/introduction.mdx
CHANGELOG gains the [Unreleased] section detailing all seven bug fixes; GPU documentation clarifies that Linux+NVIDIA uses local or remote Python backend instead of auto-downloading CUDA, and CUDA backend swap section heading is narrowed to Windows-only.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • jamiepine/voicebox#252: Introduced the CUDA binary download/restart flow and the original CudaStatus contract that this PR extends with download_supported/unsupported_reason fields.
  • jamiepine/voicebox#295: Modified backend/routes/transcription.py to handle Whisper model selection, whereas this PR adds capture settings integration to respect the configured default STT model when none is explicit.

Poem

🐇 Hippity-hop, the bugs hop away,
No more crashes on Linux today!
UTC timestamps, neat and aware,
CUDA stays Windows — that's only fair.
The avatar checks its size at the door,
And Whisper transcribes long speeches once more! 🎤

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Stability improvements: V0.6 Maybe' is vague and generic, using non-descriptive terms that don't convey meaningful information about the changeset. Replace with a specific, descriptive title that captures the main change—e.g., 'Fix stability issues: CUDA platform detection, timezone-aware timestamps, and Whisper transcription' or similar.
✅ Passed checks (4 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 87.50% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
backend/routes/tasks.py (1)

89-96: ⚠️ Potential issue | 🟡 Minor

Normalize parsed timestamps to UTC when tzinfo is missing.

Timestamps created in backend/utils/progress.py use datetime.now().isoformat(), which produces naive datetime strings without timezone information. When these strings are parsed with fromisoformat(), the .replace("Z", "+00:00") has no effect (no "Z" present), and fromisoformat() returns a naive datetime. This causes started_at to be inconsistent—sometimes naive, sometimes aware with UTC—despite the fallback on parse failure.

Proposed fix
             if timestamp_str:
                 try:
                     started_at = datetime.fromisoformat(timestamp_str.replace("Z", "+00:00"))
+                    if started_at.tzinfo is None:
+                        started_at = started_at.replace(tzinfo=UTC)
                 except (ValueError, AttributeError):
                     started_at = datetime.now(UTC)
             else:
                 started_at = datetime.now(UTC)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/routes/tasks.py` around lines 89 - 96, The parsed timestamp from
fromisoformat() may return a naive datetime (without timezone info) since the
original timestamp string lacks a "Z" suffix, making the replace operation
ineffective. After successfully parsing the timestamp_str with fromisoformat()
in the try block, check if the resulting started_at object has no timezone
information (tzinfo is None), and if so, explicitly set it to UTC using the
replace method with tzinfo=UTC. This ensures all parsed timestamps are
consistently timezone-aware datetimes in UTC, matching the fallback behavior in
the else clause.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@backend/database/models.py`:
- Around line 47-48: All DateTime column definitions in the models file that
receive timezone-aware UTC datetimes via datetime.now(UTC) must include the
timezone=True parameter to preserve timezone information through the database
round-trip. Update the created_at and updated_at columns at lines 47-48, and
apply the same timezone=True parameter to all other DateTime columns mentioned
(at lines 85, 96-97, 114, 125-126, 141, 155, 166, 257-258, and 281) to ensure
consistent behavior across all timestamp columns and prevent SQLite from
stripping timezone information on storage and retrieval.

In `@backend/routes/profiles.py`:
- Around line 151-153: Remove ".svg" from the _ALLOWED_IMAGE_EXTS set constant
to prevent SVG uploads which can pose security risks due to active content.
Additionally, ensure that the file extension validation logic (likely used
elsewhere around lines 238-243 as mentioned) properly handles edge cases like
extensionless filenames by requiring that a valid extension is present and
matches one of the allowed raster image extensions in the set. The allowed
extensions should be limited to safe raster formats only: ".png", ".jpg",
".jpeg", ".gif", ".webp", and ".bmp".

In `@backend/services/cuda.py`:
- Line 34: The CUDA_DOWNLOAD_UNSUPPORTED_REASON constant message is misleading
for non-Linux platforms like macOS because it specifically mentions "Linux
users" when the actual gate applies to all non-Windows systems. Update this
constant string to use platform-agnostic language that covers all non-Windows
platforms instead of Linux-specific guidance (e.g., replace "Linux users" with
"users on non-Windows platforms" or similar terminology).

---

Outside diff comments:
In `@backend/routes/tasks.py`:
- Around line 89-96: The parsed timestamp from fromisoformat() may return a
naive datetime (without timezone info) since the original timestamp string lacks
a "Z" suffix, making the replace operation ineffective. After successfully
parsing the timestamp_str with fromisoformat() in the try block, check if the
resulting started_at object has no timezone information (tzinfo is None), and if
so, explicitly set it to UTC using the replace method with tzinfo=UTC. This
ensures all parsed timestamps are consistently timezone-aware datetimes in UTC,
matching the fallback behavior in the else clause.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 83e4e74a-e457-4ca9-93cc-9ef933ba0b60

📥 Commits

Reviewing files that changed from the base of the PR and between b35b909 and 28b7aab.

📒 Files selected for processing (20)
  • CHANGELOG.md
  • app/src/lib/api/types.ts
  • backend/backends/pytorch_backend.py
  • backend/database/models.py
  • backend/routes/cuda.py
  • backend/routes/generations.py
  • backend/routes/profiles.py
  • backend/routes/tasks.py
  • backend/services/channels.py
  • backend/services/cuda.py
  • backend/services/export_import.py
  • backend/services/generation.py
  • backend/services/history.py
  • backend/services/profiles.py
  • backend/services/stories.py
  • backend/tests/test_cuda_download.py
  • backend/utils/tasks.py
  • docs/content/docs/overview/gpu-acceleration.mdx
  • docs/content/docs/overview/introduction.mdx
  • tauri/src-tauri/src/main.rs

Comment thread backend/database/models.py Outdated
Comment thread backend/routes/profiles.py Outdated
Comment thread backend/services/cuda.py Outdated
@dustinwloring1988 dustinwloring1988 changed the title V0.6 Maybe Stability improvements: V0.6 Maybe Jun 21, 2026
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