meshagent-livekit 0.0.20__tar.gz → 0.0.21__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of meshagent-livekit might be problematic. Click here for more details.
- {meshagent_livekit-0.0.20 → meshagent_livekit-0.0.21}/CHANGELOG.md +3 -0
- {meshagent_livekit-0.0.20/meshagent_livekit.egg-info → meshagent_livekit-0.0.21}/PKG-INFO +3 -3
- {meshagent_livekit-0.0.20 → meshagent_livekit-0.0.21}/meshagent/livekit/agents/voice.py +90 -19
- meshagent_livekit-0.0.21/meshagent/livekit/version.py +1 -0
- {meshagent_livekit-0.0.20 → meshagent_livekit-0.0.21/meshagent_livekit.egg-info}/PKG-INFO +3 -3
- {meshagent_livekit-0.0.20 → meshagent_livekit-0.0.21}/meshagent_livekit.egg-info/requires.txt +2 -2
- {meshagent_livekit-0.0.20 → meshagent_livekit-0.0.21}/pyproject.toml +2 -2
- meshagent_livekit-0.0.20/meshagent/livekit/version.py +0 -1
- {meshagent_livekit-0.0.20 → meshagent_livekit-0.0.21}/LICENSE +0 -0
- {meshagent_livekit-0.0.20 → meshagent_livekit-0.0.21}/MANIFEST.in +0 -0
- {meshagent_livekit-0.0.20 → meshagent_livekit-0.0.21}/README.md +0 -0
- {meshagent_livekit-0.0.20 → meshagent_livekit-0.0.21}/meshagent/livekit/__init__.py +0 -0
- {meshagent_livekit-0.0.20 → meshagent_livekit-0.0.21}/meshagent/livekit/agents/transcriber.py +0 -0
- {meshagent_livekit-0.0.20 → meshagent_livekit-0.0.21}/meshagent/livekit/livekit_protocol.py +0 -0
- {meshagent_livekit-0.0.20 → meshagent_livekit-0.0.21}/meshagent/livekit/livekit_protocol_test.py +0 -0
- {meshagent_livekit-0.0.20 → meshagent_livekit-0.0.21}/meshagent/livekit/tools/speech.py +0 -0
- {meshagent_livekit-0.0.20 → meshagent_livekit-0.0.21}/meshagent_livekit.egg-info/SOURCES.txt +0 -0
- {meshagent_livekit-0.0.20 → meshagent_livekit-0.0.21}/meshagent_livekit.egg-info/dependency_links.txt +0 -0
- {meshagent_livekit-0.0.20 → meshagent_livekit-0.0.21}/meshagent_livekit.egg-info/top_level.txt +0 -0
- {meshagent_livekit-0.0.20 → meshagent_livekit-0.0.21}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: meshagent-livekit
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.21
|
|
4
4
|
Summary: Livekit support for Meshagent
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
Project-URL: Documentation, https://meshagent.com
|
|
@@ -20,6 +20,6 @@ Requires-Dist: livekit-plugins-elevenlabs~=1.0.19
|
|
|
20
20
|
Requires-Dist: livekit-plugins-playai~=1.0.19
|
|
21
21
|
Requires-Dist: livekit-plugins-silero~=1.0.19
|
|
22
22
|
Requires-Dist: livekit-plugins-turn-detector~=1.0.19
|
|
23
|
-
Requires-Dist: meshagent-api~=0.0.
|
|
24
|
-
Requires-Dist: meshagent-tools~=0.0.
|
|
23
|
+
Requires-Dist: meshagent-api~=0.0.21
|
|
24
|
+
Requires-Dist: meshagent-tools~=0.0.21
|
|
25
25
|
Dynamic: license-file
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import asyncio
|
|
3
3
|
|
|
4
|
-
from meshagent.api import RoomMessage, ErrorResponse, JsonResponse, FileResponse, Requirement, Participant
|
|
4
|
+
from meshagent.api import RoomMessage, ErrorResponse, JsonResponse, FileResponse, Requirement, Participant, JsonResponse, EmptyResponse, TextResponse
|
|
5
5
|
from meshagent.api.room_server_client import RoomClient
|
|
6
6
|
|
|
7
7
|
from meshagent.agents import ToolResponseAdapter
|
|
@@ -9,12 +9,17 @@ from meshagent.tools import ToolContext, Toolkit
|
|
|
9
9
|
from livekit.agents import Agent, AgentSession
|
|
10
10
|
from livekit.agents.llm import RawFunctionTool, ToolError, function_tool
|
|
11
11
|
|
|
12
|
+
from livekit.agents import BackgroundAudioPlayer, AudioConfig, BuiltinAudioClip
|
|
13
|
+
|
|
14
|
+
from typing import Annotated
|
|
12
15
|
from livekit.plugins import openai, silero
|
|
13
16
|
#from livekit.plugins.turn_detector.multilingual import MultilingualModel
|
|
14
17
|
import uuid
|
|
15
18
|
import asyncio
|
|
16
19
|
import logging
|
|
17
20
|
|
|
21
|
+
import os
|
|
22
|
+
|
|
18
23
|
import json
|
|
19
24
|
|
|
20
25
|
from typing import Any
|
|
@@ -23,7 +28,7 @@ from livekit.plugins import openai
|
|
|
23
28
|
|
|
24
29
|
from livekit.plugins import openai, silero
|
|
25
30
|
from livekit import rtc
|
|
26
|
-
from livekit.agents import Agent, AgentSession
|
|
31
|
+
from livekit.agents import Agent, AgentSession, RunContext
|
|
27
32
|
|
|
28
33
|
from typing import Optional
|
|
29
34
|
|
|
@@ -33,10 +38,40 @@ from meshagent.api.schema_util import merge, prompt_schema
|
|
|
33
38
|
|
|
34
39
|
from meshagent.agents import SingleRoomAgent
|
|
35
40
|
|
|
41
|
+
from livekit.plugins.turn_detector.multilingual import MultilingualModel
|
|
42
|
+
|
|
43
|
+
import re
|
|
36
44
|
|
|
37
45
|
logger = logging.getLogger("voice")
|
|
38
46
|
|
|
39
47
|
|
|
48
|
+
def _replace_non_matching(text: str, allowed_chars: str, replacement: str) -> str:
|
|
49
|
+
"""
|
|
50
|
+
Replaces every character in `text` that does not match the given
|
|
51
|
+
`allowed_chars` regex set with `replacement`.
|
|
52
|
+
|
|
53
|
+
Parameters:
|
|
54
|
+
-----------
|
|
55
|
+
text : str
|
|
56
|
+
The input string on which the replacement is to be done.
|
|
57
|
+
allowed_chars : str
|
|
58
|
+
A string defining the set of allowed characters (part of a character set).
|
|
59
|
+
For example, "a-zA-Z0-9" will keep only letters and digits.
|
|
60
|
+
replacement : str
|
|
61
|
+
The string to replace non-matching characters with.
|
|
62
|
+
|
|
63
|
+
Returns:
|
|
64
|
+
--------
|
|
65
|
+
str
|
|
66
|
+
A new string where all characters not in `allowed_chars` are replaced.
|
|
67
|
+
"""
|
|
68
|
+
# Build a regex that matches any character NOT in allowed_chars
|
|
69
|
+
pattern = rf"[^{allowed_chars}]"
|
|
70
|
+
return re.sub(pattern, replacement, text)
|
|
71
|
+
|
|
72
|
+
def safe_tool_name(name: str):
|
|
73
|
+
return _replace_non_matching(name, "a-zA-Z0-9_-", "_")
|
|
74
|
+
|
|
40
75
|
class VoiceConnection:
|
|
41
76
|
def __init__(self, *, room: RoomClient, breakout_room: str):
|
|
42
77
|
self.room = room
|
|
@@ -166,13 +201,14 @@ class Voicebot(SingleRoomAgent):
|
|
|
166
201
|
self, toolkits: list[Toolkit], context: ToolContext, name: str, description: str | None, input_schema: dict
|
|
167
202
|
) -> RawFunctionTool:
|
|
168
203
|
|
|
204
|
+
name = safe_tool_name(name)
|
|
169
205
|
async def _tool_called(raw_arguments: dict) -> Any:
|
|
170
206
|
try:
|
|
171
207
|
|
|
172
208
|
tool = None
|
|
173
209
|
for toolkit in toolkits:
|
|
174
210
|
for t in toolkit.tools:
|
|
175
|
-
if t.name == name:
|
|
211
|
+
if safe_tool_name(t.name) == name:
|
|
176
212
|
tool = t
|
|
177
213
|
|
|
178
214
|
if tool is None:
|
|
@@ -180,8 +216,12 @@ class Voicebot(SingleRoomAgent):
|
|
|
180
216
|
f"Could not find tool {name}"
|
|
181
217
|
)
|
|
182
218
|
|
|
183
|
-
|
|
184
|
-
|
|
219
|
+
try:
|
|
220
|
+
logger.info(f"executing tool {name}: {raw_arguments}")
|
|
221
|
+
tool_result = await tool.execute(context=context, **raw_arguments)
|
|
222
|
+
except Exception as e:
|
|
223
|
+
logger.error(f"failed to call tool {tool.name}: {e}")
|
|
224
|
+
return ToolError("f{e}")
|
|
185
225
|
if self.tool_adapter == None:
|
|
186
226
|
|
|
187
227
|
if isinstance(tool_result, ErrorResponse):
|
|
@@ -189,7 +229,17 @@ class Voicebot(SingleRoomAgent):
|
|
|
189
229
|
|
|
190
230
|
if isinstance(tool_result, JsonResponse):
|
|
191
231
|
return json.dumps(tool_result.json)
|
|
232
|
+
|
|
233
|
+
if isinstance(tool_result, TextResponse):
|
|
234
|
+
return tool_result.text
|
|
192
235
|
|
|
236
|
+
if isinstance(tool_result, EmptyResponse):
|
|
237
|
+
return "success"
|
|
238
|
+
|
|
239
|
+
if tool_result == None:
|
|
240
|
+
return "success"
|
|
241
|
+
|
|
242
|
+
|
|
193
243
|
raise ToolError(
|
|
194
244
|
f"Tool '{name}' returned an unexpected result {type(tool_result)}, attach a tool response adapter"
|
|
195
245
|
)
|
|
@@ -197,6 +247,8 @@ class Voicebot(SingleRoomAgent):
|
|
|
197
247
|
else:
|
|
198
248
|
|
|
199
249
|
text = await self.tool_adapter.to_plain_text(room=context.room, response=tool_result)
|
|
250
|
+
if text == None:
|
|
251
|
+
text = "success"
|
|
200
252
|
return text
|
|
201
253
|
|
|
202
254
|
except Exception as e:
|
|
@@ -206,15 +258,26 @@ class Voicebot(SingleRoomAgent):
|
|
|
206
258
|
|
|
207
259
|
return function_tool(
|
|
208
260
|
_tool_called,
|
|
209
|
-
raw_schema={"name": name, "description": description, "parameters": input_schema},
|
|
261
|
+
raw_schema={"name": name, "description": description, "strict" : True, "parameters": input_schema},
|
|
210
262
|
)
|
|
211
263
|
|
|
212
|
-
async def create_agent(self, *, context: ToolContext):
|
|
213
|
-
|
|
264
|
+
async def create_agent(self, *, context: ToolContext, session: AgentSession):
|
|
265
|
+
|
|
266
|
+
@function_tool
|
|
267
|
+
async def say(context: RunContext, text: str):
|
|
268
|
+
"says something out loud to the user"
|
|
269
|
+
logger.info(f"saying: {text}")
|
|
270
|
+
session.say(text)
|
|
271
|
+
return "success"
|
|
272
|
+
|
|
273
|
+
return Agent(
|
|
214
274
|
instructions="\n".join(self.rules),
|
|
215
275
|
allow_interruptions=True,
|
|
216
|
-
tools=
|
|
217
|
-
|
|
276
|
+
tools=[
|
|
277
|
+
*await self.make_function_tools(context=context),
|
|
278
|
+
say
|
|
279
|
+
]
|
|
280
|
+
)
|
|
218
281
|
|
|
219
282
|
# agent = Agent(
|
|
220
283
|
# instructions="""
|
|
@@ -230,17 +293,14 @@ class Voicebot(SingleRoomAgent):
|
|
|
230
293
|
def create_session(self) -> AgentSession:
|
|
231
294
|
|
|
232
295
|
session = AgentSession(
|
|
296
|
+
max_tool_steps=50,
|
|
233
297
|
allow_interruptions=True,
|
|
234
298
|
vad=silero.VAD.load(),
|
|
235
299
|
stt=openai.STT(),
|
|
236
300
|
tts=openai.TTS(voice="echo"),
|
|
237
|
-
llm=openai.
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
voice="alloy",
|
|
241
|
-
turn_detection=None,
|
|
242
|
-
input_audio_transcription=None,
|
|
243
|
-
),
|
|
301
|
+
llm=openai.LLM(),
|
|
302
|
+
#turn_detection=MultilingualModel(),
|
|
303
|
+
|
|
244
304
|
)
|
|
245
305
|
return session
|
|
246
306
|
|
|
@@ -251,12 +311,23 @@ class Voicebot(SingleRoomAgent):
|
|
|
251
311
|
|
|
252
312
|
logger.info("starting voice agent")
|
|
253
313
|
|
|
314
|
+
session = self.create_session()
|
|
315
|
+
|
|
254
316
|
agent = await self.create_agent(context=ToolContext(
|
|
255
317
|
room=self.room,
|
|
256
318
|
caller=self.room.local_participant,
|
|
257
319
|
on_behalf_of=participant
|
|
258
|
-
))
|
|
259
|
-
|
|
320
|
+
), session=session)
|
|
321
|
+
|
|
322
|
+
background_audio = BackgroundAudioPlayer(
|
|
323
|
+
thinking_sound=[
|
|
324
|
+
#AudioConfig(
|
|
325
|
+
# os.path.dirname(os.path.abspath(__file__)) +"/sfx/thinking.mp3", volume=0.2),
|
|
326
|
+
AudioConfig(BuiltinAudioClip.KEYBOARD_TYPING, volume=0.3),
|
|
327
|
+
AudioConfig(BuiltinAudioClip.KEYBOARD_TYPING2, volume=0.4),
|
|
328
|
+
],
|
|
329
|
+
)
|
|
330
|
+
await background_audio.start(room=connection.livekit_room, agent_session=session)
|
|
260
331
|
|
|
261
332
|
await session.start(agent=agent, room=connection.livekit_room)
|
|
262
333
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.0.21"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: meshagent-livekit
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.21
|
|
4
4
|
Summary: Livekit support for Meshagent
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
Project-URL: Documentation, https://meshagent.com
|
|
@@ -20,6 +20,6 @@ Requires-Dist: livekit-plugins-elevenlabs~=1.0.19
|
|
|
20
20
|
Requires-Dist: livekit-plugins-playai~=1.0.19
|
|
21
21
|
Requires-Dist: livekit-plugins-silero~=1.0.19
|
|
22
22
|
Requires-Dist: livekit-plugins-turn-detector~=1.0.19
|
|
23
|
-
Requires-Dist: meshagent-api~=0.0.
|
|
24
|
-
Requires-Dist: meshagent-tools~=0.0.
|
|
23
|
+
Requires-Dist: meshagent-api~=0.0.21
|
|
24
|
+
Requires-Dist: meshagent-tools~=0.0.21
|
|
25
25
|
Dynamic: license-file
|
|
@@ -21,8 +21,8 @@ dependencies = [
|
|
|
21
21
|
"livekit-plugins-playai~=1.0.19",
|
|
22
22
|
"livekit-plugins-silero~=1.0.19",
|
|
23
23
|
"livekit-plugins-turn-detector~=1.0.19",
|
|
24
|
-
"meshagent-api~=0.0.
|
|
25
|
-
"meshagent-tools~=0.0.
|
|
24
|
+
"meshagent-api~=0.0.21",
|
|
25
|
+
"meshagent-tools~=0.0.21"
|
|
26
26
|
]
|
|
27
27
|
|
|
28
28
|
[project.urls]
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.0.20"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{meshagent_livekit-0.0.20 → meshagent_livekit-0.0.21}/meshagent/livekit/agents/transcriber.py
RENAMED
|
File without changes
|
|
File without changes
|
{meshagent_livekit-0.0.20 → meshagent_livekit-0.0.21}/meshagent/livekit/livekit_protocol_test.py
RENAMED
|
File without changes
|
|
File without changes
|
{meshagent_livekit-0.0.20 → meshagent_livekit-0.0.21}/meshagent_livekit.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{meshagent_livekit-0.0.20 → meshagent_livekit-0.0.21}/meshagent_livekit.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|