Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: voice mode #4642

Open
wants to merge 48 commits into
base: main
Choose a base branch
from
Open
Changes from 2 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
294b498
WIP
phact Nov 13, 2024
5f6833f
works
phact Nov 13, 2024
931052d
stereo
phact Nov 14, 2024
99d5f64
ui v0
phact Nov 14, 2024
8bd3f2d
unnecessary import
phact Nov 14, 2024
e2163ae
Merge branch 'main' into voice_mode
phact Nov 15, 2024
dca19cd
update steps in voice ws
phact Nov 15, 2024
c2f15fe
[autofix.ci] apply automated fixes
autofix-ci[bot] Nov 15, 2024
2863d48
unused
phact Nov 20, 2024
e97e561
merge
phact Nov 20, 2024
c4773b7
Merge branch 'voice_mode' of github.com:phact/langflow into voice_mode
phact Nov 20, 2024
b48837a
Merge branch 'main' into voice_mode
phact Nov 20, 2024
86755db
[autofix.ci] apply automated fixes
autofix-ci[bot] Nov 20, 2024
de727ca
Merge branch 'main' into voice_mode
phact Nov 22, 2024
5b8c4bd
Merge branch 'voice_mode' of github.com:phact/langflow into voice_mode
phact Nov 25, 2024
824d3fd
Merge branch 'langflow-ai:main' into voice_mode
phact Nov 25, 2024
86a630c
cleanly handle missing OPENAI key
phact Nov 25, 2024
968baa3
ruff
phact Nov 25, 2024
4fa7b2e
Merge branch 'main' into voice_mode
phact Nov 25, 2024
3d77aed
Merge branch 'main' into voice_mode
phact Nov 27, 2024
47a18ab
[autofix.ci] apply automated fixes
autofix-ci[bot] Nov 27, 2024
d3d2c8a
Merge branch 'main' into voice_mode
phact Dec 3, 2024
d75d9d8
fix genericIconComponent path
phact Dec 3, 2024
9e443b3
merge main
phact Jan 6, 2025
0f40fb9
update for recent async fixes
phact Jan 7, 2025
28b6101
Merge branch 'main' into voice_mode
phact Jan 7, 2025
55aad4d
accidentally commited html file
phact Jan 10, 2025
d41cb0c
better prompt and threading
phact Jan 28, 2025
d3d425f
client barge-in detection
phact Jan 28, 2025
baa855f
fmt
phact Jan 28, 2025
be9c40d
error handling
phact Jan 28, 2025
bee04ea
fixed VAD with 24 to 16Hz resampling
phact Jan 31, 2025
edfc435
comment out debug file
phact Feb 1, 2025
eae0a9d
better_vad
phact Feb 4, 2025
9b1059f
lock
phact Feb 4, 2025
ab6711d
merge
phact Feb 4, 2025
7b5f6d3
router
phact Feb 4, 2025
3d174bd
[autofix.ci] apply automated fixes
autofix-ci[bot] Feb 4, 2025
2dc9ad1
mcp fixes
phact Feb 5, 2025
4843119
timeout fix
phact Feb 5, 2025
7c12985
Merge remote-tracking branch 'refs/remotes/phact/voice_mode' into voi…
phact Feb 5, 2025
4a11a82
global variable exception handling
phact Feb 5, 2025
b008fcf
don't close the websocket
phact Feb 5, 2025
41f7db6
fix double send bug
phact Feb 6, 2025
762fca6
fix double send bug
phact Feb 6, 2025
78bc7f1
response.output_item event type typo
phact Feb 6, 2025
c616465
voice_mode logging
phact Feb 6, 2025
e797175
vad + dummy check
phact Feb 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/backend/base/langflow/api/v1/__init__.py
Original file line number Diff line number Diff line change
@@ -7,11 +7,11 @@
from langflow.api.v1.login import router as login_router
from langflow.api.v1.monitor import router as monitor_router
from langflow.api.v1.starter_projects import router as starter_projects_router
from langflow.api.v1.voice_mode import router as voice_mode_router
from langflow.api.v1.store import router as store_router
from langflow.api.v1.users import router as users_router
from langflow.api.v1.validate import router as validate_router
from langflow.api.v1.variable import router as variables_router
from langflow.api.v1.voice_mode import router as voice_mode_router

__all__ = [
"api_key_router",
18 changes: 8 additions & 10 deletions src/backend/base/langflow/api/v1/voice_mode.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,27 @@
import asyncio
import os
import json
from typing import Annotated
import os
from uuid import UUID, uuid4

from fastapi import APIRouter, BackgroundTasks, Depends
import websockets
from starlette.websockets import WebSocket, WebSocketDisconnect
from fastapi import APIRouter, BackgroundTasks
from loguru import logger
from sqlalchemy import select
from starlette.websockets import WebSocket, WebSocketDisconnect

from langflow.api.utils import CurrentActiveUser, DbSession
from langflow.api.v1.chat import build_flow
from langflow.api.v1.schemas import InputValueRequest
from langflow.services.auth.utils import get_current_user_for_websocket, get_current_user_by_jwt
from langflow.services.database.models import User
from langflow.services.auth.utils import get_current_user_by_jwt
from langflow.services.database.models.flow.model import Flow
from langflow.services.deps import async_session_scope
from sqlalchemy import select

router = APIRouter(prefix="/voice", tags=["Voice"])

SILENCE_THRESHOLD = 0.5
PREFIX_PADDING_MS = 300
SILENCE_DURATION_MS = 500
SESSION_INSTRUCTIONS = "Always call the execute_flow function with the user's question as the input parameter and use that to craft your responses."

Check failure on line 24 in src/backend/base/langflow/api/v1/voice_mode.py

GitHub Actions / Ruff Style Check (3.12)

Ruff (E501)

src/backend/base/langflow/api/v1/voice_mode.py:24:121: E501 Line too long (148 > 120)


async def get_flow_desc_from_db(flow_id: str) -> Flow:
@@ -33,7 +31,7 @@
result = await session.exec(stmt)
flow = result.scalar_one_or_none()
if not flow:
raise ValueError(f"Flow {flow_id} not found")

Check failure on line 34 in src/backend/base/langflow/api/v1/voice_mode.py

GitHub Actions / Ruff Style Check (3.12)

Ruff (TRY003)

src/backend/base/langflow/api/v1/voice_mode.py:34:19: TRY003 Avoid specifying long messages outside the exception class

Check failure on line 34 in src/backend/base/langflow/api/v1/voice_mode.py

GitHub Actions / Ruff Style Check (3.12)

Ruff (EM102)

src/backend/base/langflow/api/v1/voice_mode.py:34:30: EM102 Exception must not use an f-string literal, assign to variable first
return flow.description


@@ -94,15 +92,15 @@
await openai_ws.send(json.dumps(function_output))
await openai_ws.send(json.dumps({"type": "response.create"}))

except Exception as e:

Check failure on line 95 in src/backend/base/langflow/api/v1/voice_mode.py

GitHub Actions / Ruff Style Check (3.12)

Ruff (BLE001)

src/backend/base/langflow/api/v1/voice_mode.py:95:12: BLE001 Do not catch blind exception: `Exception`
logger.error(f"Error executing flow: {str(e)}")
logger.error(f"Error executing flow: {e!s}")
# Send error back to OpenAI with correct format
function_output = {
"type": "conversation.item.create",
"item": {
"type": "function_call_output",
"call_id": function_call.get("call_id"),
"output": f"Error executing flow: {str(e)}",
"output": f"Error executing flow: {e!s}",
},
}
await openai_ws.send(json.dumps(function_output))
@@ -116,7 +114,7 @@
session: DbSession,
):
# Generate a unique session ID for this conversation
conversation_id = str(uuid4()) # renamed to avoid confusion with session param

Check failure on line 117 in src/backend/base/langflow/api/v1/voice_mode.py

GitHub Actions / Ruff Style Check (3.12)

Ruff (F841)

src/backend/base/langflow/api/v1/voice_mode.py:117:5: F841 Local variable `conversation_id` is assigned to but never used
current_user = await get_current_user_by_jwt(websocket.cookies.get("access_token_lf"), session)
await websocket.accept()

@@ -136,8 +134,8 @@
},
}
# }
except Exception as e:

Check failure on line 137 in src/backend/base/langflow/api/v1/voice_mode.py

GitHub Actions / Ruff Style Check (3.12)

Ruff (BLE001)

src/backend/base/langflow/api/v1/voice_mode.py:137:12: BLE001 Do not catch blind exception: `Exception`
await websocket.send_json({"error": f"Failed to load flow: {str(e)}"})
await websocket.send_json({"error": f"Failed to load flow: {e!s}"})
logger.error(e)
return