Conversation
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
🚧 Files skipped from review as they are similar to previous changes (4)
📝 WalkthroughWalkthroughCelune 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. ChangesUnified runtime expansion
Possibly related PRs
Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 14
🧹 Nitpick comments (3)
tests/test_backends_and_extensions.py (1)
972-977: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick winAssert 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 winAdd concrete event payload types to subscribed handlers.
Typing the
eventparameters 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 winAssert the default identity is absent here.
This test can still pass if a custom pack named
Celuneinherits 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
📒 Files selected for processing (68)
AGENTS.mdREADME.mdcelune/__init__.pycelune/api.pycelune/backends/__init__.pycelune/backends/base.pycelune/backends/dotstts.pycelune/backends/mini.pycelune/backends/qwen3.pycelune/backends/voxcpm2.pycelune/celune.pycelune/cevoice.pycelune/chroma.pycelune/colors.pycelune/constants.pycelune/dataclasses/__init__.pycelune/dataclasses/celune.pycelune/dataclasses/events.pycelune/dataclasses/extensions.pycelune/dataclasses/persona.pycelune/dataclasses/pipeline.pycelune/dataclasses/properties.pycelune/entrypoint.pycelune/extensions/base.pycelune/extensions/events.pycelune/extensions/manager.pycelune/paths.pycelune/persona/emotion.pycelune/persona/impl.pycelune/persona/memory.pycelune/persona/prompts.pycelune/persona/runtime.pycelune/pipeline.pycelune/terminal.pycelune/typing/__init__.pycelune/typing/analysis.pycelune/typing/backends.pycelune/typing/celune.pycelune/typing/cevoice.pycelune/typing/common.pycelune/typing/events.pycelune/typing/persona.pycelune/typing/pipeline.pycelune/ui/app.pycelune/ui/commands.pycelune/ui/terminal.pycelune/updater.pycelune/utils.pycelune/vc_backends/__init__.pycelune/vc_backends/base.pycelune/vc_backends/passthrough.pycelune/vram.pyextensions/test.pylauncher.crequirements.txttests/support.pytests/test_api_audio.pytests/test_api_webui.pytests/test_backends_and_extensions.pytests/test_celune_core.pytests/test_cevoice.pytests/test_extension_events.pytests/test_package_api.pytests/test_persona_emotion.pytests/test_persona_memory.pytests/test_pipeline.pytests/test_runtime_and_ui_commands.pytests/test_runtime_paths.py
| class _RefreshableWidget(Protocol): | ||
| def refresh(self, *args, **kwargs) -> object: |
There was a problem hiding this comment.
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.
| 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
There was a problem hiding this comment.
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
⛔ Files ignored due to path filters (1)
uv.lockis excluded by!**/*.lock
📒 Files selected for processing (29)
celune/analysis.pycelune/api.pycelune/backends/dotstts.pycelune/backends/mini.pycelune/backends/qwen3.pycelune/backends/voxcpm2.pycelune/celune.pycelune/constants.pycelune/dataclasses/pipeline.pycelune/entrypoint.pycelune/extensions/manager.pycelune/paths.pycelune/persona/impl.pycelune/persona/runtime.pycelune/pipeline.pycelune/ui/app.pycelune/ui/terminal.pycelune/utils.pyextensions/test.pylauncher.cpyproject.tomlscripts/build_nuitka.ps1scripts/build_nuitka.shtests/test_backends_and_extensions.pytests/test_celune_core.pytests/test_persona_api.pytests/test_pipeline.pytests/test_runtime_and_ui_commands.pytests/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
|
Detected potential slop in commit The following jobs have failed:
Please check the logs and unslop your code: https://github.com/celunah/celune/actions/runs/28101889312 |
There was a problem hiding this comment.
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
📒 Files selected for processing (3)
pyproject.tomlscripts/build_nuitka.ps1scripts/build_nuitka.sh
🚧 Files skipped from review as they are similar to previous changes (1)
- scripts/build_nuitka.sh
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
celune/entrypoint.py (1)
974-976: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueStartup 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 throughstring(...)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
📒 Files selected for processing (12)
celune/api.pycelune/celune.pycelune/entrypoint.pycelune/extensions/manager.pycelune/i18n.pycelune/pipeline.pycelune/ui/app.pycelune/ui/commands.pycelune/ui/headless.pyscripts/build_nuitka.ps1tests/test_namedays_i18n_updater.pytests/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
|
@coderabbitai review |
✅ Action performedReview finished.
|
Who said 3 months is too much? She needs to be good.
Summary by CodeRabbit
Release Notes
New Features
POST /v1/convert(streams converted FLAC withx-sample-rate).@celune.subscribe(...)(exposed publicly)./backendand/cevoice.Documentation
Bug Fixes / Improvements