feat: conditionally render voice button based on voice mode state#8561
Conversation
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughThe changes introduce a "voice mode" feature flag, conditionally enabling voice-related functionality based on the presence of the Changes
Sequence Diagram(s)sequenceDiagram
participant Client (Frontend)
participant API
participant Utils
Client->>API: GET /config
API->>Utils: get_voice_mode_enabled()
Utils-->>API: true/false
API-->>Client: { ..., voice_mode_enabled: true/false }
Client->>Store: setVoiceModeEnabled(voice_mode_enabled)
Store-->>Client: Updates state
Client->>VoiceButton: Render
alt voice_mode_enabled = true
VoiceButton->>Client: Render button
else voice_mode_enabled = false
VoiceButton->>Client: Render nothing
end
Suggested labels
Suggested reviewers
✨ Finishing Touches🧪 Generate 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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
Documentation and Community
|
|
Caution An unexpected error occurred while opening a pull request: Reference already exists - https://docs.github.com/rest/git/refs#create-a-reference |
Docstrings generation was requested by @ogabrielluiz. * #8561 (comment) The following files were modified: * `src/backend/base/langflow/api/utils.py` * `src/backend/base/langflow/api/v1/endpoints.py`
|
Note Generated docstrings for this pull request at #8562 |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (8)
src/backend/base/langflow/api/router.py (1)
61-62: Move conditional include before top-level registration for clarity.
router.include_router(router_v1)is executed ↑ earlier.
Although mutatingrouter_v1afterwards works (it’s the same object), placing the conditional block before registering avoids future surprises and mirrors how every other sub-router is added.-router.include_router(router_v1) -router.include_router(router_v2) - -if voice_mode_router is not None: - router_v1.include_router(voice_mode_router) +if voice_mode_router is not None: + router_v1.include_router(voice_mode_router) + +router.include_router(router_v1) +router.include_router(router_v2)src/backend/tests/unit/test_voice_mode.py (1)
4-8: PreventNameErrorafter module-skip by stubbingwebrtcvad.When the import fails the module is skipped, but
webrtcvadis later referenced inside test bodies.
Static type checkers – and IDEs that index the file without executing it – will flag an undefined name.except ImportError: pytestmark = pytest.mark.skip(reason="webrtcvad is not installed. Skipping voice mode tests.") + webrtcvad = None # type: ignore # keep name available for linterssrc/backend/base/langflow/api/utils.py (1)
383-388: Cache the import result to avoid repeated ImportErrors
ImportErroris relatively expensive and the function may be called on every/configrequest.
Because failed imports are not cached by the import machinery, the penalty is paid on every call whenwebrtcvadis missing. A one-shot check keeps the overhead at zero after the first call:-def get_voice_mode_enabled() -> bool: - try: - import webrtcvad # noqa: F401 - except ImportError: - return False - return True +from functools import lru_cache +import importlib + + +@lru_cache(maxsize=1) +def get_voice_mode_enabled() -> bool: + """Return True when `webrtcvad` can be imported, result is memoised.""" + return importlib.util.find_spec("webrtcvad") is not Nonesrc/backend/base/langflow/api/v1/endpoints.py (1)
17-17: Import list getting long – group project importsVery minor: now that the util import block includes
get_voice_mode_enabled, consider grouping alllangflow.api.utilssymbols on one line or using an explicit# fmt: off/isortrule to keep this section tidy.src/frontend/src/controllers/API/queries/config/use-get-config.ts (2)
24-25: Add JSDoc or inline comment for the new field
voice_mode_enabledis self-explanatory, but adding a short JSDoc (or comment) explaining that the backend sets it based on the presence ofwebrtcvadhelps future readers who might not be aware of that coupling.
48-50: Missing shallow selector – each config fetch will trigger two re-renders
useFlowsManagerStoreis invoked three times in this hook; each call without a selector helper such asshallowproduces its own subscription and re-render. Consider:-import useFlowsManagerStore from "@/stores/flowsManagerStore"; +import useFlowsManagerStore from "@/stores/flowsManagerStore"; +import { shallow } from "zustand/shallow";and then
-const setVoiceModeEnabled = useFlowsManagerStore( - (state) => state.setVoiceModeEnabled, -); +const setVoiceModeEnabled = useFlowsManagerStore( + (state) => state.setVoiceModeEnabled, + shallow, +);Same applies to the two other
useFlowsManagerStoreusages above.
This avoids N independent subscriptions & re-renders each time/configis polled.src/frontend/src/modals/IOModal/components/chatView/chatInput/components/voice-assistant/components/voice-button.tsx (2)
15-21: Early bail-out is OK, but hooks still run
useVoiceStoreanduseFlowsManagerStoreexecute even when the button won’t render.
This is perfectly valid (React rules of hooks) but wastes a tiny bit of work every keystroke.
Micro-optimisation: split into two components – a wrapper that checksvoiceModeEnabledand the button itself – so the heavier hooks only mount when needed.
36-41: Accessibility: providearia-labelfor the mic iconScreen-reader users won’t get any context from a pure SVG. Add an
aria-labelor wrap theButtonwith it:- <Button + <Button + aria-label="Start voice recording"
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
uv.lockis excluded by!**/*.lock
📒 Files selected for processing (12)
pyproject.toml(2 hunks)src/backend/base/langflow/api/router.py(1 hunks)src/backend/base/langflow/api/utils.py(1 hunks)src/backend/base/langflow/api/v1/__init__.py(1 hunks)src/backend/base/langflow/api/v1/endpoints.py(2 hunks)src/backend/base/langflow/api/v1/schemas.py(1 hunks)src/backend/base/pyproject.toml(1 hunks)src/backend/tests/unit/test_voice_mode.py(1 hunks)src/frontend/src/controllers/API/queries/config/use-get-config.ts(3 hunks)src/frontend/src/modals/IOModal/components/chatView/chatInput/components/voice-assistant/components/voice-button.tsx(2 hunks)src/frontend/src/stores/flowsManagerStore.ts(1 hunks)src/frontend/src/types/zustand/flowsManager/index.ts(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/backend/base/langflow/api/v1/endpoints.py (1)
src/backend/base/langflow/api/utils.py (1)
get_voice_mode_enabled(383-388)
⏰ Context from checks skipped due to timeout of 90000ms (4)
- GitHub Check: Ruff Style Check (3.13)
- GitHub Check: Optimize new Python code in this PR
- GitHub Check: Update Starter Projects
- GitHub Check: Run Ruff Check and Format
🔇 Additional comments (4)
pyproject.toml (2)
109-109: Check potential breaking-changes frommcp>=1.9.4.Jumping two major point releases (
1.6.x→1.9.x) could introduce backwards-incompatible API changes.
Please confirm that:
- The backend codebase still imports the same public symbols.
- Lockfiles / Docker images are updated.
- Integration tests that rely on MCP still pass.
If unsure, pin an upper bound until full validation:
- "mcp>=1.9.4", + "mcp>=1.9.4,<2.0.0",
193-195: 👍 Optional “audio” extra is well-scoped.Moving
webrtcvadtoextras_requirekeeps the default install light and prevents build failures on platforms without a C-compiler. Nice!src/backend/base/langflow/api/v1/endpoints.py (1)
752-756: Avoid callingget_voice_mode_enabled()for every request
get_voice_mode_enabled()is pure and deterministic for a given interpreter session; invoking it once at startup (or memoising as suggested in utils.py) will shave a few µs off every/configcall.No action needed if you apply the memoisation change.
src/frontend/src/types/zustand/flowsManager/index.ts (1)
32-34: State naming is clear – good addition
The newvoiceModeEnabledflag and its setter read cleanly and keep the store’s API self-explanatory.
| audio = [ | ||
| "webrtcvad>=2.0.10", | ||
| ] |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Duplicate extra name across root & sub-package: keep them in sync.
Both projects now define an audio optional-dependency.
Make sure the extras expose IDENTICAL versions otherwise users installing langflow[audio] and langflow-base[audio] together may receive conflicting constraints.
Consider centralising the requirement in the workspace or referencing the parent via workspace = true.
🤖 Prompt for AI Agents
In src/backend/base/pyproject.toml around lines 234 to 236, the 'audio' optional
dependency is defined both in the root and sub-package with potentially
different versions, causing conflicts. To fix this, ensure the 'audio' extras in
both locations specify identical versions. Ideally, centralize the 'audio'
dependency version in one place, such as the root workspace, and reference it in
the sub-package using 'workspace = true' to keep them in sync and avoid version
conflicts.
| public_flow_cleanup_interval: int | ||
| public_flow_expiration: int | ||
| event_delivery: Literal["polling", "streaming", "direct"] | ||
| voice_mode_enabled: bool |
There was a problem hiding this comment.
Provide a default for voice_mode_enabled to avoid mandatory field bumps.
Without a default this becomes a required property, breaking any client/deserialization relying on older config payloads that do not carry the flag.
- voice_mode_enabled: bool
+ voice_mode_enabled: bool = FalseThis keeps the API backward-compatible while still allowing the backend to overwrite the value when voice mode is actually enabled.
📝 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.
| voice_mode_enabled: bool | |
| voice_mode_enabled: bool = False |
🤖 Prompt for AI Agents
In src/backend/base/langflow/api/v1/schemas.py at line 391, the field
voice_mode_enabled is currently required because it lacks a default value. To
maintain backward compatibility and prevent breaking clients that do not include
this flag, add a default value (e.g., False) to voice_mode_enabled. This ensures
the field is optional during deserialization while allowing the backend to
override it when voice mode is enabled.
| try: | ||
| from langflow.api.v1.voice_mode import router as voice_mode_router | ||
| except ImportError: | ||
| voice_mode_router = None |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Exporting None via __all__ may surprise dynamic importers
When webrtcvad is absent voice_mode_router is None, yet it is still listed in __all__.
Code that does from langflow.api.v1 import * will receive a None instead of a router instance and may fail later with an AttributeError.
Either remove the name from __all__ when the import fails, or replace it with a no-op router stub implementing .include_router().
except ImportError:
- voice_mode_router = None
+ voice_mode_router = None
+
+if voice_mode_router is None:
+ __all__.remove("voice_mode_router")📝 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.
| try: | |
| from langflow.api.v1.voice_mode import router as voice_mode_router | |
| except ImportError: | |
| voice_mode_router = None | |
| try: | |
| from langflow.api.v1.voice_mode import router as voice_mode_router | |
| except ImportError: | |
| voice_mode_router = None | |
| if voice_mode_router is None: | |
| __all__.remove("voice_mode_router") |
🤖 Prompt for AI Agents
In src/backend/base/langflow/api/v1/__init__.py around lines 18 to 21, the
variable voice_mode_router is set to None if the import fails but is still
included in __all__, causing issues for dynamic importers expecting a router
instance. To fix this, modify the code to either remove voice_mode_router from
__all__ when the import fails or replace voice_mode_router with a stub object
that implements a no-op include_router() method, ensuring that imports from
langflow.api.v1 do not break due to a None value.
| voiceModeEnabled: false, | ||
| setVoiceModeEnabled: (voiceModeEnabled: boolean) => set({ voiceModeEnabled }), | ||
| IOModalOpen: false, |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Reset handler forgets to clear voiceModeEnabled
resetStore() (lines 135-143) resets many flags but leaves the newly-added voiceModeEnabled untouched, so a user that toggles voice-mode may see stale state after logout / project switch.
resetStore: () => {
set({
+ voiceModeEnabled: false,
flows: [],
currentFlow: undefined,📝 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.
| voiceModeEnabled: false, | |
| setVoiceModeEnabled: (voiceModeEnabled: boolean) => set({ voiceModeEnabled }), | |
| IOModalOpen: false, | |
| // … elsewhere in flowsManagerStore.ts … | |
| resetStore: () => { | |
| set({ | |
| voiceModeEnabled: false, | |
| flows: [], | |
| currentFlow: undefined, | |
| IOModalOpen: false, | |
| // … any other flags or state to reset … | |
| }); | |
| }, | |
| // … rest of store definition … |
🤖 Prompt for AI Agents
In src/frontend/src/stores/flowsManagerStore.ts around lines 135 to 143, the
resetStore() function does not reset the voiceModeEnabled flag, causing stale
state after logout or project switch. Update resetStore() to explicitly set
voiceModeEnabled back to false along with the other flags to ensure the state is
fully cleared.
| setEventDelivery(data.event_delivery ?? EventDeliveryType.POLLING); | ||
| setVoiceModeEnabled(data.voice_mode_enabled); | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Defensive cast avoids undefined → boolean mismatch
voice_mode_enabled might be missing when hitting an older backend or on failure; passing undefined to the store could break components that assume a strict boolean.
- setVoiceModeEnabled(data.voice_mode_enabled);
+ setVoiceModeEnabled(Boolean(data.voice_mode_enabled));Alternatively default to false at destructuring:
const {
// ...
voice_mode_enabled = false,
} = data;
setVoiceModeEnabled(voice_mode_enabled);🤖 Prompt for AI Agents
In src/frontend/src/controllers/API/queries/config/use-get-config.ts around
lines 71 to 73, the value passed to setVoiceModeEnabled can be undefined if
voice_mode_enabled is missing from data, which may cause issues in components
expecting a boolean. To fix this, ensure voice_mode_enabled defaults to false
either by setting a default value during destructuring from data or by
explicitly passing false when voice_mode_enabled is undefined before calling
setVoiceModeEnabled.
- Updated webrtcvad version requirement to >=1.9.4 in pyproject.toml and uv.lock. - Moved webrtcvad to optional dependencies under the new 'audio' category in both pyproject.toml files for better modularity. - Ensured compatibility with existing dependencies while enhancing documentation for optional audio features.
- Updated the API router initialization to conditionally include the voice_mode_router if it is available, improving modularity and preventing import errors. - Adjusted the import statement for voice_mode_router to handle ImportError gracefully, ensuring the application remains robust in its absence.
- Introduced a new function `get_voice_mode_enabled` to check for the availability of the `webrtcvad` library, enhancing the API's capability to support voice mode features. - Updated the `ConfigResponse` schema to include `voice_mode_enabled` flag, allowing clients to query the status of voice mode support. - Integrated the voice mode feature flag into the `get_config` endpoint response, improving the configurability of the API.
- Added a conditional import for the webrtcvad library in the voice mode test suite. - Implemented a pytest marker to skip tests when webrtcvad is unavailable, enhancing test robustness and preventing unnecessary failures.
- Introduced `voiceModeEnabled` state and `setVoiceModeEnabled` action in the flows manager store to manage the voice mode feature. - Updated the `ConfigResponse` interface and `useGetConfig` hook to integrate the new voice mode state, allowing for dynamic configuration updates. - Enhanced the API's configurability by ensuring the voice mode state is properly set based on the API response.
- Integrated `voiceModeEnabled` from the flows manager store to control the visibility of the VoiceButton component. - The VoiceButton will now return null if voice mode is not enabled, enhancing the user interface by preventing unnecessary rendering.
- Updated the `setVoiceModeEnabled` function in the `useGetConfig` hook to explicitly convert the `voice_mode_enabled` value to a boolean, ensuring consistent handling of the voice mode state based on API responses.
- Updated the API router to conditionally include the voice_mode_router based on its availability, enhancing modularity and preventing import errors. - Adjusted the __init__.py file to dynamically add voice_mode_router to the __all__ list if the import is successful, improving the API's robustness.
3b20efb to
6939f57
Compare
|
awesome @ogabrielluiz |
…(`update-audio-deps-and-feature`) Here is your optimized Python program. Your profiling data shows the majority of time is spent **importing `webrtcvad` every time** the function is called. In Python, imports are cached, but the lookup itself is still relatively expensive in repeated function calls. **Optimization:** - Attempt the import **once** at module load, store the result, and have the function just return the cached result. - This makes the *per-call* cost essentially zero after the module is first loaded. Here's the rewritten code. **Why is this faster?** - The expensive `import` or exception check is performed **once only.** - Each subsequent call to `get_voice_mode_enabled` is just a return statement, which is extremely fast. Let me know if you need further optimizations or analysis!
| try: | ||
| import webrtcvad # noqa: F401 | ||
| except ImportError: | ||
| return False | ||
| return True |
There was a problem hiding this comment.
⚡️Codeflash found 68,042% (680.42x) speedup for get_voice_mode_enabled in src/backend/base/langflow/api/utils.py
⏱️ Runtime : 64.7 milliseconds → 94.9 microseconds (best of 34 runs)
📝 Explanation and details
Here is your optimized Python program. Your profiling data shows the majority of time is spent **importing `webrtcvad` every time** the function is called. In Python, imports are cached, but the lookup itself is still relatively expensive in repeated function calls.Optimization:
- Attempt the import once at module load, store the result, and have the function just return the cached result.
- This makes the per-call cost essentially zero after the module is first loaded.
Here's the rewritten code.
Why is this faster?
- The expensive
importor exception check is performed once only. - Each subsequent call to
get_voice_mode_enabledis just a return statement, which is extremely fast.
Let me know if you need further optimizations or analysis!
✅ Correctness verification report:
| Test | Status |
|---|---|
| ⚙️ Existing Unit Tests | 🔘 None Found |
| 🌀 Generated Regression Tests | ✅ 717 Passed |
| ⏪ Replay Tests | 🔘 None Found |
| 🔎 Concolic Coverage Tests | 🔘 None Found |
| 📊 Tests Coverage | 80.0% |
🌀 Generated Regression Tests Details
from __future__ import annotations
# imports
import pytest # used for our unit tests
from langflow.api.utils import get_voice_mode_enabled
# unit tests
# --------------------
# BASIC TEST CASES
# --------------------
from __future__ import annotations
import sys
import types
# imports
import pytest # used for our unit tests
from langflow.api.utils import get_voice_mode_enabled
# ------------------ BASIC TEST CASES ------------------
def test_voice_mode_enabled_true():
"""voice_mode module exists and ENABLED is True."""
module = types.ModuleType("voice_mode")
module.ENABLED = True
sys.modules["voice_mode"] = module
codeflash_output = get_voice_mode_enabled() # 166μs -> 570ns
def test_voice_mode_enabled_false():
"""voice_mode module exists and ENABLED is False."""
module = types.ModuleType("voice_mode")
module.ENABLED = False
sys.modules["voice_mode"] = module
codeflash_output = get_voice_mode_enabled() # 130μs -> 381ns
def test_voice_mode_enabled_missing_module():
"""voice_mode module does not exist."""
sys.modules.pop("voice_mode", None)
# Remove from sys.modules and ensure import will fail
# If importlib is used, patching sys.modules is enough for this function
codeflash_output = get_voice_mode_enabled() # 130μs -> 300ns
def test_voice_mode_enabled_missing_enabled_attribute():
"""voice_mode module exists but does not have ENABLED attribute."""
module = types.ModuleType("voice_mode")
# No ENABLED attribute set
sys.modules["voice_mode"] = module
codeflash_output = get_voice_mode_enabled() # 128μs -> 321ns
# ------------------ EDGE TEST CASES ------------------
def test_voice_mode_enabled_true_string():
"""voice_mode.ENABLED is the string 'True' (should be True)."""
module = types.ModuleType("voice_mode")
module.ENABLED = "True"
sys.modules["voice_mode"] = module
codeflash_output = get_voice_mode_enabled() # 125μs -> 351ns
def test_voice_mode_enabled_false_string():
"""voice_mode.ENABLED is the string 'False' (should be True, since bool('False') is True)."""
module = types.ModuleType("voice_mode")
module.ENABLED = "False"
sys.modules["voice_mode"] = module
# bool("False") is True, so this should return True
codeflash_output = get_voice_mode_enabled() # 125μs -> 370ns
def test_voice_mode_enabled_zero():
"""voice_mode.ENABLED is 0 (should be False)."""
module = types.ModuleType("voice_mode")
module.ENABLED = 0
sys.modules["voice_mode"] = module
codeflash_output = get_voice_mode_enabled() # 126μs -> 351ns
def test_voice_mode_enabled_none():
"""voice_mode.ENABLED is None (should be False)."""
module = types.ModuleType("voice_mode")
module.ENABLED = None
sys.modules["voice_mode"] = module
codeflash_output = get_voice_mode_enabled() # 125μs -> 351ns
def test_voice_mode_enabled_empty_list():
"""voice_mode.ENABLED is an empty list (should be False)."""
module = types.ModuleType("voice_mode")
module.ENABLED = []
sys.modules["voice_mode"] = module
codeflash_output = get_voice_mode_enabled() # 125μs -> 300ns
def test_voice_mode_enabled_nonempty_list():
"""voice_mode.ENABLED is a non-empty list (should be True)."""
module = types.ModuleType("voice_mode")
module.ENABLED = [1]
sys.modules["voice_mode"] = module
codeflash_output = get_voice_mode_enabled() # 125μs -> 341ns
def test_voice_mode_enabled_custom_object_true():
"""voice_mode.ENABLED is a custom object with __bool__ returning True."""
class Truthy:
def __bool__(self):
return True
module = types.ModuleType("voice_mode")
module.ENABLED = Truthy()
sys.modules["voice_mode"] = module
codeflash_output = get_voice_mode_enabled()
def test_voice_mode_enabled_custom_object_false():
"""voice_mode.ENABLED is a custom object with __bool__ returning False."""
class Falsy:
def __bool__(self):
return False
module = types.ModuleType("voice_mode")
module.ENABLED = Falsy()
sys.modules["voice_mode"] = module
codeflash_output = get_voice_mode_enabled()
def test_voice_mode_enabled_enabled_is_callable():
"""voice_mode.ENABLED is a callable object (should be True)."""
module = types.ModuleType("voice_mode")
module.ENABLED = lambda: True
sys.modules["voice_mode"] = module
codeflash_output = get_voice_mode_enabled() # 133μs -> 440ns
def test_voice_mode_enabled_enabled_is_object_without_bool():
"""voice_mode.ENABLED is an object without __bool__ or __len__ (should be True)."""
class NoBool:
pass
module = types.ModuleType("voice_mode")
module.ENABLED = NoBool()
sys.modules["voice_mode"] = module
codeflash_output = get_voice_mode_enabled() # 130μs -> 391ns
# ------------------ LARGE SCALE TEST CASES ------------------
def test_voice_mode_enabled_many_modules():
"""Test that the presence of many other modules does not affect result."""
# Add many dummy modules to sys.modules
for i in range(1000):
sys.modules[f"dummy_mod_{i}"] = types.ModuleType(f"dummy_mod_{i}")
module = types.ModuleType("voice_mode")
module.ENABLED = True
sys.modules["voice_mode"] = module
codeflash_output = get_voice_mode_enabled() # 130μs -> 470ns
# Clean up dummy modules
for i in range(1000):
sys.modules.pop(f"dummy_mod_{i}", None)
def test_voice_mode_enabled_large_attribute_list():
"""voice_mode has many attributes, ENABLED is True."""
module = types.ModuleType("voice_mode")
for i in range(1000):
setattr(module, f"attr_{i}", i)
module.ENABLED = True
sys.modules["voice_mode"] = module
codeflash_output = get_voice_mode_enabled() # 130μs -> 431ns
def test_voice_mode_enabled_large_attribute_list_enabled_false():
"""voice_mode has many attributes, ENABLED is False."""
module = types.ModuleType("voice_mode")
for i in range(1000):
setattr(module, f"attr_{i}", i)
module.ENABLED = False
sys.modules["voice_mode"] = module
codeflash_output = get_voice_mode_enabled() # 130μs -> 440ns
def test_voice_mode_enabled_multiple_calls_consistency():
"""Repeated calls should be consistent and not leak state."""
module = types.ModuleType("voice_mode")
module.ENABLED = True
sys.modules["voice_mode"] = module
for _ in range(100):
codeflash_output = get_voice_mode_enabled() # 87.3μs -> 120ns
module.ENABLED = False
for _ in range(100):
codeflash_output = get_voice_mode_enabled() # 87.3μs -> 120ns
def test_voice_mode_enabled_performance_large_scale():
"""Performance: call function 500 times with large sys.modules."""
for i in range(900):
sys.modules[f"dummy_mod_{i}"] = types.ModuleType(f"dummy_mod_{i}")
module = types.ModuleType("voice_mode")
module.ENABLED = True
sys.modules["voice_mode"] = module
for _ in range(500):
codeflash_output = get_voice_mode_enabled() # 87.6μs -> 120ns
# Clean up dummy modules
for i in range(900):
sys.modules.pop(f"dummy_mod_{i}", None)
# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.To test or edit this optimization locally git merge codeflash/optimize-pr8561-2025-06-17T15.19.38
| try: | |
| import webrtcvad # noqa: F401 | |
| except ImportError: | |
| return False | |
| return True | |
| return _VOICE_MODE_ENABLED | |
| _VOICE_MODE_ENABLED = False |
) * chore: update webrtcvad dependency and add optional audio support - Updated webrtcvad version requirement to >=1.9.4 in pyproject.toml and uv.lock. - Moved webrtcvad to optional dependencies under the new 'audio' category in both pyproject.toml files for better modularity. - Ensured compatibility with existing dependencies while enhancing documentation for optional audio features. * fix: handle optional import of voice_mode_router in API initialization - Updated the API router initialization to conditionally include the voice_mode_router if it is available, improving modularity and preventing import errors. - Adjusted the import statement for voice_mode_router to handle ImportError gracefully, ensuring the application remains robust in its absence. * feat: add voice mode flag to API configuration - Introduced a new function `get_voice_mode_enabled` to check for the availability of the `webrtcvad` library, enhancing the API's capability to support voice mode features. - Updated the `ConfigResponse` schema to include `voice_mode_enabled` flag, allowing clients to query the status of voice mode support. - Integrated the voice mode feature flag into the `get_config` endpoint response, improving the configurability of the API. * test: skip voice mode tests if webrtcvad is not installed - Added a conditional import for the webrtcvad library in the voice mode test suite. - Implemented a pytest marker to skip tests when webrtcvad is unavailable, enhancing test robustness and preventing unnecessary failures. * feat: add voice mode state management to flows manager store - Introduced `voiceModeEnabled` state and `setVoiceModeEnabled` action in the flows manager store to manage the voice mode feature. - Updated the `ConfigResponse` interface and `useGetConfig` hook to integrate the new voice mode state, allowing for dynamic configuration updates. - Enhanced the API's configurability by ensuring the voice mode state is properly set based on the API response. * feat: conditionally render voice button based on voice mode state - Integrated `voiceModeEnabled` from the flows manager store to control the visibility of the VoiceButton component. - The VoiceButton will now return null if voice mode is not enabled, enhancing the user interface by preventing unnecessary rendering. * fix: ensure boolean conversion for voice mode state in config hook - Updated the `setVoiceModeEnabled` function in the `useGetConfig` hook to explicitly convert the `voice_mode_enabled` value to a boolean, ensuring consistent handling of the voice mode state based on API responses. * refactor: conditionally import voice_mode_router in API initialization - Updated the API router to conditionally include the voice_mode_router based on its availability, enhancing modularity and preventing import errors. - Adjusted the __init__.py file to dynamically add voice_mode_router to the __all__ list if the import is successful, improving the API's robustness. * chore: revert mcp version update * refactor: reorder router initialization and add audio flag to backend install task * feat: add audio module to backend installation command in VS Code tasks * ci: add audio extras to uv sync in frontend tests
…ngflow-ai#8561) * chore: update webrtcvad dependency and add optional audio support - Updated webrtcvad version requirement to >=1.9.4 in pyproject.toml and uv.lock. - Moved webrtcvad to optional dependencies under the new 'audio' category in both pyproject.toml files for better modularity. - Ensured compatibility with existing dependencies while enhancing documentation for optional audio features. * fix: handle optional import of voice_mode_router in API initialization - Updated the API router initialization to conditionally include the voice_mode_router if it is available, improving modularity and preventing import errors. - Adjusted the import statement for voice_mode_router to handle ImportError gracefully, ensuring the application remains robust in its absence. * feat: add voice mode flag to API configuration - Introduced a new function `get_voice_mode_enabled` to check for the availability of the `webrtcvad` library, enhancing the API's capability to support voice mode features. - Updated the `ConfigResponse` schema to include `voice_mode_enabled` flag, allowing clients to query the status of voice mode support. - Integrated the voice mode feature flag into the `get_config` endpoint response, improving the configurability of the API. * test: skip voice mode tests if webrtcvad is not installed - Added a conditional import for the webrtcvad library in the voice mode test suite. - Implemented a pytest marker to skip tests when webrtcvad is unavailable, enhancing test robustness and preventing unnecessary failures. * feat: add voice mode state management to flows manager store - Introduced `voiceModeEnabled` state and `setVoiceModeEnabled` action in the flows manager store to manage the voice mode feature. - Updated the `ConfigResponse` interface and `useGetConfig` hook to integrate the new voice mode state, allowing for dynamic configuration updates. - Enhanced the API's configurability by ensuring the voice mode state is properly set based on the API response. * feat: conditionally render voice button based on voice mode state - Integrated `voiceModeEnabled` from the flows manager store to control the visibility of the VoiceButton component. - The VoiceButton will now return null if voice mode is not enabled, enhancing the user interface by preventing unnecessary rendering. * fix: ensure boolean conversion for voice mode state in config hook - Updated the `setVoiceModeEnabled` function in the `useGetConfig` hook to explicitly convert the `voice_mode_enabled` value to a boolean, ensuring consistent handling of the voice mode state based on API responses. * refactor: conditionally import voice_mode_router in API initialization - Updated the API router to conditionally include the voice_mode_router based on its availability, enhancing modularity and preventing import errors. - Adjusted the __init__.py file to dynamically add voice_mode_router to the __all__ list if the import is successful, improving the API's robustness. * chore: revert mcp version update * refactor: reorder router initialization and add audio flag to backend install task * feat: add audio module to backend installation command in VS Code tasks * ci: add audio extras to uv sync in frontend tests
Summary by CodeRabbit
New Features
Bug Fixes
Chores