Skip to content

Commit 3106456

Browse files
committed
Initial working
0 parents  commit 3106456

File tree

7 files changed

+190
-0
lines changed

7 files changed

+190
-0
lines changed

.gitignore

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
.env
2+
.env.*
3+
.DS_Store
4+
__pycache__
5+
.idea
6+
KMS
7+
uv.lock
8+
.venv
9+
.vscode
10+
*.egg-info
11+
.pytest_cache
12+
.ruff_cache

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 LiveKit, Inc.
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<a href="https://livekit.io/">
2+
<img src="./.github/assets/livekit-mark.png" alt="LiveKit logo" width="100" height="100">
3+
</a>
4+
5+
# Voice AI Assistant with LiveKit Agents
6+
7+
<p>
8+
<a href="https://cloud.livekit.io/projects/p_/sandbox"><strong>Deploy a sandbox app</strong></a>
9+
10+
<a href="https://docs.livekit.io/agents/">LiveKit Agents Docs</a>
11+
12+
<a href="https://livekit.io/cloud">LiveKit Cloud</a>
13+
14+
<a href="https://blog.livekit.io/">Blog</a>
15+
</p>
16+
17+
A simple voice AI assistant built with [LiveKit Agents for Python](https://github.com/livekit/agents).
18+
19+
## Dev Setup
20+
21+
Clone the repository and install dependencies to a virtual environment:
22+
23+
```console
24+
cd agent-starter-python
25+
uv sync
26+
```
27+
28+
Set up the environment by copying `.env.example` to `.env` and filling in the required values:
29+
30+
- `LIVEKIT_URL`
31+
- `LIVEKIT_API_KEY`
32+
- `LIVEKIT_API_SECRET`
33+
- `OPENAI_API_KEY`
34+
- `DEEPGRAM_API_KEY`
35+
36+
You can also do this automatically using the LiveKit CLI:
37+
38+
```bash
39+
lk app env -w .env
40+
```
41+
42+
Run the agent:
43+
44+
```console
45+
uv run python src/agent.py dev
46+
```
47+
48+
This agent requires a frontend application to communicate with. Use a [starter app](https://docs.livekit.io/agents/start/frontend/#starter-apps), our hosted [Sandbox](https://cloud.livekit.io/projects/p_/sandbox) frontends, or the [LiveKit Agents Playground](https://agents-playground.livekit.io/).

evals/test_agent.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import pytest
2+
3+
from livekit.agents import AgentSession, llm
4+
from livekit.plugins import openai
5+
from agent import Assistant
6+
7+
8+
def _llm() -> llm.LLM:
9+
return openai.LLM(model="gpt-4o-mini", temperature=0.45)
10+
11+
@pytest.mark.asyncio
12+
async def test_greeting() -> None:
13+
14+
async with (
15+
_llm() as llm,
16+
AgentSession(llm=llm) as session,
17+
):
18+
await session.start(Assistant())
19+
result = await session.run(user_input="Hi there how are you?")
20+
await result.expect.message(role="assistant").judge(
21+
llm, intent="should offer a friendly greeting to the user"
22+
)
23+
result.expect.no_more_events()
24+

pyproject.toml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
[build-system]
2+
requires = ["setuptools>=61.0", "wheel"]
3+
build-backend = "setuptools.build_meta"
4+
5+
[project]
6+
name = "agent-starter-python"
7+
version = "0.1.0"
8+
description = "Simple voice AI assistant built with LiveKit Agents for Python"
9+
requires-python = ">=3.9"
10+
11+
dependencies = [
12+
"livekit-agents",
13+
"livekit-plugins-openai",
14+
"livekit-plugins-turn-detector",
15+
"livekit-plugins-silero",
16+
"livekit-plugins-cartesia",
17+
"livekit-plugins-deepgram",
18+
"python-dotenv",
19+
"livekit-plugins-noise-cancellation~=0.2.1",
20+
]
21+
22+
[dependency-groups]
23+
dev = [
24+
"pytest",
25+
"pytest-asyncio",
26+
]
27+
28+
[tool.uv.sources]
29+
livekit-agents = { path = "../../livekit/agents/livekit-agents", editable = true }
30+
livekit-plugins-openai = { path = "../../livekit/agents/livekit-plugins/livekit-plugins-openai", editable = true }
31+
livekit-plugins-turn-detector = { path = "../../livekit/agents/livekit-plugins/livekit-plugins-turn-detector", editable = true }
32+
livekit-plugins-silero = { path = "../../livekit/agents/livekit-plugins/livekit-plugins-silero", editable = true }
33+
livekit-plugins-cartesia = { path = "../../livekit/agents/livekit-plugins/livekit-plugins-cartesia", editable = true }
34+
livekit-plugins-deepgram = { path = "../../livekit/agents/livekit-plugins/livekit-plugins-deepgram", editable = true }
35+
36+
[tool.setuptools.packages.find]
37+
where = ["src"]
38+
39+
[tool.setuptools.package-dir]
40+
"" = "src"
41+
42+
[tool.pytest.ini_options]
43+
asyncio_mode = "auto"
44+
asyncio_default_fixture_loop_scope = "function"

src/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# This file makes the src directory a Python package

src/agent.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
from dotenv import load_dotenv
2+
3+
from livekit import agents
4+
from livekit.agents import AgentSession, Agent, RoomInputOptions
5+
from livekit.plugins import openai, noise_cancellation, silero, deepgram, cartesia
6+
from livekit.plugins.turn_detector.multilingual import MultilingualModel
7+
8+
load_dotenv()
9+
10+
11+
class Assistant(Agent):
12+
def __init__(self) -> None:
13+
super().__init__(instructions="You are a helpful voice AI assistant.")
14+
15+
16+
async def entrypoint(ctx: agents.JobContext):
17+
session = AgentSession(
18+
stt=deepgram.STT(),
19+
llm=openai.LLM(model="gpt-4o-mini"),
20+
tts=cartesia.TTS(),
21+
vad=silero.VAD.load(),
22+
turn_detection=MultilingualModel(),
23+
)
24+
25+
await session.start(
26+
room=ctx.room,
27+
agent=Assistant(),
28+
room_input_options=RoomInputOptions(
29+
# LiveKit Cloud enhanced noise cancellation
30+
# - If self-hosting, omit this parameter
31+
# - For telephony applications, use `BVCTelephony` for best results
32+
noise_cancellation=noise_cancellation.BVC(),
33+
),
34+
)
35+
36+
await ctx.connect()
37+
38+
39+
if __name__ == "__main__":
40+
agents.cli.run_app(agents.WorkerOptions(entrypoint_fnc=entrypoint))

0 commit comments

Comments
 (0)