Skip to content

Celune 4.2.0#20

Open
celunah wants to merge 19 commits into
mainfrom
dev
Open

Celune 4.2.0#20
celunah wants to merge 19 commits into
mainfrom
dev

Conversation

@celunah

@celunah celunah commented Jun 22, 2026

Copy link
Copy Markdown
Owner

Who said 3 months is too much? She needs to be good.

Summary by CodeRabbit

Release Notes

  • New Features

    • Added voice-conversion audio conversion via POST /v1/convert (streams converted FLAC with x-sample-rate).
    • Extended WebUI with uploaded-audio conversion for voice-conversion mode.
    • Added event-based extension subscriptions via @celune.subscribe(...) (exposed publicly).
    • Added hot-reload UI commands: /backend and /cevoice.
    • Introduced a passthrough voice-conversion backend option.
  • Documentation

    • README now includes an “Extensions” section.
  • Bug Fixes / Improvements

    • Improved uploaded-audio decoding, sample-rate aware responses, and streaming “first chunk” timing.
    • Expanded i18n across UI/CLI/API messages and refined runtime environment behavior for Hugging Face caching.

@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0132ffb6-70ba-46a6-ac6f-b10889be01dc

📥 Commits

Reviewing files that changed from the base of the PR and between fc5b536 and 8395f2e.

📒 Files selected for processing (4)
  • celune/constants.py
  • celune/entrypoint.py
  • celune/i18n.py
  • celune/ui/app.py
🚧 Files skipped from review as they are similar to previous changes (4)
  • celune/constants.py
  • celune/i18n.py
  • celune/entrypoint.py
  • celune/ui/app.py

📝 Walkthrough

Walkthrough

Celune 4.2.0 adds voice-conversion runtime support, typed extension events, Persona emotion prompting, Hugging Face cache configuration, and updated UI/API logging and command flows.

Changes

Unified runtime expansion

Layer / File(s) Summary
Docs, versioning, and runtime bootstrap
AGENTS.md, README.md, pyproject.toml, requirements.txt, launcher.c, scripts/build_nuitka.*, celune/__init__.py, celune/paths.py
CI guidance, extension docs, version pins, dependency lists, build guards, and Hugging Face runtime configuration are updated together.
Shared dataclasses and extension dispatch
celune/dataclasses/*, celune/typing/*, celune/extensions/*, celune/vc_backends/*, celune/cevoice.py
Typed event payloads, subscription dispatch, context overrides, voice-conversion backend interfaces, and protected CEVOICE temp-path handling are added and wired into exports.
Persona emotion and runtime flow
celune/persona/*, celune/constants.py, celune/analysis.py
Persona emotion analysis, prompt structure changes, pinned remote-code revisions, and related Persona runtime and identity handling changes are added together.
Core runtime, API, and audio conversion
celune/api.py, celune/celune.py, celune/pipeline.py, celune/backends/*, tests/support.py
Uploaded audio decoding, /v1/convert, voice-conversion routing, backend cleanup, stream timing metadata, and VC-mode runtime state are added across runtime and backend code.
UI, CLI, and runtime logging
celune/ui/*, celune/utils.py, celune/entrypoint.py, celune/chroma.py, celune/colors.py, celune/updater.py, celune/terminal.py
Terminal escapes, log capture, command hot-reload flows, and supporting utility and type adjustments are updated together.
Tests and examples
tests/*, extensions/test.py
Tests cover VC mode, hot reload, extension events, Persona emotion, API conversion, UI logging, and runtime path configuration.

Possibly related PRs

  • celunah/celune#7: Shares backend cleanup and backend-compatibility changes with this PR, including celune/backends/base.py and the BackendError to FileNotFoundError shift.
  • celunah/celune#15: Touches the same celune/api.py audio upload path that this PR extends with voice-conversion decoding and /v1/convert.

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Poem

🐇 I hop through logs and prompt-strings bright,
New voices dance through cache and light.
Events now whisper, typed and clear,
Reloads roll back with nary a tear.
I nibble a carrot and cheer, “Hooray!”

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 79.24% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the PR’s main change: a Celune 4.2.0 release/version bump.
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.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev

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.

@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: 14

🧹 Nitpick comments (3)
tests/test_backends_and_extensions.py (1)

972-977: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Assert override delegation arguments explicitly.

This test currently enters with_backend("mini") / with_cevoice("nova") but does not verify the override hooks received those exact values (Line 999-Line 1002). Add call assertions so future regressions in delegation are caught.

Suggested test tightening
     def setUp(self) -> None:
+        self.backend_override = mock.Mock(
+            side_effect=lambda backend_name: contextlib.nullcontext(
+                cast(Celune, SimpleNamespace())
+            )
+        )
+        self.cevoice_override = mock.Mock(
+            side_effect=lambda bundle: contextlib.nullcontext(
+                cast(Celune, SimpleNamespace())
+            )
+        )
         self.logs: list[tuple[str, str]] = []
         self.dev_logs: list[tuple[str, str]] = []
@@
-            backend_override=lambda backend_name: contextlib.nullcontext(
-                cast(Celune, SimpleNamespace())
-            ),
-            cevoice_override=lambda bundle: contextlib.nullcontext(
-                cast(Celune, SimpleNamespace())
-            ),
+            backend_override=self.backend_override,
+            cevoice_override=self.cevoice_override,
         )
@@
         with extension.with_backend("mini"):
             pass
         with extension.with_cevoice("nova"):
             pass
+        self.backend_override.assert_called_once_with("mini")
+        self.cevoice_override.assert_called_once_with("nova")

Also applies to: 999-1002

🤖 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 `@tests/test_backends_and_extensions.py` around lines 972 - 977, The test is
not verifying that the override hooks receive the correct delegation arguments.
Replace the lambda functions for backend_override and cevoice_override with call
assertion objects (such as unittest.mock.Mock or similar) that will capture the
arguments passed to them, then add assertions after the with_backend("mini") and
with_cevoice("nova") calls to verify these mocks were called with the expected
argument values to catch future regressions in delegation.
extensions/test.py (1)

7-9: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Add concrete event payload types to subscribed handlers.

Typing the event parameters here keeps the example aligned with the typed event contract the extension API is introducing.

Proposed patch
 import celune
 from celune import CeluneExtension
+from celune.dataclasses.events import ReadyEvent, VoiceChangedEvent
 from celune.utils import discard
@@
-    def on_ready(self, event) -> None:
+    def on_ready(self, event: ReadyEvent) -> None:
@@
-    def on_voice_changed(self, event) -> None:
+    def on_voice_changed(self, event: VoiceChangedEvent) -> None:

As per coding guidelines, avoid broad types and prefer concrete, meaningful types in Python signatures.

Also applies to: 18-18, 52-52

🤖 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 `@extensions/test.py` around lines 7 - 9, Replace the broad or untyped event
parameters in the subscribed event handlers with concrete event payload types.
Locate the handler functions at the indicated line numbers (likely decorated
with event subscription patterns) and replace any generic event parameter types
(such as Any or untyped event) with the specific, concrete event payload types
that match the typed event contract expected by the extension API. Ensure you
import any necessary concrete event types from the celune module if they are not
already imported.

Source: Coding guidelines

tests/test_pipeline.py (1)

1434-1447: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Assert the default identity is absent here.

This test can still pass if a custom pack named Celune inherits the default Celune identity fields, because it only checks the name label. Add negative assertions like the non-default pack test above.

Proposed test tightening
         self.assertIn("Celune:", prompt)
         self.assertIn("You are Celune", prompt)
+        self.assertNotIn("Gender: female", prompt)
+        self.assertNotIn("The speaker uses a more confident", prompt)
🤖 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 `@tests/test_pipeline.py` around lines 1434 - 1447, The test
test_named_celune_custom_pack_does_not_use_default_identity currently only
verifies positive assertions that the name labels are present, but does not
verify that default identity fields are actually absent from the custom pack.
Add negative assertions using assertNotIn to check that the default Celune
identity fields that should not be inherited are not present in the prompt
variable, similar to the pattern used in the non-default pack test mentioned in
the review.
🤖 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 `@celune/api.py`:
- Around line 1909-1910: The `/v1/convert` route contains a blocking synchronous
call to celune.convert_audio() inside an async function which stalls the event
loop and delays other requests. Similarly, the `/v1/sfx` route at line 1849
calls the blocking celune.play_audio() method with the same issue. Move both of
these blocking operations off the event loop by wrapping them in an executor
call (such as loop.run_in_executor() or asyncio.to_thread()) so they run in a
thread pool instead of blocking the async event loop.

In `@celune/celune.py`:
- Around line 498-503: The _cleanup_residual_temp_data method calls
temp_dir.iterdir() without verifying that the directory exists first, causing a
FileNotFoundError on fresh installations. Add a guard clause at the beginning of
the method to check if temp_dir.exists() before attempting to iterate over its
contents, and return early if the directory does not exist.
- Around line 1788-1800: After loading the new model with
self.backend.load_model(new_model_name), the self.model_name attribute is not
updated to reflect the newly loaded model, causing it to remain stale. Add a
line after the model loading statement to update self.model_name to the
new_model_name value so that subsequent voice switches correctly identify the
current model and saved metadata reflects the correct model name.

In `@celune/entrypoint.py`:
- Around line 971-973: The ANSI title initialization block with the if
runtime.supports_ansi() check and subsequent sys.stdout.write/flush calls is
currently positioned outside the startup try block, which means any failures in
writing to stdout will bypass error handling and crash the startup sequence.
Move this entire block inside the startup try block (or alternatively guard it
with contextlib.suppress) to ensure that output stream failures are properly
caught and handled by the existing startup error handling mechanism.

In `@celune/extensions/manager.py`:
- Around line 388-392: The handler assignment to
self._event_registrations[owner_key] at line 388 does not clean up previously
registered handlers for the same owner_key before replacing them, causing old
callbacks to remain active and fire multiple times when autoload() or handler
registration runs again. Before assigning the new handlers list to
self._event_registrations[owner_key], check if handlers already exist for that
owner_key and properly unsubscribe or clean them up to prevent callback leaks
and duplicates.
- Around line 113-117: The unregister_all() method only unregisters extensions
but does not clean up module-level subscriptions that are registered under
module:* owner keys, leaving stale handlers active. After unregistering all
extensions in the loop, also clear or unregister any module-level handlers to
ensure complete cleanup of all auto-registered handlers and fully honor the
"unregister all" contract.

In `@celune/paths.py`:
- Around line 133-137: The portable-cache configuration is incomplete. In
addition to setting _HF_HOME_ENV and _HF_HUB_CACHE_ENV in the compiled/forced
branch shown in the diff, you need to also set TRANSFORMERS_CACHE to
default_transformers_cache. Add a similar conditional check after the
_HF_HUB_CACHE_ENV block that checks if TRANSFORMERS_CACHE is not in os.environ
and sets it to the default_transformers_cache variable that was computed
earlier, ensuring all three cache paths are properly configured.

In `@celune/persona/impl.py`:
- Line 250: The current check in the return statement at line 250 only validates
that voice_bundle_is_default is true, but this applies Celune defaults
(age/gender) to any character with a default voice bundle, not just Celune
itself. Add character gating to the condition by checking both that
voice_bundle_is_default is true AND that the engine's character/identity is
specifically Celune (likely by checking an additional engine attribute that
identifies the character as Celune) to ensure Celune defaults are only applied
when the character is actually Celune.

In `@celune/pipeline.py`:
- Around line 1471-1476: The exception handling in the loader.materialize() call
silently catches all exceptions and sets target_references to an empty tuple
without any logging or error reporting. Instead of silently dropping the
failure, add logging to record when loader.materialize() fails, including the
actual error details. Additionally, consider whether the voice conversion
feature requires these references to function properly with the current backend,
and if so, return None from the function to prevent silent behavioral changes
rather than continuing with empty target_references.

In `@celune/ui/app.py`:
- Around line 364-365: The refresh method in the _RefreshableWidget Protocol has
a return type annotation of object, which is too broad. Examine where the
refresh method is implemented or used throughout the codebase to determine what
specific type it should actually return, then replace the object return type
annotation with the more specific and narrower type that reflects the actual
usage. This will strengthen the type guarantees for this Protocol definition.

In `@celune/utils.py`:
- Line 843: The current implementation in the return statement that translates
special characters and removes double spaces using a single replace call is
incomplete because it only handles pairs of spaces. When the translated text
contains 3 or more consecutive spaces, the single replace pass will leave double
spaces behind. Fix this by using a regex-based approach with the re module to
replace one or more consecutive spaces with a single space in one pass, or
alternatively use a loop to repeatedly call replace until no double spaces
remain in the text.

In `@launcher.c`:
- Line 687: The printfe call at line 687 contains unescaped percent signs in the
format string "%PATH%" which are interpreted as format specifiers, causing
undefined behavior. To fix this, escape each percent sign by doubling it,
changing "%PATH%" to "%%PATH%%" in the format string argument to printfe. This
ensures the percent signs are printed literally rather than being parsed as
format specifiers.

In `@tests/test_celune_core.py`:
- Around line 911-923: The test needs to capture the value of
celune._reload_pending at the time each signal is recorded to properly verify
the ordering contract. Modify the record_signal function to append
celune._reload_pending to the tuple along with signal_type, celune.cur_state,
and celune.loaded, update the signal_states list type annotation from tuple[str,
str, bool] to tuple[str, str, bool, bool] to reflect the 4-element tuples, and
update the assertion that checks signal_states to include the expected
_reload_pending value for each recorded signal state.

In `@tests/test_runtime_paths.py`:
- Around line 181-201: The assertion checking
os.environ["HF_HUB_DISABLE_PROGRESS_BARS"] in the
test_huggingface_runtime_disables_global_progress_and_logs method is located
after the with block exits, meaning it validates the restored environment rather
than the patched one. Move this assertion inside the with block, after the
configure_huggingface_runtime() call, so it checks the environment while the
mock.patch.dict context is still active.

---

Nitpick comments:
In `@extensions/test.py`:
- Around line 7-9: Replace the broad or untyped event parameters in the
subscribed event handlers with concrete event payload types. Locate the handler
functions at the indicated line numbers (likely decorated with event
subscription patterns) and replace any generic event parameter types (such as
Any or untyped event) with the specific, concrete event payload types that match
the typed event contract expected by the extension API. Ensure you import any
necessary concrete event types from the celune module if they are not already
imported.

In `@tests/test_backends_and_extensions.py`:
- Around line 972-977: The test is not verifying that the override hooks receive
the correct delegation arguments. Replace the lambda functions for
backend_override and cevoice_override with call assertion objects (such as
unittest.mock.Mock or similar) that will capture the arguments passed to them,
then add assertions after the with_backend("mini") and with_cevoice("nova")
calls to verify these mocks were called with the expected argument values to
catch future regressions in delegation.

In `@tests/test_pipeline.py`:
- Around line 1434-1447: The test
test_named_celune_custom_pack_does_not_use_default_identity currently only
verifies positive assertions that the name labels are present, but does not
verify that default identity fields are actually absent from the custom pack.
Add negative assertions using assertNotIn to check that the default Celune
identity fields that should not be inherited are not present in the prompt
variable, similar to the pattern used in the non-default pack test mentioned in
the review.
🪄 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: 6a4bf112-5886-4e11-8af4-6b43caa7bd84

📥 Commits

Reviewing files that changed from the base of the PR and between fa13554 and 53bb99c.

📒 Files selected for processing (68)
  • AGENTS.md
  • README.md
  • celune/__init__.py
  • celune/api.py
  • celune/backends/__init__.py
  • celune/backends/base.py
  • celune/backends/dotstts.py
  • celune/backends/mini.py
  • celune/backends/qwen3.py
  • celune/backends/voxcpm2.py
  • celune/celune.py
  • celune/cevoice.py
  • celune/chroma.py
  • celune/colors.py
  • celune/constants.py
  • celune/dataclasses/__init__.py
  • celune/dataclasses/celune.py
  • celune/dataclasses/events.py
  • celune/dataclasses/extensions.py
  • celune/dataclasses/persona.py
  • celune/dataclasses/pipeline.py
  • celune/dataclasses/properties.py
  • celune/entrypoint.py
  • celune/extensions/base.py
  • celune/extensions/events.py
  • celune/extensions/manager.py
  • celune/paths.py
  • celune/persona/emotion.py
  • celune/persona/impl.py
  • celune/persona/memory.py
  • celune/persona/prompts.py
  • celune/persona/runtime.py
  • celune/pipeline.py
  • celune/terminal.py
  • celune/typing/__init__.py
  • celune/typing/analysis.py
  • celune/typing/backends.py
  • celune/typing/celune.py
  • celune/typing/cevoice.py
  • celune/typing/common.py
  • celune/typing/events.py
  • celune/typing/persona.py
  • celune/typing/pipeline.py
  • celune/ui/app.py
  • celune/ui/commands.py
  • celune/ui/terminal.py
  • celune/updater.py
  • celune/utils.py
  • celune/vc_backends/__init__.py
  • celune/vc_backends/base.py
  • celune/vc_backends/passthrough.py
  • celune/vram.py
  • extensions/test.py
  • launcher.c
  • requirements.txt
  • tests/support.py
  • tests/test_api_audio.py
  • tests/test_api_webui.py
  • tests/test_backends_and_extensions.py
  • tests/test_celune_core.py
  • tests/test_cevoice.py
  • tests/test_extension_events.py
  • tests/test_package_api.py
  • tests/test_persona_emotion.py
  • tests/test_persona_memory.py
  • tests/test_pipeline.py
  • tests/test_runtime_and_ui_commands.py
  • tests/test_runtime_paths.py

Comment thread celune/api.py Outdated
Comment thread celune/celune.py
Comment thread celune/celune.py
Comment thread celune/entrypoint.py Outdated
Comment thread celune/extensions/manager.py
Comment thread celune/ui/app.py
Comment on lines +364 to +365
class _RefreshableWidget(Protocol):
def refresh(self, *args, **kwargs) -> object:

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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Narrow the Protocol.refresh typing instead of returning object.

At Line 365, -> object is broader than needed and weakens local type guarantees.

Proposed fix
         class _RefreshableWidget(Protocol):
-            def refresh(self, *args, **kwargs) -> object:
+            def refresh(self, layout: bool = False) -> None:
                 """Refresh one widget in place.

As per coding guidelines, "Avoid using broad types like Any, object or T, unless the function explicitly requires a broad type."

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
class _RefreshableWidget(Protocol):
def refresh(self, *args, **kwargs) -> object:
class _RefreshableWidget(Protocol):
def refresh(self, layout: bool = False) -> None:
"""Refresh one widget in place.
🤖 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 `@celune/ui/app.py` around lines 364 - 365, The refresh method in the
_RefreshableWidget Protocol has a return type annotation of object, which is too
broad. Examine where the refresh method is implemented or used throughout the
codebase to determine what specific type it should actually return, then replace
the object return type annotation with the more specific and narrower type that
reflects the actual usage. This will strengthen the type guarantees for this
Protocol definition.

Source: Coding guidelines

Comment thread celune/utils.py Outdated
Comment thread launcher.c Outdated
Comment thread tests/test_celune_core.py Outdated
Comment thread tests/test_runtime_paths.py Outdated

@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

🤖 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 `@pyproject.toml`:
- Line 129: The pytest configuration in pyproject.toml is globally silencing all
DeprecationWarnings which masks both internal and external deprecation signals.
Remove or replace the filterwarnings setting that contains
"ignore::DeprecationWarning" with a more targeted approach that only suppresses
specific known third-party deprecations, allowing first-party deprecation
warnings to surface and help catch regressions during release validation.

In `@scripts/build_nuitka.ps1`:
- Around line 11-20: The process termination logic is brittle because
Stop-Process will fail with an error if the specified process does not exist,
since ErrorActionPreference defaults to Stop. Modify both Stop-Process calls
(for celune and celune-bin process names) to include the ErrorAction
SilentlyContinue parameter, so that the script continues gracefully even if
either process is not running. Additionally, consider checking for both celune
and celune-bin processes in the initial condition to ensure both are terminated
if either exists.

In `@scripts/build_nuitka.sh`:
- Around line 14-18: The pkill commands for celune and celune-bin will cause the
build script to fail under set -euo pipefail if the processes don't exist
(returning non-zero exit code), and the pattern-based matching with pgrep and
pkill is too broad and can match unintended process names. Guard both pkill
invocations with || true to prevent script failure when processes aren't
running, and use the -x flag with pkill to match exact process names only
instead of pattern matching, ensuring only the intended celune and celune-bin
processes are terminated.
🪄 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: 2254934e-f9a5-4228-906c-a99f0fffcbbd

📥 Commits

Reviewing files that changed from the base of the PR and between 53bb99c and 705e439.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (29)
  • celune/analysis.py
  • celune/api.py
  • celune/backends/dotstts.py
  • celune/backends/mini.py
  • celune/backends/qwen3.py
  • celune/backends/voxcpm2.py
  • celune/celune.py
  • celune/constants.py
  • celune/dataclasses/pipeline.py
  • celune/entrypoint.py
  • celune/extensions/manager.py
  • celune/paths.py
  • celune/persona/impl.py
  • celune/persona/runtime.py
  • celune/pipeline.py
  • celune/ui/app.py
  • celune/ui/terminal.py
  • celune/utils.py
  • extensions/test.py
  • launcher.c
  • pyproject.toml
  • scripts/build_nuitka.ps1
  • scripts/build_nuitka.sh
  • tests/test_backends_and_extensions.py
  • tests/test_celune_core.py
  • tests/test_persona_api.py
  • tests/test_pipeline.py
  • tests/test_runtime_and_ui_commands.py
  • tests/test_runtime_paths.py
✅ Files skipped from review due to trivial changes (1)
  • launcher.c
🚧 Files skipped from review as they are similar to previous changes (12)
  • celune/entrypoint.py
  • extensions/test.py
  • celune/utils.py
  • tests/test_runtime_paths.py
  • celune/api.py
  • tests/test_celune_core.py
  • tests/test_backends_and_extensions.py
  • tests/test_runtime_and_ui_commands.py
  • celune/extensions/manager.py
  • celune/pipeline.py
  • celune/celune.py
  • tests/test_pipeline.py

Comment thread pyproject.toml Outdated
Comment thread scripts/build_nuitka.ps1 Outdated
Comment thread scripts/build_nuitka.sh Outdated
@github-actions

Copy link
Copy Markdown

Detected potential slop in commit 09c7210e2098c6a245fb2d41406c98dc6afb3b53.

The following jobs have failed:

  • Windows Launcher Build failed

Please check the logs and unslop your code: https://github.com/celunah/celune/actions/runs/28101889312

@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: 1

🤖 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 `@scripts/build_nuitka.ps1`:
- Line 16: The conditional in build_nuitka.ps1 has a stray leading plus sign
before the if statement, which makes the PowerShell script invalid. Remove the
extra plus in the existingProcesses check and keep the condition as a normal if
block so the script can execute correctly.
🪄 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: 552ce4a9-3e9f-49c9-80d1-24e5b0c1b781

📥 Commits

Reviewing files that changed from the base of the PR and between 705e439 and 3e89cbc.

📒 Files selected for processing (3)
  • pyproject.toml
  • scripts/build_nuitka.ps1
  • scripts/build_nuitka.sh
🚧 Files skipped from review as they are similar to previous changes (1)
  • scripts/build_nuitka.sh

Comment thread scripts/build_nuitka.ps1 Outdated

@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: 2

🧹 Nitpick comments (1)
celune/entrypoint.py (1)

974-976: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Startup window-title text is still hardcoded English.

Every other user-facing string in this path was localized, but the OSC title "{APP_NAME} is starting up..." remains an inline literal. Consider routing it through string(...) for consistency with the rest of the i18n migration.

🤖 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 `@celune/entrypoint.py` around lines 974 - 976, The startup window title in the
runtime.supports_ansi() block is still an inline English literal, so route the
`"{APP_NAME} is starting up..."` text through `string(...)` to match the rest of
the i18n migration. Update the logic around the `sys.stdout.write` call in
`entrypoint.py` so the OSC title uses the localized string helper while
preserving `APP_NAME` interpolation and the existing ANSI behavior.
🤖 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 `@celune/entrypoint.py`:
- Line 1182: The exception display fallback is unreachable because the current
print in entrypoint.py always treats exc as truthy. Update the handling around
the print(exc or string("cli.no_error_description")) call to use the exception’s
string form instead, so an empty exception message can fall back to the
localized no-error description. Keep the change localized to the
exception-printing path in the entrypoint logic.
- Around line 1259-1265: The start/run command path in entrypoint.py reads
args[1] without checking whether it exists, which causes an IndexError when the
command is invoked with no extra arguments. Update the args[0] in {"start",
"run"} branch to guard the args[1] access with a length check before comparing
against "--verbose" and "-v", following the same safe pattern used by the
verbose handling logic, so the existing invalid-argument flow can run when no
trailing flag is present.

---

Nitpick comments:
In `@celune/entrypoint.py`:
- Around line 974-976: The startup window title in the runtime.supports_ansi()
block is still an inline English literal, so route the `"{APP_NAME} is starting
up..."` text through `string(...)` to match the rest of the i18n migration.
Update the logic around the `sys.stdout.write` call in `entrypoint.py` so the
OSC title uses the localized string helper while preserving `APP_NAME`
interpolation and the existing ANSI behavior.
🪄 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: f9bbf4b7-b2d3-4f5d-a124-92af064e3cf6

📥 Commits

Reviewing files that changed from the base of the PR and between 3e89cbc and fc5b536.

📒 Files selected for processing (12)
  • celune/api.py
  • celune/celune.py
  • celune/entrypoint.py
  • celune/extensions/manager.py
  • celune/i18n.py
  • celune/pipeline.py
  • celune/ui/app.py
  • celune/ui/commands.py
  • celune/ui/headless.py
  • scripts/build_nuitka.ps1
  • tests/test_namedays_i18n_updater.py
  • tests/test_pipeline.py
🚧 Files skipped from review as they are similar to previous changes (8)
  • scripts/build_nuitka.ps1
  • celune/extensions/manager.py
  • celune/ui/commands.py
  • celune/api.py
  • tests/test_pipeline.py
  • celune/pipeline.py
  • celune/ui/app.py
  • celune/celune.py

Comment thread celune/entrypoint.py Outdated
Comment thread celune/entrypoint.py Outdated
@celunah

celunah commented Jun 24, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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