mirror of
https://github.com/NousResearch/atropos.git
synced 2026-04-19 12:57:58 +00:00
Fix formatting issues in community environments - Applied black, isort, trailing whitespace, and end-of-file fixes - Remaining flake8 issues (unused imports, line length) noted for future cleanup
This commit is contained in:
parent
e85a170c34
commit
7f2e1a4f90
34 changed files with 1560 additions and 821 deletions
|
|
@ -1,37 +1,22 @@
|
|||
import sys # Import sys for sys.exit
|
||||
import logging
|
||||
import os
|
||||
import sys # Import sys for sys.exit
|
||||
from pathlib import Path
|
||||
|
||||
from dotenv import load_dotenv
|
||||
from livekit.agents import Agent, AgentSession, JobContext, WorkerOptions, cli, mcp
|
||||
from livekit.plugins import deepgram, openai, silero
|
||||
from livekit.plugins.turn_detector.multilingual import MultilingualModel
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv(dotenv_path=Path(__file__).parent.parent / '.env')
|
||||
load_dotenv(dotenv_path=Path(__file__).parent.parent / ".env")
|
||||
|
||||
logger = logging.getLogger("stone-agent")
|
||||
|
||||
|
||||
from livekit.agents import (
|
||||
Agent,
|
||||
AgentSession,
|
||||
ChatContext,
|
||||
JobContext,
|
||||
WorkerOptions,
|
||||
cli,
|
||||
mcp,
|
||||
RunContext,
|
||||
function_tool,
|
||||
from typing import ( # Ensure List and Optional are imported for tool type hints
|
||||
List,
|
||||
Optional,
|
||||
)
|
||||
from livekit.agents.voice.agent import ModelSettings # Import ModelSettings
|
||||
from livekit.agents.llm import (
|
||||
ChatRole,
|
||||
LLM,
|
||||
ChatMessage
|
||||
)
|
||||
from livekit.plugins import deepgram, openai, silero, anthropic
|
||||
from livekit.plugins.turn_detector.multilingual import MultilingualModel
|
||||
from typing import List, Optional # Ensure List and Optional are imported for tool type hints
|
||||
|
||||
# Import the original FunctionAgents from the official agent files
|
||||
# These files should be in the same directory as router_agent.py
|
||||
|
|
@ -43,6 +28,22 @@ from contact_agent import ContactAgent
|
|||
from gmail_agent import GmailAgent
|
||||
from go_agent import GoAgent
|
||||
from listen_agent import ListenAgent
|
||||
from livekit.agents import (
|
||||
Agent,
|
||||
AgentSession,
|
||||
ChatContext,
|
||||
JobContext,
|
||||
RunContext,
|
||||
WorkerOptions,
|
||||
cli,
|
||||
function_tool,
|
||||
mcp,
|
||||
)
|
||||
from livekit.agents.llm import LLM, ChatMessage, ChatRole
|
||||
from livekit.agents.voice.agent import ModelSettings # Import ModelSettings
|
||||
from livekit.plugins import anthropic, deepgram, openai, silero
|
||||
from livekit.plugins.turn_detector.multilingual import MultilingualModel
|
||||
|
||||
# from mem_agent import MemoryAgent
|
||||
|
||||
logger = logging.getLogger("router-agent")
|
||||
|
|
@ -51,8 +52,12 @@ load_dotenv()
|
|||
# Determine the absolute path for server scripts relative to this file
|
||||
_current_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
|
||||
@function_tool
|
||||
async def delegate_to_router_agent(context: RunContext, original_query: str = "User wants to talk about something else."):
|
||||
async def delegate_to_router_agent(
|
||||
context: RunContext,
|
||||
original_query: str = "User wants to talk about something else.",
|
||||
):
|
||||
"""
|
||||
Call this function to delegate the conversation back to the main RouterAgent.
|
||||
This is used when your current task is complete, or the user asks for functionality
|
||||
|
|
@ -60,20 +65,31 @@ async def delegate_to_router_agent(context: RunContext, original_query: str = "U
|
|||
Args:
|
||||
original_query: A brief description of why the delegation is happening or the user's last relevant query.
|
||||
"""
|
||||
logger.info(f"Specialist Agent: Delegating back to RouterAgent. Reason/Query: '{original_query}'")
|
||||
logger.info(
|
||||
f"Specialist Agent: Delegating back to RouterAgent. Reason/Query: '{original_query}'"
|
||||
)
|
||||
# Try to access _chat_ctx via context.session, as context.agent was problematic
|
||||
if not hasattr(context, 'session') or context.session is None:
|
||||
logger.error("delegate_to_router_agent: RunContext does not have a valid 'session' attribute.")
|
||||
if not hasattr(context, "session") or context.session is None:
|
||||
logger.error(
|
||||
"delegate_to_router_agent: RunContext does not have a valid 'session' attribute."
|
||||
)
|
||||
# This is a critical failure for context propagation.
|
||||
# Depending on desired behavior, could raise an error or attempt a recovery (though recovery is hard here).
|
||||
# For now, we'll let it fail if it tries to access _chat_ctx on a None session,
|
||||
# For now, we'll let it fail if it tries to access _chat_ctx on a None session,
|
||||
# or re-raise a more specific error.
|
||||
raise AttributeError("RunContext is missing the session attribute, cannot retrieve ChatContext.")
|
||||
raise AttributeError(
|
||||
"RunContext is missing the session attribute, cannot retrieve ChatContext."
|
||||
)
|
||||
|
||||
return (
|
||||
RouterAgent(chat_ctx=context.session._chat_ctx),
|
||||
"Okay, let me switch you back to the main assistant.",
|
||||
)
|
||||
|
||||
return RouterAgent(chat_ctx=context.session._chat_ctx), "Okay, let me switch you back to the main assistant."
|
||||
|
||||
class RouterAgent(Agent):
|
||||
"""Routes user queries to specialized agents."""
|
||||
|
||||
def __init__(self, chat_ctx: ChatContext):
|
||||
super().__init__(
|
||||
instructions="""
|
||||
|
|
@ -101,7 +117,7 @@ class RouterAgent(Agent):
|
|||
If uncertain, you can ask one clarifying question to determine the correct agent, but prefer to route directly if possible.
|
||||
""",
|
||||
allow_interruptions=True,
|
||||
chat_ctx=chat_ctx
|
||||
chat_ctx=chat_ctx,
|
||||
)
|
||||
|
||||
async def on_enter(self):
|
||||
|
|
@ -109,7 +125,6 @@ class RouterAgent(Agent):
|
|||
logger.info("RouterAgent entered. Waiting for user query.")
|
||||
self.session.generate_reply()
|
||||
|
||||
|
||||
@function_tool
|
||||
async def delegate_to_math_agent(self, query: str):
|
||||
"""
|
||||
|
|
@ -117,11 +132,13 @@ class RouterAgent(Agent):
|
|||
Args:
|
||||
query: The user's original voice query that is mathematical in nature.
|
||||
"""
|
||||
logger.info(f"RouterAgent: Delegating to MathSpecialistAgent for query: '{query}'")
|
||||
logger.info(
|
||||
f"RouterAgent: Delegating to MathSpecialistAgent for query: '{query}'"
|
||||
)
|
||||
# Pass the delegate_to_router_agent tool to the CalculatorAgent
|
||||
math_agent = CalculatorAgent(
|
||||
chat_ctx=self.session._chat_ctx,
|
||||
tools=[delegate_to_router_agent] # Pass the tool
|
||||
tools=[delegate_to_router_agent], # Pass the tool
|
||||
)
|
||||
return math_agent, "Okay, I'll connect you with my math specialist for that."
|
||||
|
||||
|
|
@ -132,13 +149,18 @@ class RouterAgent(Agent):
|
|||
Args:
|
||||
query: The user's original voice query.
|
||||
"""
|
||||
logger.info(f"RouterAgent: Delegating to AskAgent (for perplexity tasks) for query: '{query}'")
|
||||
logger.info(
|
||||
f"RouterAgent: Delegating to AskAgent (for perplexity tasks) for query: '{query}'"
|
||||
)
|
||||
try:
|
||||
perplexity_agent = AskAgent(
|
||||
chat_ctx=self.session._chat_ctx,
|
||||
tools=[delegate_to_router_agent] # Pass the tool
|
||||
tools=[delegate_to_router_agent], # Pass the tool
|
||||
)
|
||||
return (
|
||||
perplexity_agent,
|
||||
"Alright, let me get my knowledge expert to help with that question.",
|
||||
)
|
||||
return perplexity_agent, "Alright, let me get my knowledge expert to help with that question."
|
||||
except AttributeError as e:
|
||||
logger.error(f"Unexpected AttributeError: {e}")
|
||||
raise
|
||||
|
|
@ -153,7 +175,7 @@ class RouterAgent(Agent):
|
|||
logger.info(f"RouterAgent: Delegating to CalendarAgent for query: '{query}'")
|
||||
calendar_agent = CalendarAgent(
|
||||
chat_ctx=self.session._chat_ctx,
|
||||
tools=[delegate_to_router_agent] # Pass the tool
|
||||
tools=[delegate_to_router_agent], # Pass the tool
|
||||
)
|
||||
return calendar_agent, "Okay, let me check your calendar."
|
||||
|
||||
|
|
@ -167,7 +189,7 @@ class RouterAgent(Agent):
|
|||
logger.info(f"RouterAgent: Delegating to CallerAgent for query: '{query}'")
|
||||
caller_agent = CallerAgent(
|
||||
chat_ctx=self.session._chat_ctx,
|
||||
tools=[delegate_to_router_agent] # Pass the tool
|
||||
tools=[delegate_to_router_agent], # Pass the tool
|
||||
)
|
||||
return caller_agent, "Sure, I can try to make that call for you."
|
||||
|
||||
|
|
@ -181,7 +203,7 @@ class RouterAgent(Agent):
|
|||
logger.info(f"RouterAgent: Delegating to ContactAgent for query: '{query}'")
|
||||
contact_agent = ContactAgent(
|
||||
chat_ctx=self.session._chat_ctx,
|
||||
tools=[delegate_to_router_agent] # Pass the tool
|
||||
tools=[delegate_to_router_agent], # Pass the tool
|
||||
)
|
||||
return contact_agent, "Let me look up that contact information for you."
|
||||
|
||||
|
|
@ -195,7 +217,7 @@ class RouterAgent(Agent):
|
|||
logger.info(f"RouterAgent: Delegating to GmailAgent for query: '{query}'")
|
||||
gmail_agent = GmailAgent(
|
||||
chat_ctx=self.session._chat_ctx,
|
||||
tools=[delegate_to_router_agent] # Pass the tool
|
||||
tools=[delegate_to_router_agent], # Pass the tool
|
||||
)
|
||||
return gmail_agent, "Okay, I'll check your emails."
|
||||
|
||||
|
|
@ -209,7 +231,7 @@ class RouterAgent(Agent):
|
|||
logger.info(f"RouterAgent: Delegating to GoAgent for query: '{query}'")
|
||||
go_agent = GoAgent(
|
||||
chat_ctx=self.session._chat_ctx,
|
||||
tools=[delegate_to_router_agent] # Pass the tool
|
||||
tools=[delegate_to_router_agent], # Pass the tool
|
||||
)
|
||||
return go_agent, "Let me get my navigation expert for that."
|
||||
|
||||
|
|
@ -223,10 +245,11 @@ class RouterAgent(Agent):
|
|||
logger.info(f"RouterAgent: Delegating to ListenAgent for query: '{query}'")
|
||||
listen_agent = ListenAgent(
|
||||
chat_ctx=self.session._chat_ctx,
|
||||
tools=[delegate_to_router_agent] # Pass the tool
|
||||
tools=[delegate_to_router_agent], # Pass the tool
|
||||
)
|
||||
return listen_agent, "Okay, let's get some music playing."
|
||||
|
||||
|
||||
async def entrypoint(ctx: JobContext):
|
||||
"""Main entrypoint for the multi-agent LiveKit application."""
|
||||
await ctx.connect()
|
||||
|
|
@ -237,21 +260,27 @@ async def entrypoint(ctx: JobContext):
|
|||
stt=openai.STT(model="gpt-4o-mini-transcribe", detect_language=True),
|
||||
tts=openai.TTS(voice="alloy", model="tts-1-hd"),
|
||||
llm=openai.LLM(model="gpt-4o"),
|
||||
turn_detection=MultilingualModel()
|
||||
turn_detection=MultilingualModel(),
|
||||
)
|
||||
logger.info(
|
||||
"AgentSession configured. MCP servers will be managed by individual specialist agents."
|
||||
)
|
||||
logger.info("AgentSession configured. MCP servers will be managed by individual specialist agents.")
|
||||
|
||||
initial_agent = RouterAgent(chat_ctx=session._chat_ctx)
|
||||
await session.start(agent=initial_agent, room=ctx.room)
|
||||
logger.info("RouterAgent session started.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Setup basic logging if running directly
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
||||
)
|
||||
try:
|
||||
cli.run_app(WorkerOptions(entrypoint_fnc=entrypoint))
|
||||
except SystemExit: # Allow sys.exit() to pass through without logging as critical
|
||||
except SystemExit: # Allow sys.exit() to pass through without logging as critical
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.critical(f"Unhandled exception at top level: {e}", exc_info=True)
|
||||
sys.exit(1) # Ensure exit with error code
|
||||
sys.exit(1) # Ensure exit with error code
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue