From 5d6b51078a4f4062c7cea3a2e73d084f75928de8 Mon Sep 17 00:00:00 2001 From: Willem Carel de Jongh Date: Tue, 1 Apr 2025 15:39:17 +0200 Subject: [PATCH 01/55] Fix import error --- cookbook/playground/demo.py | 18 ++++ cookbook/playground/teams_demo.py | 16 +-- libs/agno/agno/agent/agent.py | 93 +++++++++++++++-- libs/agno/agno/api/agent.py | 33 +++++- libs/agno/agno/api/routes.py | 2 + libs/agno/agno/api/schemas/agent.py | 8 ++ libs/agno/agno/api/schemas/team.py | 12 ++- libs/agno/agno/api/team.py | 33 +++++- libs/agno/agno/team/team.py | 149 +++++++++++++++++++++++++++- 9 files changed, 344 insertions(+), 20 deletions(-) diff --git a/cookbook/playground/demo.py b/cookbook/playground/demo.py index 2ff0a25920..0611554900 100644 --- a/cookbook/playground/demo.py +++ b/cookbook/playground/demo.py @@ -6,6 +6,8 @@ from agno.agent import Agent from agno.memory.v2 import Memory from agno.memory.v2.db.sqlite import SqliteMemoryDb +from agno.embedder.openai import OpenAIEmbedder +from agno.knowledge.pdf_url import PDFUrlKnowledgeBase from agno.models.openai import OpenAIChat from agno.playground import Playground, serve_playground_app from agno.storage.sqlite import SqliteStorage @@ -14,6 +16,7 @@ from agno.tools.exa import ExaTools from agno.tools.yfinance import YFinanceTools from agno.tools.youtube import YouTubeTools +from agno.vectordb.lancedb import LanceDb, SearchType agent_storage_file: str = "tmp/agents.db" memory_storage_file: str = "tmp/memory.db" @@ -40,6 +43,10 @@ num_history_responses=5, add_datetime_to_instructions=True, markdown=True, + instructions=[ + "Never answer like a bat", + ], + register_on_platform=False, ) web_agent = Agent( @@ -61,6 +68,17 @@ num_history_responses=5, add_datetime_to_instructions=True, markdown=True, + register_on_platform=True, + debug_mode=True, + knowledge=PDFUrlKnowledgeBase( + urls=["https://agno-public.s3.amazonaws.com/recipes/ThaiRecipes.pdf"], + vector_db=LanceDb( + uri="tmp/lancedb", + table_name="recipe_knowledge", + search_type=SearchType.hybrid, + embedder=OpenAIEmbedder(id="text-embedding-3-small"), + ), + ), ) finance_agent = Agent( diff --git a/cookbook/playground/teams_demo.py b/cookbook/playground/teams_demo.py index 157333e188..861b4abfc9 100644 --- a/cookbook/playground/teams_demo.py +++ b/cookbook/playground/teams_demo.py @@ -78,7 +78,7 @@ tools=[DuckDuckGoTools()], agent_id="web_agent", instructions=[ - "You are an experienced web researcher and news analyst! 🔍", + "You are an experienced web researcher and news analyst!", ], memory=memory, enable_user_memories=True, @@ -98,7 +98,7 @@ YFinanceTools(stock_price=True, analyst_recommendations=True, company_info=True) ], instructions=[ - "You are a skilled financial analyst with expertise in market data! 📊", + "You are a skilled financial analyst with expertise in market data!", "Follow these steps when analyzing financial data:", "Start with the latest stock price, trading volume, and daily range", "Present detailed analyst recommendations and consensus target prices", @@ -142,7 +142,7 @@ A comprehensive research report with clear sections and data-driven insights. """), instructions=[ - "You are the lead researcher of a research team! 🔍", + "You are the lead researcher of a research team!", ], memory=memory, enable_user_memories=True, @@ -169,7 +169,7 @@ A comprehensive report with clear sections and data-driven insights. """), instructions=[ - "You are the lead editor of a prestigious financial news desk! 📰", + "You are the lead editor of a prestigious financial news desk!", ], memory=memory, enable_user_memories=True, @@ -188,14 +188,14 @@ finance_agent, research_agent, file_agent, - audio_agent, - video_agent, + # audio_agent, + # video_agent, ], model=OpenAIChat(id="gpt-4o"), mode="route", team_id="financial_news_team", instructions=[ - "You are the lead editor of a prestigious financial news desk! 📰", + "You are the lead editor of a prestigious financial news desk!", "If you are given a file send it to the file agent.", "If you are given an audio file send it to the audio agent.", "If you are given a video file send it to the video agent.", @@ -216,6 +216,8 @@ memory=memory, enable_user_memories=True, expected_output="A good financial news report.", + context="use USD as currency", + register_on_platform=True, ) app = Playground( diff --git a/libs/agno/agno/agent/agent.py b/libs/agno/agno/agent/agent.py index 53b424cc85..0a39b48ae1 100644 --- a/libs/agno/agno/agent/agent.py +++ b/libs/agno/agno/agent/agent.py @@ -1,5 +1,7 @@ from __future__ import annotations +import asyncio +import threading from collections import ChainMap, defaultdict, deque from dataclasses import asdict, dataclass from os import getenv @@ -349,7 +351,6 @@ def __init__( self.name = name self.agent_id = agent_id self.introduction = introduction - self.user_id = user_id self.session_id = session_id @@ -573,6 +574,9 @@ def _run( self.run_id = str(uuid4()) self.run_response = RunResponse(run_id=self.run_id, session_id=session_id, agent_id=self.agent_id) + + self._register_agent_on_platform() + log_debug(f"Agent Run Start: {self.run_response.run_id}", center=True) # 2. Update the Model and resolve context @@ -1158,6 +1162,14 @@ async def _arun( self.run_id = str(uuid4()) self.run_response = RunResponse(run_id=self.run_id, session_id=session_id, agent_id=self.agent_id) + # 1.4 Register the agent on the platform + + def _run_async_in_thread(coro): + asyncio.run(coro) + + t = threading.Thread(target=_run_async_in_thread, args=(self._aregister_agent_on_platform(),), daemon=True) + t.start() + log_debug(f"Async Agent Run Start: {self.run_response.run_id}", center=True, symbol="*") # 2. Update the Model and resolve context @@ -1492,7 +1504,14 @@ async def _arun( # Log Agent Run await self._alog_agent_run(user_id=user_id, session_id=session_id) - log_debug(f"Agent Run End: {self.run_response.run_id}", center=True, symbol="*") + # Define a synchronous wrapper to run the async function + def run_async_in_thread(): + asyncio.run(alog_agent_run()) + + # Run the synchronous wrapper in a separate thread + await asyncio.to_thread(run_async_in_thread) + + log_debug(f"Async Agent Run End: {self.run_response.run_id}", center=True, symbol="*") if self.stream_intermediate_steps: yield self.create_run_response( content=self.run_response.content, @@ -4134,7 +4153,34 @@ def _create_run_data(self) -> Dict[str, Any]: return run_data - def _log_agent_run(self, session_id: str, user_id: Optional[str] = None) -> None: + def _register_agent_on_platform(self) -> None: + + self.set_monitoring() + if not self.monitoring: + return + + from agno.api.agent import AgentCreate, create_agent + + try: + create_agent(app=AgentCreate(name=self.name, agent_id=self.agent_id, config=self.to_platform_dict())) + except Exception as e: + log_debug(f"Could not create Agent app: {e}") + + async def _aregister_agent_on_platform(self) -> None: + self.set_monitoring() + if not self.monitoring: + return + + from agno.api.agent import AgentCreate, acreate_agent + + try: + await acreate_agent( + agent=AgentCreate(name=self.name, agent_id=self.agent_id, config=self.to_platform_dict()) + ) + except Exception as e: + log_debug(f"Could not create Agent app: {e}") + + def _log_agent_run(self) -> None: self.set_monitoring() if not self.telemetry and not self.monitoring: @@ -5009,6 +5055,41 @@ def cli_app( if message in _exit_on: break - self.print_response( - message=message, stream=stream, markdown=markdown, user_id=user_id, session_id=session_id, **kwargs - ) + self.print_response(message=message, stream=stream, markdown=markdown, **kwargs) + + def to_platform_dict(self) -> Dict[str, Any]: + tools = [] + if self.tools is not None: + for tool in self.tools: + functions = [] + for function in tool.functions.keys(): + print(function) + functions.append({"name": function, "parameters": tool.functions[function].to_dict()}) + tools.append({"name": tool.name, "functions": functions}) + + model = None + if self.model is not None: + model = { + "name": self.model.__class__.__name__, + "id": self.model.id, + "provider": self.model.provider, + "response_format": self.model.response_format, + } + + payload = { + "instructions": self.instructions if self.instructions is not None else [], + "tools": tools, + "memory": { + "name": self.memory.__class__.__name__ if self.memory is not None else None, + }, + "storage": { + "name": self.storage.__class__.__name__ if self.storage is not None else None, + }, + "knowledge": { + "name": self.knowledge.__class__.__name__ if self.knowledge is not None else None, + }, + "model": model, + "name": self.name, + "description": self.description, + } + return payload diff --git a/libs/agno/agno/api/agent.py b/libs/agno/agno/api/agent.py index 6f3687355b..53c918a218 100644 --- a/libs/agno/agno/api/agent.py +++ b/libs/agno/agno/api/agent.py @@ -1,6 +1,6 @@ from agno.api.api import api from agno.api.routes import ApiRoutes -from agno.api.schemas.agent import AgentRunCreate, AgentSessionCreate +from agno.api.schemas.agent import AgentCreate, AgentRunCreate, AgentSessionCreate from agno.cli.settings import agno_cli_settings from agno.utils.log import log_debug @@ -25,7 +25,6 @@ def create_agent_run(run: AgentRunCreate, monitor: bool = False) -> None: if not agno_cli_settings.api_enabled: return - log_debug("Logging Agent Run") with api.AuthenticatedClient() as api_client: try: api_client.post( @@ -41,7 +40,6 @@ async def acreate_agent_run(run: AgentRunCreate, monitor: bool = False) -> None: if not agno_cli_settings.api_enabled: return - log_debug("Logging Agent Run (Async)") async with api.AuthenticatedAsyncClient() as api_client: try: await api_client.post( @@ -50,3 +48,32 @@ async def acreate_agent_run(run: AgentRunCreate, monitor: bool = False) -> None: ) except Exception as e: log_debug(f"Could not create Agent run: {e}") + + +def create_agent(agent: AgentCreate) -> None: + if not agno_cli_settings.api_enabled: + return + + with api.AuthenticatedClient() as api_client: + try: + api_client.post( + ApiRoutes.AGENT_CREATE, + json={"agent": agent.model_dump()}, + ) + except Exception as e: + log_debug(f"Could not create Agent: {e}") + + +async def acreate_agent(agent: AgentCreate) -> None: + if not agno_cli_settings.api_enabled: + return + + async with api.AuthenticatedAsyncClient() as api_client: + try: + payload = {"agent": agent.model_dump(exclude_none=True)} + await api_client.post( + ApiRoutes.AGENT_CREATE, + json=payload, + ) + except Exception as e: + log_debug(f"Could not create Agent: {e}") diff --git a/libs/agno/agno/api/routes.py b/libs/agno/agno/api/routes.py index 69b6825c53..9f339cdf08 100644 --- a/libs/agno/agno/api/routes.py +++ b/libs/agno/agno/api/routes.py @@ -22,10 +22,12 @@ class ApiRoutes: # Agent paths AGENT_SESSION_CREATE: str = "/v1/agent-sessions" AGENT_RUN_CREATE: str = "/v1/agent-runs" + AGENT_CREATE: str = "/v2/agents" # Team paths TEAM_RUN_CREATE: str = "/v1/team-runs" TEAM_SESSION_CREATE: str = "/v1/team-sessions" + TEAM_CREATE: str = "/v2/teams" # Telemetry paths # TODO: Update to use the new telemetry paths diff --git a/libs/agno/agno/api/schemas/agent.py b/libs/agno/agno/api/schemas/agent.py index b8b261c49f..9b7c43a2cf 100644 --- a/libs/agno/agno/api/schemas/agent.py +++ b/libs/agno/agno/api/schemas/agent.py @@ -18,3 +18,11 @@ class AgentRunCreate(BaseModel): run_id: Optional[str] = None run_data: Optional[Dict[str, Any]] = None agent_data: Optional[Dict[str, Any]] = None + + +class AgentCreate(BaseModel): + """Data sent to API to create an Agent""" + + agent_id: str + name: Optional[str] = None + config: Dict[str, Any] diff --git a/libs/agno/agno/api/schemas/team.py b/libs/agno/agno/api/schemas/team.py index 284a819863..5caa01802d 100644 --- a/libs/agno/agno/api/schemas/team.py +++ b/libs/agno/agno/api/schemas/team.py @@ -4,17 +4,25 @@ class TeamSessionCreate(BaseModel): - """Data sent to API to create an Team Session""" + """Data sent to API to create a Team Session""" session_id: str team_data: Optional[Dict[str, Any]] = None class TeamRunCreate(BaseModel): - """Data sent to API to create an Team Run""" + """Data sent to API to create a Team Run""" session_id: str team_session_id: Optional[str] = None run_id: Optional[str] = None run_data: Optional[Dict[str, Any]] = None team_data: Optional[Dict[str, Any]] = None + + +class TeamCreate(BaseModel): + """Data sent to API to create aTeam""" + + team_id: str + name: Optional[str] = None + config: Dict[str, Any] diff --git a/libs/agno/agno/api/team.py b/libs/agno/agno/api/team.py index b90da149d6..6b4f291f4d 100644 --- a/libs/agno/agno/api/team.py +++ b/libs/agno/agno/api/team.py @@ -1,6 +1,6 @@ from agno.api.api import api from agno.api.routes import ApiRoutes -from agno.api.schemas.team import TeamRunCreate, TeamSessionCreate +from agno.api.schemas.team import TeamCreate, TeamRunCreate, TeamSessionCreate from agno.cli.settings import agno_cli_settings from agno.utils.log import log_debug @@ -53,3 +53,34 @@ def upsert_team_session(session: TeamSessionCreate, monitor: bool = False) -> No except Exception as e: log_debug(f"Could not create Agent session: {e}") return + + +def create_team(team: TeamCreate) -> None: + if not agno_cli_settings.api_enabled: + return + + with api.AuthenticatedClient() as api_client: + try: + api_client.post( + ApiRoutes.TEAM_CREATE, + json={"team": team.model_dump(exclude_none=True)}, + ) + except Exception as e: + log_debug(f"Could not create Team: {e}") + + +async def acreate_team(team: TeamCreate) -> None: + if not agno_cli_settings.api_enabled: + return + + async with api.AuthenticatedAsyncClient() as api_client: + try: + payload = {"team": team.model_dump(exclude_none=True)} + await api_client.post( + ApiRoutes.TEAM_CREATE, + json=payload, + ) + except Exception as e: + print(f"Could not create Team: {e}") + + log_debug(f"Could not create Team: {e}") diff --git a/libs/agno/agno/team/team.py b/libs/agno/agno/team/team.py index 098b932d09..933fba2b99 100644 --- a/libs/agno/agno/team/team.py +++ b/libs/agno/agno/team/team.py @@ -1,5 +1,6 @@ import asyncio import json +import threading from collections import ChainMap, defaultdict, deque from dataclasses import asdict, dataclass, replace from os import getenv @@ -219,6 +220,7 @@ class Team: # This helps us improve the Teams implementation and provide better support telemetry: bool = True + def __init__( self, members: List[Union[Agent, "Team"]], @@ -546,6 +548,9 @@ def run( # Configure the model for runs self._configure_model(show_tool_calls=show_tool_calls) + # Register the team on the platform + self._register_team_on_platform() + # Run the team last_exception = None num_attempts = retries + 1 @@ -1229,6 +1234,12 @@ async def arun( # Configure the model for runs self._configure_model(show_tool_calls=show_tool_calls) + def _run_async_in_thread(coro): + asyncio.run(coro) + + t = threading.Thread(target=_run_async_in_thread, args=(self._aregister_team_on_platform(),), daemon=True) + t.start() + # Run the team last_exception = None num_attempts = retries + 1 @@ -6190,7 +6201,7 @@ def _get_team_session(self, session_id: str, user_id: Optional[str] = None) -> T created_at=int(time()), ) - def _log_team_run(self, session_id: str, user_id: Optional[str] = None) -> None: + def _log_team_run(self) -> None: if not self.telemetry and not self.monitoring: return @@ -6258,3 +6269,139 @@ def _log_team_session(self, session_id: str, user_id: Optional[str] = None): ) except Exception as e: log_debug(f"Could not create team monitor: {e}") + + def deep_copy(self, *, update: Optional[Dict[str, Any]] = None) -> "Team": + """Create a deep copy of the Team with optional updates. + Args: + update: Optional dictionary of attributes to update in the copy + Returns: + A new Team instance with copied attributes + """ + # Get all instance attributes + attributes = self.__dict__.copy() + + excluded_fields = ["team_session", "session_name", "_functions_for_model"] + # Deep copy each field + copied_attributes = {} + for field_name, field_value in attributes.items(): + if field_name in excluded_fields: + continue + copied_attributes[field_name] = self._deep_copy_field(field_name, field_value) + + # Create new instance + team_copy = Team.__new__(Team) + team_copy.__dict__ = copied_attributes + + # Apply any updates + if update: + for key, value in update.items(): + setattr(team_copy, key, value) + + return team_copy + + def _deep_copy_field(self, field_name: str, field_value: Any) -> Any: + """Deep copy a single field value. + Args: + field_name: Name of the field being copied + field_value: Value to copy + Returns: + Deep copied value + """ + from copy import copy, deepcopy + + # Handle special cases + if field_name == "members": + # Deep copy each member + if field_value is not None: + return [member.deep_copy() for member in field_value] + return None + + # For memory use the deep_copy methods + if field_name == "memory" and field_value is not None: + return field_value.deep_copy() + + # For storage, model and reasoning_model, use a deep copy + elif field_name in ("storage", "model", "reasoning_model") and field_value is not None: + try: + return deepcopy(field_value) + except Exception: + try: + return copy(field_value) + except Exception as e: + log_warning(f"Failed to copy field: {field_name} - {e}") + return field_value + + # For compound types, attempt a deep copy + elif isinstance(field_value, (list, dict, set)): + try: + return deepcopy(field_value) + except Exception as e: + log_warning(f"Failed to deepcopy field: {field_name} - {e}") + try: + return copy(field_value) + except Exception as e: + log_warning(f"Failed to copy field: {field_name} - {e}") + return field_value + + # For pydantic models, attempt a model_copy + elif isinstance(field_value, BaseModel): + try: + return field_value.model_copy(deep=True) + except Exception: + try: + return field_value.model_copy(deep=False) + except Exception as e: + log_warning(f"Failed to copy field: {field_name} - {e}") + return field_value + + # For other types, attempt a shallow copy first + try: + from copy import copy + + return copy(field_value) + except Exception: + # If copy fails, return as is + return field_value + + def _register_team_on_platform(self) -> None: + from agno.api.team import TeamCreate, create_team + + try: + create_team( + team=TeamCreate( + team_id=self.team_id, + name=self.name, + config=self.to_platform_dict(), + ), + ) + except Exception as e: + log_debug(f"Could not create team on platform: {e}") + print(f"Could not create team on platform: {e}") + + async def _aregister_team_on_platform(self) -> None: + from agno.api.team import TeamCreate, acreate_team + + try: + await acreate_team( + team=TeamCreate( + team_id=self.team_id, + name=self.name, + config=self.to_platform_dict(), + ), + ) + except Exception as e: + print(f"Could not create team on platform: {e}") + log_debug(f"Could not create team on platform: {e}") + + def to_platform_dict(self) -> Dict[str, Any]: + return { + "members": [member.to_platform_dict() for member in self.members], + "mode": self.mode, + "model": self.model.to_dict() if self.model is not None else None, + "name": self.name, + "instructions": self.instructions, + "description": self.description, + "storage": self.storage.__class__.__name__ if self.storage is not None else None, + # "tools": [tool.to_dict() for tool in self.tools] if self.tools is not None else None, + # "memory": self.memory.to_dict() if self.memory is not None else None, + } From 962bd6b4b4e717ee956f8f2ad6ec84c5ad1978df Mon Sep 17 00:00:00 2001 From: Willem Carel de Jongh Date: Wed, 16 Apr 2025 13:30:43 +0200 Subject: [PATCH 02/55] Remove register fields --- cookbook/playground/demo.py | 4 +--- libs/agno/agno/agent/agent.py | 8 ++++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/cookbook/playground/demo.py b/cookbook/playground/demo.py index 0611554900..3ac4c3f564 100644 --- a/cookbook/playground/demo.py +++ b/cookbook/playground/demo.py @@ -44,9 +44,8 @@ add_datetime_to_instructions=True, markdown=True, instructions=[ - "Never answer like a bat", + "Always answer like a pirate", ], - register_on_platform=False, ) web_agent = Agent( @@ -68,7 +67,6 @@ num_history_responses=5, add_datetime_to_instructions=True, markdown=True, - register_on_platform=True, debug_mode=True, knowledge=PDFUrlKnowledgeBase( urls=["https://agno-public.s3.amazonaws.com/recipes/ThaiRecipes.pdf"], diff --git a/libs/agno/agno/agent/agent.py b/libs/agno/agno/agent/agent.py index 0a39b48ae1..6ea0d0990c 100644 --- a/libs/agno/agno/agent/agent.py +++ b/libs/agno/agno/agent/agent.py @@ -1505,11 +1505,11 @@ def _run_async_in_thread(coro): await self._alog_agent_run(user_id=user_id, session_id=session_id) # Define a synchronous wrapper to run the async function - def run_async_in_thread(): - asyncio.run(alog_agent_run()) + # def run_async_in_thread(): + # asyncio.run(alog_agent_run()) - # Run the synchronous wrapper in a separate thread - await asyncio.to_thread(run_async_in_thread) + # # Run the synchronous wrapper in a separate thread + # await asyncio.to_thread(run_async_in_thread) log_debug(f"Async Agent Run End: {self.run_response.run_id}", center=True, symbol="*") if self.stream_intermediate_steps: From 8b300f457f2d8c1ddce4112e138327d1a0ef669f Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Thu, 17 Apr 2025 11:18:14 +0530 Subject: [PATCH 03/55] update --- cookbook/playground/teams_demo.py | 1 - 1 file changed, 1 deletion(-) diff --git a/cookbook/playground/teams_demo.py b/cookbook/playground/teams_demo.py index 861b4abfc9..f8babaae2e 100644 --- a/cookbook/playground/teams_demo.py +++ b/cookbook/playground/teams_demo.py @@ -217,7 +217,6 @@ enable_user_memories=True, expected_output="A good financial news report.", context="use USD as currency", - register_on_platform=True, ) app = Playground( From e4ee42374e8b2dd61e9a95f76252b4ca3c62ab59 Mon Sep 17 00:00:00 2001 From: Ayush <97244608+Ayush0054@users.noreply.github.com> Date: Tue, 22 Apr 2025 01:21:32 +0530 Subject: [PATCH 04/55] Api registrations teams agent registration fix (#2871) ## Summary Describe key changes, mention related issues or motivation for the changes. (If applicable, issue number: #____) ## Type of change - [ ] Bug fix - [ ] New feature - [ ] Breaking change - [ ] Improvement - [ ] Model update - [ ] Other: --- ## Checklist - [ ] Code complies with style guidelines - [ ] Ran format/validation scripts (`./scripts/format.sh` and `./scripts/validate.sh`) - [ ] Self-review completed - [ ] Documentation updated (comments, docstrings) - [ ] Examples and guides: Relevant cookbook examples have been included or updated (if applicable) - [ ] Tested in clean environment - [ ] Tests added/updated (if applicable) --- ## Additional Notes Add any important context (deployment instructions, screenshots, security considerations, etc.) --- libs/agno/agno/agent/agent.py | 5 +++-- libs/agno/agno/api/schemas/agent.py | 2 ++ libs/agno/agno/api/schemas/team.py | 1 + libs/agno/agno/team/team.py | 9 ++++++++- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/libs/agno/agno/agent/agent.py b/libs/agno/agno/agent/agent.py index 6ea0d0990c..526c6b001e 100644 --- a/libs/agno/agno/agent/agent.py +++ b/libs/agno/agno/agent/agent.py @@ -4162,7 +4162,8 @@ def _register_agent_on_platform(self) -> None: from agno.api.agent import AgentCreate, create_agent try: - create_agent(app=AgentCreate(name=self.name, agent_id=self.agent_id, config=self.to_platform_dict())) + log_debug(f"Creating Agent app: {self.name}, {self.agent_id}, {self.team_id},") + create_agent(app=AgentCreate(name=self.name, agent_id=self.agent_id, team_id=self.team_id, config=self.to_platform_dict())) except Exception as e: log_debug(f"Could not create Agent app: {e}") @@ -4175,7 +4176,7 @@ async def _aregister_agent_on_platform(self) -> None: try: await acreate_agent( - agent=AgentCreate(name=self.name, agent_id=self.agent_id, config=self.to_platform_dict()) + agent=AgentCreate(name=self.name, agent_id=self.agent_id, team_id=self.team_id, config=self.to_platform_dict()) ) except Exception as e: log_debug(f"Could not create Agent app: {e}") diff --git a/libs/agno/agno/api/schemas/agent.py b/libs/agno/agno/api/schemas/agent.py index 9b7c43a2cf..ec210df051 100644 --- a/libs/agno/agno/api/schemas/agent.py +++ b/libs/agno/agno/api/schemas/agent.py @@ -24,5 +24,7 @@ class AgentCreate(BaseModel): """Data sent to API to create an Agent""" agent_id: str + team_id: Optional[str] = None + app_id: Optional[str] = None name: Optional[str] = None config: Dict[str, Any] diff --git a/libs/agno/agno/api/schemas/team.py b/libs/agno/agno/api/schemas/team.py index 5caa01802d..9f062e08d6 100644 --- a/libs/agno/agno/api/schemas/team.py +++ b/libs/agno/agno/api/schemas/team.py @@ -24,5 +24,6 @@ class TeamCreate(BaseModel): """Data sent to API to create aTeam""" team_id: str + app_id: Optional[str] = None name: Optional[str] = None config: Dict[str, Any] diff --git a/libs/agno/agno/team/team.py b/libs/agno/agno/team/team.py index 933fba2b99..ebae7609b0 100644 --- a/libs/agno/agno/team/team.py +++ b/libs/agno/agno/team/team.py @@ -550,6 +550,9 @@ def run( # Register the team on the platform self._register_team_on_platform() + + for member in self.members: + member._register_agent_on_platform() # Run the team last_exception = None @@ -1239,6 +1242,9 @@ def _run_async_in_thread(coro): t = threading.Thread(target=_run_async_in_thread, args=(self._aregister_team_on_platform(),), daemon=True) t.start() + for member in self.members: + t = threading.Thread(target=_run_async_in_thread, args=(member._aregister_agent_on_platform(),), daemon=True) + t.start() # Run the team last_exception = None @@ -6374,6 +6380,7 @@ def _register_team_on_platform(self) -> None: config=self.to_platform_dict(), ), ) + except Exception as e: log_debug(f"Could not create team on platform: {e}") print(f"Could not create team on platform: {e}") @@ -6395,7 +6402,7 @@ async def _aregister_team_on_platform(self) -> None: def to_platform_dict(self) -> Dict[str, Any]: return { - "members": [member.to_platform_dict() for member in self.members], + "members": [member.to_platform_dict() for member in self.members ], "mode": self.mode, "model": self.model.to_dict() if self.model is not None else None, "name": self.name, From 4d1bc4313958802f612d65a18e8e7fb2b66b7d01 Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Wed, 23 Apr 2025 10:14:03 +0530 Subject: [PATCH 05/55] update --- libs/agno/agno/agent/agent.py | 12 +-- libs/agno/agno/team/team.py | 135 ++++++++-------------------------- 2 files changed, 36 insertions(+), 111 deletions(-) diff --git a/libs/agno/agno/agent/agent.py b/libs/agno/agno/agent/agent.py index 526c6b001e..859f223720 100644 --- a/libs/agno/agno/agent/agent.py +++ b/libs/agno/agno/agent/agent.py @@ -575,7 +575,7 @@ def _run( self.run_response = RunResponse(run_id=self.run_id, session_id=session_id, agent_id=self.agent_id) - self._register_agent_on_platform() + self.register_agent_on_platform() log_debug(f"Agent Run Start: {self.run_response.run_id}", center=True) @@ -4153,7 +4153,7 @@ def _create_run_data(self) -> Dict[str, Any]: return run_data - def _register_agent_on_platform(self) -> None: + def register_agent_on_platform(self) -> None: self.set_monitoring() if not self.monitoring: @@ -4163,7 +4163,7 @@ def _register_agent_on_platform(self) -> None: try: log_debug(f"Creating Agent app: {self.name}, {self.agent_id}, {self.team_id},") - create_agent(app=AgentCreate(name=self.name, agent_id=self.agent_id, team_id=self.team_id, config=self.to_platform_dict())) + create_agent(app=AgentCreate(name=self.name, agent_id=self.agent_id, team_id=self.team_id, config=self.get_agent_config_dict())) except Exception as e: log_debug(f"Could not create Agent app: {e}") @@ -4176,12 +4176,12 @@ async def _aregister_agent_on_platform(self) -> None: try: await acreate_agent( - agent=AgentCreate(name=self.name, agent_id=self.agent_id, team_id=self.team_id, config=self.to_platform_dict()) + agent=AgentCreate(name=self.name, agent_id=self.agent_id, team_id=self.team_id, config=self.get_agent_config_dict()) ) except Exception as e: log_debug(f"Could not create Agent app: {e}") - def _log_agent_run(self) -> None: + def _log_agent_run(self, session_id: str, user_id: Optional[str] = None) -> None: self.set_monitoring() if not self.telemetry and not self.monitoring: @@ -5058,7 +5058,7 @@ def cli_app( self.print_response(message=message, stream=stream, markdown=markdown, **kwargs) - def to_platform_dict(self) -> Dict[str, Any]: + def get_agent_config_dict(self) -> Dict[str, Any]: tools = [] if self.tools is not None: for tool in self.tools: diff --git a/libs/agno/agno/team/team.py b/libs/agno/agno/team/team.py index ebae7609b0..5079598a89 100644 --- a/libs/agno/agno/team/team.py +++ b/libs/agno/agno/team/team.py @@ -551,8 +551,7 @@ def run( # Register the team on the platform self._register_team_on_platform() - for member in self.members: - member._register_agent_on_platform() + # Run the team last_exception = None @@ -642,7 +641,11 @@ def run( _tools.append(self.get_member_information) self._add_tools_to_model(self.model, tools=_tools) # type: ignore - + for member in self.members: + if isinstance(member, Agent): + member.register_agent_on_platform() + elif isinstance(member, Team): + member._register_team_on_platform() # Run the team try: self.run_response = TeamRunResponse(run_id=self.run_id, session_id=session_id, team_id=self.team_id) @@ -1237,14 +1240,14 @@ async def arun( # Configure the model for runs self._configure_model(show_tool_calls=show_tool_calls) - def _run_async_in_thread(coro): + def _run_async_in_thread(coro_func): + # Call the function to get the coroutine object + coro = coro_func() asyncio.run(coro) - t = threading.Thread(target=_run_async_in_thread, args=(self._aregister_team_on_platform(),), daemon=True) + t = threading.Thread(target=_run_async_in_thread, args=(self._aregister_team_on_platform,), daemon=True) t.start() - for member in self.members: - t = threading.Thread(target=_run_async_in_thread, args=(member._aregister_agent_on_platform(),), daemon=True) - t.start() + # Run the team last_exception = None @@ -1331,7 +1334,15 @@ def _run_async_in_thread(coro): _tools.append(self.get_set_shared_context_function(session_id=session_id)) self._add_tools_to_model(self.model, tools=_tools) # type: ignore - + for member in self.members: + if isinstance(member, Agent): + # Don't call the function directly, just pass the reference + t = threading.Thread(target=_run_async_in_thread, args=(member._aregister_agent_on_platform,), daemon=True) + t.start() + elif isinstance(member, Team): + # Don't call the function directly, just pass the reference + t = threading.Thread(target=_run_async_in_thread, args=(member._aregister_team_on_platform,), daemon=True) + t.start() # Run the team try: self.run_response = TeamRunResponse(run_id=self.run_id, session_id=session_id, team_id=self.team_id) @@ -6207,7 +6218,7 @@ def _get_team_session(self, session_id: str, user_id: Optional[str] = None) -> T created_at=int(time()), ) - def _log_team_run(self) -> None: + def _log_team_run(self, session_id: str, user_id: Optional[str] = None) -> None: if not self.telemetry and not self.monitoring: return @@ -6276,99 +6287,6 @@ def _log_team_session(self, session_id: str, user_id: Optional[str] = None): except Exception as e: log_debug(f"Could not create team monitor: {e}") - def deep_copy(self, *, update: Optional[Dict[str, Any]] = None) -> "Team": - """Create a deep copy of the Team with optional updates. - Args: - update: Optional dictionary of attributes to update in the copy - Returns: - A new Team instance with copied attributes - """ - # Get all instance attributes - attributes = self.__dict__.copy() - - excluded_fields = ["team_session", "session_name", "_functions_for_model"] - # Deep copy each field - copied_attributes = {} - for field_name, field_value in attributes.items(): - if field_name in excluded_fields: - continue - copied_attributes[field_name] = self._deep_copy_field(field_name, field_value) - - # Create new instance - team_copy = Team.__new__(Team) - team_copy.__dict__ = copied_attributes - - # Apply any updates - if update: - for key, value in update.items(): - setattr(team_copy, key, value) - - return team_copy - - def _deep_copy_field(self, field_name: str, field_value: Any) -> Any: - """Deep copy a single field value. - Args: - field_name: Name of the field being copied - field_value: Value to copy - Returns: - Deep copied value - """ - from copy import copy, deepcopy - - # Handle special cases - if field_name == "members": - # Deep copy each member - if field_value is not None: - return [member.deep_copy() for member in field_value] - return None - - # For memory use the deep_copy methods - if field_name == "memory" and field_value is not None: - return field_value.deep_copy() - - # For storage, model and reasoning_model, use a deep copy - elif field_name in ("storage", "model", "reasoning_model") and field_value is not None: - try: - return deepcopy(field_value) - except Exception: - try: - return copy(field_value) - except Exception as e: - log_warning(f"Failed to copy field: {field_name} - {e}") - return field_value - - # For compound types, attempt a deep copy - elif isinstance(field_value, (list, dict, set)): - try: - return deepcopy(field_value) - except Exception as e: - log_warning(f"Failed to deepcopy field: {field_name} - {e}") - try: - return copy(field_value) - except Exception as e: - log_warning(f"Failed to copy field: {field_name} - {e}") - return field_value - - # For pydantic models, attempt a model_copy - elif isinstance(field_value, BaseModel): - try: - return field_value.model_copy(deep=True) - except Exception: - try: - return field_value.model_copy(deep=False) - except Exception as e: - log_warning(f"Failed to copy field: {field_name} - {e}") - return field_value - - # For other types, attempt a shallow copy first - try: - from copy import copy - - return copy(field_value) - except Exception: - # If copy fails, return as is - return field_value - def _register_team_on_platform(self) -> None: from agno.api.team import TeamCreate, create_team @@ -6402,13 +6320,20 @@ async def _aregister_team_on_platform(self) -> None: def to_platform_dict(self) -> Dict[str, Any]: return { - "members": [member.to_platform_dict() for member in self.members ], + "members": [ + { + **member.get_agent_config_dict(), + "agent_id": member.agent_id if hasattr(member, "agent_id") else None, + "team_id": member.team_id if hasattr(member, "team_id") else None + } + for member in self.members if member is not None + ], "mode": self.mode, "model": self.model.to_dict() if self.model is not None else None, "name": self.name, "instructions": self.instructions, "description": self.description, "storage": self.storage.__class__.__name__ if self.storage is not None else None, - # "tools": [tool.to_dict() for tool in self.tools] if self.tools is not None else None, + # "tools": [tool.to_dict() for tool in self.tools] if self.tools is not None else None, # "memory": self.memory.to_dict() if self.memory is not None else None, } From a8f58e211c22f99ab67deb47ffec558270ce45d8 Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Wed, 23 Apr 2025 15:43:08 +0530 Subject: [PATCH 06/55] update --- libs/agno/agno/agent/agent.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/agno/agno/agent/agent.py b/libs/agno/agno/agent/agent.py index 859f223720..34d659e3d7 100644 --- a/libs/agno/agno/agent/agent.py +++ b/libs/agno/agno/agent/agent.py @@ -4163,7 +4163,7 @@ def register_agent_on_platform(self) -> None: try: log_debug(f"Creating Agent app: {self.name}, {self.agent_id}, {self.team_id},") - create_agent(app=AgentCreate(name=self.name, agent_id=self.agent_id, team_id=self.team_id, config=self.get_agent_config_dict())) + create_agent(agent=AgentCreate(name=self.name, agent_id=self.agent_id, team_id=self.team_id, config=self.get_agent_config_dict())) except Exception as e: log_debug(f"Could not create Agent app: {e}") From 23b1b6c61bfd91b4c71597e43f0c0dd488f26c00 Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Wed, 23 Apr 2025 17:57:36 +0530 Subject: [PATCH 07/55] update --- libs/agno/agno/team/team.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/agno/agno/team/team.py b/libs/agno/agno/team/team.py index 5079598a89..274bc5f00d 100644 --- a/libs/agno/agno/team/team.py +++ b/libs/agno/agno/team/team.py @@ -6322,7 +6322,7 @@ def to_platform_dict(self) -> Dict[str, Any]: return { "members": [ { - **member.get_agent_config_dict(), + **(member.get_agent_config_dict() if isinstance(member, Agent) else member.to_platform_dict() if isinstance(member, Team) else {}), "agent_id": member.agent_id if hasattr(member, "agent_id") else None, "team_id": member.team_id if hasattr(member, "team_id") else None } From 1bba1a1e537bdd47ab10689825f4f189c923bc9e Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Wed, 23 Apr 2025 19:51:33 +0530 Subject: [PATCH 08/55] update --- libs/agno/agno/team/team.py | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/libs/agno/agno/team/team.py b/libs/agno/agno/team/team.py index 274bc5f00d..0d0e81e450 100644 --- a/libs/agno/agno/team/team.py +++ b/libs/agno/agno/team/team.py @@ -646,6 +646,12 @@ def run( member.register_agent_on_platform() elif isinstance(member, Team): member._register_team_on_platform() + # Register team members recursively + for team_member in member.members: + if isinstance(team_member, Agent): + team_member.register_agent_on_platform() + elif isinstance(team_member, Team): + team_member._register_team_on_platform() # Run the team try: self.run_response = TeamRunResponse(run_id=self.run_id, session_id=session_id, team_id=self.team_id) @@ -1335,14 +1341,21 @@ def _run_async_in_thread(coro_func): self._add_tools_to_model(self.model, tools=_tools) # type: ignore for member in self.members: - if isinstance(member, Agent): - # Don't call the function directly, just pass the reference - t = threading.Thread(target=_run_async_in_thread, args=(member._aregister_agent_on_platform,), daemon=True) - t.start() - elif isinstance(member, Team): - # Don't call the function directly, just pass the reference - t = threading.Thread(target=_run_async_in_thread, args=(member._aregister_team_on_platform,), daemon=True) - t.start() + if isinstance(member, Agent): + + t = threading.Thread(target=_run_async_in_thread, args=(member._aregister_agent_on_platform,), daemon=True) + t.start() + elif isinstance(member, Team): + + t = threading.Thread(target=_run_async_in_thread, args=(member._aregister_team_on_platform,), daemon=True) + t.start() + for team_member in member.members: + if isinstance(team_member, Agent): + t2 = threading.Thread(target=_run_async_in_thread, args=(team_member._aregister_agent_on_platform,), daemon=True) + t2.start() + elif isinstance(team_member, Team): + t2 = threading.Thread(target=_run_async_in_thread, args=(team_member._aregister_team_on_platform,), daemon=True) + t2.start() # Run the team try: self.run_response = TeamRunResponse(run_id=self.run_id, session_id=session_id, team_id=self.team_id) From 198a167902c4e28385c6262470de71eccb769aeb Mon Sep 17 00:00:00 2001 From: Dirk Brand Date: Wed, 23 Apr 2025 16:57:20 +0200 Subject: [PATCH 09/55] Update --- libs/agno/agno/agent/agent.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/libs/agno/agno/agent/agent.py b/libs/agno/agno/agent/agent.py index 34d659e3d7..58c28bfe61 100644 --- a/libs/agno/agno/agent/agent.py +++ b/libs/agno/agno/agent/agent.py @@ -574,8 +574,9 @@ def _run( self.run_id = str(uuid4()) self.run_response = RunResponse(run_id=self.run_id, session_id=session_id, agent_id=self.agent_id) - - self.register_agent_on_platform() + # 1.4 Register the agent on the platform + thread = threading.Thread(target=self.register_agent_on_platform) + thread.start() log_debug(f"Agent Run Start: {self.run_response.run_id}", center=True) @@ -1163,12 +1164,10 @@ async def _arun( self.run_response = RunResponse(run_id=self.run_id, session_id=session_id, agent_id=self.agent_id) # 1.4 Register the agent on the platform - - def _run_async_in_thread(coro): - asyncio.run(coro) - - t = threading.Thread(target=_run_async_in_thread, args=(self._aregister_agent_on_platform(),), daemon=True) - t.start() + + # Create a task to run the agent registration in the background + # This won't block the execution flow + asyncio.create_task(self._aregister_agent_on_platform()) log_debug(f"Async Agent Run Start: {self.run_response.run_id}", center=True, symbol="*") @@ -4162,10 +4161,12 @@ def register_agent_on_platform(self) -> None: from agno.api.agent import AgentCreate, create_agent try: - log_debug(f"Creating Agent app: {self.name}, {self.agent_id}, {self.team_id},") + log_debug(f"Creating Agent on Platform: {self.name}, {self.agent_id}, {self.team_id},") + print("HERE", self.agent_id, self.get_agent_config_dict()) create_agent(agent=AgentCreate(name=self.name, agent_id=self.agent_id, team_id=self.team_id, config=self.get_agent_config_dict())) except Exception as e: log_debug(f"Could not create Agent app: {e}") + log_debug(f"Agent app created: {self.name}, {self.agent_id}, {self.team_id},") async def _aregister_agent_on_platform(self) -> None: self.set_monitoring() @@ -4175,11 +4176,13 @@ async def _aregister_agent_on_platform(self) -> None: from agno.api.agent import AgentCreate, acreate_agent try: + log_debug(f"Creating Agent on Platform: {self.name}, {self.agent_id}, {self.team_id},") await acreate_agent( agent=AgentCreate(name=self.name, agent_id=self.agent_id, team_id=self.team_id, config=self.get_agent_config_dict()) ) except Exception as e: log_debug(f"Could not create Agent app: {e}") + log_debug(f"Agent app created: {self.name}, {self.agent_id}, {self.team_id},") def _log_agent_run(self, session_id: str, user_id: Optional[str] = None) -> None: self.set_monitoring() @@ -5064,7 +5067,6 @@ def get_agent_config_dict(self) -> Dict[str, Any]: for tool in self.tools: functions = [] for function in tool.functions.keys(): - print(function) functions.append({"name": function, "parameters": tool.functions[function].to_dict()}) tools.append({"name": tool.name, "functions": functions}) From 71a59a5cd01721a847c7bf0774e23dbe01a6f598 Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Thu, 24 Apr 2025 01:31:56 +0530 Subject: [PATCH 10/55] update --- libs/agno/agno/team/team.py | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/libs/agno/agno/team/team.py b/libs/agno/agno/team/team.py index 0d0e81e450..88df9efb5b 100644 --- a/libs/agno/agno/team/team.py +++ b/libs/agno/agno/team/team.py @@ -549,7 +549,8 @@ def run( self._configure_model(show_tool_calls=show_tool_calls) # Register the team on the platform - self._register_team_on_platform() + thread = threading.Thread(target=self._register_team_on_platform) + thread.start() @@ -643,15 +644,19 @@ def run( self._add_tools_to_model(self.model, tools=_tools) # type: ignore for member in self.members: if isinstance(member, Agent): - member.register_agent_on_platform() + thread = threading.Thread(target=member.register_agent_on_platform) + thread.start() elif isinstance(member, Team): - member._register_team_on_platform() + thread = threading.Thread(target=member._register_team_on_platform) + thread.start() # Register team members recursively for team_member in member.members: if isinstance(team_member, Agent): - team_member.register_agent_on_platform() + thread = threading.Thread(target=team_member.register_agent_on_platform) + thread.start() elif isinstance(team_member, Team): - team_member._register_team_on_platform() + thread = threading.Thread(target=team_member._register_team_on_platform) + thread.start() # Run the team try: self.run_response = TeamRunResponse(run_id=self.run_id, session_id=session_id, team_id=self.team_id) @@ -1246,13 +1251,9 @@ async def arun( # Configure the model for runs self._configure_model(show_tool_calls=show_tool_calls) - def _run_async_in_thread(coro_func): - # Call the function to get the coroutine object - coro = coro_func() - asyncio.run(coro) + - t = threading.Thread(target=_run_async_in_thread, args=(self._aregister_team_on_platform,), daemon=True) - t.start() + asyncio.create_task(self._aregister_team_on_platform()) # Run the team @@ -1342,20 +1343,15 @@ def _run_async_in_thread(coro_func): self._add_tools_to_model(self.model, tools=_tools) # type: ignore for member in self.members: if isinstance(member, Agent): - - t = threading.Thread(target=_run_async_in_thread, args=(member._aregister_agent_on_platform,), daemon=True) - t.start() + asyncio.create_task(member._aregister_agent_on_platform()) elif isinstance(member, Team): - t = threading.Thread(target=_run_async_in_thread, args=(member._aregister_team_on_platform,), daemon=True) - t.start() + asyncio.create_task(member._aregister_team_on_platform()) for team_member in member.members: if isinstance(team_member, Agent): - t2 = threading.Thread(target=_run_async_in_thread, args=(team_member._aregister_agent_on_platform,), daemon=True) - t2.start() + asyncio.create_task(team_member._aregister_agent_on_platform()) elif isinstance(team_member, Team): - t2 = threading.Thread(target=_run_async_in_thread, args=(team_member._aregister_team_on_platform,), daemon=True) - t2.start() + asyncio.create_task(team_member._aregister_team_on_platform()) # Run the team try: self.run_response = TeamRunResponse(run_id=self.run_id, session_id=session_id, team_id=self.team_id) From 0d9a456bb144ca9203bc7eb21362d054a1e57a93 Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Thu, 24 Apr 2025 21:19:56 +0530 Subject: [PATCH 11/55] update --- libs/agno/agno/team/team.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libs/agno/agno/team/team.py b/libs/agno/agno/team/team.py index 88df9efb5b..7ea554ab52 100644 --- a/libs/agno/agno/team/team.py +++ b/libs/agno/agno/team/team.py @@ -419,7 +419,8 @@ def _initialize_member(self, member: Union["Team", Agent], session_id: str): member.markdown = True member.team_session_id = session_id - member.team_id = self.team_id + if isinstance(member, Agent): + member.team_id = self.team_id if member.name is None: log_warning("Team member name is undefined.") From 22d184ec72c5800e9823d9804517a450725e3d42 Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Thu, 24 Apr 2025 23:20:02 +0530 Subject: [PATCH 12/55] add parent_team_id --- libs/agno/agno/agent/agent.py | 4 ++-- libs/agno/agno/api/schemas/team.py | 1 + libs/agno/agno/team/team.py | 16 +++++++++------- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/libs/agno/agno/agent/agent.py b/libs/agno/agno/agent/agent.py index 58c28bfe61..2f8da5ea93 100644 --- a/libs/agno/agno/agent/agent.py +++ b/libs/agno/agno/agent/agent.py @@ -1167,7 +1167,7 @@ async def _arun( # Create a task to run the agent registration in the background # This won't block the execution flow - asyncio.create_task(self._aregister_agent_on_platform()) + asyncio.create_task(self.aregister_agent_on_platform()) log_debug(f"Async Agent Run Start: {self.run_response.run_id}", center=True, symbol="*") @@ -4168,7 +4168,7 @@ def register_agent_on_platform(self) -> None: log_debug(f"Could not create Agent app: {e}") log_debug(f"Agent app created: {self.name}, {self.agent_id}, {self.team_id},") - async def _aregister_agent_on_platform(self) -> None: + async def aregister_agent_on_platform(self) -> None: self.set_monitoring() if not self.monitoring: return diff --git a/libs/agno/agno/api/schemas/team.py b/libs/agno/agno/api/schemas/team.py index 9f062e08d6..9b19b43e1b 100644 --- a/libs/agno/agno/api/schemas/team.py +++ b/libs/agno/agno/api/schemas/team.py @@ -24,6 +24,7 @@ class TeamCreate(BaseModel): """Data sent to API to create aTeam""" team_id: str + parent_team_id: Optional[str] = None app_id: Optional[str] = None name: Optional[str] = None config: Dict[str, Any] diff --git a/libs/agno/agno/team/team.py b/libs/agno/agno/team/team.py index 7ea554ab52..8e7d3ec01e 100644 --- a/libs/agno/agno/team/team.py +++ b/libs/agno/agno/team/team.py @@ -648,7 +648,7 @@ def run( thread = threading.Thread(target=member.register_agent_on_platform) thread.start() elif isinstance(member, Team): - thread = threading.Thread(target=member._register_team_on_platform) + thread = threading.Thread(target=member._register_team_on_platform(team_id=self.team_id)) thread.start() # Register team members recursively for team_member in member.members: @@ -656,7 +656,7 @@ def run( thread = threading.Thread(target=team_member.register_agent_on_platform) thread.start() elif isinstance(team_member, Team): - thread = threading.Thread(target=team_member._register_team_on_platform) + thread = threading.Thread(target=team_member._register_team_on_platform(team_id=self.team_id)) thread.start() # Run the team try: @@ -1344,15 +1344,15 @@ async def arun( self._add_tools_to_model(self.model, tools=_tools) # type: ignore for member in self.members: if isinstance(member, Agent): - asyncio.create_task(member._aregister_agent_on_platform()) + asyncio.create_task(member.aregister_agent_on_platform) elif isinstance(member, Team): - asyncio.create_task(member._aregister_team_on_platform()) + asyncio.create_task(member._aregister_team_on_platform(team_id=self.team_id)) for team_member in member.members: if isinstance(team_member, Agent): asyncio.create_task(team_member._aregister_agent_on_platform()) elif isinstance(team_member, Team): - asyncio.create_task(team_member._aregister_team_on_platform()) + asyncio.create_task(team_member._aregister_team_on_platform(team_id=self.team_id)) # Run the team try: self.run_response = TeamRunResponse(run_id=self.run_id, session_id=session_id, team_id=self.team_id) @@ -6297,7 +6297,7 @@ def _log_team_session(self, session_id: str, user_id: Optional[str] = None): except Exception as e: log_debug(f"Could not create team monitor: {e}") - def _register_team_on_platform(self) -> None: + def _register_team_on_platform(self,team_id: Optional[str] = None) -> None: from agno.api.team import TeamCreate, create_team try: @@ -6306,6 +6306,7 @@ def _register_team_on_platform(self) -> None: team_id=self.team_id, name=self.name, config=self.to_platform_dict(), + parent_team_id=team_id ), ) @@ -6313,7 +6314,7 @@ def _register_team_on_platform(self) -> None: log_debug(f"Could not create team on platform: {e}") print(f"Could not create team on platform: {e}") - async def _aregister_team_on_platform(self) -> None: + async def _aregister_team_on_platform(self,team_id: Optional[str] = None) -> None: from agno.api.team import TeamCreate, acreate_team try: @@ -6322,6 +6323,7 @@ async def _aregister_team_on_platform(self) -> None: team_id=self.team_id, name=self.name, config=self.to_platform_dict(), + parent_team_id=team_id ), ) except Exception as e: From 58fedb08d71054d1b0021fe89251dc50a37ee277 Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Fri, 25 Apr 2025 13:28:56 +0530 Subject: [PATCH 13/55] update --- libs/agno/agno/team/team.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/agno/agno/team/team.py b/libs/agno/agno/team/team.py index 8e7d3ec01e..6820a75e2d 100644 --- a/libs/agno/agno/team/team.py +++ b/libs/agno/agno/team/team.py @@ -1344,13 +1344,13 @@ async def arun( self._add_tools_to_model(self.model, tools=_tools) # type: ignore for member in self.members: if isinstance(member, Agent): - asyncio.create_task(member.aregister_agent_on_platform) + asyncio.create_task(member.aregister_agent_on_platform()) elif isinstance(member, Team): asyncio.create_task(member._aregister_team_on_platform(team_id=self.team_id)) for team_member in member.members: if isinstance(team_member, Agent): - asyncio.create_task(team_member._aregister_agent_on_platform()) + asyncio.create_task(team_member.aregister_agent_on_platform()) elif isinstance(team_member, Team): asyncio.create_task(team_member._aregister_team_on_platform(team_id=self.team_id)) # Run the team From 11d9cbc5d0e8e9d18fe12854a0fb3625fb520662 Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Mon, 28 Apr 2025 18:21:42 +0530 Subject: [PATCH 14/55] update --- libs/agno/agno/team/team.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libs/agno/agno/team/team.py b/libs/agno/agno/team/team.py index 6820a75e2d..09f23a9e7f 100644 --- a/libs/agno/agno/team/team.py +++ b/libs/agno/agno/team/team.py @@ -6298,6 +6298,10 @@ def _log_team_session(self, session_id: str, user_id: Optional[str] = None): log_debug(f"Could not create team monitor: {e}") def _register_team_on_platform(self,team_id: Optional[str] = None) -> None: + self._set_monitoring() + if not self.monitoring: + return + from agno.api.team import TeamCreate, create_team try: @@ -6315,6 +6319,10 @@ def _register_team_on_platform(self,team_id: Optional[str] = None) -> None: print(f"Could not create team on platform: {e}") async def _aregister_team_on_platform(self,team_id: Optional[str] = None) -> None: + self._set_monitoring() + if not self.monitoring: + return + from agno.api.team import TeamCreate, acreate_team try: From 46a4176a9dfa72ee8dad2ace88f6a49c9456e55c Mon Sep 17 00:00:00 2001 From: Ayush <97244608+Ayush0054@users.noreply.github.com> Date: Wed, 30 Apr 2025 16:56:35 +0530 Subject: [PATCH 15/55] app registration (#2992) ## Summary Describe key changes, mention related issues or motivation for the changes. (If applicable, issue number: #____) ## Type of change - [ ] Bug fix - [ ] New feature - [ ] Breaking change - [ ] Improvement - [ ] Model update - [ ] Other: --- ## Checklist - [ ] Code complies with style guidelines - [ ] Ran format/validation scripts (`./scripts/format.sh` and `./scripts/validate.sh`) - [ ] Self-review completed - [ ] Documentation updated (comments, docstrings) - [ ] Examples and guides: Relevant cookbook examples have been included or updated (if applicable) - [ ] Tested in clean environment - [ ] Tests added/updated (if applicable) --- ## Additional Notes Add any important context (deployment instructions, screenshots, security considerations, etc.) --- cookbook/agents_from_scratch/simple_agent.py | 23 ++- cookbook/playground/teams_demo.py | 20 ++- libs/agno/agno/agent/agent.py | 7 +- libs/agno/agno/api/app.py | 38 +++++ libs/agno/agno/api/routes.py | 2 + libs/agno/agno/api/schemas/app.py | 12 ++ libs/agno/agno/playground/playground.py | 166 +++++++++++++++++-- libs/agno/agno/team/team.py | 13 +- 8 files changed, 254 insertions(+), 27 deletions(-) create mode 100644 libs/agno/agno/api/app.py create mode 100644 libs/agno/agno/api/schemas/app.py diff --git a/cookbook/agents_from_scratch/simple_agent.py b/cookbook/agents_from_scratch/simple_agent.py index 0c575d8a19..f6dfb0dbd4 100644 --- a/cookbook/agents_from_scratch/simple_agent.py +++ b/cookbook/agents_from_scratch/simple_agent.py @@ -7,9 +7,10 @@ from agno.agent import Agent from agno.models.openai import OpenAIChat - +from agno.playground import Playground simple_agent = Agent( name="Simple Agent", + agent_id="simple-agent", model=OpenAIChat(id="gpt-4o"), instructions=dedent("""\ You are an enthusiastic news reporter with a flair for storytelling! 🗽 @@ -27,5 +28,23 @@ markdown=True, ) + +playground = Playground( + agents=[simple_agent], + name="Simple Agent", + app_id="simple-agent", + monitoring=True, + ) + +# Get the FastAPI app +app = playground.get_app(use_async=False) + if __name__ == "__main__": - simple_agent.print_response("Share a news story from NYC and SF.", stream=True) + # Start the playground server + playground.register_playground_app( + app="simple_agent:app", + host="localhost", + port=7777, + reload=True, + ) + diff --git a/cookbook/playground/teams_demo.py b/cookbook/playground/teams_demo.py index f8babaae2e..5fb82bb6ae 100644 --- a/cookbook/playground/teams_demo.py +++ b/cookbook/playground/teams_demo.py @@ -219,10 +219,24 @@ context="use USD as currency", ) -app = Playground( +# Create a single Playground instance to avoid duplication +playground = Playground( teams=[research_team, financial_news_team, multimodal_team], agents=[web_agent, finance_agent, research_agent, simple_agent], -).get_app() + name="Playground Demo app", + description="This is a demo app for the Playground.", + app_id="playground-demo-app", + monitoring=True, +) + +# Get the FastAPI app +app = playground.get_app(use_async=False) if __name__ == "__main__": - serve_playground_app("teams_demo:app", reload=True) + # Start the playground server + playground.register_playground_app( + app="teams_demo:app", + host="localhost", + port=7777, + reload=True, + ) diff --git a/libs/agno/agno/agent/agent.py b/libs/agno/agno/agent/agent.py index 2f8da5ea93..01deba0581 100644 --- a/libs/agno/agno/agent/agent.py +++ b/libs/agno/agno/agent/agent.py @@ -258,7 +258,8 @@ class Agent: team_session_id: Optional[str] = None # Optional team ID. Indicates this agent is part of a team. team_id: Optional[str] = None - + # Optional app ID. Indicates this agent is part of an app. + app_id: Optional[str] = None # --- Debug & Monitoring --- # Enable debug logs debug_mode: bool = False @@ -4163,7 +4164,7 @@ def register_agent_on_platform(self) -> None: try: log_debug(f"Creating Agent on Platform: {self.name}, {self.agent_id}, {self.team_id},") print("HERE", self.agent_id, self.get_agent_config_dict()) - create_agent(agent=AgentCreate(name=self.name, agent_id=self.agent_id, team_id=self.team_id, config=self.get_agent_config_dict())) + create_agent(agent=AgentCreate(name=self.name, agent_id=self.agent_id, team_id=self.team_id, app_id=self.app_id, config=self.get_agent_config_dict())) except Exception as e: log_debug(f"Could not create Agent app: {e}") log_debug(f"Agent app created: {self.name}, {self.agent_id}, {self.team_id},") @@ -4178,7 +4179,7 @@ async def aregister_agent_on_platform(self) -> None: try: log_debug(f"Creating Agent on Platform: {self.name}, {self.agent_id}, {self.team_id},") await acreate_agent( - agent=AgentCreate(name=self.name, agent_id=self.agent_id, team_id=self.team_id, config=self.get_agent_config_dict()) + agent=AgentCreate(name=self.name, agent_id=self.agent_id, team_id=self.team_id, app_id=self.app_id, config=self.get_agent_config_dict()) ) except Exception as e: log_debug(f"Could not create Agent app: {e}") diff --git a/libs/agno/agno/api/app.py b/libs/agno/agno/api/app.py new file mode 100644 index 0000000000..1d5785e7ae --- /dev/null +++ b/libs/agno/agno/api/app.py @@ -0,0 +1,38 @@ +from agno.api.api import api +from agno.api.routes import ApiRoutes +from agno.api.schemas.app import AppCreate +from agno.cli.settings import agno_cli_settings +from agno.utils.log import log_debug + + +def create_app(app: AppCreate) -> None: + if not agno_cli_settings.api_enabled: + return + + with api.AuthenticatedClient() as api_client: + try: + print("HERE") + api_client.post( + ApiRoutes.APP_CREATE, + json={"app": app.model_dump()}, + ) + print("HERE2") + except Exception as e: + log_debug(f"Could not create App: {e}") + + +async def acreate_app(app: AppCreate) -> None: + if not agno_cli_settings.api_enabled: + return + + async with api.AuthenticatedAsyncClient() as api_client: + try: + print("HERE") + payload = {"app": app.model_dump(exclude_none=True)} + await api_client.post( + ApiRoutes.APP_CREATE, + json=payload, + ) + print("HERE2") + except Exception as e: + log_debug(f"Could not create App: {e}") diff --git a/libs/agno/agno/api/routes.py b/libs/agno/agno/api/routes.py index 9f339cdf08..edaf792dde 100644 --- a/libs/agno/agno/api/routes.py +++ b/libs/agno/agno/api/routes.py @@ -24,6 +24,8 @@ class ApiRoutes: AGENT_RUN_CREATE: str = "/v1/agent-runs" AGENT_CREATE: str = "/v2/agents" + # App paths + APP_CREATE: str = "/v2/apps" # Team paths TEAM_RUN_CREATE: str = "/v1/team-runs" TEAM_SESSION_CREATE: str = "/v1/team-sessions" diff --git a/libs/agno/agno/api/schemas/app.py b/libs/agno/agno/api/schemas/app.py new file mode 100644 index 0000000000..51a18acefb --- /dev/null +++ b/libs/agno/agno/api/schemas/app.py @@ -0,0 +1,12 @@ +from typing import Any, Dict, Optional + +from pydantic import BaseModel + + +class AppCreate(BaseModel): + """Data sent to API to create an App""" + + app_id: Optional[str] = None + name: Optional[str] = None + description: Optional[str] = None + config: Dict[str, Any] diff --git a/libs/agno/agno/playground/playground.py b/libs/agno/agno/playground/playground.py index 71962314de..fc32c3af38 100644 --- a/libs/agno/agno/playground/playground.py +++ b/libs/agno/agno/playground/playground.py @@ -1,19 +1,27 @@ -from typing import List, Optional, Set +import asyncio +import threading +from os import getenv +from typing import Any, Dict, List, Optional, Set, Union +from urllib.parse import quote from uuid import uuid4 from fastapi import FastAPI, HTTPException from fastapi.responses import JSONResponse from fastapi.routing import APIRouter +from rich import box +from rich.panel import Panel from starlette.middleware.cors import CORSMiddleware from starlette.requests import Request from agno.agent.agent import Agent from agno.api.playground import PlaygroundEndpointCreate, create_playground_endpoint +from agno.cli.console import console +from agno.cli.settings import agno_cli_settings from agno.playground.async_router import get_async_playground_router from agno.playground.settings import PlaygroundSettings from agno.playground.sync_router import get_sync_playground_router from agno.team.team import Team -from agno.utils.log import logger +from agno.utils.log import log_debug, logger from agno.workflow.workflow import Workflow @@ -26,6 +34,10 @@ def __init__( settings: Optional[PlaygroundSettings] = None, api_app: Optional[FastAPI] = None, router: Optional[APIRouter] = None, + app_id: Optional[str] = None, + name: Optional[str] = None, + description: Optional[str] = None, + monitoring: bool = False, ): if not agents and not workflows and not teams: raise ValueError("Either agents, teams or workflows must be provided.") @@ -33,26 +45,57 @@ def __init__( self.agents: Optional[List[Agent]] = agents self.workflows: Optional[List[Workflow]] = workflows self.teams: Optional[List[Team]] = teams - + self.settings: PlaygroundSettings = settings or PlaygroundSettings() + self.api_app: Optional[FastAPI] = api_app + self.router: Optional[APIRouter] = router + self.endpoints_created: Dict[str, Dict[str, str]] = {} + self.app_id: Optional[str] = app_id + self.name: Optional[str] = name + self.monitoring = monitoring + self.description = description if self.agents: for agent in self.agents: if not agent.agent_id: - agent.agent_id = generate_id(agent.name) + agent.agent_id = generate_id(agent.name) + if not agent.app_id: + agent.app_id = self.app_id if self.teams: for team in self.teams: if not team.team_id: team.team_id = generate_id(team.name) + if not team.app_id: + team.app_id = self.app_id if self.workflows: for workflow in self.workflows: if not workflow.workflow_id: workflow.workflow_id = generate_id(workflow.name) - self.settings: PlaygroundSettings = settings or PlaygroundSettings() - self.api_app: Optional[FastAPI] = api_app - self.router: Optional[APIRouter] = router - self.endpoints_created: Set[str] = set() + def set_app_id(self) -> str: + # If app_id is already set, keep it instead of overriding with UUID + if self.app_id is None: + app_id_parts = [] + if self.agents and self.agents is not None: + app_id_parts.append(f"agent-{self.agents[0].agent_id}") + if self.teams and self.teams is not None: + app_id_parts.append(f"team-{self.teams[0].team_id}") + if self.workflows and self.workflows is not None: + app_id_parts.append(f"workflow-{self.workflows[0].workflow_id}") + + if app_id_parts: + self.app_id = "-".join(app_id_parts) + + # Don't override existing app_id + return self.app_id + + def _set_monitoring(self) -> None: + """Override monitoring and telemetry settings based on environment variables.""" + + # Only override if the environment variable is set + monitor_env = getenv("AGNO_MONITOR") + if monitor_env is not None: + self.monitoring = monitor_env.lower() == "true" def get_router(self) -> APIRouter: return get_sync_playground_router(self.agents, self.workflows, self.teams) @@ -111,23 +154,118 @@ async def general_exception_handler(request: Request, call_next): expose_headers=["*"], ) + + # asyncio.create_task(self.aregister_app_on_platform()) return self.api_app - def create_endpoint(self, endpoint: str, prefix: str = "/v1") -> None: - if endpoint in self.endpoints_created: - return + def register_playground_app( + self, + app: Union[str, FastAPI], + *, + scheme: str = "http", + host: str = "localhost", + port: int = 7777, + reload: bool = False, + prefix="/v1", + **kwargs, + ): + import uvicorn try: - logger.info(f"Creating playground endpoint: {endpoint}") create_playground_endpoint( - playground=PlaygroundEndpointCreate(endpoint=endpoint, playground_data={"prefix": prefix}) + playground=PlaygroundEndpointCreate( + endpoint=f"{scheme}://{host}:{port}", playground_data={"prefix": prefix} + ), ) except Exception as e: logger.error(f"Could not create playground endpoint: {e}") logger.error("Please try again.") return - self.endpoints_created.add(endpoint) + logger.info(f"Starting playground on {scheme}://{host}:{port}") + # Encode the full endpoint (host:port) + encoded_endpoint = quote(f"{host}:{port}") + self.endpoints_created = f"{scheme}://{host}:{port}" + + + # Create a panel with the playground URL + url = f"{agno_cli_settings.playground_url}?endpoint={encoded_endpoint}" + panel = Panel( + f"[bold green]Playground URL:[/bold green] [link={url}]{url}[/link]", + title="Agent Playground", + expand=False, + border_style="cyan", + box=box.HEAVY, + padding=(2, 2), + ) + + # Print the panel + console.print(panel) + print(app, "this is app") + self.set_app_id() + thread = threading.Thread(target=self.register_app_on_platform) + thread.start() + if self.agents: + for agent in self.agents: + t1 = threading.Thread(target=agent.register_agent_on_platform) + t1.start() + if self.teams: + for team in self.teams: + t2 = threading.Thread(target=team._register_team_on_platform) + t2.start() + uvicorn.run(app=app, host=host, port=port, reload=reload, **kwargs) + + def register_app_on_platform(self) -> None: + self._set_monitoring() + if not self.monitoring: + return + + from agno.api.app import AppCreate, create_app + + try: + print(f"Creating Agent on Platform: {self.name}, {self.app_id}") + # print("HERE", self.playground_to_dict()) + create_app(app=AppCreate(name=self.name, app_id=self.app_id, config=self.playground_to_dict())) + except Exception as e: + log_debug(f"Could not create Agent app: {e}") + log_debug(f"Agent app created: {self.name}, {self.app_id}") + + async def aregister_app_on_platform(self) -> None: + self._set_monitoring() + if not self.monitoring: + return + + from agno.api.app import AppCreate, acreate_app + + try: + log_debug(f"Creating App on Platform: {self.name}, {self.agent_id}, {self.team_id},") + await acreate_app(app=AppCreate(name=self.name, app_id=self.app_id, config=self.playground_to_dict())) + + except Exception as e: + log_debug(f"Could not create App: {e}") + log_debug(f"App created: {self.name}, {self.agent_id}, {self.team_id},") + + def playground_to_dict(self) -> Dict[str, Any]: + payload = { + "agents": [ + { + **agent.get_agent_config_dict(), + "agent_id": agent.agent_id, + "team_id": agent.team_id + } for agent in self.agents + ] if self.agents else [], + "teams": [ + { + **team.to_platform_dict(), + "team_id": team.team_id + } for team in self.teams + ] if self.teams else [], + "endpoint": self.endpoints_created, + "type": "playground", + "description": self.description + } + print(payload, "this is payload") + return payload def generate_id(name: Optional[str] = None) -> str: diff --git a/libs/agno/agno/team/team.py b/libs/agno/agno/team/team.py index 09f23a9e7f..b90498ef53 100644 --- a/libs/agno/agno/team/team.py +++ b/libs/agno/agno/team/team.py @@ -208,7 +208,8 @@ class Team: reasoning_model: Optional[Model] = None reasoning_min_steps: int = 1 reasoning_max_steps: int = 10 - + # Optional app ID. Indicates this team is part of an app. + app_id: Optional[str] = None # --- Debug & Monitoring --- # Enable debug logs debug_mode: bool = False @@ -6310,7 +6311,8 @@ def _register_team_on_platform(self,team_id: Optional[str] = None) -> None: team_id=self.team_id, name=self.name, config=self.to_platform_dict(), - parent_team_id=team_id + parent_team_id=team_id, + app_id=self.app_id ), ) @@ -6331,7 +6333,8 @@ async def _aregister_team_on_platform(self,team_id: Optional[str] = None) -> Non team_id=self.team_id, name=self.name, config=self.to_platform_dict(), - parent_team_id=team_id + parent_team_id=team_id, + app_id=self.app_id ), ) except Exception as e: @@ -6343,8 +6346,8 @@ def to_platform_dict(self) -> Dict[str, Any]: "members": [ { **(member.get_agent_config_dict() if isinstance(member, Agent) else member.to_platform_dict() if isinstance(member, Team) else {}), - "agent_id": member.agent_id if hasattr(member, "agent_id") else None, - "team_id": member.team_id if hasattr(member, "team_id") else None + "agent_id": member.agent_id if isinstance(member, Agent) and member.agent_id is not None else str(uuid4()), + "team_id": member.team_id if isinstance(member, Agent) and member.team_id is not None else str(uuid4()) } for member in self.members if member is not None ], From 8196effe4596a2362c8a48b79e40e65201505516 Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Wed, 30 Apr 2025 20:50:38 +0530 Subject: [PATCH 16/55] fix --- libs/agno/agno/playground/playground.py | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/libs/agno/agno/playground/playground.py b/libs/agno/agno/playground/playground.py index b1c42c3d48..7852c4f8b9 100644 --- a/libs/agno/agno/playground/playground.py +++ b/libs/agno/agno/playground/playground.py @@ -55,31 +55,26 @@ def __init__( self.description = description if self.agents: for agent in self.agents: - - if not agent.agent_id: - agent.agent_id = generate_id(agent.name) if not agent.app_id: agent.app_id = self.app_id + agent.initialize_agent() if self.teams: for team in self.teams: - if not team.team_id: - team.team_id = generate_id(team.name) if not team.app_id: team.app_id = self.app_id - - agent.initialize_agent() - - if self.teams: - for team in self.teams: team.initialize_team() for member in team.members: if isinstance(member, Agent): + # Ensure agent is initialized independently without team_id + if not member.app_id: + member.app_id = self.app_id + # Clear any team_id before initialization + member.team_id = None member.initialize_agent() elif isinstance(member, Team): member.initialize_team() - if self.workflows: for workflow in self.workflows: if not workflow.workflow_id: From 95236a744fe9b0244109259155090885a47659d7 Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Wed, 30 Apr 2025 20:53:30 +0530 Subject: [PATCH 17/55] formatting --- cookbook/agents_from_scratch/simple_agent.py | 12 ++--- libs/agno/agno/agent/agent.py | 24 ++++++--- libs/agno/agno/playground/playground.py | 29 +++++------ libs/agno/agno/team/team.py | 51 +++++++++++--------- 4 files changed, 62 insertions(+), 54 deletions(-) diff --git a/cookbook/agents_from_scratch/simple_agent.py b/cookbook/agents_from_scratch/simple_agent.py index f6dfb0dbd4..c8ae810370 100644 --- a/cookbook/agents_from_scratch/simple_agent.py +++ b/cookbook/agents_from_scratch/simple_agent.py @@ -8,6 +8,7 @@ from agno.agent import Agent from agno.models.openai import OpenAIChat from agno.playground import Playground + simple_agent = Agent( name="Simple Agent", agent_id="simple-agent", @@ -30,11 +31,11 @@ playground = Playground( - agents=[simple_agent], - name="Simple Agent", - app_id="simple-agent", - monitoring=True, - ) + agents=[simple_agent], + name="Simple Agent", + app_id="simple-agent", + monitoring=True, +) # Get the FastAPI app app = playground.get_app(use_async=False) @@ -47,4 +48,3 @@ port=7777, reload=True, ) - diff --git a/libs/agno/agno/agent/agent.py b/libs/agno/agno/agent/agent.py index 73621aa3cb..113cd55613 100644 --- a/libs/agno/agno/agent/agent.py +++ b/libs/agno/agno/agent/agent.py @@ -1,10 +1,8 @@ from __future__ import annotations - import asyncio import threading from collections import ChainMap, defaultdict, deque - from dataclasses import asdict, dataclass from os import getenv from textwrap import dedent @@ -270,7 +268,6 @@ class Agent: # Optional team session state. Set by the team leader agent. team_session_state: Optional[Dict[str, Any]] = None - # --- Debug & Monitoring --- # Enable debug logs debug_mode: bool = False @@ -1260,7 +1257,7 @@ async def _arun( self.run_response = RunResponse(run_id=self.run_id, session_id=session_id, agent_id=self.agent_id) # 1.4 Register the agent on the platform - + # Create a task to run the agent registration in the background # This won't block the execution flow asyncio.create_task(self.aregister_agent_on_platform()) @@ -4420,7 +4417,6 @@ def _create_run_data(self) -> Dict[str, Any]: return run_data def register_agent_on_platform(self) -> None: - self.set_monitoring() if not self.monitoring: return @@ -4430,7 +4426,15 @@ def register_agent_on_platform(self) -> None: try: log_debug(f"Creating Agent on Platform: {self.name}, {self.agent_id}, {self.team_id},") print("HERE", self.agent_id, self.get_agent_config_dict()) - create_agent(agent=AgentCreate(name=self.name, agent_id=self.agent_id, team_id=self.team_id, app_id=self.app_id, config=self.get_agent_config_dict())) + create_agent( + agent=AgentCreate( + name=self.name, + agent_id=self.agent_id, + team_id=self.team_id, + app_id=self.app_id, + config=self.get_agent_config_dict(), + ) + ) except Exception as e: log_debug(f"Could not create Agent app: {e}") log_debug(f"Agent app created: {self.name}, {self.agent_id}, {self.team_id},") @@ -4445,7 +4449,13 @@ async def aregister_agent_on_platform(self) -> None: try: log_debug(f"Creating Agent on Platform: {self.name}, {self.agent_id}, {self.team_id},") await acreate_agent( - agent=AgentCreate(name=self.name, agent_id=self.agent_id, team_id=self.team_id, app_id=self.app_id, config=self.get_agent_config_dict()) + agent=AgentCreate( + name=self.name, + agent_id=self.agent_id, + team_id=self.team_id, + app_id=self.app_id, + config=self.get_agent_config_dict(), + ) ) except Exception as e: log_debug(f"Could not create Agent app: {e}") diff --git a/libs/agno/agno/playground/playground.py b/libs/agno/agno/playground/playground.py index 7852c4f8b9..341ea151e7 100644 --- a/libs/agno/agno/playground/playground.py +++ b/libs/agno/agno/playground/playground.py @@ -66,10 +66,9 @@ def __init__( team.initialize_team() for member in team.members: if isinstance(member, Agent): - # Ensure agent is initialized independently without team_id if not member.app_id: member.app_id = self.app_id - # Clear any team_id before initialization + member.team_id = None member.initialize_agent() elif isinstance(member, Team): @@ -162,7 +161,6 @@ async def general_exception_handler(request: Request, call_next): expose_headers=["*"], ) - # asyncio.create_task(self.aregister_app_on_platform()) return self.api_app @@ -195,7 +193,6 @@ def register_playground_app( encoded_endpoint = quote(f"{host}:{port}") self.endpoints_created = f"{scheme}://{host}:{port}" - # Create a panel with the playground URL url = f"{agno_cli_settings.playground_url}?endpoint={encoded_endpoint}" panel = Panel( @@ -210,7 +207,7 @@ def register_playground_app( # Print the panel console.print(panel) print(app, "this is app") - self.set_app_id() + self.set_app_id() thread = threading.Thread(target=self.register_app_on_platform) thread.start() if self.agents: @@ -256,21 +253,17 @@ async def aregister_app_on_platform(self) -> None: def playground_to_dict(self) -> Dict[str, Any]: payload = { "agents": [ - { - **agent.get_agent_config_dict(), - "agent_id": agent.agent_id, - "team_id": agent.team_id - } for agent in self.agents - ] if self.agents else [], - "teams": [ - { - **team.to_platform_dict(), - "team_id": team.team_id - } for team in self.teams - ] if self.teams else [], + {**agent.get_agent_config_dict(), "agent_id": agent.agent_id, "team_id": agent.team_id} + for agent in self.agents + ] + if self.agents + else [], + "teams": [{**team.to_platform_dict(), "team_id": team.team_id} for team in self.teams] + if self.teams + else [], "endpoint": self.endpoints_created, "type": "playground", - "description": self.description + "description": self.description, } print(payload, "this is payload") return payload diff --git a/libs/agno/agno/team/team.py b/libs/agno/agno/team/team.py index 69fbabc313..5f6e4b54dd 100644 --- a/libs/agno/agno/team/team.py +++ b/libs/agno/agno/team/team.py @@ -228,7 +228,6 @@ class Team: # This helps us improve the Teams implementation and provide better support telemetry: bool = True - def __init__( self, members: List[Union[Agent, "Team"]], @@ -422,7 +421,6 @@ def _initialize_member(self, member: Union["Team", Agent], session_id: Optional[ if self.markdown: member.markdown = True - if session_id is not None: member.team_session_id = session_id @@ -605,8 +603,6 @@ def run( thread = threading.Thread(target=self._register_team_on_platform) thread.start() - - # Run the team last_exception = None num_attempts = retries + 1 @@ -708,7 +704,9 @@ def run( thread = threading.Thread(target=team_member.register_agent_on_platform) thread.start() elif isinstance(team_member, Team): - thread = threading.Thread(target=team_member._register_team_on_platform(team_id=self.team_id)) + thread = threading.Thread( + target=team_member._register_team_on_platform(team_id=self.team_id) + ) thread.start() # Run the team try: @@ -1367,10 +1365,7 @@ async def arun( # Configure the model for runs self._configure_model(show_tool_calls=show_tool_calls) - - asyncio.create_task(self._aregister_team_on_platform()) - # Run the team last_exception = None @@ -1461,13 +1456,12 @@ async def arun( if isinstance(member, Agent): asyncio.create_task(member.aregister_agent_on_platform()) elif isinstance(member, Team): - asyncio.create_task(member._aregister_team_on_platform(team_id=self.team_id)) for team_member in member.members: if isinstance(team_member, Agent): asyncio.create_task(team_member.aregister_agent_on_platform()) elif isinstance(team_member, Team): - asyncio.create_task(team_member._aregister_team_on_platform(team_id=self.team_id)) + asyncio.create_task(team_member._aregister_team_on_platform(team_id=self.team_id)) # Run the team try: self.run_response = TeamRunResponse(run_id=self.run_id, session_id=session_id, team_id=self.team_id) @@ -6735,11 +6729,11 @@ def _log_team_session(self, session_id: str, user_id: Optional[str] = None): except Exception as e: log_debug(f"Could not create team monitor: {e}") - def _register_team_on_platform(self,team_id: Optional[str] = None) -> None: + def _register_team_on_platform(self, team_id: Optional[str] = None) -> None: self._set_monitoring() if not self.monitoring: return - + from agno.api.team import TeamCreate, create_team try: @@ -6749,19 +6743,19 @@ def _register_team_on_platform(self,team_id: Optional[str] = None) -> None: name=self.name, config=self.to_platform_dict(), parent_team_id=team_id, - app_id=self.app_id + app_id=self.app_id, ), ) - + except Exception as e: log_debug(f"Could not create team on platform: {e}") print(f"Could not create team on platform: {e}") - async def _aregister_team_on_platform(self,team_id: Optional[str] = None) -> None: + async def _aregister_team_on_platform(self, team_id: Optional[str] = None) -> None: self._set_monitoring() if not self.monitoring: return - + from agno.api.team import TeamCreate, acreate_team try: @@ -6771,7 +6765,7 @@ async def _aregister_team_on_platform(self,team_id: Optional[str] = None) -> Non name=self.name, config=self.to_platform_dict(), parent_team_id=team_id, - app_id=self.app_id + app_id=self.app_id, ), ) except Exception as e: @@ -6782,11 +6776,22 @@ def to_platform_dict(self) -> Dict[str, Any]: return { "members": [ { - **(member.get_agent_config_dict() if isinstance(member, Agent) else member.to_platform_dict() if isinstance(member, Team) else {}), - "agent_id": member.agent_id if isinstance(member, Agent) and member.agent_id is not None else str(uuid4()), - "team_id": member.team_id if isinstance(member, Agent) and member.team_id is not None else str(uuid4()) - } - for member in self.members if member is not None + **( + member.get_agent_config_dict() + if isinstance(member, Agent) + else member.to_platform_dict() + if isinstance(member, Team) + else {} + ), + "agent_id": member.agent_id + if isinstance(member, Agent) and member.agent_id is not None + else str(uuid4()), + "team_id": member.team_id + if isinstance(member, Agent) and member.team_id is not None + else str(uuid4()), + } + for member in self.members + if member is not None ], "mode": self.mode, "model": self.model.to_dict() if self.model is not None else None, @@ -6794,6 +6799,6 @@ def to_platform_dict(self) -> Dict[str, Any]: "instructions": self.instructions, "description": self.description, "storage": self.storage.__class__.__name__ if self.storage is not None else None, - # "tools": [tool.to_dict() for tool in self.tools] if self.tools is not None else None, + # "tools": [tool.to_dict() for tool in self.tools] if self.tools is not None else None, # "memory": self.memory.to_dict() if self.memory is not None else None, } From ffc89c4dd3efe425c6286924834605e1cd7f0399 Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Thu, 1 May 2025 01:54:22 +0530 Subject: [PATCH 18/55] update --- libs/agno/agno/team/team.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/libs/agno/agno/team/team.py b/libs/agno/agno/team/team.py index 5f6e4b54dd..bdd879d951 100644 --- a/libs/agno/agno/team/team.py +++ b/libs/agno/agno/team/team.py @@ -439,6 +439,7 @@ def _initialize_member(self, member: Union["Team", Agent], session_id: Optional[ if isinstance(member, Agent): member.team_id = self.team_id + member.set_agent_id() if member.name is None: log_warning("Team member name is undefined.") @@ -6735,7 +6736,7 @@ def _register_team_on_platform(self, team_id: Optional[str] = None) -> None: return from agno.api.team import TeamCreate, create_team - + print(self.to_platform_dict(),"--------------------------------_________---------***************") try: create_team( team=TeamCreate( @@ -6783,12 +6784,8 @@ def to_platform_dict(self) -> Dict[str, Any]: if isinstance(member, Team) else {} ), - "agent_id": member.agent_id - if isinstance(member, Agent) and member.agent_id is not None - else str(uuid4()), - "team_id": member.team_id - if isinstance(member, Agent) and member.team_id is not None - else str(uuid4()), + "agent_id": member.agent_id if hasattr(member, "agent_id") else None, + "team_id": member.team_id if hasattr(member, "team_id") else None } for member in self.members if member is not None From 204cae9f06dba3faad9698975a3795c5bc35db3b Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Thu, 1 May 2025 02:12:35 +0530 Subject: [PATCH 19/55] update --- libs/agno/agno/team/team.py | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/libs/agno/agno/team/team.py b/libs/agno/agno/team/team.py index bdd879d951..cd879ad8b1 100644 --- a/libs/agno/agno/team/team.py +++ b/libs/agno/agno/team/team.py @@ -440,7 +440,11 @@ def _initialize_member(self, member: Union["Team", Agent], session_id: Optional[ if isinstance(member, Agent): member.team_id = self.team_id member.set_agent_id() - + elif isinstance(member, Team): + if member.team_id is None: + member.team_id = str(uuid4()) + for sub_member in member.members: + self._initialize_member(sub_member, session_id) if member.name is None: log_warning("Team member name is undefined.") @@ -6785,7 +6789,26 @@ def to_platform_dict(self) -> Dict[str, Any]: else {} ), "agent_id": member.agent_id if hasattr(member, "agent_id") else None, - "team_id": member.team_id if hasattr(member, "team_id") else None + "team_id": member.team_id if hasattr(member, "team_id") else None, + "members": ( + [ + { + **( + sub_member.get_agent_config_dict() + if isinstance(sub_member, Agent) + else sub_member.to_platform_dict() + if isinstance(sub_member, Team) + else {} + ), + "agent_id": sub_member.agent_id if hasattr(sub_member, "agent_id") else None, + "team_id": sub_member.team_id if hasattr(sub_member, "team_id") else None + } + for sub_member in member.members + if sub_member is not None + ] + if isinstance(member, Team) and hasattr(member, "members") + else [] + ) } for member in self.members if member is not None From 671eec64691d4c9f4b9f241e4cdc9171787a8d45 Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Fri, 2 May 2025 16:16:27 +0530 Subject: [PATCH 20/55] revert cookbook files --- cookbook/agents_from_scratch/simple_agent.py | 21 +----------- cookbook/playground/demo.py | 19 ----------- cookbook/playground/teams_demo.py | 35 ++++++-------------- 3 files changed, 11 insertions(+), 64 deletions(-) diff --git a/cookbook/agents_from_scratch/simple_agent.py b/cookbook/agents_from_scratch/simple_agent.py index c8ae810370..0c575d8a19 100644 --- a/cookbook/agents_from_scratch/simple_agent.py +++ b/cookbook/agents_from_scratch/simple_agent.py @@ -7,11 +7,9 @@ from agno.agent import Agent from agno.models.openai import OpenAIChat -from agno.playground import Playground simple_agent = Agent( name="Simple Agent", - agent_id="simple-agent", model=OpenAIChat(id="gpt-4o"), instructions=dedent("""\ You are an enthusiastic news reporter with a flair for storytelling! 🗽 @@ -29,22 +27,5 @@ markdown=True, ) - -playground = Playground( - agents=[simple_agent], - name="Simple Agent", - app_id="simple-agent", - monitoring=True, -) - -# Get the FastAPI app -app = playground.get_app(use_async=False) - if __name__ == "__main__": - # Start the playground server - playground.register_playground_app( - app="simple_agent:app", - host="localhost", - port=7777, - reload=True, - ) + simple_agent.print_response("Share a news story from NYC and SF.", stream=True) diff --git a/cookbook/playground/demo.py b/cookbook/playground/demo.py index f0be8b5e73..e3eee218b5 100644 --- a/cookbook/playground/demo.py +++ b/cookbook/playground/demo.py @@ -7,8 +7,6 @@ from agno.agent import Agent from agno.memory.v2 import Memory from agno.memory.v2.db.sqlite import SqliteMemoryDb -from agno.embedder.openai import OpenAIEmbedder -from agno.knowledge.pdf_url import PDFUrlKnowledgeBase from agno.models.openai import OpenAIChat from agno.playground import Playground, serve_playground_app from agno.storage.sqlite import SqliteStorage @@ -17,12 +15,8 @@ from agno.tools.exa import ExaTools from agno.tools.yfinance import YFinanceTools from agno.tools.youtube import YouTubeTools - -from agno.vectordb.lancedb import LanceDb, SearchType - from pydantic import BaseModel, Field - agent_storage_file: str = "tmp/agents.db" memory_storage_file: str = "tmp/memory.db" image_agent_storage_file: str = "tmp/image_agent.db" @@ -48,9 +42,6 @@ num_history_responses=5, add_datetime_to_instructions=True, markdown=True, - instructions=[ - "Always answer like a pirate", - ], ) web_agent = Agent( @@ -72,16 +63,6 @@ num_history_responses=5, add_datetime_to_instructions=True, markdown=True, - debug_mode=True, - knowledge=PDFUrlKnowledgeBase( - urls=["https://agno-public.s3.amazonaws.com/recipes/ThaiRecipes.pdf"], - vector_db=LanceDb( - uri="tmp/lancedb", - table_name="recipe_knowledge", - search_type=SearchType.hybrid, - embedder=OpenAIEmbedder(id="text-embedding-3-small"), - ), - ), ) finance_agent = Agent( diff --git a/cookbook/playground/teams_demo.py b/cookbook/playground/teams_demo.py index 5fb82bb6ae..157333e188 100644 --- a/cookbook/playground/teams_demo.py +++ b/cookbook/playground/teams_demo.py @@ -78,7 +78,7 @@ tools=[DuckDuckGoTools()], agent_id="web_agent", instructions=[ - "You are an experienced web researcher and news analyst!", + "You are an experienced web researcher and news analyst! 🔍", ], memory=memory, enable_user_memories=True, @@ -98,7 +98,7 @@ YFinanceTools(stock_price=True, analyst_recommendations=True, company_info=True) ], instructions=[ - "You are a skilled financial analyst with expertise in market data!", + "You are a skilled financial analyst with expertise in market data! 📊", "Follow these steps when analyzing financial data:", "Start with the latest stock price, trading volume, and daily range", "Present detailed analyst recommendations and consensus target prices", @@ -142,7 +142,7 @@ A comprehensive research report with clear sections and data-driven insights. """), instructions=[ - "You are the lead researcher of a research team!", + "You are the lead researcher of a research team! 🔍", ], memory=memory, enable_user_memories=True, @@ -169,7 +169,7 @@ A comprehensive report with clear sections and data-driven insights. """), instructions=[ - "You are the lead editor of a prestigious financial news desk!", + "You are the lead editor of a prestigious financial news desk! 📰", ], memory=memory, enable_user_memories=True, @@ -188,14 +188,14 @@ finance_agent, research_agent, file_agent, - # audio_agent, - # video_agent, + audio_agent, + video_agent, ], model=OpenAIChat(id="gpt-4o"), mode="route", team_id="financial_news_team", instructions=[ - "You are the lead editor of a prestigious financial news desk!", + "You are the lead editor of a prestigious financial news desk! 📰", "If you are given a file send it to the file agent.", "If you are given an audio file send it to the audio agent.", "If you are given a video file send it to the video agent.", @@ -216,27 +216,12 @@ memory=memory, enable_user_memories=True, expected_output="A good financial news report.", - context="use USD as currency", ) -# Create a single Playground instance to avoid duplication -playground = Playground( +app = Playground( teams=[research_team, financial_news_team, multimodal_team], agents=[web_agent, finance_agent, research_agent, simple_agent], - name="Playground Demo app", - description="This is a demo app for the Playground.", - app_id="playground-demo-app", - monitoring=True, -) - -# Get the FastAPI app -app = playground.get_app(use_async=False) +).get_app() if __name__ == "__main__": - # Start the playground server - playground.register_playground_app( - app="teams_demo:app", - host="localhost", - port=7777, - reload=True, - ) + serve_playground_app("teams_demo:app", reload=True) From 65ac24cd9223d2d573b8be6ce79e430456292549 Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Fri, 2 May 2025 16:16:57 +0530 Subject: [PATCH 21/55] update --- cookbook/playground/app_registration.py | 242 ++++++++++++++++++++++++ 1 file changed, 242 insertions(+) create mode 100644 cookbook/playground/app_registration.py diff --git a/cookbook/playground/app_registration.py b/cookbook/playground/app_registration.py new file mode 100644 index 0000000000..eb4309f6fa --- /dev/null +++ b/cookbook/playground/app_registration.py @@ -0,0 +1,242 @@ +from textwrap import dedent + +from agno.agent import Agent +from agno.memory.v2 import Memory +from agno.memory.v2.db.postgres import PostgresMemoryDb +from agno.models.anthropic import Claude +from agno.models.google.gemini import Gemini +from agno.models.openai import OpenAIChat +from agno.playground import Playground, serve_playground_app +from agno.storage.postgres import PostgresStorage +from agno.team.team import Team +from agno.tools.duckduckgo import DuckDuckGoTools +from agno.tools.exa import ExaTools +from agno.tools.yfinance import YFinanceTools + +db_url = "postgresql+psycopg://ai:ai@localhost:5532/ai" + +memory_db = PostgresMemoryDb(table_name="memory", db_url=db_url) + +# No need to set the model, it gets set by the agent to the agent's model +memory = Memory(db=memory_db) + + +file_agent = Agent( + name="File Upload Agent", + agent_id="file-upload-agent", + role="Answer questions about the uploaded files", + model=Claude(id="claude-3-7-sonnet-latest"), + storage=PostgresStorage( + table_name="agent_sessions", db_url=db_url, auto_upgrade_schema=True + ), + memory=memory, + enable_user_memories=True, + instructions=[ + "You are an AI agent that can analyze files.", + "You are given a file and you need to answer questions about the file.", + ], + show_tool_calls=True, + markdown=True, +) + +video_agent = Agent( + name="Video Understanding Agent", + model=Gemini(id="gemini-2.0-flash"), + agent_id="video-understanding-agent", + role="Answer questions about video files", + storage=PostgresStorage( + table_name="agent_sessions", db_url=db_url, auto_upgrade_schema=True + ), + memory=memory, + enable_user_memories=True, + add_history_to_messages=True, + add_datetime_to_instructions=True, + show_tool_calls=True, + markdown=True, +) + +audio_agent = Agent( + name="Audio Understanding Agent", + agent_id="audio-understanding-agent", + role="Answer questions about audio files", + model=OpenAIChat(id="gpt-4o-audio-preview"), + storage=PostgresStorage( + table_name="agent_sessions", db_url=db_url, auto_upgrade_schema=True + ), + memory=memory, + enable_user_memories=True, + add_history_to_messages=True, + add_datetime_to_instructions=True, + show_tool_calls=True, + markdown=True, +) + +web_agent = Agent( + name="Web Agent", + role="Search the web for information", + model=OpenAIChat(id="gpt-4o"), + tools=[DuckDuckGoTools()], + agent_id="web_agent", + instructions=[ + "You are an experienced web researcher and news analyst!", + ], + memory=memory, + enable_user_memories=True, + show_tool_calls=True, + markdown=True, + storage=PostgresStorage( + table_name="web_agent", db_url=db_url, auto_upgrade_schema=True + ), +) + +finance_agent = Agent( + name="Finance Agent", + role="Get financial data", + agent_id="finance_agent", + model=OpenAIChat(id="gpt-4o"), + tools=[ + YFinanceTools(stock_price=True, analyst_recommendations=True, company_info=True) + ], + instructions=[ + "You are a skilled financial analyst with expertise in market data!", + "Follow these steps when analyzing financial data:", + "Start with the latest stock price, trading volume, and daily range", + "Present detailed analyst recommendations and consensus target prices", + "Include key metrics: P/E ratio, market cap, 52-week range", + "Analyze trading patterns and volume trends", + ], + memory=memory, + enable_user_memories=True, + show_tool_calls=True, + markdown=True, +) + +simple_agent = Agent( + name="Simple Agent", + role="Simple agent", + model=OpenAIChat(id="gpt-4o"), + instructions=["You are a simple agent"], + memory=memory, + enable_user_memories=True, +) + +research_agent = Agent( + name="Research Agent", + role="Research agent", + model=OpenAIChat(id="gpt-4o"), + instructions=["You are a research agent"], + tools=[DuckDuckGoTools(), ExaTools()], + agent_id="research_agent", + memory=memory, + enable_user_memories=True, +) + +research_team = Team( + name="Research Team", + description="A team of agents that research the web", + members=[research_agent, simple_agent], + model=OpenAIChat(id="gpt-4o"), + mode="coordinate", + team_id="research_team", + success_criteria=dedent("""\ + A comprehensive research report with clear sections and data-driven insights. + """), + instructions=[ + "You are the lead researcher of a research team!", + ], + memory=memory, + enable_user_memories=True, + add_datetime_to_instructions=True, + show_tool_calls=True, + markdown=True, + enable_agentic_context=True, + storage=PostgresStorage( + table_name="research_team", + db_url=db_url, + mode="team", + auto_upgrade_schema=True, + ), +) + +multimodal_team = Team( + name="Multimodal Team", + description="A team of agents that can handle multiple modalities", + members=[file_agent, audio_agent, video_agent], + model=OpenAIChat(id="gpt-4o"), + mode="route", + team_id="multimodal_team", + success_criteria=dedent("""\ + A comprehensive report with clear sections and data-driven insights. + """), + instructions=[ + "You are the lead editor of a prestigious financial news desk!", + ], + memory=memory, + enable_user_memories=True, + storage=PostgresStorage( + table_name="multimodal_team", + db_url=db_url, + mode="team", + auto_upgrade_schema=True, + ), +) +financial_news_team = Team( + name="Financial News Team", + description="A team of agents that search the web for financial news and analyze it.", + members=[ + web_agent, + finance_agent, + research_agent, + file_agent, + audio_agent, + video_agent, + ], + model=OpenAIChat(id="gpt-4o"), + mode="route", + team_id="financial_news_team", + instructions=[ + "You are the lead editor of a prestigious financial news desk!", + "If you are given a file send it to the file agent.", + "If you are given an audio file send it to the audio agent.", + "If you are given a video file send it to the video agent.", + "Use USD as currency.", + "If the user is just being conversational, you should respond directly WITHOUT forwarding a task to a member.", + ], + add_datetime_to_instructions=True, + show_tool_calls=True, + markdown=True, + enable_agentic_context=True, + show_members_responses=True, + storage=PostgresStorage( + table_name="financial_news_team", + db_url=db_url, + mode="team", + auto_upgrade_schema=True, + ), + memory=memory, + enable_user_memories=True, + expected_output="A good financial news report.", + context="use USD as currency", +) + +# Create a single Playground instance to avoid duplication +playground = Playground( + teams=[research_team, financial_news_team, multimodal_team], + agents=[web_agent, finance_agent, research_agent, simple_agent], + name="App Registration Demo app", + description="This is a demo app for the App Registration.", + app_id="app-registration-demo-app", + monitoring=True, +) + +# Get the FastAPI app +app = playground.get_app(use_async=False) + +if __name__ == "__main__": + # Start the playground server + playground.serve_playground_app( + app="app_registration:app", + host="localhost", + port=7777, + reload=True, + ) From 38a3f094889a6df7ba276d6d6ccfea929f42d113 Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Fri, 2 May 2025 16:50:54 +0530 Subject: [PATCH 22/55] formatting --- libs/agno/agno/agent/agent.py | 26 ++++++++++++------------- libs/agno/agno/api/app.py | 6 ++---- libs/agno/agno/playground/playground.py | 7 ++----- libs/agno/agno/team/team.py | 6 +++--- 4 files changed, 20 insertions(+), 25 deletions(-) diff --git a/libs/agno/agno/agent/agent.py b/libs/agno/agno/agent/agent.py index 113cd55613..d564b42fea 100644 --- a/libs/agno/agno/agent/agent.py +++ b/libs/agno/agno/agent/agent.py @@ -1654,14 +1654,7 @@ async def _arun( # Log Agent Run await self._alog_agent_run(user_id=user_id, session_id=session_id) - # Define a synchronous wrapper to run the async function - # def run_async_in_thread(): - # asyncio.run(alog_agent_run()) - - # # Run the synchronous wrapper in a separate thread - # await asyncio.to_thread(run_async_in_thread) - - log_debug(f"Async Agent Run End: {self.run_response.run_id}", center=True, symbol="*") + log_debug(f" Agent Run End: {self.run_response.run_id}", center=True, symbol="*") if self.stream_intermediate_steps: yield self.create_run_response( content=self.run_response.content, @@ -4425,7 +4418,6 @@ def register_agent_on_platform(self) -> None: try: log_debug(f"Creating Agent on Platform: {self.name}, {self.agent_id}, {self.team_id},") - print("HERE", self.agent_id, self.get_agent_config_dict()) create_agent( agent=AgentCreate( name=self.name, @@ -5473,7 +5465,9 @@ def cli_app( if message in _exit_on: break - self.print_response(message=message, stream=stream, markdown=markdown, **kwargs) + self.print_response( + message=message, stream=stream, markdown=markdown, user_id=user_id, session_id=session_id**kwargs + ) def get_agent_config_dict(self) -> Dict[str, Any]: tools = [] @@ -5498,13 +5492,19 @@ def get_agent_config_dict(self) -> Dict[str, Any]: "tools": tools, "memory": { "name": self.memory.__class__.__name__ if self.memory is not None else None, - }, + } + if self.memory is not None + else None, "storage": { "name": self.storage.__class__.__name__ if self.storage is not None else None, - }, + } + if self.storage is not None + else None, "knowledge": { "name": self.knowledge.__class__.__name__ if self.knowledge is not None else None, - }, + } + if self.knowledge is not None + else None, "model": model, "name": self.name, "description": self.description, diff --git a/libs/agno/agno/api/app.py b/libs/agno/agno/api/app.py index 1d5785e7ae..111582f720 100644 --- a/libs/agno/agno/api/app.py +++ b/libs/agno/agno/api/app.py @@ -11,12 +11,11 @@ def create_app(app: AppCreate) -> None: with api.AuthenticatedClient() as api_client: try: - print("HERE") api_client.post( ApiRoutes.APP_CREATE, json={"app": app.model_dump()}, ) - print("HERE2") + except Exception as e: log_debug(f"Could not create App: {e}") @@ -27,12 +26,11 @@ async def acreate_app(app: AppCreate) -> None: async with api.AuthenticatedAsyncClient() as api_client: try: - print("HERE") payload = {"app": app.model_dump(exclude_none=True)} await api_client.post( ApiRoutes.APP_CREATE, json=payload, ) - print("HERE2") + except Exception as e: log_debug(f"Could not create App: {e}") diff --git a/libs/agno/agno/playground/playground.py b/libs/agno/agno/playground/playground.py index 341ea151e7..963e97e93e 100644 --- a/libs/agno/agno/playground/playground.py +++ b/libs/agno/agno/playground/playground.py @@ -164,7 +164,7 @@ async def general_exception_handler(request: Request, call_next): # asyncio.create_task(self.aregister_app_on_platform()) return self.api_app - def register_playground_app( + def serve_playground_app( self, app: Union[str, FastAPI], *, @@ -206,7 +206,6 @@ def register_playground_app( # Print the panel console.print(panel) - print(app, "this is app") self.set_app_id() thread = threading.Thread(target=self.register_app_on_platform) thread.start() @@ -228,8 +227,7 @@ def register_app_on_platform(self) -> None: from agno.api.app import AppCreate, create_app try: - print(f"Creating Agent on Platform: {self.name}, {self.app_id}") - # print("HERE", self.playground_to_dict()) + log_debug(f"Creating app on Platform: {self.name}, {self.app_id}") create_app(app=AppCreate(name=self.name, app_id=self.app_id, config=self.playground_to_dict())) except Exception as e: log_debug(f"Could not create Agent app: {e}") @@ -265,7 +263,6 @@ def playground_to_dict(self) -> Dict[str, Any]: "type": "playground", "description": self.description, } - print(payload, "this is payload") return payload diff --git a/libs/agno/agno/team/team.py b/libs/agno/agno/team/team.py index cd879ad8b1..472ebefdfb 100644 --- a/libs/agno/agno/team/team.py +++ b/libs/agno/agno/team/team.py @@ -6740,7 +6740,7 @@ def _register_team_on_platform(self, team_id: Optional[str] = None) -> None: return from agno.api.team import TeamCreate, create_team - print(self.to_platform_dict(),"--------------------------------_________---------***************") + try: create_team( team=TeamCreate( @@ -6801,14 +6801,14 @@ def to_platform_dict(self) -> Dict[str, Any]: else {} ), "agent_id": sub_member.agent_id if hasattr(sub_member, "agent_id") else None, - "team_id": sub_member.team_id if hasattr(sub_member, "team_id") else None + "team_id": sub_member.team_id if hasattr(sub_member, "team_id") else None, } for sub_member in member.members if sub_member is not None ] if isinstance(member, Team) and hasattr(member, "members") else [] - ) + ), } for member in self.members if member is not None From 62e53f1e970c877b3c0872f9298961955bc39bbd Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Sat, 3 May 2025 01:52:34 +0530 Subject: [PATCH 23/55] update --- libs/agno/agno/playground/playground.py | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/libs/agno/agno/playground/playground.py b/libs/agno/agno/playground/playground.py index 963e97e93e..59a1c37443 100644 --- a/libs/agno/agno/playground/playground.py +++ b/libs/agno/agno/playground/playground.py @@ -82,16 +82,7 @@ def __init__( def set_app_id(self) -> str: # If app_id is already set, keep it instead of overriding with UUID if self.app_id is None: - app_id_parts = [] - if self.agents and self.agents is not None: - app_id_parts.append(f"agent-{self.agents[0].agent_id}") - if self.teams and self.teams is not None: - app_id_parts.append(f"team-{self.teams[0].team_id}") - if self.workflows and self.workflows is not None: - app_id_parts.append(f"workflow-{self.workflows[0].workflow_id}") - - if app_id_parts: - self.app_id = "-".join(app_id_parts) + self.app_id = str(uuid4()) # Don't override existing app_id return self.app_id From cb144048e44dfddbfba1ec0873758311d5a71f89 Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Mon, 5 May 2025 17:40:32 +0530 Subject: [PATCH 24/55] remove registration of members inside teams two times --- libs/agno/agno/team/team.py | 31 +++---------------------------- 1 file changed, 3 insertions(+), 28 deletions(-) diff --git a/libs/agno/agno/team/team.py b/libs/agno/agno/team/team.py index 472ebefdfb..2658f93b26 100644 --- a/libs/agno/agno/team/team.py +++ b/libs/agno/agno/team/team.py @@ -696,24 +696,8 @@ def run( _tools.append(self.get_member_information) self._add_tools_to_model(self.model, tools=_tools) # type: ignore - for member in self.members: - if isinstance(member, Agent): - thread = threading.Thread(target=member.register_agent_on_platform) - thread.start() - elif isinstance(member, Team): - thread = threading.Thread(target=member._register_team_on_platform(team_id=self.team_id)) - thread.start() - # Register team members recursively - for team_member in member.members: - if isinstance(team_member, Agent): - thread = threading.Thread(target=team_member.register_agent_on_platform) - thread.start() - elif isinstance(team_member, Team): - thread = threading.Thread( - target=team_member._register_team_on_platform(team_id=self.team_id) - ) - thread.start() - # Run the team + + # # Run the team try: self.run_response = TeamRunResponse(run_id=self.run_id, session_id=session_id, team_id=self.team_id) # Configure the team leader model @@ -1457,16 +1441,7 @@ async def arun( _tools.append(self.get_set_shared_context_function(session_id=session_id)) self._add_tools_to_model(self.model, tools=_tools) # type: ignore - for member in self.members: - if isinstance(member, Agent): - asyncio.create_task(member.aregister_agent_on_platform()) - elif isinstance(member, Team): - asyncio.create_task(member._aregister_team_on_platform(team_id=self.team_id)) - for team_member in member.members: - if isinstance(team_member, Agent): - asyncio.create_task(team_member.aregister_agent_on_platform()) - elif isinstance(team_member, Team): - asyncio.create_task(team_member._aregister_team_on_platform(team_id=self.team_id)) + # Run the team try: self.run_response = TeamRunResponse(run_id=self.run_id, session_id=session_id, team_id=self.team_id) From d8aed150ef35f8050ed8f38931c66b697d5634c0 Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Mon, 5 May 2025 21:41:02 +0530 Subject: [PATCH 25/55] update --- libs/agno/agno/agent/agent.py | 8 +++---- libs/agno/agno/api/agent.py | 5 ++-- libs/agno/agno/api/app.py | 5 ++-- libs/agno/agno/api/team.py | 5 ++-- libs/agno/agno/playground/playground.py | 31 +++++-------------------- libs/agno/agno/team/team.py | 14 ++++++----- 6 files changed, 24 insertions(+), 44 deletions(-) diff --git a/libs/agno/agno/agent/agent.py b/libs/agno/agno/agent/agent.py index d564b42fea..a619ec51ce 100644 --- a/libs/agno/agno/agent/agent.py +++ b/libs/agno/agno/agent/agent.py @@ -605,7 +605,7 @@ def _run( self.run_response = RunResponse(run_id=self.run_id, session_id=session_id, agent_id=self.agent_id) # 1.4 Register the agent on the platform - thread = threading.Thread(target=self.register_agent_on_platform) + thread = threading.Thread(target=self._register_agent) thread.start() log_debug(f"Agent Run Start: {self.run_response.run_id}", center=True) @@ -1260,7 +1260,7 @@ async def _arun( # Create a task to run the agent registration in the background # This won't block the execution flow - asyncio.create_task(self.aregister_agent_on_platform()) + asyncio.create_task(self._aregister_agent()) log_debug(f"Async Agent Run Start: {self.run_response.run_id}", center=True, symbol="*") @@ -4409,7 +4409,7 @@ def _create_run_data(self) -> Dict[str, Any]: return run_data - def register_agent_on_platform(self) -> None: + def _register_agent(self) -> None: self.set_monitoring() if not self.monitoring: return @@ -4431,7 +4431,7 @@ def register_agent_on_platform(self) -> None: log_debug(f"Could not create Agent app: {e}") log_debug(f"Agent app created: {self.name}, {self.agent_id}, {self.team_id},") - async def aregister_agent_on_platform(self) -> None: + async def _aregister_agent(self) -> None: self.set_monitoring() if not self.monitoring: return diff --git a/libs/agno/agno/api/agent.py b/libs/agno/agno/api/agent.py index 53c918a218..f71d44a702 100644 --- a/libs/agno/agno/api/agent.py +++ b/libs/agno/agno/api/agent.py @@ -58,7 +58,7 @@ def create_agent(agent: AgentCreate) -> None: try: api_client.post( ApiRoutes.AGENT_CREATE, - json={"agent": agent.model_dump()}, + json=agent.model_dump(exclude_none=True), ) except Exception as e: log_debug(f"Could not create Agent: {e}") @@ -70,10 +70,9 @@ async def acreate_agent(agent: AgentCreate) -> None: async with api.AuthenticatedAsyncClient() as api_client: try: - payload = {"agent": agent.model_dump(exclude_none=True)} await api_client.post( ApiRoutes.AGENT_CREATE, - json=payload, + json=agent.model_dump(exclude_none=True), ) except Exception as e: log_debug(f"Could not create Agent: {e}") diff --git a/libs/agno/agno/api/app.py b/libs/agno/agno/api/app.py index 111582f720..493c173477 100644 --- a/libs/agno/agno/api/app.py +++ b/libs/agno/agno/api/app.py @@ -13,7 +13,7 @@ def create_app(app: AppCreate) -> None: try: api_client.post( ApiRoutes.APP_CREATE, - json={"app": app.model_dump()}, + json=app.model_dump(exclude_none=True), ) except Exception as e: @@ -26,10 +26,9 @@ async def acreate_app(app: AppCreate) -> None: async with api.AuthenticatedAsyncClient() as api_client: try: - payload = {"app": app.model_dump(exclude_none=True)} await api_client.post( ApiRoutes.APP_CREATE, - json=payload, + json=app.model_dump(exclude_none=True), ) except Exception as e: diff --git a/libs/agno/agno/api/team.py b/libs/agno/agno/api/team.py index 6b4f291f4d..9f37f7d8ef 100644 --- a/libs/agno/agno/api/team.py +++ b/libs/agno/agno/api/team.py @@ -63,7 +63,7 @@ def create_team(team: TeamCreate) -> None: try: api_client.post( ApiRoutes.TEAM_CREATE, - json={"team": team.model_dump(exclude_none=True)}, + json=team.model_dump(exclude_none=True), ) except Exception as e: log_debug(f"Could not create Team: {e}") @@ -75,10 +75,9 @@ async def acreate_team(team: TeamCreate) -> None: async with api.AuthenticatedAsyncClient() as api_client: try: - payload = {"team": team.model_dump(exclude_none=True)} await api_client.post( ApiRoutes.TEAM_CREATE, - json=payload, + json=team.model_dump(exclude_none=True), ) except Exception as e: print(f"Could not create Team: {e}") diff --git a/libs/agno/agno/playground/playground.py b/libs/agno/agno/playground/playground.py index 59a1c37443..f614df5cfb 100644 --- a/libs/agno/agno/playground/playground.py +++ b/libs/agno/agno/playground/playground.py @@ -152,10 +152,9 @@ async def general_exception_handler(request: Request, call_next): expose_headers=["*"], ) - # asyncio.create_task(self.aregister_app_on_platform()) return self.api_app - def serve_playground_app( + def serve( self, app: Union[str, FastAPI], *, @@ -198,16 +197,13 @@ def serve_playground_app( # Print the panel console.print(panel) self.set_app_id() - thread = threading.Thread(target=self.register_app_on_platform) - thread.start() + self.register_app_on_platform() if self.agents: for agent in self.agents: - t1 = threading.Thread(target=agent.register_agent_on_platform) - t1.start() + agent._register_agent() if self.teams: for team in self.teams: - t2 = threading.Thread(target=team._register_team_on_platform) - t2.start() + team._register_team() uvicorn.run(app=app, host=host, port=port, reload=reload, **kwargs) def register_app_on_platform(self) -> None: @@ -219,27 +215,12 @@ def register_app_on_platform(self) -> None: try: log_debug(f"Creating app on Platform: {self.name}, {self.app_id}") - create_app(app=AppCreate(name=self.name, app_id=self.app_id, config=self.playground_to_dict())) + create_app(app=AppCreate(name=self.name, app_id=self.app_id, config=self.to_dict())) except Exception as e: log_debug(f"Could not create Agent app: {e}") log_debug(f"Agent app created: {self.name}, {self.app_id}") - async def aregister_app_on_platform(self) -> None: - self._set_monitoring() - if not self.monitoring: - return - - from agno.api.app import AppCreate, acreate_app - - try: - log_debug(f"Creating App on Platform: {self.name}, {self.agent_id}, {self.team_id},") - await acreate_app(app=AppCreate(name=self.name, app_id=self.app_id, config=self.playground_to_dict())) - - except Exception as e: - log_debug(f"Could not create App: {e}") - log_debug(f"App created: {self.name}, {self.agent_id}, {self.team_id},") - - def playground_to_dict(self) -> Dict[str, Any]: + def to_dict(self) -> Dict[str, Any]: payload = { "agents": [ {**agent.get_agent_config_dict(), "agent_id": agent.agent_id, "team_id": agent.team_id} diff --git a/libs/agno/agno/team/team.py b/libs/agno/agno/team/team.py index 2658f93b26..a1f02fd716 100644 --- a/libs/agno/agno/team/team.py +++ b/libs/agno/agno/team/team.py @@ -88,6 +88,7 @@ class Team: # Team UUID (autogenerated if not set) team_id: Optional[str] = None # If this team is part of a team itself, this is the role of the team + parent_team_id: Optional[str] = None role: Optional[str] = None # --- User settings --- @@ -443,6 +444,7 @@ def _initialize_member(self, member: Union["Team", Agent], session_id: Optional[ elif isinstance(member, Team): if member.team_id is None: member.team_id = str(uuid4()) + member.parent_team_id = self.team_id for sub_member in member.members: self._initialize_member(sub_member, session_id) if member.name is None: @@ -605,7 +607,7 @@ def run( self._configure_model(show_tool_calls=show_tool_calls) # Register the team on the platform - thread = threading.Thread(target=self._register_team_on_platform) + thread = threading.Thread(target=self._register_team) thread.start() # Run the team @@ -1354,7 +1356,7 @@ async def arun( # Configure the model for runs self._configure_model(show_tool_calls=show_tool_calls) - asyncio.create_task(self._aregister_team_on_platform()) + asyncio.create_task(self._aregister_team()) # Run the team last_exception = None @@ -6709,7 +6711,7 @@ def _log_team_session(self, session_id: str, user_id: Optional[str] = None): except Exception as e: log_debug(f"Could not create team monitor: {e}") - def _register_team_on_platform(self, team_id: Optional[str] = None) -> None: + def _register_team(self) -> None: self._set_monitoring() if not self.monitoring: return @@ -6722,7 +6724,7 @@ def _register_team_on_platform(self, team_id: Optional[str] = None) -> None: team_id=self.team_id, name=self.name, config=self.to_platform_dict(), - parent_team_id=team_id, + parent_team_id=self.parent_team_id, app_id=self.app_id, ), ) @@ -6731,7 +6733,7 @@ def _register_team_on_platform(self, team_id: Optional[str] = None) -> None: log_debug(f"Could not create team on platform: {e}") print(f"Could not create team on platform: {e}") - async def _aregister_team_on_platform(self, team_id: Optional[str] = None) -> None: + async def _aregister_team(self) -> None: self._set_monitoring() if not self.monitoring: return @@ -6744,7 +6746,7 @@ async def _aregister_team_on_platform(self, team_id: Optional[str] = None) -> No team_id=self.team_id, name=self.name, config=self.to_platform_dict(), - parent_team_id=team_id, + parent_team_id=self.parent_team_id, app_id=self.app_id, ), ) From 7a65bb17d956b2a945777a1097ed6f605f4283ef Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Mon, 5 May 2025 21:52:45 +0530 Subject: [PATCH 26/55] update --- cookbook/playground/app_registration.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cookbook/playground/app_registration.py b/cookbook/playground/app_registration.py index eb4309f6fa..26b85105ec 100644 --- a/cookbook/playground/app_registration.py +++ b/cookbook/playground/app_registration.py @@ -234,7 +234,7 @@ if __name__ == "__main__": # Start the playground server - playground.serve_playground_app( + playground.serve( app="app_registration:app", host="localhost", port=7777, From d515ffd45e29787c70982f8a8f05b6061d9cb68e Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Mon, 5 May 2025 23:49:22 +0530 Subject: [PATCH 27/55] update endpoint --- libs/agno/agno/playground/playground.py | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/libs/agno/agno/playground/playground.py b/libs/agno/agno/playground/playground.py index f614df5cfb..1465341710 100644 --- a/libs/agno/agno/playground/playground.py +++ b/libs/agno/agno/playground/playground.py @@ -14,7 +14,7 @@ from starlette.requests import Request from agno.agent.agent import Agent -from agno.api.playground import PlaygroundEndpointCreate, create_playground_endpoint +from agno.api.playground import PlaygroundEndpointCreate from agno.cli.console import console from agno.cli.settings import agno_cli_settings from agno.playground.async_router import get_async_playground_router @@ -167,21 +167,11 @@ def serve( ): import uvicorn - try: - create_playground_endpoint( - playground=PlaygroundEndpointCreate( - endpoint=f"{scheme}://{host}:{port}", playground_data={"prefix": prefix} - ), - ) - except Exception as e: - logger.error(f"Could not create playground endpoint: {e}") - logger.error("Please try again.") - return logger.info(f"Starting playground on {scheme}://{host}:{port}") # Encode the full endpoint (host:port) encoded_endpoint = quote(f"{host}:{port}") - self.endpoints_created = f"{scheme}://{host}:{port}" + self.endpoints_created = PlaygroundEndpointCreate(endpoint=f"{scheme}://{host}:{port}", playground_data={"prefix": prefix}) # Create a panel with the playground URL url = f"{agno_cli_settings.playground_url}?endpoint={encoded_endpoint}" From ef17f01cb90f646ca766ff7cf9c9ad271d466e40 Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Tue, 6 May 2025 12:40:44 +0530 Subject: [PATCH 28/55] update --- libs/agno/agno/playground/playground.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/agno/agno/playground/playground.py b/libs/agno/agno/playground/playground.py index 1465341710..936d009cbd 100644 --- a/libs/agno/agno/playground/playground.py +++ b/libs/agno/agno/playground/playground.py @@ -221,7 +221,7 @@ def to_dict(self) -> Dict[str, Any]: "teams": [{**team.to_platform_dict(), "team_id": team.team_id} for team in self.teams] if self.teams else [], - "endpoint": self.endpoints_created, + "endpointData": self.endpoints_created, "type": "playground", "description": self.description, } From 297b90911657cba8cc965eee15aad9be985f2b3a Mon Sep 17 00:00:00 2001 From: Anurag Date: Tue, 6 May 2025 19:51:44 +0530 Subject: [PATCH 29/55] feat: apps status (#3097) New status endpoint to help differentiate between different apps with same endpoints --- libs/agno/agno/playground/async_router.py | 12 +++++++++--- libs/agno/agno/playground/playground.py | 4 ++-- libs/agno/agno/playground/sync_router.py | 12 +++++++++--- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/libs/agno/agno/playground/async_router.py b/libs/agno/agno/playground/async_router.py index dcb3d44051..169d7dff49 100644 --- a/libs/agno/agno/playground/async_router.py +++ b/libs/agno/agno/playground/async_router.py @@ -114,7 +114,7 @@ async def team_chat_response_streamer( def get_async_playground_router( - agents: Optional[List[Agent]] = None, workflows: Optional[List[Workflow]] = None, teams: Optional[List[Team]] = None + agents: Optional[List[Agent]] = None, workflows: Optional[List[Workflow]] = None, teams: Optional[List[Team]] = None, active_app_id: Optional[str] = None ) -> APIRouter: playground_router = APIRouter(prefix="/playground", tags=["Playground"]) @@ -136,8 +136,14 @@ def get_async_playground_router( workflow.workflow_id = str(uuid4()) @playground_router.get("/status") - async def playground_status(): - return {"playground": "available"} + async def playground_status(app_id: Optional[str] = None): + if app_id is None: + return {"playground": "available"} + else: + if active_app_id == app_id: + return {"playground": "available"} + else: + return {"playground": "unavailable"} @playground_router.get("/agents", response_model=List[AgentGetResponse]) async def get_agents(): diff --git a/libs/agno/agno/playground/playground.py b/libs/agno/agno/playground/playground.py index 936d009cbd..9b37cc5bbd 100644 --- a/libs/agno/agno/playground/playground.py +++ b/libs/agno/agno/playground/playground.py @@ -96,10 +96,10 @@ def _set_monitoring(self) -> None: self.monitoring = monitor_env.lower() == "true" def get_router(self) -> APIRouter: - return get_sync_playground_router(self.agents, self.workflows, self.teams) + return get_sync_playground_router(self.agents, self.workflows, self.teams, self.app_id) def get_async_router(self) -> APIRouter: - return get_async_playground_router(self.agents, self.workflows, self.teams) + return get_async_playground_router(self.agents, self.workflows, self.teams, self.app_id) def get_app(self, use_async: bool = True, prefix: str = "/v1") -> FastAPI: if not self.api_app: diff --git a/libs/agno/agno/playground/sync_router.py b/libs/agno/agno/playground/sync_router.py index c9fbcecfbc..97c90a516c 100644 --- a/libs/agno/agno/playground/sync_router.py +++ b/libs/agno/agno/playground/sync_router.py @@ -114,7 +114,7 @@ def team_chat_response_streamer( def get_sync_playground_router( - agents: Optional[List[Agent]] = None, workflows: Optional[List[Workflow]] = None, teams: Optional[List[Team]] = None + agents: Optional[List[Agent]] = None, workflows: Optional[List[Workflow]] = None, teams: Optional[List[Team]] = None, active_app_id: Optional[str] = None ) -> APIRouter: playground_router = APIRouter(prefix="/playground", tags=["Playground"]) if agents is None and workflows is None and teams is None: @@ -135,8 +135,14 @@ def get_sync_playground_router( workflow.workflow_id = str(uuid4()) @playground_router.get("/status") - def playground_status(): - return {"playground": "available"} + def playground_status(app_id: Optional[str] = None): + if app_id is None: + return {"playground": "available"} + else: + if active_app_id == app_id: + return {"playground": "available"} + else: + return {"playground": "unavailable"} @playground_router.get("/agents", response_model=List[AgentGetResponse]) def get_agents(): From cfa4dc7290f95a96adb938a1aaf33956742ee0b3 Mon Sep 17 00:00:00 2001 From: Ayush <97244608+Ayush0054@users.noreply.github.com> Date: Fri, 9 May 2025 19:03:35 +0530 Subject: [PATCH 30/55] workflow registration init (#3117) ## Summary Describe key changes, mention related issues or motivation for the changes. (If applicable, issue number: #____) ## Type of change - [ ] Bug fix - [ ] New feature - [ ] Breaking change - [ ] Improvement - [ ] Model update - [ ] Other: --- ## Checklist - [ ] Code complies with style guidelines - [ ] Ran format/validation scripts (`./scripts/format.sh` and `./scripts/validate.sh`) - [ ] Self-review completed - [ ] Documentation updated (comments, docstrings) - [ ] Examples and guides: Relevant cookbook examples have been included or updated (if applicable) - [ ] Tested in clean environment - [ ] Tests added/updated (if applicable) --- ## Additional Notes Add any important context (deployment instructions, screenshots, security considerations, etc.) --- cookbook/workflows/workflows_playground.py | 16 ++- libs/agno/agno/agent/agent.py | 19 ++- libs/agno/agno/api/routes.py | 2 + libs/agno/agno/api/schemas/agent.py | 1 + libs/agno/agno/api/schemas/team.py | 1 + libs/agno/agno/api/schemas/workflows.py | 12 ++ libs/agno/agno/api/workflows.py | 36 ++++++ libs/agno/agno/playground/playground.py | 18 ++- libs/agno/agno/team/team.py | 5 + libs/agno/agno/workflow/workflow.py | 136 +++++++++++++++++++-- 10 files changed, 224 insertions(+), 22 deletions(-) create mode 100644 libs/agno/agno/api/schemas/workflows.py create mode 100644 libs/agno/agno/api/workflows.py diff --git a/cookbook/workflows/workflows_playground.py b/cookbook/workflows/workflows_playground.py index 77abd73a03..88a76ab3bf 100644 --- a/cookbook/workflows/workflows_playground.py +++ b/cookbook/workflows/workflows_playground.py @@ -48,14 +48,22 @@ ) # Initialize the Playground with the workflows -app = Playground( +playground = Playground( workflows=[ blog_post_generator, personalised_email_generator, investment_report_generator, startup_idea_validator, - ] -).get_app() + ], + # app_id="workflows-playground-app", +) +app = playground.get_app(use_async=False) if __name__ == "__main__": - serve_playground_app("workflows_playground:app", reload=True) + # Start the playground server + playground.serve( + app="workflows_playground:app", + host="localhost", + port=7777, + reload=True, + ) diff --git a/libs/agno/agno/agent/agent.py b/libs/agno/agno/agent/agent.py index 082133ed4e..2488146fa7 100644 --- a/libs/agno/agno/agent/agent.py +++ b/libs/agno/agno/agent/agent.py @@ -2,7 +2,6 @@ import asyncio import threading - from collections import ChainMap, defaultdict, deque from dataclasses import asdict, dataclass from os import getenv @@ -266,6 +265,9 @@ class Agent: # Optional app ID. Indicates this agent is part of an app. app_id: Optional[str] = None + # Optional workflow ID. Indicates this agent is part of a workflow. + workflow_id: Optional[str] = None + # Optional team session state. Set by the team leader agent. team_session_state: Optional[Dict[str, Any]] = None @@ -4432,6 +4434,7 @@ def _create_run_data(self) -> Dict[str, Any]: return run_data def _register_agent(self) -> None: + """Register this agent with Agno's platform.""" self.set_monitoring() if not self.monitoring: return @@ -4439,19 +4442,24 @@ def _register_agent(self) -> None: from agno.api.agent import AgentCreate, create_agent try: - log_debug(f"Creating Agent on Platform: {self.name}, {self.agent_id}, {self.team_id},") + # Ensure we have a valid session_id + if not self.session_id: + self.session_id = str(uuid4()) + + log_debug(f"Creating Agent on Platform: {self.name}, {self.agent_id}, {self.team_id}, {self.workflow_id}") create_agent( agent=AgentCreate( name=self.name, agent_id=self.agent_id, + workflow_id=self.workflow_id, team_id=self.team_id, app_id=self.app_id, config=self.get_agent_config_dict(), ) ) + log_debug(f"Agent created: {self.name}, {self.agent_id}, {self.team_id}, {self.workflow_id}") except Exception as e: - log_debug(f"Could not create Agent app: {e}") - log_debug(f"Agent app created: {self.name}, {self.agent_id}, {self.team_id},") + log_warning(f"Could not create Agent: {e}") async def _aregister_agent(self) -> None: self.set_monitoring() @@ -4466,6 +4474,7 @@ async def _aregister_agent(self) -> None: agent=AgentCreate( name=self.name, agent_id=self.agent_id, + workflow_id=self.workflow_id, team_id=self.team_id, app_id=self.app_id, config=self.get_agent_config_dict(), @@ -5503,7 +5512,6 @@ def cli_app( message=message, stream=stream, markdown=markdown, user_id=user_id, session_id=session_id**kwargs ) - def get_agent_config_dict(self) -> Dict[str, Any]: tools = [] if self.tools is not None: @@ -5578,4 +5586,3 @@ async def acli_app( await self.aprint_response( message=message, stream=stream, markdown=markdown, user_id=user_id, session_id=session_id, **kwargs ) - diff --git a/libs/agno/agno/api/routes.py b/libs/agno/agno/api/routes.py index edaf792dde..cac46cc073 100644 --- a/libs/agno/agno/api/routes.py +++ b/libs/agno/agno/api/routes.py @@ -31,6 +31,8 @@ class ApiRoutes: TEAM_SESSION_CREATE: str = "/v1/team-sessions" TEAM_CREATE: str = "/v2/teams" + # Workflow paths + WORKFLOW_CREATE: str = "/v2/workflows" # Telemetry paths # TODO: Update to use the new telemetry paths AGENT_TELEMETRY_SESSION_CREATE: str = "/v1/telemetry/agent/session/create" diff --git a/libs/agno/agno/api/schemas/agent.py b/libs/agno/agno/api/schemas/agent.py index ec210df051..ccb91bd165 100644 --- a/libs/agno/agno/api/schemas/agent.py +++ b/libs/agno/agno/api/schemas/agent.py @@ -26,5 +26,6 @@ class AgentCreate(BaseModel): agent_id: str team_id: Optional[str] = None app_id: Optional[str] = None + workflow_id: Optional[str] = None name: Optional[str] = None config: Dict[str, Any] diff --git a/libs/agno/agno/api/schemas/team.py b/libs/agno/agno/api/schemas/team.py index 9b19b43e1b..e78449332d 100644 --- a/libs/agno/agno/api/schemas/team.py +++ b/libs/agno/agno/api/schemas/team.py @@ -26,5 +26,6 @@ class TeamCreate(BaseModel): team_id: str parent_team_id: Optional[str] = None app_id: Optional[str] = None + workflow_id: Optional[str] = None name: Optional[str] = None config: Dict[str, Any] diff --git a/libs/agno/agno/api/schemas/workflows.py b/libs/agno/agno/api/schemas/workflows.py new file mode 100644 index 0000000000..f283dd818f --- /dev/null +++ b/libs/agno/agno/api/schemas/workflows.py @@ -0,0 +1,12 @@ +from typing import Any, Dict, Optional + +from pydantic import BaseModel + + +class WorkflowCreate(BaseModel): + """Data sent to API to create aWorkflow""" + + workflow_id: str + app_id: Optional[str] = None + name: Optional[str] = None + config: Dict[str, Any] diff --git a/libs/agno/agno/api/workflows.py b/libs/agno/agno/api/workflows.py new file mode 100644 index 0000000000..3e92f6cced --- /dev/null +++ b/libs/agno/agno/api/workflows.py @@ -0,0 +1,36 @@ +from agno.api.api import api +from agno.api.routes import ApiRoutes +from agno.api.schemas.workflows import WorkflowCreate +from agno.cli.settings import agno_cli_settings +from agno.utils.log import log_debug + + +def create_workflow(workflow: WorkflowCreate) -> None: + if not agno_cli_settings.api_enabled: + return + + with api.AuthenticatedClient() as api_client: + try: + print( + f"Creating Workflow**********************************************************, {workflow.workflow_id}" + ) + api_client.post( + ApiRoutes.WORKFLOW_CREATE, + json=workflow.model_dump(exclude_none=True), + ) + except Exception as e: + log_debug(f"Could not create Workflow: {e}") + + +async def acreate_workflow(workflow: WorkflowCreate) -> None: + if not agno_cli_settings.api_enabled: + return + + async with api.AuthenticatedAsyncClient() as api_client: + try: + await api_client.post( + ApiRoutes.WORKFLOW_CREATE, + json=workflow.model_dump(exclude_none=True), + ) + except Exception as e: + log_debug(f"Could not create Team: {e}") diff --git a/libs/agno/agno/playground/playground.py b/libs/agno/agno/playground/playground.py index 9b37cc5bbd..04bdaff7d9 100644 --- a/libs/agno/agno/playground/playground.py +++ b/libs/agno/agno/playground/playground.py @@ -53,6 +53,7 @@ def __init__( self.name: Optional[str] = name self.monitoring = monitoring self.description = description + self.set_app_id() if self.agents: for agent in self.agents: if not agent.app_id: @@ -76,6 +77,8 @@ def __init__( if self.workflows: for workflow in self.workflows: + if not workflow.app_id: + workflow.app_id = self.app_id if not workflow.workflow_id: workflow.workflow_id = generate_id(workflow.name) @@ -167,11 +170,12 @@ def serve( ): import uvicorn - logger.info(f"Starting playground on {scheme}://{host}:{port}") # Encode the full endpoint (host:port) encoded_endpoint = quote(f"{host}:{port}") - self.endpoints_created = PlaygroundEndpointCreate(endpoint=f"{scheme}://{host}:{port}", playground_data={"prefix": prefix}) + self.endpoints_created = PlaygroundEndpointCreate( + endpoint=f"{scheme}://{host}:{port}", playground_data={"prefix": prefix} + ) # Create a panel with the playground URL url = f"{agno_cli_settings.playground_url}?endpoint={encoded_endpoint}" @@ -190,10 +194,13 @@ def serve( self.register_app_on_platform() if self.agents: for agent in self.agents: - agent._register_agent() + agent._register_agent() if self.teams: for team in self.teams: team._register_team() + if self.workflows: + for workflow in self.workflows: + workflow._register_workflow() uvicorn.run(app=app, host=host, port=port, reload=reload, **kwargs) def register_app_on_platform(self) -> None: @@ -221,6 +228,11 @@ def to_dict(self) -> Dict[str, Any]: "teams": [{**team.to_platform_dict(), "team_id": team.team_id} for team in self.teams] if self.teams else [], + "workflows": [ + {**workflow.to_config_dict(), "workflow_id": workflow.workflow_id} for workflow in self.workflows + ] + if self.workflows + else [], "endpointData": self.endpoints_created, "type": "playground", "description": self.description, diff --git a/libs/agno/agno/team/team.py b/libs/agno/agno/team/team.py index 4bdcfd94ed..6f1d6d829d 100644 --- a/libs/agno/agno/team/team.py +++ b/libs/agno/agno/team/team.py @@ -89,6 +89,8 @@ class Team: team_id: Optional[str] = None # If this team is part of a team itself, this is the role of the team parent_team_id: Optional[str] = None + # The workflow this team belongs to + workflow_id: Optional[str] = None role: Optional[str] = None # --- User settings --- @@ -6719,6 +6721,7 @@ def _register_team(self) -> None: from agno.api.team import TeamCreate, create_team + print(f"Registering team**********************************************************, {self.workflow_id}") try: create_team( team=TeamCreate( @@ -6727,6 +6730,7 @@ def _register_team(self) -> None: config=self.to_platform_dict(), parent_team_id=self.parent_team_id, app_id=self.app_id, + workflow_id=self.workflow_id, ), ) @@ -6749,6 +6753,7 @@ async def _aregister_team(self) -> None: config=self.to_platform_dict(), parent_team_id=self.parent_team_id, app_id=self.app_id, + workflow_id=self.workflow_id, ), ) except Exception as e: diff --git a/libs/agno/agno/workflow/workflow.py b/libs/agno/agno/workflow/workflow.py index c1512f7469..1ca7e42b44 100644 --- a/libs/agno/agno/workflow/workflow.py +++ b/libs/agno/agno/workflow/workflow.py @@ -17,6 +17,7 @@ from agno.run.response import RunEvent, RunResponse # noqa: F401 from agno.storage.base import Storage from agno.storage.session.workflow import WorkflowSession +from agno.team.team import Team from agno.utils.common import nested_model_dump from agno.utils.log import log_debug, log_warning, logger, set_log_level_to_debug, set_log_level_to_info from agno.utils.merge_dict import merge_dictionaries @@ -29,6 +30,8 @@ class Workflow: name: Optional[str] = None # Workflow UUID (autogenerated if not set) workflow_id: Optional[str] = None + # Workflow app_id (autogenerated if not set) + app_id: Optional[str] = None # Workflow description (only shown in the UI) description: Optional[str] = None @@ -143,10 +146,25 @@ def run_workflow(self, **kwargs: Any): # Set mode, debug, workflow_id, session_id, initialize memory self.set_storage_mode() self.set_debug() - self.set_workflow_id() + self.set_monitoring() + self.set_workflow_id() # Ensure workflow_id is set self.set_session_id() self.initialize_memory() + # Update workflow_id for all agents before registration + for field_name, value in self.__class__.__dict__.items(): + if isinstance(value, Agent): + value.initialize_agent() + value.workflow_id = self.workflow_id + print(value.agent_id) + if isinstance(value, Team): + value.initialize_team() + value.workflow_id = self.workflow_id + print(value.team_id) + + # Register the workflow, which will also register agents and teams + self._register_workflow() + # Create a run_id self.run_id = str(uuid4()) @@ -254,15 +272,17 @@ def set_debug(self) -> None: set_log_level_to_info() def set_monitoring(self) -> None: - if self.monitoring or getenv("AGNO_MONITOR", "false").lower() == "true": - self.monitoring = True - else: - self.monitoring = False + """Override monitoring and telemetry settings based on environment variables.""" - if self.telemetry or getenv("AGNO_TELEMETRY", "true").lower() == "true": - self.telemetry = True - else: - self.telemetry = False + # Only override if the environment variable is set + monitor_env = getenv("AGNO_MONITOR") + if monitor_env is not None: + self.monitoring = monitor_env.lower() == "true" + + # Override telemetry if environment variable is set + telemetry_env = getenv("AGNO_TELEMETRY") + if telemetry_env is not None: + self.telemetry = telemetry_env.lower() == "true" def initialize_memory(self) -> None: if self.memory is None: @@ -640,3 +660,101 @@ def _deep_copy_field(self, field_name: str, field_value: Any) -> Any: # For other types, return as is return field_value + + def _register_workflow(self, force: bool = False) -> None: + """Register this workflow with Agno's platform. + + Args: + force: If True, register the workflow even if monitoring is disabled + """ + self.set_monitoring() + if not self.monitoring: + return + + if not self.workflow_id: + self.set_workflow_id() + + try: + from agno.api.schemas.workflows import WorkflowCreate + from agno.api.workflows import create_workflow + + workflow_config = self.to_config_dict() + log_debug(f"Registering workflow: {self.name} (ID: {self.workflow_id})") + print(f"Workflow config: {workflow_config}") + # Register the workflow as an app + create_workflow( + workflow=WorkflowCreate( + name=self.name, workflow_id=self.workflow_id, app_id=self.app_id, config=workflow_config + ) + ) + + log_debug(f"Successfully registered workflow: {self.name} (ID: {self.workflow_id})") + return True + except Exception as e: + log_warning(f"Failed to register workflow: {e}") + return False + + def to_config_dict(self) -> Dict[str, Any]: + """Convert the workflow to a config dictionary including all agents and teams. + + Returns: + Dict[str, Any]: Dictionary representation of the workflow config. + """ + # Basic workflow information + config = { + "name": self.name, + "description": self.description, + "type": "workflow", + "app_id": self.app_id, + "storage": { + "name": self.storage.__class__.__name__ if self.storage is not None else None, + }, + "memory": self.memory, + } + + agents = [] + teams = [] + + for attr_name in dir(self.__class__): + # Skip private/special attributes and methods + if attr_name.startswith("_") or callable(getattr(self.__class__, attr_name)): + continue + + # Get the class attribute + attr_value = getattr(self.__class__, attr_name) + + if isinstance(attr_value, Agent): + # Skip agents already in the list + if any(a.get("name") == (attr_value.name or attr_name) for a in agents): + continue + + agent_config = attr_value.get_agent_config_dict() + agent_config.update( + { + "agent_id": attr_value.agent_id if hasattr(attr_value, "agent_id") else None, + "name": attr_value.name or attr_name, + "workflow_id": self.workflow_id, + } + ) + agents.append(agent_config) + + elif isinstance(attr_value, Team): + if any(t.get("name") == (attr_value.name or attr_name) for t in teams): + continue + + team_config = attr_value.to_platform_dict() + team_config.update( + { + "team_id": attr_value.team_id if hasattr(attr_value, "team_id") else None, + "name": attr_value.name or attr_name, + "workflow_id": self.workflow_id, + } + ) + teams.append(team_config) + + if agents: + config["agents"] = agents + if teams: + config["teams"] = teams + + return config From fd0cc449d6d4f913024325234a0b3bb50ff3dbbe Mon Sep 17 00:00:00 2001 From: Anurag Date: Tue, 13 May 2025 01:31:05 +0530 Subject: [PATCH 31/55] Raise HTTPException in status if appid is not same (#3172) --- libs/agno/agno/playground/async_router.py | 2 +- libs/agno/agno/playground/sync_router.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/agno/agno/playground/async_router.py b/libs/agno/agno/playground/async_router.py index 169d7dff49..0923ee504b 100644 --- a/libs/agno/agno/playground/async_router.py +++ b/libs/agno/agno/playground/async_router.py @@ -143,7 +143,7 @@ async def playground_status(app_id: Optional[str] = None): if active_app_id == app_id: return {"playground": "available"} else: - return {"playground": "unavailable"} + raise HTTPException(status_code=404, detail="Playground not available") @playground_router.get("/agents", response_model=List[AgentGetResponse]) async def get_agents(): diff --git a/libs/agno/agno/playground/sync_router.py b/libs/agno/agno/playground/sync_router.py index 97c90a516c..b763a86e19 100644 --- a/libs/agno/agno/playground/sync_router.py +++ b/libs/agno/agno/playground/sync_router.py @@ -142,7 +142,7 @@ def playground_status(app_id: Optional[str] = None): if active_app_id == app_id: return {"playground": "available"} else: - return {"playground": "unavailable"} + raise HTTPException(status_code=404, detail="Playground not available") @playground_router.get("/agents", response_model=List[AgentGetResponse]) def get_agents(): From 47b543a97fb0cd323f933a1aef680a33bad850d3 Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Tue, 13 May 2025 17:23:19 +0530 Subject: [PATCH 32/55] update --- cookbook/workflows/workflows_playground.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cookbook/workflows/workflows_playground.py b/cookbook/workflows/workflows_playground.py index 88a76ab3bf..8ced4d5479 100644 --- a/cookbook/workflows/workflows_playground.py +++ b/cookbook/workflows/workflows_playground.py @@ -55,7 +55,8 @@ investment_report_generator, startup_idea_validator, ], - # app_id="workflows-playground-app", + app_id="workflows-playground-app", + name="Workflows Playground", ) app = playground.get_app(use_async=False) From 4f911834b7d49a9928083c83d9c4037b013e2c88 Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Thu, 15 May 2025 11:18:39 +0530 Subject: [PATCH 33/55] update --- cookbook/agent_concepts/memory/playground.py | 17 +- .../rag/agentic_rag_agent_ui.py | 18 +- cookbook/agents_from_scratch/playground.py | 14 +- cookbook/playground/agno_assist.py | 16 +- cookbook/playground/app_registration.py | 242 ------------------ cookbook/playground/groq_agents.py | 9 +- 6 files changed, 61 insertions(+), 255 deletions(-) delete mode 100644 cookbook/playground/app_registration.py diff --git a/cookbook/agent_concepts/memory/playground.py b/cookbook/agent_concepts/memory/playground.py index 47b3a700c8..602d0652e7 100644 --- a/cookbook/agent_concepts/memory/playground.py +++ b/cookbook/agent_concepts/memory/playground.py @@ -44,7 +44,20 @@ ) -app = Playground(agents=[agent]).get_app() +playground = Playground( + agents=[ + agent, + ], + app_id="memory-playground-app", + name="Memory Playground", +) +app = playground.get_app() if __name__ == "__main__": - serve_playground_app("playground:app") + # Start the playground server + playground.serve( + app="playground:app", + host="localhost", + port=7777, + reload=True, + ) diff --git a/cookbook/agent_concepts/rag/agentic_rag_agent_ui.py b/cookbook/agent_concepts/rag/agentic_rag_agent_ui.py index fa5311830e..1630e8ed8f 100644 --- a/cookbook/agent_concepts/rag/agentic_rag_agent_ui.py +++ b/cookbook/agent_concepts/rag/agentic_rag_agent_ui.py @@ -46,9 +46,21 @@ markdown=True, ) -app = Playground(agents=[rag_agent]).get_app() +playground = Playground( + agents=[ + rag_agent, + ], + app_id="agentic-rag-agent-ui-app", + name="Agentic RAG Agent UI", +) +app = playground.get_app() if __name__ == "__main__": - # Load the knowledge base: Comment after first run as the knowledge base is already loaded + knowledge_base.load(upsert=True) - serve_playground_app("agentic_rag_agent_ui:app", reload=True) + playground.serve( + app="agentic_rag_agent_ui:app", + host="localhost", + port=7777, + reload=True, + ) diff --git a/cookbook/agents_from_scratch/playground.py b/cookbook/agents_from_scratch/playground.py index 673530af72..f76c0686da 100644 --- a/cookbook/agents_from_scratch/playground.py +++ b/cookbook/agents_from_scratch/playground.py @@ -23,4 +23,16 @@ if __name__ == "__main__": # Run the playground app - serve_playground_app("playground:app", reload=True) + playground = Playground(agents=[simple_agent, + agent_with_tools, + agent_with_knowledge, + agent_with_storage, + agno_assist, + ], + app_id="agents-from-scratch-playground-app", + name="Agents from Scratch Playground", +) +app = playground.get_app() + +if __name__ == "__main__": + playground.serve(app="playground:app", reload=True) diff --git a/cookbook/playground/agno_assist.py b/cookbook/playground/agno_assist.py index 7b3e8a2ada..4f5006ee18 100644 --- a/cookbook/playground/agno_assist.py +++ b/cookbook/playground/agno_assist.py @@ -32,7 +32,7 @@ from agno.embedder.openai import OpenAIEmbedder from agno.knowledge.url import UrlKnowledge from agno.models.openai import OpenAIChat -from agno.playground import Playground, serve_playground_app +from agno.playground import Playground from agno.storage.sqlite import SqliteStorage from agno.tools.dalle import DalleTools from agno.tools.eleven_labs import ElevenLabsTools @@ -180,10 +180,20 @@ ) # Create and configure the playground app -app = Playground(agents=[agno_support, agno_support_voice]).get_app() +playground = Playground( + agents=[agno_support, agno_support_voice], + app_id="agno-assist-playground-app", + name="Agno Assist Playground", +) +app = playground.get_app() if __name__ == "__main__": load_kb = False if load_kb: agent_knowledge.load(recreate=True) - serve_playground_app("agno_assist:app", reload=True) + playground.serve(app="agno_assist:app", reload=True) + + + + + diff --git a/cookbook/playground/app_registration.py b/cookbook/playground/app_registration.py deleted file mode 100644 index 26b85105ec..0000000000 --- a/cookbook/playground/app_registration.py +++ /dev/null @@ -1,242 +0,0 @@ -from textwrap import dedent - -from agno.agent import Agent -from agno.memory.v2 import Memory -from agno.memory.v2.db.postgres import PostgresMemoryDb -from agno.models.anthropic import Claude -from agno.models.google.gemini import Gemini -from agno.models.openai import OpenAIChat -from agno.playground import Playground, serve_playground_app -from agno.storage.postgres import PostgresStorage -from agno.team.team import Team -from agno.tools.duckduckgo import DuckDuckGoTools -from agno.tools.exa import ExaTools -from agno.tools.yfinance import YFinanceTools - -db_url = "postgresql+psycopg://ai:ai@localhost:5532/ai" - -memory_db = PostgresMemoryDb(table_name="memory", db_url=db_url) - -# No need to set the model, it gets set by the agent to the agent's model -memory = Memory(db=memory_db) - - -file_agent = Agent( - name="File Upload Agent", - agent_id="file-upload-agent", - role="Answer questions about the uploaded files", - model=Claude(id="claude-3-7-sonnet-latest"), - storage=PostgresStorage( - table_name="agent_sessions", db_url=db_url, auto_upgrade_schema=True - ), - memory=memory, - enable_user_memories=True, - instructions=[ - "You are an AI agent that can analyze files.", - "You are given a file and you need to answer questions about the file.", - ], - show_tool_calls=True, - markdown=True, -) - -video_agent = Agent( - name="Video Understanding Agent", - model=Gemini(id="gemini-2.0-flash"), - agent_id="video-understanding-agent", - role="Answer questions about video files", - storage=PostgresStorage( - table_name="agent_sessions", db_url=db_url, auto_upgrade_schema=True - ), - memory=memory, - enable_user_memories=True, - add_history_to_messages=True, - add_datetime_to_instructions=True, - show_tool_calls=True, - markdown=True, -) - -audio_agent = Agent( - name="Audio Understanding Agent", - agent_id="audio-understanding-agent", - role="Answer questions about audio files", - model=OpenAIChat(id="gpt-4o-audio-preview"), - storage=PostgresStorage( - table_name="agent_sessions", db_url=db_url, auto_upgrade_schema=True - ), - memory=memory, - enable_user_memories=True, - add_history_to_messages=True, - add_datetime_to_instructions=True, - show_tool_calls=True, - markdown=True, -) - -web_agent = Agent( - name="Web Agent", - role="Search the web for information", - model=OpenAIChat(id="gpt-4o"), - tools=[DuckDuckGoTools()], - agent_id="web_agent", - instructions=[ - "You are an experienced web researcher and news analyst!", - ], - memory=memory, - enable_user_memories=True, - show_tool_calls=True, - markdown=True, - storage=PostgresStorage( - table_name="web_agent", db_url=db_url, auto_upgrade_schema=True - ), -) - -finance_agent = Agent( - name="Finance Agent", - role="Get financial data", - agent_id="finance_agent", - model=OpenAIChat(id="gpt-4o"), - tools=[ - YFinanceTools(stock_price=True, analyst_recommendations=True, company_info=True) - ], - instructions=[ - "You are a skilled financial analyst with expertise in market data!", - "Follow these steps when analyzing financial data:", - "Start with the latest stock price, trading volume, and daily range", - "Present detailed analyst recommendations and consensus target prices", - "Include key metrics: P/E ratio, market cap, 52-week range", - "Analyze trading patterns and volume trends", - ], - memory=memory, - enable_user_memories=True, - show_tool_calls=True, - markdown=True, -) - -simple_agent = Agent( - name="Simple Agent", - role="Simple agent", - model=OpenAIChat(id="gpt-4o"), - instructions=["You are a simple agent"], - memory=memory, - enable_user_memories=True, -) - -research_agent = Agent( - name="Research Agent", - role="Research agent", - model=OpenAIChat(id="gpt-4o"), - instructions=["You are a research agent"], - tools=[DuckDuckGoTools(), ExaTools()], - agent_id="research_agent", - memory=memory, - enable_user_memories=True, -) - -research_team = Team( - name="Research Team", - description="A team of agents that research the web", - members=[research_agent, simple_agent], - model=OpenAIChat(id="gpt-4o"), - mode="coordinate", - team_id="research_team", - success_criteria=dedent("""\ - A comprehensive research report with clear sections and data-driven insights. - """), - instructions=[ - "You are the lead researcher of a research team!", - ], - memory=memory, - enable_user_memories=True, - add_datetime_to_instructions=True, - show_tool_calls=True, - markdown=True, - enable_agentic_context=True, - storage=PostgresStorage( - table_name="research_team", - db_url=db_url, - mode="team", - auto_upgrade_schema=True, - ), -) - -multimodal_team = Team( - name="Multimodal Team", - description="A team of agents that can handle multiple modalities", - members=[file_agent, audio_agent, video_agent], - model=OpenAIChat(id="gpt-4o"), - mode="route", - team_id="multimodal_team", - success_criteria=dedent("""\ - A comprehensive report with clear sections and data-driven insights. - """), - instructions=[ - "You are the lead editor of a prestigious financial news desk!", - ], - memory=memory, - enable_user_memories=True, - storage=PostgresStorage( - table_name="multimodal_team", - db_url=db_url, - mode="team", - auto_upgrade_schema=True, - ), -) -financial_news_team = Team( - name="Financial News Team", - description="A team of agents that search the web for financial news and analyze it.", - members=[ - web_agent, - finance_agent, - research_agent, - file_agent, - audio_agent, - video_agent, - ], - model=OpenAIChat(id="gpt-4o"), - mode="route", - team_id="financial_news_team", - instructions=[ - "You are the lead editor of a prestigious financial news desk!", - "If you are given a file send it to the file agent.", - "If you are given an audio file send it to the audio agent.", - "If you are given a video file send it to the video agent.", - "Use USD as currency.", - "If the user is just being conversational, you should respond directly WITHOUT forwarding a task to a member.", - ], - add_datetime_to_instructions=True, - show_tool_calls=True, - markdown=True, - enable_agentic_context=True, - show_members_responses=True, - storage=PostgresStorage( - table_name="financial_news_team", - db_url=db_url, - mode="team", - auto_upgrade_schema=True, - ), - memory=memory, - enable_user_memories=True, - expected_output="A good financial news report.", - context="use USD as currency", -) - -# Create a single Playground instance to avoid duplication -playground = Playground( - teams=[research_team, financial_news_team, multimodal_team], - agents=[web_agent, finance_agent, research_agent, simple_agent], - name="App Registration Demo app", - description="This is a demo app for the App Registration.", - app_id="app-registration-demo-app", - monitoring=True, -) - -# Get the FastAPI app -app = playground.get_app(use_async=False) - -if __name__ == "__main__": - # Start the playground server - playground.serve( - app="app_registration:app", - host="localhost", - port=7777, - reload=True, - ) diff --git a/cookbook/playground/groq_agents.py b/cookbook/playground/groq_agents.py index 17eb6d8e8f..4d32676387 100644 --- a/cookbook/playground/groq_agents.py +++ b/cookbook/playground/groq_agents.py @@ -91,9 +91,10 @@ markdown=True, ) -app = Playground(agents=[finance_agent, youtube_agent, web_agent]).get_app( - use_async=False -) +playground = Playground(agents=[finance_agent, youtube_agent, web_agent]).get_app( + use_async=False + ) if __name__ == "__main__": - serve_playground_app("groq_agents:app", reload=True) + + playground.serve(app="groq_agents:app", reload=True) From f5337910968ee5ab24978a2d95c364d186395be7 Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Thu, 15 May 2025 13:07:42 +0530 Subject: [PATCH 34/55] update --- libs/agno/agno/agent/agent.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/agno/agno/agent/agent.py b/libs/agno/agno/agent/agent.py index d8520476c3..74aa913d99 100644 --- a/libs/agno/agno/agent/agent.py +++ b/libs/agno/agno/agent/agent.py @@ -5961,7 +5961,7 @@ def get_agent_config_dict(self) -> Dict[str, Any]: "name": self.model.__class__.__name__, "id": self.model.id, "provider": self.model.provider, - "response_format": self.model.response_format, + } payload = { From b783e5cdfcc8c1f188c5390d523889350674bbbb Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Thu, 15 May 2025 14:44:20 +0530 Subject: [PATCH 35/55] update --- cookbook/playground/blog_to_podcast.py | 15 ++++++++------- cookbook/playground/demo.py | 19 +++++++------------ cookbook/playground/gemini_agents.py | 5 +++-- cookbook/playground/grok_agents.py | 5 +++-- cookbook/playground/groq_agents.py | 7 +++---- cookbook/playground/mcp_demo.py | 4 ++-- cookbook/playground/multimodal_agents.py | 7 ++++--- cookbook/playground/ollama_agents.py | 8 +++++--- cookbook/playground/reasoning_demo.py | 9 ++++++--- cookbook/playground/teams_demo.py | 16 +++++++++++----- cookbook/playground/upload_files.py | 5 +++-- libs/agno/agno/agent/agent.py | 19 +++++++------------ libs/agno/agno/api/workflows.py | 3 --- libs/agno/agno/playground/playground.py | 3 ++- libs/agno/agno/team/team.py | 6 ++++-- 15 files changed, 68 insertions(+), 63 deletions(-) diff --git a/cookbook/playground/blog_to_podcast.py b/cookbook/playground/blog_to_podcast.py index d44ff77d14..1b4d45c564 100644 --- a/cookbook/playground/blog_to_podcast.py +++ b/cookbook/playground/blog_to_podcast.py @@ -1,6 +1,6 @@ from agno.agent import Agent from agno.models.openai import OpenAIChat -from agno.playground import Playground, serve_playground_app +from agno.playground import Playground from agno.storage.sqlite import SqliteStorage from agno.tools.eleven_labs import ElevenLabsTools from agno.tools.firecrawl import FirecrawlTools @@ -42,11 +42,12 @@ ), ) -app = Playground( - agents=[ - blog_to_podcast_agent, - ] -).get_app(use_async=False) +playground = Playground( + agents=[blog_to_podcast_agent], + app_id="blog-to-podcast-playground-app", + name="Blog to Podcast Playground", +) +app = playground.get_app() if __name__ == "__main__": - serve_playground_app("blog_to_podcast:app", reload=True) + playground.serve(app="blog_to_podcast:app", reload=True) diff --git a/cookbook/playground/demo.py b/cookbook/playground/demo.py index e3eee218b5..94df7e1836 100644 --- a/cookbook/playground/demo.py +++ b/cookbook/playground/demo.py @@ -216,17 +216,12 @@ class MovieScript(BaseModel): response_model=MovieScript, ) -app = Playground( - agents=[ - simple_agent, - web_agent, - finance_agent, - youtube_agent, - research_agent, - image_agent, - movie_writer, - ], -).get_app() +playground = Playground( + agents=[simple_agent, web_agent, finance_agent, youtube_agent, research_agent, image_agent, movie_writer], + app_id="demo-playground-app", + name="Demo Playground", +) +app = playground.get_app() if __name__ == "__main__": - serve_playground_app("demo:app", reload=True) + playground.serve(app="demo:app", reload=True) diff --git a/cookbook/playground/gemini_agents.py b/cookbook/playground/gemini_agents.py index c001eb9d9a..3cf7c9cd6e 100644 --- a/cookbook/playground/gemini_agents.py +++ b/cookbook/playground/gemini_agents.py @@ -11,7 +11,8 @@ debug_mode=True, ) -app = Playground(agents=[finance_agent]).get_app(use_async=False) +playground = Playground(agents=[finance_agent]) +app = playground.get_app(use_async=False) if __name__ == "__main__": - serve_playground_app("gemini_agents:app", reload=True) + playground.serve(app="gemini_agents:app", reload=True) diff --git a/cookbook/playground/grok_agents.py b/cookbook/playground/grok_agents.py index ea3f64da1a..23dd0076e5 100644 --- a/cookbook/playground/grok_agents.py +++ b/cookbook/playground/grok_agents.py @@ -90,7 +90,8 @@ markdown=True, ) -app = Playground(agents=[finance_agent, youtube_agent, web_agent]).get_app() +playground = Playground(agents=[finance_agent, youtube_agent, web_agent]) +app = playground.get_app() if __name__ == "__main__": - serve_playground_app("grok_agents:app", reload=True) + playground.serve(app="grok_agents:app", reload=True) diff --git a/cookbook/playground/groq_agents.py b/cookbook/playground/groq_agents.py index 4d32676387..db1eb2d142 100644 --- a/cookbook/playground/groq_agents.py +++ b/cookbook/playground/groq_agents.py @@ -91,10 +91,9 @@ markdown=True, ) -playground = Playground(agents=[finance_agent, youtube_agent, web_agent]).get_app( - use_async=False - ) +playground = Playground(agents=[finance_agent, youtube_agent, web_agent]) +app = playground.get_app(use_async=False) if __name__ == "__main__": - playground.serve(app="groq_agents:app", reload=True) + playground.serve(app="groq_agents:app", reload=True) diff --git a/cookbook/playground/mcp_demo.py b/cookbook/playground/mcp_demo.py index d5a8a09ee3..f33b2fa5c5 100644 --- a/cookbook/playground/mcp_demo.py +++ b/cookbook/playground/mcp_demo.py @@ -52,10 +52,10 @@ async def run_server() -> None: ) playground = Playground(agents=[agent]) - app = playground.get_app() + playground.get_app() # Serve the app while keeping the MCPTools context manager alive - serve_playground_app(app) + playground.serve(app="mcp_demo:app", reload=True) if __name__ == "__main__": diff --git a/cookbook/playground/multimodal_agents.py b/cookbook/playground/multimodal_agents.py index f47366c274..1dcb16d7f9 100644 --- a/cookbook/playground/multimodal_agents.py +++ b/cookbook/playground/multimodal_agents.py @@ -176,7 +176,7 @@ ) -app = Playground( +playground= Playground( agents=[ image_agent, ml_gif_agent, @@ -186,7 +186,8 @@ gif_agent, audio_agent, ] -).get_app(use_async=False) +) +app=playground.get_app(use_async=False) if __name__ == "__main__": - serve_playground_app("multimodal_agents:app", reload=True) + playground.serve(app="multimodal_agents:app", reload=True) diff --git a/cookbook/playground/ollama_agents.py b/cookbook/playground/ollama_agents.py index 96c9263e8d..1e9cf08143 100644 --- a/cookbook/playground/ollama_agents.py +++ b/cookbook/playground/ollama_agents.py @@ -2,7 +2,7 @@ from agno.agent import Agent from agno.models.ollama import Ollama -from agno.playground import Playground, serve_playground_app +from agno.playground import Playground from agno.storage.sqlite import SqliteStorage from agno.tools.duckduckgo import DuckDuckGoTools from agno.tools.yfinance import YFinanceTools @@ -88,7 +88,9 @@ markdown=True, ) -app = Playground(agents=[web_agent, finance_agent, youtube_agent]).get_app() +playground = Playground(agents=[web_agent, finance_agent, youtube_agent], name="Ollama Agents", description="A playground for ollama agents", app_id="ollama-agents") +app = playground.get_app(use_async=False) + if __name__ == "__main__": - serve_playground_app("ollama_agents:app", reload=True) + playground.serve(app="ollama_agents:app", reload=True) diff --git a/cookbook/playground/reasoning_demo.py b/cookbook/playground/reasoning_demo.py index 6fdbdb2070..de5e6796f4 100644 --- a/cookbook/playground/reasoning_demo.py +++ b/cookbook/playground/reasoning_demo.py @@ -222,7 +222,7 @@ ) -app = Playground( +playground = Playground( agents=[ cot_agent, reasoning_tool_agent, @@ -231,11 +231,14 @@ thinking_tool_agent, ], teams=[reasoning_finance_team], -).get_app() + name="Reasoning Demo", + description="A playground for reasoning", +) +app = playground.get_app() if __name__ == "__main__": asyncio.run(agno_docs.aload(recreate=True)) - serve_playground_app("reasoning_demo:app", reload=True) + playground.serve(app="reasoning_demo:app", reload=True) # reasoning_tool_agent diff --git a/cookbook/playground/teams_demo.py b/cookbook/playground/teams_demo.py index 157333e188..702db964db 100644 --- a/cookbook/playground/teams_demo.py +++ b/cookbook/playground/teams_demo.py @@ -218,10 +218,16 @@ expected_output="A good financial news report.", ) -app = Playground( - teams=[research_team, financial_news_team, multimodal_team], - agents=[web_agent, finance_agent, research_agent, simple_agent], -).get_app() + +playground = Playground( + agents=[simple_agent, web_agent, finance_agent, research_agent], + teams=[research_team, multimodal_team, financial_news_team], + app_id="teams-demo-playground-app", + name="Teams Demo Playground", + description="A playground for teams and agents", +) +app = playground.get_app() if __name__ == "__main__": - serve_playground_app("teams_demo:app", reload=True) + playground.serve(app="teams_demo:app", reload=True) + diff --git a/cookbook/playground/upload_files.py b/cookbook/playground/upload_files.py index 41d1c82e69..69b884d97f 100644 --- a/cookbook/playground/upload_files.py +++ b/cookbook/playground/upload_files.py @@ -77,7 +77,8 @@ markdown=True, ) -app = Playground(agents=[file_agent, audio_agent, video_agent]).get_app() +playground = Playground(agents=[file_agent, audio_agent, video_agent], name="Upload Files Playground", description="Upload files and ask questions about them" ,app_id="upload-files-playground") +app = playground.get_app() if __name__ == "__main__": - serve_playground_app("upload_files:app", reload=True) + playground.serve(app="upload_files:app", reload=True) diff --git a/libs/agno/agno/agent/agent.py b/libs/agno/agno/agent/agent.py index 74aa913d99..0c8e02d4a2 100644 --- a/libs/agno/agno/agent/agent.py +++ b/libs/agno/agno/agent/agent.py @@ -5968,24 +5968,19 @@ def get_agent_config_dict(self) -> Dict[str, Any]: "instructions": self.instructions if self.instructions is not None else [], "tools": tools, "memory": { - "name": self.memory.__class__.__name__ if self.memory is not None else None, - } - if self.memory is not None - else None, + "name": self.memory.__class__.__name__, + } if self.memory is not None else None, "storage": { - "name": self.storage.__class__.__name__ if self.storage is not None else None, - } - if self.storage is not None - else None, + "name": self.storage.__class__.__name__, + } if self.storage is not None else None, "knowledge": { - "name": self.knowledge.__class__.__name__ if self.knowledge is not None else None, - } - if self.knowledge is not None - else None, + "name": self.knowledge.__class__.__name__, + } if self.knowledge is not None else None, "model": model, "name": self.name, "description": self.description, } + payload = {k: v for k, v in payload.items() if v is not None} return payload async def acli_app( diff --git a/libs/agno/agno/api/workflows.py b/libs/agno/agno/api/workflows.py index 3e92f6cced..ade6bc382f 100644 --- a/libs/agno/agno/api/workflows.py +++ b/libs/agno/agno/api/workflows.py @@ -11,9 +11,6 @@ def create_workflow(workflow: WorkflowCreate) -> None: with api.AuthenticatedClient() as api_client: try: - print( - f"Creating Workflow**********************************************************, {workflow.workflow_id}" - ) api_client.post( ApiRoutes.WORKFLOW_CREATE, json=workflow.model_dump(exclude_none=True), diff --git a/libs/agno/agno/playground/playground.py b/libs/agno/agno/playground/playground.py index 04bdaff7d9..4a0aed60ab 100644 --- a/libs/agno/agno/playground/playground.py +++ b/libs/agno/agno/playground/playground.py @@ -37,7 +37,7 @@ def __init__( app_id: Optional[str] = None, name: Optional[str] = None, description: Optional[str] = None, - monitoring: bool = False, + monitoring: bool = True, ): if not agents and not workflows and not teams: raise ValueError("Either agents, teams or workflows must be provided.") @@ -237,6 +237,7 @@ def to_dict(self) -> Dict[str, Any]: "type": "playground", "description": self.description, } + payload = {k: v for k, v in payload.items() if v is not None} return payload diff --git a/libs/agno/agno/team/team.py b/libs/agno/agno/team/team.py index 988b6ec0bc..54279828e2 100644 --- a/libs/agno/agno/team/team.py +++ b/libs/agno/agno/team/team.py @@ -6794,7 +6794,7 @@ async def _aregister_team(self) -> None: log_debug(f"Could not create team on platform: {e}") def to_platform_dict(self) -> Dict[str, Any]: - return { + payload = { "members": [ { **( @@ -6836,5 +6836,7 @@ def to_platform_dict(self) -> Dict[str, Any]: "description": self.description, "storage": self.storage.__class__.__name__ if self.storage is not None else None, # "tools": [tool.to_dict() for tool in self.tools] if self.tools is not None else None, - # "memory": self.memory.to_dict() if self.memory is not None else None, + "memory": self.memory.to_dict() if self.memory is not None else None, } + payload = {k: v for k, v in payload.items() if v is not None} + return payload From cef7766897d144f550f5a027fbc694759b6be713 Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Thu, 15 May 2025 14:52:26 +0530 Subject: [PATCH 36/55] update --- cookbook/playground/audio_conversation_agent.py | 5 +++-- cookbook/playground/azure_openai_agents.py | 12 ++++++++---- cookbook/playground/basic.py | 12 ++++++++---- cookbook/playground/blog_to_podcast.py | 1 + cookbook/playground/coding_agent.py | 5 +++-- cookbook/playground/demo.py | 1 + cookbook/playground/gemini_agents.py | 2 +- cookbook/playground/grok_agents.py | 2 +- cookbook/playground/groq_agents.py | 2 +- cookbook/playground/mcp_demo.py | 2 +- cookbook/playground/multimodal_agents.py | 5 ++++- cookbook/playground/reasoning_demo.py | 1 + cookbook/reasoning/tools/thinking_playground.py | 5 +++-- 13 files changed, 36 insertions(+), 19 deletions(-) diff --git a/cookbook/playground/audio_conversation_agent.py b/cookbook/playground/audio_conversation_agent.py index 9acd94c275..6a89535d4c 100644 --- a/cookbook/playground/audio_conversation_agent.py +++ b/cookbook/playground/audio_conversation_agent.py @@ -19,7 +19,8 @@ ), ) -app = Playground(agents=[audio_and_text_agent]).get_app() +playground = Playground(agents=[audio_and_text_agent], name="Audio Conversation Agent", description="A playground for audio conversation agent", app_id="audio-conversation-agent") +app = playground.get_app() if __name__ == "__main__": - serve_playground_app("audio_conversation_agent:app", reload=True) + playground.serve(app="audio_conversation_agent:app", reload=True) diff --git a/cookbook/playground/azure_openai_agents.py b/cookbook/playground/azure_openai_agents.py index f6e3f8174b..17441f2ef6 100644 --- a/cookbook/playground/azure_openai_agents.py +++ b/cookbook/playground/azure_openai_agents.py @@ -149,9 +149,13 @@ markdown=True, ) -app = Playground( - agents=[web_agent, finance_agent, youtube_agent, research_agent, image_agent] -).get_app() +playground = Playground( + agents=[web_agent, finance_agent, youtube_agent, research_agent, image_agent], + name="Azure OpenAI Agents", + description="A playground for Azure OpenAI agents", + app_id="azure-openai-agents", +) +app = playground.get_app() if __name__ == "__main__": - serve_playground_app("azure_openai_agents:app", reload=True) + playground.serve(app="azure_openai_agents:app", reload=True) diff --git a/cookbook/playground/basic.py b/cookbook/playground/basic.py index e5e05967a9..53cd263d3b 100644 --- a/cookbook/playground/basic.py +++ b/cookbook/playground/basic.py @@ -36,11 +36,15 @@ markdown=True, ) -app = Playground( +playground = Playground( agents=[ basic_agent, - ] -).get_app() + ], + name="Basic Agent", + description="A playground for basic agent", + app_id="basic-agent", +) +app = playground.get_app() if __name__ == "__main__": - serve_playground_app("basic:app", reload=True) + playground.serve(app="basic:app", reload=True) diff --git a/cookbook/playground/blog_to_podcast.py b/cookbook/playground/blog_to_podcast.py index 1b4d45c564..3162631e5f 100644 --- a/cookbook/playground/blog_to_podcast.py +++ b/cookbook/playground/blog_to_podcast.py @@ -46,6 +46,7 @@ agents=[blog_to_podcast_agent], app_id="blog-to-podcast-playground-app", name="Blog to Podcast Playground", + description="A playground for blog to podcast", ) app = playground.get_app() diff --git a/cookbook/playground/coding_agent.py b/cookbook/playground/coding_agent.py index 0d69100bcb..ff804e9213 100644 --- a/cookbook/playground/coding_agent.py +++ b/cookbook/playground/coding_agent.py @@ -26,7 +26,8 @@ ), ) -app = Playground(agents=[coding_agent]).get_app() +playground = Playground(agents=[coding_agent], name="Coding Agent", description="A playground for coding agent", app_id="coding-agent") +app = playground.get_app() if __name__ == "__main__": - serve_playground_app("coding_agent:app", reload=True) + playground.serve(app="coding_agent:app", reload=True) diff --git a/cookbook/playground/demo.py b/cookbook/playground/demo.py index 94df7e1836..7b3915a7a4 100644 --- a/cookbook/playground/demo.py +++ b/cookbook/playground/demo.py @@ -220,6 +220,7 @@ class MovieScript(BaseModel): agents=[simple_agent, web_agent, finance_agent, youtube_agent, research_agent, image_agent, movie_writer], app_id="demo-playground-app", name="Demo Playground", + description="A playground for demo", ) app = playground.get_app() diff --git a/cookbook/playground/gemini_agents.py b/cookbook/playground/gemini_agents.py index 3cf7c9cd6e..2638f3899c 100644 --- a/cookbook/playground/gemini_agents.py +++ b/cookbook/playground/gemini_agents.py @@ -11,7 +11,7 @@ debug_mode=True, ) -playground = Playground(agents=[finance_agent]) +playground = Playground(agents=[finance_agent], name="Gemini Agents", description="A playground for Gemini agents", app_id="gemini-agents") app = playground.get_app(use_async=False) if __name__ == "__main__": diff --git a/cookbook/playground/grok_agents.py b/cookbook/playground/grok_agents.py index 23dd0076e5..523ce678a8 100644 --- a/cookbook/playground/grok_agents.py +++ b/cookbook/playground/grok_agents.py @@ -90,7 +90,7 @@ markdown=True, ) -playground = Playground(agents=[finance_agent, youtube_agent, web_agent]) +playground = Playground(agents=[finance_agent, youtube_agent, web_agent], name="Grok Agents", description="A playground for Grok agents", app_id="grok-agents") app = playground.get_app() if __name__ == "__main__": diff --git a/cookbook/playground/groq_agents.py b/cookbook/playground/groq_agents.py index db1eb2d142..ada5ae8019 100644 --- a/cookbook/playground/groq_agents.py +++ b/cookbook/playground/groq_agents.py @@ -91,7 +91,7 @@ markdown=True, ) -playground = Playground(agents=[finance_agent, youtube_agent, web_agent]) +playground = Playground(agents=[finance_agent, youtube_agent, web_agent], name="Groq Agents", description="A playground for Groq agents", app_id="groq-agents") app = playground.get_app(use_async=False) if __name__ == "__main__": diff --git a/cookbook/playground/mcp_demo.py b/cookbook/playground/mcp_demo.py index f33b2fa5c5..493a963ead 100644 --- a/cookbook/playground/mcp_demo.py +++ b/cookbook/playground/mcp_demo.py @@ -51,7 +51,7 @@ async def run_server() -> None: markdown=True, ) - playground = Playground(agents=[agent]) + playground = Playground(agents=[agent], name="MCP Demo", description="A playground for MCP", app_id="mcp-demo") playground.get_app() # Serve the app while keeping the MCPTools context manager alive diff --git a/cookbook/playground/multimodal_agents.py b/cookbook/playground/multimodal_agents.py index 1dcb16d7f9..622ed87123 100644 --- a/cookbook/playground/multimodal_agents.py +++ b/cookbook/playground/multimodal_agents.py @@ -185,7 +185,10 @@ fal_agent, gif_agent, audio_agent, - ] + ], + name="Multimodal Agents", + description="A playground for multimodal agents", + app_id="multimodal-agents", ) app=playground.get_app(use_async=False) diff --git a/cookbook/playground/reasoning_demo.py b/cookbook/playground/reasoning_demo.py index de5e6796f4..bc176bea7f 100644 --- a/cookbook/playground/reasoning_demo.py +++ b/cookbook/playground/reasoning_demo.py @@ -232,6 +232,7 @@ ], teams=[reasoning_finance_team], name="Reasoning Demo", + app_id="reasoning-demo", description="A playground for reasoning", ) app = playground.get_app() diff --git a/cookbook/reasoning/tools/thinking_playground.py b/cookbook/reasoning/tools/thinking_playground.py index 35790a26d9..a6e447b65b 100644 --- a/cookbook/reasoning/tools/thinking_playground.py +++ b/cookbook/reasoning/tools/thinking_playground.py @@ -45,7 +45,8 @@ markdown=True, ) -app = Playground(agents=[thinking_web_agent, thinking_finance_agent]).get_app() +playground = Playground(agents=[thinking_web_agent, thinking_finance_agent], name="Thinking Playground", description="A playground for thinking", app_id="thinking-playground") +app = playground.get_app() if __name__ == "__main__": - serve_playground_app("thinking_playground:app", reload=True) + playground.serve(app="thinking_playground:app", reload=True) From af07b1e55133658775b6c128fcb9c1e8964892b7 Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Thu, 15 May 2025 14:58:05 +0530 Subject: [PATCH 37/55] update --- .../rag/agentic_rag_agent_ui.py | 3 +-- cookbook/agents_from_scratch/playground.py | 20 ++++++++++--------- cookbook/playground/agno_assist.py | 5 ----- .../playground/audio_conversation_agent.py | 7 ++++++- cookbook/playground/blog_to_podcast.py | 2 +- cookbook/playground/coding_agent.py | 7 ++++++- cookbook/playground/demo.py | 12 +++++++++-- cookbook/playground/gemini_agents.py | 7 ++++++- cookbook/playground/grok_agents.py | 7 ++++++- cookbook/playground/groq_agents.py | 10 +++++++--- cookbook/playground/mcp_demo.py | 7 ++++++- cookbook/playground/multimodal_agents.py | 6 +++--- cookbook/playground/ollama_agents.py | 7 ++++++- cookbook/playground/teams_demo.py | 3 +-- cookbook/playground/upload_files.py | 7 ++++++- .../reasoning/tools/thinking_playground.py | 7 ++++++- libs/agno/agno/agent/agent.py | 20 +++++++++---------- libs/agno/agno/playground/async_router.py | 5 ++++- libs/agno/agno/playground/sync_router.py | 5 ++++- 19 files changed, 99 insertions(+), 48 deletions(-) diff --git a/cookbook/agent_concepts/rag/agentic_rag_agent_ui.py b/cookbook/agent_concepts/rag/agentic_rag_agent_ui.py index 1630e8ed8f..d351fe2376 100644 --- a/cookbook/agent_concepts/rag/agentic_rag_agent_ui.py +++ b/cookbook/agent_concepts/rag/agentic_rag_agent_ui.py @@ -50,13 +50,12 @@ agents=[ rag_agent, ], - app_id="agentic-rag-agent-ui-app", + app_id="agentic-rag-agent-ui-app", name="Agentic RAG Agent UI", ) app = playground.get_app() if __name__ == "__main__": - knowledge_base.load(upsert=True) playground.serve( app="agentic_rag_agent_ui:app", diff --git a/cookbook/agents_from_scratch/playground.py b/cookbook/agents_from_scratch/playground.py index f76c0686da..ce0b12f034 100644 --- a/cookbook/agents_from_scratch/playground.py +++ b/cookbook/agents_from_scratch/playground.py @@ -23,15 +23,17 @@ if __name__ == "__main__": # Run the playground app - playground = Playground(agents=[simple_agent, - agent_with_tools, - agent_with_knowledge, - agent_with_storage, - agno_assist, - ], - app_id="agents-from-scratch-playground-app", - name="Agents from Scratch Playground", -) + playground = Playground( + agents=[ + simple_agent, + agent_with_tools, + agent_with_knowledge, + agent_with_storage, + agno_assist, + ], + app_id="agents-from-scratch-playground-app", + name="Agents from Scratch Playground", + ) app = playground.get_app() if __name__ == "__main__": diff --git a/cookbook/playground/agno_assist.py b/cookbook/playground/agno_assist.py index 4f5006ee18..cf5eb7a7e1 100644 --- a/cookbook/playground/agno_assist.py +++ b/cookbook/playground/agno_assist.py @@ -192,8 +192,3 @@ if load_kb: agent_knowledge.load(recreate=True) playground.serve(app="agno_assist:app", reload=True) - - - - - diff --git a/cookbook/playground/audio_conversation_agent.py b/cookbook/playground/audio_conversation_agent.py index 6a89535d4c..b3ee50319b 100644 --- a/cookbook/playground/audio_conversation_agent.py +++ b/cookbook/playground/audio_conversation_agent.py @@ -19,7 +19,12 @@ ), ) -playground = Playground(agents=[audio_and_text_agent], name="Audio Conversation Agent", description="A playground for audio conversation agent", app_id="audio-conversation-agent") +playground = Playground( + agents=[audio_and_text_agent], + name="Audio Conversation Agent", + description="A playground for audio conversation agent", + app_id="audio-conversation-agent", +) app = playground.get_app() if __name__ == "__main__": diff --git a/cookbook/playground/blog_to_podcast.py b/cookbook/playground/blog_to_podcast.py index 3162631e5f..040c7ff8ae 100644 --- a/cookbook/playground/blog_to_podcast.py +++ b/cookbook/playground/blog_to_podcast.py @@ -51,4 +51,4 @@ app = playground.get_app() if __name__ == "__main__": - playground.serve(app="blog_to_podcast:app", reload=True) + playground.serve(app="blog_to_podcast:app", reload=True) diff --git a/cookbook/playground/coding_agent.py b/cookbook/playground/coding_agent.py index ff804e9213..eabb3b784b 100644 --- a/cookbook/playground/coding_agent.py +++ b/cookbook/playground/coding_agent.py @@ -26,7 +26,12 @@ ), ) -playground = Playground(agents=[coding_agent], name="Coding Agent", description="A playground for coding agent", app_id="coding-agent") +playground = Playground( + agents=[coding_agent], + name="Coding Agent", + description="A playground for coding agent", + app_id="coding-agent", +) app = playground.get_app() if __name__ == "__main__": diff --git a/cookbook/playground/demo.py b/cookbook/playground/demo.py index 7b3915a7a4..627488f523 100644 --- a/cookbook/playground/demo.py +++ b/cookbook/playground/demo.py @@ -217,7 +217,15 @@ class MovieScript(BaseModel): ) playground = Playground( - agents=[simple_agent, web_agent, finance_agent, youtube_agent, research_agent, image_agent, movie_writer], + agents=[ + simple_agent, + web_agent, + finance_agent, + youtube_agent, + research_agent, + image_agent, + movie_writer, + ], app_id="demo-playground-app", name="Demo Playground", description="A playground for demo", @@ -225,4 +233,4 @@ class MovieScript(BaseModel): app = playground.get_app() if __name__ == "__main__": - playground.serve(app="demo:app", reload=True) + playground.serve(app="demo:app", reload=True) diff --git a/cookbook/playground/gemini_agents.py b/cookbook/playground/gemini_agents.py index 2638f3899c..3a0420e7a9 100644 --- a/cookbook/playground/gemini_agents.py +++ b/cookbook/playground/gemini_agents.py @@ -11,7 +11,12 @@ debug_mode=True, ) -playground = Playground(agents=[finance_agent], name="Gemini Agents", description="A playground for Gemini agents", app_id="gemini-agents") +playground = Playground( + agents=[finance_agent], + name="Gemini Agents", + description="A playground for Gemini agents", + app_id="gemini-agents", +) app = playground.get_app(use_async=False) if __name__ == "__main__": diff --git a/cookbook/playground/grok_agents.py b/cookbook/playground/grok_agents.py index 523ce678a8..f1a1d77d94 100644 --- a/cookbook/playground/grok_agents.py +++ b/cookbook/playground/grok_agents.py @@ -90,7 +90,12 @@ markdown=True, ) -playground = Playground(agents=[finance_agent, youtube_agent, web_agent], name="Grok Agents", description="A playground for Grok agents", app_id="grok-agents") +playground = Playground( + agents=[finance_agent, youtube_agent, web_agent], + name="Grok Agents", + description="A playground for Grok agents", + app_id="grok-agents", +) app = playground.get_app() if __name__ == "__main__": diff --git a/cookbook/playground/groq_agents.py b/cookbook/playground/groq_agents.py index ada5ae8019..4412394db9 100644 --- a/cookbook/playground/groq_agents.py +++ b/cookbook/playground/groq_agents.py @@ -91,9 +91,13 @@ markdown=True, ) -playground = Playground(agents=[finance_agent, youtube_agent, web_agent], name="Groq Agents", description="A playground for Groq agents", app_id="groq-agents") +playground = Playground( + agents=[finance_agent, youtube_agent, web_agent], + name="Groq Agents", + description="A playground for Groq agents", + app_id="groq-agents", +) app = playground.get_app(use_async=False) if __name__ == "__main__": - - playground.serve(app="groq_agents:app", reload=True) + playground.serve(app="groq_agents:app", reload=True) diff --git a/cookbook/playground/mcp_demo.py b/cookbook/playground/mcp_demo.py index 493a963ead..0348f804ef 100644 --- a/cookbook/playground/mcp_demo.py +++ b/cookbook/playground/mcp_demo.py @@ -51,7 +51,12 @@ async def run_server() -> None: markdown=True, ) - playground = Playground(agents=[agent], name="MCP Demo", description="A playground for MCP", app_id="mcp-demo") + playground = Playground( + agents=[agent], + name="MCP Demo", + description="A playground for MCP", + app_id="mcp-demo", + ) playground.get_app() # Serve the app while keeping the MCPTools context manager alive diff --git a/cookbook/playground/multimodal_agents.py b/cookbook/playground/multimodal_agents.py index 622ed87123..02c1271183 100644 --- a/cookbook/playground/multimodal_agents.py +++ b/cookbook/playground/multimodal_agents.py @@ -176,7 +176,7 @@ ) -playground= Playground( +playground = Playground( agents=[ image_agent, ml_gif_agent, @@ -190,7 +190,7 @@ description="A playground for multimodal agents", app_id="multimodal-agents", ) -app=playground.get_app(use_async=False) +app = playground.get_app(use_async=False) if __name__ == "__main__": - playground.serve(app="multimodal_agents:app", reload=True) + playground.serve(app="multimodal_agents:app", reload=True) diff --git a/cookbook/playground/ollama_agents.py b/cookbook/playground/ollama_agents.py index 1e9cf08143..e014538fbe 100644 --- a/cookbook/playground/ollama_agents.py +++ b/cookbook/playground/ollama_agents.py @@ -88,7 +88,12 @@ markdown=True, ) -playground = Playground(agents=[web_agent, finance_agent, youtube_agent], name="Ollama Agents", description="A playground for ollama agents", app_id="ollama-agents") +playground = Playground( + agents=[web_agent, finance_agent, youtube_agent], + name="Ollama Agents", + description="A playground for ollama agents", + app_id="ollama-agents", +) app = playground.get_app(use_async=False) diff --git a/cookbook/playground/teams_demo.py b/cookbook/playground/teams_demo.py index 702db964db..61ed090650 100644 --- a/cookbook/playground/teams_demo.py +++ b/cookbook/playground/teams_demo.py @@ -229,5 +229,4 @@ app = playground.get_app() if __name__ == "__main__": - playground.serve(app="teams_demo:app", reload=True) - + playground.serve(app="teams_demo:app", reload=True) diff --git a/cookbook/playground/upload_files.py b/cookbook/playground/upload_files.py index 69b884d97f..b137317ae7 100644 --- a/cookbook/playground/upload_files.py +++ b/cookbook/playground/upload_files.py @@ -77,7 +77,12 @@ markdown=True, ) -playground = Playground(agents=[file_agent, audio_agent, video_agent], name="Upload Files Playground", description="Upload files and ask questions about them" ,app_id="upload-files-playground") +playground = Playground( + agents=[file_agent, audio_agent, video_agent], + name="Upload Files Playground", + description="Upload files and ask questions about them", + app_id="upload-files-playground", +) app = playground.get_app() if __name__ == "__main__": diff --git a/cookbook/reasoning/tools/thinking_playground.py b/cookbook/reasoning/tools/thinking_playground.py index a6e447b65b..a05a9496c9 100644 --- a/cookbook/reasoning/tools/thinking_playground.py +++ b/cookbook/reasoning/tools/thinking_playground.py @@ -45,7 +45,12 @@ markdown=True, ) -playground = Playground(agents=[thinking_web_agent, thinking_finance_agent], name="Thinking Playground", description="A playground for thinking", app_id="thinking-playground") +playground = Playground( + agents=[thinking_web_agent, thinking_finance_agent], + name="Thinking Playground", + description="A playground for thinking", + app_id="thinking-playground", +) app = playground.get_app() if __name__ == "__main__": diff --git a/libs/agno/agno/agent/agent.py b/libs/agno/agno/agent/agent.py index 0c8e02d4a2..ad5d3d4128 100644 --- a/libs/agno/agno/agent/agent.py +++ b/libs/agno/agno/agent/agent.py @@ -621,12 +621,10 @@ def _run( # 1.3 Create a run_id and RunResponse self.run_id = str(uuid4()) - # 1.4 Register the agent on the platform thread = threading.Thread(target=self._register_agent) thread.start() - log_debug(f"Agent Run Start: {run_response.run_id}", center=True) # 2.1 Prepare arguments for the model @@ -643,7 +641,6 @@ def _run( ) run_response.model = self.model.id if self.model is not None else None - # 2.2 Resolve context if self.context is not None and self.resolve_context: self.resolve_run_context() @@ -1349,17 +1346,14 @@ async def _arun( # 1.3 Create a run_id and RunResponse self.run_id = str(uuid4()) - # 1.4 Register the agent on the platform # Create a task to run the agent registration in the background # This won't block the execution flow asyncio.create_task(self._aregister_agent()) - log_debug(f"Async Agent Run Start: {run_response.run_id}", center=True, symbol="*") - # 2.1 Prepare arguments for the model self.set_default_model() response_format = self._get_response_format() @@ -1777,7 +1771,6 @@ async def _arun( # Log Agent Run await self._alog_agent_run(user_id=user_id, session_id=session_id) - log_debug(f"Agent Run End: {run_response.run_id}", center=True, symbol="*") if self.stream_intermediate_steps: @@ -5961,7 +5954,6 @@ def get_agent_config_dict(self) -> Dict[str, Any]: "name": self.model.__class__.__name__, "id": self.model.id, "provider": self.model.provider, - } payload = { @@ -5969,13 +5961,19 @@ def get_agent_config_dict(self) -> Dict[str, Any]: "tools": tools, "memory": { "name": self.memory.__class__.__name__, - } if self.memory is not None else None, + } + if self.memory is not None + else None, "storage": { "name": self.storage.__class__.__name__, - } if self.storage is not None else None, + } + if self.storage is not None + else None, "knowledge": { "name": self.knowledge.__class__.__name__, - } if self.knowledge is not None else None, + } + if self.knowledge is not None + else None, "model": model, "name": self.name, "description": self.description, diff --git a/libs/agno/agno/playground/async_router.py b/libs/agno/agno/playground/async_router.py index 0923ee504b..689a807620 100644 --- a/libs/agno/agno/playground/async_router.py +++ b/libs/agno/agno/playground/async_router.py @@ -114,7 +114,10 @@ async def team_chat_response_streamer( def get_async_playground_router( - agents: Optional[List[Agent]] = None, workflows: Optional[List[Workflow]] = None, teams: Optional[List[Team]] = None, active_app_id: Optional[str] = None + agents: Optional[List[Agent]] = None, + workflows: Optional[List[Workflow]] = None, + teams: Optional[List[Team]] = None, + active_app_id: Optional[str] = None, ) -> APIRouter: playground_router = APIRouter(prefix="/playground", tags=["Playground"]) diff --git a/libs/agno/agno/playground/sync_router.py b/libs/agno/agno/playground/sync_router.py index b763a86e19..1fe67e11c8 100644 --- a/libs/agno/agno/playground/sync_router.py +++ b/libs/agno/agno/playground/sync_router.py @@ -114,7 +114,10 @@ def team_chat_response_streamer( def get_sync_playground_router( - agents: Optional[List[Agent]] = None, workflows: Optional[List[Workflow]] = None, teams: Optional[List[Team]] = None, active_app_id: Optional[str] = None + agents: Optional[List[Agent]] = None, + workflows: Optional[List[Workflow]] = None, + teams: Optional[List[Team]] = None, + active_app_id: Optional[str] = None, ) -> APIRouter: playground_router = APIRouter(prefix="/playground", tags=["Playground"]) if agents is None and workflows is None and teams is None: From 867be50df7837b2ba513d098434a4783ea543d26 Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Mon, 19 May 2025 13:56:29 +0530 Subject: [PATCH 38/55] update --- libs/agno/agno/workflow/workflow.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libs/agno/agno/workflow/workflow.py b/libs/agno/agno/workflow/workflow.py index 1ca7e42b44..d6b7f3ce22 100644 --- a/libs/agno/agno/workflow/workflow.py +++ b/libs/agno/agno/workflow/workflow.py @@ -91,10 +91,12 @@ def __init__( debug_mode: bool = False, monitoring: bool = False, telemetry: bool = True, + app_id: Optional[str] = None, ): self.name = name or self.__class__.__name__ self.workflow_id = workflow_id self.description = description or self.__class__.description + self.app_id = app_id self.user_id = user_id From d3bf39bab6802f58022dae9e0096d78d67c238ae Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Tue, 20 May 2025 14:35:23 +0530 Subject: [PATCH 39/55] update --- libs/agno/agno/agent/agent.py | 8 ++++++++ libs/agno/agno/team/team.py | 14 +++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/libs/agno/agno/agent/agent.py b/libs/agno/agno/agent/agent.py index ad5d3d4128..7dc1441a2f 100644 --- a/libs/agno/agno/agent/agent.py +++ b/libs/agno/agno/agent/agent.py @@ -5961,6 +5961,14 @@ def get_agent_config_dict(self) -> Dict[str, Any]: "tools": tools, "memory": { "name": self.memory.__class__.__name__, + "model": { + "name": self.memory.model.name, + "model": self.memory.model.id, + "provider": self.memory.model.provider, + } + if self.memory.model is not None + else None, + "db": self.memory.db.__dict__() if self.memory.db is not None else None, } if self.memory is not None else None, diff --git a/libs/agno/agno/team/team.py b/libs/agno/agno/team/team.py index 54279828e2..3121e1e6df 100644 --- a/libs/agno/agno/team/team.py +++ b/libs/agno/agno/team/team.py @@ -6836,7 +6836,19 @@ def to_platform_dict(self) -> Dict[str, Any]: "description": self.description, "storage": self.storage.__class__.__name__ if self.storage is not None else None, # "tools": [tool.to_dict() for tool in self.tools] if self.tools is not None else None, - "memory": self.memory.to_dict() if self.memory is not None else None, + "memory": { + "name": self.memory.__class__.__name__, + "model": { + "name": self.memory.model.name, + "model": self.memory.model.id, + "provider": self.memory.model.provider, + } + if self.memory.model is not None + else None, + "db": self.memory.db.__dict__() if self.memory.db is not None else None, + } + if self.memory is not None + else None, } payload = {k: v for k, v in payload.items() if v is not None} return payload From 39041d5c23a226b10c5e80e3789cde12211aa3c0 Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Tue, 20 May 2025 19:55:24 +0530 Subject: [PATCH 40/55] update --- libs/agno/agno/agent/agent.py | 30 ++++++++++++++++++------------ libs/agno/agno/team/team.py | 30 ++++++++++++++++++------------ 2 files changed, 36 insertions(+), 24 deletions(-) diff --git a/libs/agno/agno/agent/agent.py b/libs/agno/agno/agent/agent.py index 7dc1441a2f..47e1260c8d 100644 --- a/libs/agno/agno/agent/agent.py +++ b/libs/agno/agno/agent/agent.py @@ -5959,19 +5959,25 @@ def get_agent_config_dict(self) -> Dict[str, Any]: payload = { "instructions": self.instructions if self.instructions is not None else [], "tools": tools, - "memory": { - "name": self.memory.__class__.__name__, - "model": { - "name": self.memory.model.name, - "model": self.memory.model.id, - "provider": self.memory.model.provider, + "memory": ( + { + "name": self.memory.__class__.__name__, + "model": { + "name": self.memory.model.name, + "model": self.memory.model.id, + "provider": self.memory.model.provider, + } + if self.memory.model + else { + "name": self.model.name, + "model": self.model.id, + "provider": self.model.provider, + }, + "db": self.memory.db.__dict__() if self.memory.db else None, } - if self.memory.model is not None - else None, - "db": self.memory.db.__dict__() if self.memory.db is not None else None, - } - if self.memory is not None - else None, + if self.memory and self.memory.db + else None + ), "storage": { "name": self.storage.__class__.__name__, } diff --git a/libs/agno/agno/team/team.py b/libs/agno/agno/team/team.py index 3121e1e6df..9021e0093b 100644 --- a/libs/agno/agno/team/team.py +++ b/libs/agno/agno/team/team.py @@ -6836,19 +6836,25 @@ def to_platform_dict(self) -> Dict[str, Any]: "description": self.description, "storage": self.storage.__class__.__name__ if self.storage is not None else None, # "tools": [tool.to_dict() for tool in self.tools] if self.tools is not None else None, - "memory": { - "name": self.memory.__class__.__name__, - "model": { - "name": self.memory.model.name, - "model": self.memory.model.id, - "provider": self.memory.model.provider, + "memory": ( + { + "name": self.memory.__class__.__name__, + "model": { + "name": self.memory.model.name, + "model": self.memory.model.id, + "provider": self.memory.model.provider, + } + if self.memory.model + else { + "name": self.model.name, + "model": self.model.id, + "provider": self.model.provider, + }, + "db": self.memory.db.__dict__() if self.memory.db else None, } - if self.memory.model is not None - else None, - "db": self.memory.db.__dict__() if self.memory.db is not None else None, - } - if self.memory is not None - else None, + if self.memory and self.memory.db + else None + ), } payload = {k: v for k, v in payload.items() if v is not None} return payload From b8c9726c6ca6f6b1d07de10a5afbd835fcc89124 Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Wed, 21 May 2025 03:21:23 +0530 Subject: [PATCH 41/55] update --- libs/agno/agno/agent/agent.py | 100 ++--------------- libs/agno/agno/app/playground/app.py | 162 +++++++++++++++++++++++---- 2 files changed, 147 insertions(+), 115 deletions(-) diff --git a/libs/agno/agno/agent/agent.py b/libs/agno/agno/agent/agent.py index 4fdd87703b..7fd6afb33c 100644 --- a/libs/agno/agno/agent/agent.py +++ b/libs/agno/agno/agent/agent.py @@ -598,71 +598,6 @@ def _run( 6. Save output to file if save_response_to_file is set """ - # 1. Prepare the Agent for the run - if isinstance(self.memory, AgentMemory): - self.memory = cast(AgentMemory, self.memory) - else: - self.memory = cast(Memory, self.memory) - # 1.2 Set streaming and stream intermediate steps - - self.stream = self.stream or (stream and self.is_streamable) - self.stream_intermediate_steps = self.stream_intermediate_steps or (stream_intermediate_steps and self.stream) - # 1.3 Create a run_id and RunResponse - self.run_id = str(uuid4()) - - # 1.4 Register the agent on the platform - thread = threading.Thread(target=self._register_agent) - thread.start() - - log_debug(f"Agent Run Start: {run_response.run_id}", center=True) - - # 2.1 Prepare arguments for the model - self.set_default_model() - response_format = self._get_response_format() - self.model = cast(Model, self.model) - - self.determine_tools_for_model( - model=self.model, - session_id=session_id, - user_id=user_id, - async_mode=False, - knowledge_filters=knowledge_filters, - ) - run_response.model = self.model.id if self.model is not None else None - - # 2.2 Resolve context - if self.context is not None and self.resolve_context: - self.resolve_run_context() - - # 3. Read existing session from storage - self.read_from_storage(session_id=session_id, user_id=user_id) - - # 4. Prepare run messages - run_messages: RunMessages = self.get_run_messages( - message=message, - session_id=session_id, - user_id=user_id, - audio=audio, - images=images, - videos=videos, - files=files, - messages=messages, - **kwargs, - ) - if len(run_messages.messages) == 0: - log_error("No messages to be sent to the model.") - - self.run_messages = run_messages - - # 5. Reason about the task if reasoning is enabled - if self.reasoning or self.reasoning_model is not None: - reasoning_generator = self.reason(run_messages=run_messages, session_id=session_id) - - if self.stream: - yield from reasoning_generator - else: - # Consume the generator without yielding - deque(reasoning_generator, maxlen=0) # 1. Reason about the task self._handle_reasoning(run_messages=run_messages, session_id=session_id) @@ -699,6 +634,10 @@ def _run( # 6. Save output to file if save_response_to_file is set self.save_run_response_to_file(message=message, session_id=session_id) + thread = threading.Thread(target=self._register_agent) + thread.start() + + # Log Agent Run self._log_agent_run(user_id=user_id, session_id=session_id) @@ -722,7 +661,6 @@ def _run( log_debug(f"Agent Run End: {run_response.run_id}", center=True, symbol="*") return run_response - def _run_stream( self, run_response: RunResponse, @@ -1059,33 +997,8 @@ async def _arun( """ # 1. Prepare the Agent for the run - if isinstance(self.memory, AgentMemory): - self.memory = cast(AgentMemory, self.memory) - else: - self.memory = cast(Memory, self.memory) - # 1.2 Set streaming and stream intermediate steps - self.stream = self.stream or (stream and self.is_streamable) - self.stream_intermediate_steps = self.stream_intermediate_steps or (stream_intermediate_steps and self.stream) - # 1.3 Create a run_id and RunResponse - self.run_id = str(uuid4()) - - # 1.4 Register the agent on the platform - - # Create a task to run the agent registration in the background - # This won't block the execution flow - asyncio.create_task(self._aregister_agent()) - - log_debug(f"Async Agent Run Start: {run_response.run_id}", center=True, symbol="*") - - # 2.1 Prepare arguments for the model - self.set_default_model() - response_format = self._get_response_format() - self.model = cast(Model, self.model) - - self.determine_tools_for_model( - model=self.model, self.model = cast(Model, self.model) - # 1. Reason about the task if reasoning is enabled + # 1. Reason about the task if reasoning is enabled await self._ahandle_reasoning(run_messages=run_messages, session_id=session_id) # Get the index of the last "user" message in messages_for_run @@ -1120,6 +1033,9 @@ async def _arun( # 6. Save output to file if save_response_to_file is set self.save_run_response_to_file(message=message, session_id=session_id) + # Register Agent + asyncio.create_task(self._aregister_agent()) + # Log Agent Run await self._alog_agent_run(user_id=user_id, session_id=session_id) diff --git a/libs/agno/agno/app/playground/app.py b/libs/agno/agno/app/playground/app.py index 844ec0f015..d57b2d6ecc 100644 --- a/libs/agno/agno/app/playground/app.py +++ b/libs/agno/agno/app/playground/app.py @@ -1,19 +1,27 @@ -from typing import List, Optional, Set +import asyncio +import threading +from os import getenv +from typing import Any, Dict, List, Optional, Set, Union +from urllib.parse import quote +from uuid import uuid4 from fastapi import FastAPI, HTTPException from fastapi.responses import JSONResponse from fastapi.routing import APIRouter +from rich import box +from rich.panel import Panel from starlette.middleware.cors import CORSMiddleware from starlette.requests import Request from agno.agent.agent import Agent -from agno.api.playground import PlaygroundEndpointCreate, create_playground_endpoint +from agno.api.playground import PlaygroundEndpointCreate +from agno.cli.console import console +from agno.cli.settings import agno_cli_settings from agno.app.playground.async_router import get_async_playground_router -from agno.app.playground.settings import PlaygroundSettings +from agno.playground.settings import PlaygroundSettings from agno.app.playground.sync_router import get_sync_playground_router -from agno.app.utils import generate_id from agno.team.team import Team -from agno.utils.log import logger +from agno.utils.log import log_debug, logger from agno.workflow.workflow import Workflow @@ -26,6 +34,10 @@ def __init__( settings: Optional[PlaygroundSettings] = None, api_app: Optional[FastAPI] = None, router: Optional[APIRouter] = None, + app_id: Optional[str] = None, + name: Optional[str] = None, + description: Optional[str] = None, + monitoring: bool = True, ): if not agents and not workflows and not teams: raise ValueError("Either agents, teams or workflows must be provided.") @@ -33,34 +45,64 @@ def __init__( self.agents: Optional[List[Agent]] = agents self.workflows: Optional[List[Workflow]] = workflows self.teams: Optional[List[Team]] = teams - + self.settings: PlaygroundSettings = settings or PlaygroundSettings() + self.api_app: Optional[FastAPI] = api_app + self.router: Optional[APIRouter] = router + self.endpoints_created: Dict[str, Dict[str, str]] = {} + self.app_id: Optional[str] = app_id + self.name: Optional[str] = name + self.monitoring = monitoring + self.description = description + self.set_app_id() if self.agents: for agent in self.agents: + if not agent.app_id: + agent.app_id = self.app_id agent.initialize_agent() if self.teams: for team in self.teams: + if not team.app_id: + team.app_id = self.app_id team.initialize_team() for member in team.members: if isinstance(member, Agent): + if not member.app_id: + member.app_id = self.app_id + + member.team_id = None member.initialize_agent() elif isinstance(member, Team): member.initialize_team() + if self.workflows: for workflow in self.workflows: + if not workflow.app_id: + workflow.app_id = self.app_id if not workflow.workflow_id: workflow.workflow_id = generate_id(workflow.name) - self.settings: PlaygroundSettings = settings or PlaygroundSettings() - self.api_app: Optional[FastAPI] = api_app - self.router: Optional[APIRouter] = router - self.endpoints_created: Set[str] = set() + def set_app_id(self) -> str: + # If app_id is already set, keep it instead of overriding with UUID + if self.app_id is None: + self.app_id = str(uuid4()) + + # Don't override existing app_id + return self.app_id + + def _set_monitoring(self) -> None: + """Override monitoring and telemetry settings based on environment variables.""" + + # Only override if the environment variable is set + monitor_env = getenv("AGNO_MONITOR") + if monitor_env is not None: + self.monitoring = monitor_env.lower() == "true" def get_router(self) -> APIRouter: - return get_sync_playground_router(self.agents, self.workflows, self.teams) + return get_sync_playground_router(self.agents, self.workflows, self.teams, self.app_id) def get_async_router(self) -> APIRouter: - return get_async_playground_router(self.agents, self.workflows, self.teams) + return get_async_playground_router(self.agents, self.workflows, self.teams, self.app_id) def get_app(self, use_async: bool = True, prefix: str = "/v1") -> FastAPI: if not self.api_app: @@ -115,18 +157,92 @@ async def general_exception_handler(request: Request, call_next): return self.api_app - def create_endpoint(self, endpoint: str, prefix: str = "/v1") -> None: - if endpoint in self.endpoints_created: + def serve( + self, + app: Union[str, FastAPI], + *, + scheme: str = "http", + host: str = "localhost", + port: int = 7777, + reload: bool = False, + prefix="/v1", + **kwargs, + ): + import uvicorn + + logger.info(f"Starting playground on {scheme}://{host}:{port}") + # Encode the full endpoint (host:port) + encoded_endpoint = quote(f"{host}:{port}") + self.endpoints_created = PlaygroundEndpointCreate( + endpoint=f"{scheme}://{host}:{port}", playground_data={"prefix": prefix} + ) + + # Create a panel with the playground URL + url = f"{agno_cli_settings.playground_url}?endpoint={encoded_endpoint}" + panel = Panel( + f"[bold green]Playground URL:[/bold green] [link={url}]{url}[/link]", + title="Agent Playground", + expand=False, + border_style="cyan", + box=box.HEAVY, + padding=(2, 2), + ) + + # Print the panel + console.print(panel) + self.set_app_id() + self.register_app_on_platform() + if self.agents: + for agent in self.agents: + agent._register_agent() + if self.teams: + for team in self.teams: + team._register_team() + if self.workflows: + for workflow in self.workflows: + workflow._register_workflow() + uvicorn.run(app=app, host=host, port=port, reload=reload, **kwargs) + + def register_app_on_platform(self) -> None: + self._set_monitoring() + if not self.monitoring: return + from agno.api.app import AppCreate, create_app + try: - logger.info(f"Creating playground endpoint: {endpoint}") - create_playground_endpoint( - playground=PlaygroundEndpointCreate(endpoint=endpoint, playground_data={"prefix": prefix}) - ) + log_debug(f"Creating app on Platform: {self.name}, {self.app_id}") + create_app(app=AppCreate(name=self.name, app_id=self.app_id, config=self.to_dict())) except Exception as e: - logger.error(f"Could not create playground endpoint: {e}") - logger.error("Please try again.") - return - - self.endpoints_created.add(endpoint) + log_debug(f"Could not create Agent app: {e}") + log_debug(f"Agent app created: {self.name}, {self.app_id}") + + def to_dict(self) -> Dict[str, Any]: + payload = { + "agents": [ + {**agent.get_agent_config_dict(), "agent_id": agent.agent_id, "team_id": agent.team_id} + for agent in self.agents + ] + if self.agents + else [], + "teams": [{**team.to_platform_dict(), "team_id": team.team_id} for team in self.teams] + if self.teams + else [], + "workflows": [ + {**workflow.to_config_dict(), "workflow_id": workflow.workflow_id} for workflow in self.workflows + ] + if self.workflows + else [], + "endpointData": self.endpoints_created, + "type": "playground", + "description": self.description, + } + payload = {k: v for k, v in payload.items() if v is not None} + return payload + + +def generate_id(name: Optional[str] = None) -> str: + if name: + return name.lower().replace(" ", "-").replace("_", "-") + else: + return str(uuid4()) \ No newline at end of file From 0edf9164166b1dbfc7d6f0a7aee5dc09bace3a16 Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Wed, 21 May 2025 03:29:55 +0530 Subject: [PATCH 42/55] update --- libs/agno/agno/agent/agent.py | 17 +++++++++-------- libs/agno/agno/app/playground/app.py | 6 +++--- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/libs/agno/agno/agent/agent.py b/libs/agno/agno/agent/agent.py index 7fd6afb33c..7326f81d51 100644 --- a/libs/agno/agno/agent/agent.py +++ b/libs/agno/agno/agent/agent.py @@ -634,10 +634,6 @@ def _run( # 6. Save output to file if save_response_to_file is set self.save_run_response_to_file(message=message, session_id=session_id) - thread = threading.Thread(target=self._register_agent) - thread.start() - - # Log Agent Run self._log_agent_run(user_id=user_id, session_id=session_id) @@ -661,6 +657,7 @@ def _run( log_debug(f"Agent Run End: {run_response.run_id}", center=True, symbol="*") return run_response + def _run_stream( self, run_response: RunResponse, @@ -878,6 +875,10 @@ def run( # Create a run_id for this specific run run_id = str(uuid4()) + # Register Agent + thread = threading.Thread(target=self._register_agent) + thread.start() + for attempt in range(num_attempts): try: # Create a new run_response for this attempt @@ -998,7 +999,7 @@ async def _arun( # 1. Prepare the Agent for the run self.model = cast(Model, self.model) - # 1. Reason about the task if reasoning is enabled + # 1. Reason about the task if reasoning is enabled await self._ahandle_reasoning(run_messages=run_messages, session_id=session_id) # Get the index of the last "user" message in messages_for_run @@ -1033,9 +1034,6 @@ async def _arun( # 6. Save output to file if save_response_to_file is set self.save_run_response_to_file(message=message, session_id=session_id) - # Register Agent - asyncio.create_task(self._aregister_agent()) - # Log Agent Run await self._alog_agent_run(user_id=user_id, session_id=session_id) @@ -1251,6 +1249,9 @@ async def arun( # Create a run_id for this specific run run_id = str(uuid4()) + # Register Agent + asyncio.create_task(self._aregister_agent()) + for attempt in range(num_attempts): try: # Create a new run_response for this attempt diff --git a/libs/agno/agno/app/playground/app.py b/libs/agno/agno/app/playground/app.py index d57b2d6ecc..43dbfa6cc7 100644 --- a/libs/agno/agno/app/playground/app.py +++ b/libs/agno/agno/app/playground/app.py @@ -15,11 +15,11 @@ from agno.agent.agent import Agent from agno.api.playground import PlaygroundEndpointCreate +from agno.app.playground.async_router import get_async_playground_router +from agno.app.playground.sync_router import get_sync_playground_router from agno.cli.console import console from agno.cli.settings import agno_cli_settings -from agno.app.playground.async_router import get_async_playground_router from agno.playground.settings import PlaygroundSettings -from agno.app.playground.sync_router import get_sync_playground_router from agno.team.team import Team from agno.utils.log import log_debug, logger from agno.workflow.workflow import Workflow @@ -245,4 +245,4 @@ def generate_id(name: Optional[str] = None) -> str: if name: return name.lower().replace(" ", "-").replace("_", "-") else: - return str(uuid4()) \ No newline at end of file + return str(uuid4()) From 27c11460cd73aaf15e6bf7bd363d3d014ff04986 Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Wed, 21 May 2025 03:55:18 +0530 Subject: [PATCH 43/55] update --- libs/agno/agno/team/team.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/libs/agno/agno/team/team.py b/libs/agno/agno/team/team.py index 9b146aa0d1..e71048cde7 100644 --- a/libs/agno/agno/team/team.py +++ b/libs/agno/agno/team/team.py @@ -7007,7 +7007,6 @@ def _register_team(self) -> None: from agno.api.team import TeamCreate, create_team - print(f"Registering team**********************************************************, {self.workflow_id}") try: create_team( team=TeamCreate( @@ -7047,6 +7046,14 @@ async def _aregister_team(self) -> None: log_debug(f"Could not create team on platform: {e}") def to_platform_dict(self) -> Dict[str, Any]: + model = None + if self.model is not None: + model = { + "name": self.model.__class__.__name__, + "id": self.model.id, + "provider": self.model.provider, + } + payload = { "members": [ { @@ -7083,7 +7090,7 @@ def to_platform_dict(self) -> Dict[str, Any]: if member is not None ], "mode": self.mode, - "model": self.model.to_dict() if self.model is not None else None, + "model": model, "name": self.name, "instructions": self.instructions, "description": self.description, @@ -7094,13 +7101,13 @@ def to_platform_dict(self) -> Dict[str, Any]: "name": self.memory.__class__.__name__, "model": { "name": self.memory.model.name, - "model": self.memory.model.id, + "id": self.memory.model.id, "provider": self.memory.model.provider, } if self.memory.model else { "name": self.model.name, - "model": self.model.id, + "id": self.model.id, "provider": self.model.provider, }, "db": self.memory.db.__dict__() if self.memory.db else None, From 6cb983256ebe750411ae08733dc18a4da809fb9f Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Wed, 21 May 2025 04:41:41 +0530 Subject: [PATCH 44/55] fastapi registration --- cookbook/apps/fastapi/basic.py | 8 ++- libs/agno/agno/app/fastapi/app.py | 110 ++++++++++++++++++++++++++---- 2 files changed, 100 insertions(+), 18 deletions(-) diff --git a/cookbook/apps/fastapi/basic.py b/cookbook/apps/fastapi/basic.py index 78618e8572..84509ada3a 100644 --- a/cookbook/apps/fastapi/basic.py +++ b/cookbook/apps/fastapi/basic.py @@ -12,9 +12,11 @@ markdown=True, ) -app = FastAPIApp( +fastapi_app = FastAPIApp( agent=basic_agent, -).get_app() +) + +app = fastapi_app.get_app() if __name__ == "__main__": - serve_fastapi_app("basic:app", port=8001, reload=True) + fastapi_app.serve_fastapi_app(app="basic:app", port=8001, reload=True) diff --git a/libs/agno/agno/app/fastapi/app.py b/libs/agno/agno/app/fastapi/app.py index 87bd40a705..71ce2d0231 100644 --- a/libs/agno/agno/app/fastapi/app.py +++ b/libs/agno/agno/app/fastapi/app.py @@ -1,18 +1,24 @@ import logging -from typing import Optional, Set +from os import getenv +from typing import Any, Dict, List, Optional +from uuid import uuid4 +import uvicorn from fastapi import FastAPI, HTTPException from fastapi.responses import JSONResponse from fastapi.routing import APIRouter +from git import Union from starlette.middleware.cors import CORSMiddleware from starlette.requests import Request from agno.agent.agent import Agent +from agno.api.app import AppCreate, create_app from agno.app.fastapi.async_router import get_async_router from agno.app.fastapi.sync_router import get_sync_router from agno.app.settings import APIAppSettings from agno.app.utils import generate_id from agno.team.team import Team +from agno.utils.log import log_debug logger = logging.getLogger(__name__) @@ -25,28 +31,55 @@ def __init__( settings: Optional[APIAppSettings] = None, api_app: Optional[FastAPI] = None, router: Optional[APIRouter] = None, + monitoring: bool = True, + app_id: Optional[str] = None, + name: Optional[str] = None, + description: Optional[str] = None, ): if not agent and not team: - raise ValueError("Either agent or team must be provided.") - - if agent and team: - raise ValueError("Only one of agent or team can be provided.") + raise ValueError("Either agent, or team must be provided.") self.agent: Optional[Agent] = agent self.team: Optional[Team] = team + self.settings: APIAppSettings = settings or APIAppSettings() + self.api_app: Optional[FastAPI] = api_app + self.router: Optional[APIRouter] = router + self.monitoring = monitoring + self.app_id: Optional[str] = app_id + self.name: Optional[str] = name + self.description = description + self.set_app_id() if self.agent: - if not self.agent.agent_id: - self.agent.agent_id = generate_id(self.agent.name) + if not self.agent.app_id: + self.agent.app_id = self.app_id + self.agent.initialize_agent() if self.team: - if not self.team.team_id: - self.team.team_id = generate_id(self.team.name) - - self.settings: APIAppSettings = settings or APIAppSettings() - self.api_app: Optional[FastAPI] = api_app - self.router: Optional[APIRouter] = router - self.endpoints_created: Set[str] = set() + if not self.team.app_id: + self.team.app_id = self.app_id + self.team.initialize_team() + for member in self.team.members: + if isinstance(member, Agent): + if not member.app_id: + member.app_id = self.app_id + member.team_id = None + member.initialize_agent() + elif isinstance(member, Team): + member.initialize_team() + + def set_app_id(self) -> str: + # If app_id is already set, keep it instead of overriding with UUID + if self.app_id is None: + self.app_id = str(uuid4()) + + # Don't override existing app_id + return self.app_id + + def _set_monitoring(self) -> None: + monitor_env = getenv("AGNO_MONITOR") + if monitor_env is not None: + self.monitoring = monitor_env.lower() == "true" def get_router(self) -> APIRouter: return get_sync_router(agent=self.agent, team=self.team) @@ -105,5 +138,52 @@ async def general_exception_handler(request: Request, call_next): allow_headers=["*"], expose_headers=["*"], ) - return self.api_app + + def serve_fastapi_app( + self, + app: Union[str, FastAPI], + *, + host: str = "localhost", + port: int = 7777, + reload: bool = False, + **kwargs, + ): + self.set_app_id() + self.register_app_on_platform() + + if self.agent: + self.agent._register_agent() + if self.team: + self.team._register_team() + logger.info(f"Starting API on {host}:{port}") + + uvicorn.run(app=app, host=host, port=port, reload=reload, **kwargs) + + def register_app_on_platform(self) -> None: + self._set_monitoring() + if not self.monitoring: + return + + try: + log_debug(f"Creating app on Platform: {self.name}, {self.app_id}") + create_app(app=AppCreate(name=self.name, app_id=self.app_id, config=self.to_dict())) + except Exception as e: + log_debug(f"Could not create Agent app: {e}") + log_debug(f"Agent app created: {self.name}, {self.app_id}") + + def to_dict(self) -> Dict[str, Any]: + payload = { + "agents": { + **self.agent.get_agent_config_dict(), + "agent_id": self.agent.agent_id, + "team_id": self.agent.team_id, + } + if self.agent + else None, + "teams": {**self.team.to_platform_dict(), "team_id": self.team.team_id} if self.team else None, + "type": "FastAPI", + "description": self.description, + } + payload = {k: v for k, v in payload.items() if v is not None} + return payload From 0c40dbe826ebce769c27a6fc694af6e6e23d0f15 Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Wed, 21 May 2025 12:36:11 +0530 Subject: [PATCH 45/55] update --- libs/agno/agno/team/team.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libs/agno/agno/team/team.py b/libs/agno/agno/team/team.py index e71048cde7..8292f800e2 100644 --- a/libs/agno/agno/team/team.py +++ b/libs/agno/agno/team/team.py @@ -7094,7 +7094,11 @@ def to_platform_dict(self) -> Dict[str, Any]: "name": self.name, "instructions": self.instructions, "description": self.description, - "storage": self.storage.__class__.__name__ if self.storage is not None else None, + "storage": { + "name": self.storage.__class__.__name__, + } + if self.storage is not None + else None, # "tools": [tool.to_dict() for tool in self.tools] if self.tools is not None else None, "memory": ( { From 8be00ec3d38c770fae051d1ea04a8eea9a9c228f Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Wed, 21 May 2025 13:50:29 +0530 Subject: [PATCH 46/55] updates --- libs/agno/agno/agent/agent.py | 6 +++--- libs/agno/agno/app/fastapi/app.py | 21 ++++++++++++++------- libs/agno/agno/team/team.py | 10 +++++----- libs/agno/agno/workflow/workflow.py | 16 +++++++++++++++- 4 files changed, 37 insertions(+), 16 deletions(-) diff --git a/libs/agno/agno/agent/agent.py b/libs/agno/agno/agent/agent.py index 7326f81d51..1e25427492 100644 --- a/libs/agno/agno/agent/agent.py +++ b/libs/agno/agno/agent/agent.py @@ -5914,7 +5914,7 @@ def get_agent_config_dict(self) -> Dict[str, Any]: if self.model is not None: model = { "name": self.model.__class__.__name__, - "id": self.model.id, + "model": self.model.id, "provider": self.model.provider, } @@ -5925,13 +5925,13 @@ def get_agent_config_dict(self) -> Dict[str, Any]: { "name": self.memory.__class__.__name__, "model": { - "name": self.memory.model.name, + "name": self.memory.model.__class__.__name__, "model": self.memory.model.id, "provider": self.memory.model.provider, } if self.memory.model else { - "name": self.model.name, + "name": self.model.__class__.__name__, "model": self.model.id, "provider": self.model.provider, }, diff --git a/libs/agno/agno/app/fastapi/app.py b/libs/agno/agno/app/fastapi/app.py index 71ce2d0231..e869072f37 100644 --- a/libs/agno/agno/app/fastapi/app.py +++ b/libs/agno/agno/app/fastapi/app.py @@ -174,15 +174,22 @@ def register_app_on_platform(self) -> None: def to_dict(self) -> Dict[str, Any]: payload = { - "agents": { - **self.agent.get_agent_config_dict(), - "agent_id": self.agent.agent_id, - "team_id": self.agent.team_id, - } + "agents": [ + { + **self.agent.get_agent_config_dict(), + "agent_id": self.agent.agent_id, + "team_id": self.agent.team_id, + } + ] if self.agent else None, - "teams": {**self.team.to_platform_dict(), "team_id": self.team.team_id} if self.team else None, - "type": "FastAPI", + "teams": [ + { + **self.team.to_platform_dict(), + "team_id": self.team.team_id, + } + ] if self.team else None, + "type": "fastapi", "description": self.description, } payload = {k: v for k, v in payload.items() if v is not None} diff --git a/libs/agno/agno/team/team.py b/libs/agno/agno/team/team.py index 8292f800e2..c7efaa1d81 100644 --- a/libs/agno/agno/team/team.py +++ b/libs/agno/agno/team/team.py @@ -7050,7 +7050,7 @@ def to_platform_dict(self) -> Dict[str, Any]: if self.model is not None: model = { "name": self.model.__class__.__name__, - "id": self.model.id, + "model": self.model.id, "provider": self.model.provider, } @@ -7104,14 +7104,14 @@ def to_platform_dict(self) -> Dict[str, Any]: { "name": self.memory.__class__.__name__, "model": { - "name": self.memory.model.name, - "id": self.memory.model.id, + "name": self.memory.model.__class__.__name__, + "model": self.memory.model.id, "provider": self.memory.model.provider, } if self.memory.model else { - "name": self.model.name, - "id": self.model.id, + "name": self.model.__class__.__name__, + "model": self.model.id, "provider": self.model.provider, }, "db": self.memory.db.__dict__() if self.memory.db else None, diff --git a/libs/agno/agno/workflow/workflow.py b/libs/agno/agno/workflow/workflow.py index d6b7f3ce22..eb7aaee01d 100644 --- a/libs/agno/agno/workflow/workflow.py +++ b/libs/agno/agno/workflow/workflow.py @@ -711,7 +711,21 @@ def to_config_dict(self) -> Dict[str, Any]: "storage": { "name": self.storage.__class__.__name__ if self.storage is not None else None, }, - "memory": self.memory, + "memory": ( + { + "name": self.memory.__class__.__name__, + "model": { + "name": self.memory.model.__class__.__name__, + "model": self.memory.model.id, + "provider": self.memory.model.provider, + } + if self.memory.model + else None, + "db": self.memory.db.__dict__() if self.memory.db else None, + } + if self.memory and self.memory.db + else None + ), } agents = [] From 9051729469a3701e54436de8e072bee8e3730909 Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Wed, 21 May 2025 13:51:41 +0530 Subject: [PATCH 47/55] update --- cookbook/apps/fastapi/study_friend.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/cookbook/apps/fastapi/study_friend.py b/cookbook/apps/fastapi/study_friend.py index 671ed92c5b..a2b0b7e7cf 100644 --- a/cookbook/apps/fastapi/study_friend.py +++ b/cookbook/apps/fastapi/study_friend.py @@ -84,9 +84,11 @@ markdown=True, ) -app = FastAPIApp( +fastapi_app = FastAPIApp( agent=StudyBuddy, -).get_app() +) + +app = fastapi_app.get_app() if __name__ == "__main__": - serve_fastapi_app("study_friend:app", port=8001, reload=True) + fastapi_app.serve_fastapi_app(app="study_friend:app", port=8001, reload=True) From f5b2efa59f542caf091530981abfc7affbbb262f Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Wed, 21 May 2025 14:13:01 +0530 Subject: [PATCH 48/55] add whatsapp app --- cookbook/apps/fastapi/basic.py | 3 + cookbook/apps/fastapi/study_friend.py | 3 + cookbook/apps/whatsapp/agent_with_media.py | 11 +- .../apps/whatsapp/agent_with_user_memory.py | 13 +- cookbook/apps/whatsapp/basic.py | 11 +- .../apps/whatsapp/image_generation_model.py | 17 +- .../apps/whatsapp/image_generation_tools.py | 13 +- cookbook/apps/whatsapp/reasoning_agent.py | 11 +- cookbook/apps/whatsapp/study_friend.py | 11 +- libs/agno/agno/app/fastapi/app.py | 4 +- libs/agno/agno/app/whatsapp/app.py | 148 +++++++++++++++++- 11 files changed, 214 insertions(+), 31 deletions(-) diff --git a/cookbook/apps/fastapi/basic.py b/cookbook/apps/fastapi/basic.py index 84509ada3a..ae332211cd 100644 --- a/cookbook/apps/fastapi/basic.py +++ b/cookbook/apps/fastapi/basic.py @@ -14,6 +14,9 @@ fastapi_app = FastAPIApp( agent=basic_agent, + name="Basic Agent", + app_id="basic_agent", + description="A basic agent that can answer questions and help with tasks.", ) app = fastapi_app.get_app() diff --git a/cookbook/apps/fastapi/study_friend.py b/cookbook/apps/fastapi/study_friend.py index a2b0b7e7cf..d0abd165b8 100644 --- a/cookbook/apps/fastapi/study_friend.py +++ b/cookbook/apps/fastapi/study_friend.py @@ -86,6 +86,9 @@ fastapi_app = FastAPIApp( agent=StudyBuddy, + name="StudyBuddy", + app_id="study_buddy", + description="A study buddy that helps users achieve their educational goals through personalized guidance, interactive learning, and comprehensive resource curation.", ) app = fastapi_app.get_app() diff --git a/cookbook/apps/whatsapp/agent_with_media.py b/cookbook/apps/whatsapp/agent_with_media.py index 39c09760d5..0d94770f64 100644 --- a/cookbook/apps/whatsapp/agent_with_media.py +++ b/cookbook/apps/whatsapp/agent_with_media.py @@ -12,9 +12,14 @@ markdown=True, ) -app = WhatsappAPI( +whatsapp_app = WhatsappAPI( agent=media_agent, -).get_app() + name="Media Agent", + app_id="media_agent", + description="A agent that can send media to the user.", +) + +app = whatsapp_app.get_app() if __name__ == "__main__": - serve_whatsapp_app("agent_with_media:app", port=8000, reload=True) + whatsapp_app.serve_whatsapp_app(app="agent_with_media:app", port=8000, reload=True) diff --git a/cookbook/apps/whatsapp/agent_with_user_memory.py b/cookbook/apps/whatsapp/agent_with_user_memory.py index 6564b751e2..f823cb3fea 100644 --- a/cookbook/apps/whatsapp/agent_with_user_memory.py +++ b/cookbook/apps/whatsapp/agent_with_user_memory.py @@ -51,9 +51,16 @@ ) -app = WhatsappAPI( +whatsapp_app = WhatsappAPI( agent=personal_agent, -).get_app() + name="Agent with User Memory", + app_id="agent_with_user_memory", + description="A agent that can chat with the user about things and make them feel good.", +) + +app = whatsapp_app.get_app() if __name__ == "__main__": - serve_whatsapp_app("agent_with_user_memory:app", port=8000, reload=True) + whatsapp_app.serve_whatsapp_app( + app="agent_with_user_memory:app", port=8000, reload=True + ) diff --git a/cookbook/apps/whatsapp/basic.py b/cookbook/apps/whatsapp/basic.py index a073a22357..9e768bac72 100644 --- a/cookbook/apps/whatsapp/basic.py +++ b/cookbook/apps/whatsapp/basic.py @@ -12,9 +12,14 @@ markdown=True, ) -app = WhatsappAPI( +whatsapp_app = WhatsappAPI( agent=basic_agent, -).get_app() + name="Basic Agent", + app_id="basic_agent", + description="A basic agent that can answer questions and help with tasks.", +) + +app = whatsapp_app.get_app() if __name__ == "__main__": - serve_whatsapp_app("basic:app", port=8000, reload=True) + whatsapp_app.serve_whatsapp_app(app="basic:app", port=8000, reload=True) diff --git a/cookbook/apps/whatsapp/image_generation_model.py b/cookbook/apps/whatsapp/image_generation_model.py index 1d8a29113d..7b4816a904 100644 --- a/cookbook/apps/whatsapp/image_generation_model.py +++ b/cookbook/apps/whatsapp/image_generation_model.py @@ -3,7 +3,7 @@ from agno.app.whatsapp.serve import serve_whatsapp_app from agno.models.google import Gemini -image_agentg = Agent( +image_agent = Agent( model=Gemini( id="gemini-2.0-flash-exp-image-generation", response_modalities=["Text", "Image"], @@ -11,9 +11,16 @@ debug_mode=True, ) -app = WhatsappAPI( - agent=image_agentg, -).get_app() +whatsapp_app = WhatsappAPI( + agent=image_agent, + name="Image Generation Model", + app_id="image_generation_model", + description="A model that generates images using the Gemini API.", +) + +app = whatsapp_app.get_app() if __name__ == "__main__": - serve_whatsapp_app("image_generation_model:app", port=8000, reload=True) + whatsapp_app.serve_whatsapp_app( + app="image_generation_model:app", port=8000, reload=True + ) diff --git a/cookbook/apps/whatsapp/image_generation_tools.py b/cookbook/apps/whatsapp/image_generation_tools.py index d88d322690..33fa5c368f 100644 --- a/cookbook/apps/whatsapp/image_generation_tools.py +++ b/cookbook/apps/whatsapp/image_generation_tools.py @@ -14,9 +14,16 @@ ) -app = WhatsappAPI( +whatsapp_app = WhatsappAPI( agent=image_agent, -).get_app() + name="Image Generation Tools", + app_id="image_generation_tools", + description="A tool that generates images using the OpenAI API.", +) + +app = whatsapp_app.get_app() if __name__ == "__main__": - serve_whatsapp_app("image_generation_tools:app", port=8000, reload=True) + whatsapp_app.serve_whatsapp_app( + app="image_generation_tools:app", port=8000, reload=True + ) diff --git a/cookbook/apps/whatsapp/reasoning_agent.py b/cookbook/apps/whatsapp/reasoning_agent.py index 63969ab23e..ae1c1b8b22 100644 --- a/cookbook/apps/whatsapp/reasoning_agent.py +++ b/cookbook/apps/whatsapp/reasoning_agent.py @@ -22,9 +22,14 @@ markdown=True, ) -app = WhatsappAPI( +whatsapp_app = WhatsappAPI( agent=reasoning_finance_agent, -).get_app() + name="Reasoning Finance Agent", + app_id="reasoning_finance_agent", + description="A finance agent that uses tables to display data and reasoning tools to reason about the data.", +) + +app = whatsapp_app.get_app() if __name__ == "__main__": - serve_whatsapp_app("reasoning_agent:app", port=8000, reload=True) + whatsapp_app.serve_whatsapp_app(app="reasoning_agent:app", port=8000, reload=True) diff --git a/cookbook/apps/whatsapp/study_friend.py b/cookbook/apps/whatsapp/study_friend.py index 72b2e3465a..fc07e821f3 100644 --- a/cookbook/apps/whatsapp/study_friend.py +++ b/cookbook/apps/whatsapp/study_friend.py @@ -98,9 +98,14 @@ markdown=True, ) -app = WhatsappAPI( +whatsapp_app = WhatsappAPI( agent=StudyBuddy, -).get_app() + name="StudyBuddy", + app_id="study_buddy", + description="A study buddy that helps users achieve their educational goals through personalized guidance, interactive learning, and comprehensive resource curation.", +) + +app = whatsapp_app.get_app() if __name__ == "__main__": - serve_whatsapp_app("study_friend:app", port=8000, reload=True) + whatsapp_app.serve_whatsapp_app(app="study_friend:app", port=8000, reload=True) diff --git a/libs/agno/agno/app/fastapi/app.py b/libs/agno/agno/app/fastapi/app.py index e869072f37..9142c3bf31 100644 --- a/libs/agno/agno/app/fastapi/app.py +++ b/libs/agno/agno/app/fastapi/app.py @@ -188,7 +188,9 @@ def to_dict(self) -> Dict[str, Any]: **self.team.to_platform_dict(), "team_id": self.team.team_id, } - ] if self.team else None, + ] + if self.team + else None, "type": "fastapi", "description": self.description, } diff --git a/libs/agno/agno/app/whatsapp/app.py b/libs/agno/agno/app/whatsapp/app.py index 0b75f0c7a6..26525db45b 100644 --- a/libs/agno/agno/app/whatsapp/app.py +++ b/libs/agno/agno/app/whatsapp/app.py @@ -1,14 +1,25 @@ -from typing import Optional, Set - -from fastapi import FastAPI +import logging +from os import getenv +from typing import Any, Dict, List, Optional, Set, Union +from uuid import uuid4 + +import uvicorn +from fastapi import FastAPI, HTTPException +from fastapi.responses import JSONResponse from fastapi.routing import APIRouter +from starlette.middleware.cors import CORSMiddleware +from starlette.requests import Request from agno.agent.agent import Agent +from agno.api.app import AppCreate, create_app from agno.app.settings import APIAppSettings from agno.app.utils import generate_id from agno.app.whatsapp.async_router import get_async_router from agno.app.whatsapp.sync_router import get_sync_router from agno.team.team import Team +from agno.utils.log import log_debug + +logger = logging.getLogger(__name__) class WhatsappAPI: @@ -19,29 +30,69 @@ def __init__( settings: Optional[APIAppSettings] = None, api_app: Optional[FastAPI] = None, router: Optional[APIRouter] = None, + monitoring: bool = True, + app_id: Optional[str] = None, + name: Optional[str] = None, + description: Optional[str] = None, ): if not agent and not team: raise ValueError("Either agent or team must be provided.") if agent and team: - raise ValueError("Only one of agent or team can be provided.") + raise ValueError("Both agent and team are provided. Only one can be specified.") self.agent: Optional[Agent] = agent self.team: Optional[Team] = team + self.settings: APIAppSettings = settings or APIAppSettings() + self.api_app: Optional[FastAPI] = api_app + self.router: Optional[APIRouter] = router + self.monitoring = monitoring + self.app_id: Optional[str] = app_id + self.name: Optional[str] = name + self.description = description + self.set_app_id() if self.agent: + if not self.agent.app_id: + self.agent.app_id = self.app_id if not self.agent.agent_id: self.agent.agent_id = generate_id(self.agent.name) + self.agent.initialize_agent() if self.team: + if not self.team.app_id: + self.team.app_id = self.app_id if not self.team.team_id: self.team.team_id = generate_id(self.team.name) + self.team.initialize_team() + for member in self.team.members: + if isinstance(member, Agent): + if not member.app_id: + member.app_id = self.app_id + if not member.agent_id: + member.agent_id = generate_id(member.name) + member.team_id = None + member.initialize_agent() + elif isinstance(member, Team): + if not member.app_id: + member.app_id = self.app_id + member.initialize_team() - self.settings: APIAppSettings = settings or APIAppSettings() - self.api_app: Optional[FastAPI] = api_app - self.router: Optional[APIRouter] = router self.endpoints_created: Set[str] = set() + def set_app_id(self) -> str: + # If app_id is already set, keep it instead of overriding with UUID + if self.app_id is None: + self.app_id = str(uuid4()) + + # Don't override existing app_id + return self.app_id + + def _set_monitoring(self) -> None: + monitor_env = getenv("AGNO_MONITOR") + if monitor_env is not None: + self.monitoring = monitor_env.lower() == "true" + def get_router(self) -> APIRouter: return get_sync_router(agent=self.agent, team=self.team) @@ -60,6 +111,24 @@ def get_app(self, use_async: bool = True, prefix: str = "") -> FastAPI: if not self.api_app: raise Exception("API App could not be created.") + @self.api_app.exception_handler(HTTPException) + async def http_exception_handler(request: Request, exc: HTTPException) -> JSONResponse: + return JSONResponse( + status_code=exc.status_code, + content={"detail": str(exc.detail)}, + ) + + async def general_exception_handler(request: Request, call_next): + try: + return await call_next(request) + except Exception as e: + return JSONResponse( + status_code=e.status_code if hasattr(e, "status_code") else 500, + content={"detail": str(e)}, + ) + + self.api_app.middleware("http")(general_exception_handler) + if not self.router: self.router = APIRouter(prefix=prefix) @@ -73,4 +142,69 @@ def get_app(self, use_async: bool = True, prefix: str = "") -> FastAPI: self.api_app.include_router(self.router) + self.api_app.add_middleware( + CORSMiddleware, + allow_origins=["*"], + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], + expose_headers=["*"], + ) return self.api_app + + def serve_whatsapp_app( + self, + app: Union[str, FastAPI], + *, + host: str = "localhost", + port: int = 7777, + reload: bool = False, + **kwargs, + ): + self.set_app_id() + self.register_app_on_platform() + + if self.agent: + self.agent._register_agent() + if self.team: + self.team._register_team() + + logger.info(f"Starting Whatsapp API on {host}:{port}") + uvicorn.run(app=app, host=host, port=port, reload=reload, **kwargs) + + def register_app_on_platform(self) -> None: + self._set_monitoring() + if not self.monitoring: + return + + try: + log_debug(f"Creating app on Platform: {self.name}, {self.app_id}") + create_app(app=AppCreate(name=self.name, app_id=self.app_id, config=self.to_dict())) + except Exception as e: + log_debug(f"Could not create Whatsapp app: {e}") + log_debug(f"Whatsapp app created: {self.name}, {self.app_id}") + + def to_dict(self) -> Dict[str, Any]: + payload = { + "agents": [ + { + **self.agent.get_agent_config_dict(), + "agent_id": self.agent.agent_id, + "team_id": self.agent.team_id, + } + ] + if self.agent + else None, + "teams": [ + { + **self.team.to_platform_dict(), + "team_id": self.team.team_id, + } + ] + if self.team + else None, + "type": "whatsapp", + "description": self.description, + } + payload = {k: v for k, v in payload.items() if v is not None} + return payload From 7ea92941d7350ec400d963f3aaa02609da19ff2f Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Wed, 21 May 2025 14:19:20 +0530 Subject: [PATCH 49/55] update --- cookbook/hackathon/workshop/playground.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cookbook/hackathon/workshop/playground.py b/cookbook/hackathon/workshop/playground.py index 2a2d1b08da..0119ca9a25 100644 --- a/cookbook/hackathon/workshop/playground.py +++ b/cookbook/hackathon/workshop/playground.py @@ -4,7 +4,9 @@ from fastapi import FastAPI # Create and configure the playground app -app = Playground(agents=[agno_support, agno_assist_voice]).get_app() +playground_app = Playground(agents=[agno_support, agno_assist_voice], name="Playground-hackathon", app_id="playground-hackathon", description="A playground for testing and playing with Agno") + +app = playground_app.get_app() if __name__ == "__main__": - serve_playground_app("playground:app", reload=True) + playground_app.serve(app="playground:app", reload=True) From e34fdfdfec45c743c9de191da22e9ad81490112b Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Fri, 23 May 2025 02:57:32 +0530 Subject: [PATCH 50/55] update --- cookbook/apps/fastapi/basic.py | 2 +- cookbook/apps/fastapi/study_friend.py | 2 +- cookbook/apps/whatsapp/agent_with_media.py | 2 +- cookbook/apps/whatsapp/agent_with_user_memory.py | 4 +--- cookbook/apps/whatsapp/basic.py | 2 +- cookbook/apps/whatsapp/image_generation_model.py | 4 +--- cookbook/apps/whatsapp/image_generation_tools.py | 4 +--- cookbook/apps/whatsapp/reasoning_agent.py | 2 +- cookbook/apps/whatsapp/study_friend.py | 2 +- cookbook/hackathon/workshop/playground.py | 7 ++++++- libs/agno/agno/agent/agent.py | 4 ++-- libs/agno/agno/app/fastapi/app.py | 6 +++--- libs/agno/agno/app/playground/app.py | 6 +++--- libs/agno/agno/app/whatsapp/app.py | 14 +++----------- libs/agno/agno/team/team.py | 4 ++-- libs/agno/agno/workflow/workflow.py | 10 ++++------ 16 files changed, 32 insertions(+), 43 deletions(-) diff --git a/cookbook/apps/fastapi/basic.py b/cookbook/apps/fastapi/basic.py index ae332211cd..19187e8eb8 100644 --- a/cookbook/apps/fastapi/basic.py +++ b/cookbook/apps/fastapi/basic.py @@ -22,4 +22,4 @@ app = fastapi_app.get_app() if __name__ == "__main__": - fastapi_app.serve_fastapi_app(app="basic:app", port=8001, reload=True) + fastapi_app.serve(app="basic:app", port=8001, reload=True) diff --git a/cookbook/apps/fastapi/study_friend.py b/cookbook/apps/fastapi/study_friend.py index d0abd165b8..e520d356c9 100644 --- a/cookbook/apps/fastapi/study_friend.py +++ b/cookbook/apps/fastapi/study_friend.py @@ -94,4 +94,4 @@ app = fastapi_app.get_app() if __name__ == "__main__": - fastapi_app.serve_fastapi_app(app="study_friend:app", port=8001, reload=True) + fastapi_app.serve(app="study_friend:app", port=8001, reload=True) diff --git a/cookbook/apps/whatsapp/agent_with_media.py b/cookbook/apps/whatsapp/agent_with_media.py index 0d94770f64..de58d3b4b1 100644 --- a/cookbook/apps/whatsapp/agent_with_media.py +++ b/cookbook/apps/whatsapp/agent_with_media.py @@ -22,4 +22,4 @@ app = whatsapp_app.get_app() if __name__ == "__main__": - whatsapp_app.serve_whatsapp_app(app="agent_with_media:app", port=8000, reload=True) + whatsapp_app.serve(app="agent_with_media:app", port=8000, reload=True) diff --git a/cookbook/apps/whatsapp/agent_with_user_memory.py b/cookbook/apps/whatsapp/agent_with_user_memory.py index f823cb3fea..ef4f894172 100644 --- a/cookbook/apps/whatsapp/agent_with_user_memory.py +++ b/cookbook/apps/whatsapp/agent_with_user_memory.py @@ -61,6 +61,4 @@ app = whatsapp_app.get_app() if __name__ == "__main__": - whatsapp_app.serve_whatsapp_app( - app="agent_with_user_memory:app", port=8000, reload=True - ) + whatsapp_app.serve(app="agent_with_user_memory:app", port=8000, reload=True) diff --git a/cookbook/apps/whatsapp/basic.py b/cookbook/apps/whatsapp/basic.py index 9e768bac72..1e0acfcd61 100644 --- a/cookbook/apps/whatsapp/basic.py +++ b/cookbook/apps/whatsapp/basic.py @@ -22,4 +22,4 @@ app = whatsapp_app.get_app() if __name__ == "__main__": - whatsapp_app.serve_whatsapp_app(app="basic:app", port=8000, reload=True) + whatsapp_app.serve(app="basic:app", port=8000, reload=True) diff --git a/cookbook/apps/whatsapp/image_generation_model.py b/cookbook/apps/whatsapp/image_generation_model.py index 7b4816a904..d0cb9b56af 100644 --- a/cookbook/apps/whatsapp/image_generation_model.py +++ b/cookbook/apps/whatsapp/image_generation_model.py @@ -21,6 +21,4 @@ app = whatsapp_app.get_app() if __name__ == "__main__": - whatsapp_app.serve_whatsapp_app( - app="image_generation_model:app", port=8000, reload=True - ) + whatsapp_app.serve(app="image_generation_model:app", port=8000, reload=True) diff --git a/cookbook/apps/whatsapp/image_generation_tools.py b/cookbook/apps/whatsapp/image_generation_tools.py index 33fa5c368f..dd3b6d7d96 100644 --- a/cookbook/apps/whatsapp/image_generation_tools.py +++ b/cookbook/apps/whatsapp/image_generation_tools.py @@ -24,6 +24,4 @@ app = whatsapp_app.get_app() if __name__ == "__main__": - whatsapp_app.serve_whatsapp_app( - app="image_generation_tools:app", port=8000, reload=True - ) + whatsapp_app.serve(app="image_generation_tools:app", port=8000, reload=True) diff --git a/cookbook/apps/whatsapp/reasoning_agent.py b/cookbook/apps/whatsapp/reasoning_agent.py index ae1c1b8b22..8c3f561b5e 100644 --- a/cookbook/apps/whatsapp/reasoning_agent.py +++ b/cookbook/apps/whatsapp/reasoning_agent.py @@ -32,4 +32,4 @@ app = whatsapp_app.get_app() if __name__ == "__main__": - whatsapp_app.serve_whatsapp_app(app="reasoning_agent:app", port=8000, reload=True) + whatsapp_app.serve(app="reasoning_agent:app", port=8000, reload=True) diff --git a/cookbook/apps/whatsapp/study_friend.py b/cookbook/apps/whatsapp/study_friend.py index fc07e821f3..7f659a8818 100644 --- a/cookbook/apps/whatsapp/study_friend.py +++ b/cookbook/apps/whatsapp/study_friend.py @@ -108,4 +108,4 @@ app = whatsapp_app.get_app() if __name__ == "__main__": - whatsapp_app.serve_whatsapp_app(app="study_friend:app", port=8000, reload=True) + whatsapp_app.serve(app="study_friend:app", port=8000, reload=True) diff --git a/cookbook/hackathon/workshop/playground.py b/cookbook/hackathon/workshop/playground.py index 0119ca9a25..204f51007f 100644 --- a/cookbook/hackathon/workshop/playground.py +++ b/cookbook/hackathon/workshop/playground.py @@ -4,7 +4,12 @@ from fastapi import FastAPI # Create and configure the playground app -playground_app = Playground(agents=[agno_support, agno_assist_voice], name="Playground-hackathon", app_id="playground-hackathon", description="A playground for testing and playing with Agno") +playground_app = Playground( + agents=[agno_support, agno_assist_voice], + name="Playground-hackathon", + app_id="playground-hackathon", + description="A playground for testing and playing with Agno", +) app = playground_app.get_app() diff --git a/libs/agno/agno/agent/agent.py b/libs/agno/agno/agent/agent.py index 29c33976f0..06835f7224 100644 --- a/libs/agno/agno/agent/agent.py +++ b/libs/agno/agno/agent/agent.py @@ -883,7 +883,7 @@ def run( run_id = str(uuid4()) # Register Agent - thread = threading.Thread(target=self._register_agent) + thread = threading.Thread(target=self.register_agent) thread.start() for attempt in range(num_attempts): @@ -5915,7 +5915,7 @@ def _create_run_data(self) -> Dict[str, Any]: return run_data - def _register_agent(self) -> None: + def register_agent(self) -> None: """Register this agent with Agno's platform.""" self.set_monitoring() if not self.monitoring: diff --git a/libs/agno/agno/app/fastapi/app.py b/libs/agno/agno/app/fastapi/app.py index 9142c3bf31..139ace5dd4 100644 --- a/libs/agno/agno/app/fastapi/app.py +++ b/libs/agno/agno/app/fastapi/app.py @@ -140,7 +140,7 @@ async def general_exception_handler(request: Request, call_next): ) return self.api_app - def serve_fastapi_app( + def serve( self, app: Union[str, FastAPI], *, @@ -153,9 +153,9 @@ def serve_fastapi_app( self.register_app_on_platform() if self.agent: - self.agent._register_agent() + self.agent.register_agent() if self.team: - self.team._register_team() + self.team.register_team() logger.info(f"Starting API on {host}:{port}") uvicorn.run(app=app, host=host, port=port, reload=reload, **kwargs) diff --git a/libs/agno/agno/app/playground/app.py b/libs/agno/agno/app/playground/app.py index 43dbfa6cc7..20b2ef05bf 100644 --- a/libs/agno/agno/app/playground/app.py +++ b/libs/agno/agno/app/playground/app.py @@ -194,13 +194,13 @@ def serve( self.register_app_on_platform() if self.agents: for agent in self.agents: - agent._register_agent() + agent.register_agent() if self.teams: for team in self.teams: - team._register_team() + team.register_team() if self.workflows: for workflow in self.workflows: - workflow._register_workflow() + workflow.register_workflow() uvicorn.run(app=app, host=host, port=port, reload=reload, **kwargs) def register_app_on_platform(self) -> None: diff --git a/libs/agno/agno/app/whatsapp/app.py b/libs/agno/agno/app/whatsapp/app.py index 26525db45b..3d93bd0001 100644 --- a/libs/agno/agno/app/whatsapp/app.py +++ b/libs/agno/agno/app/whatsapp/app.py @@ -55,27 +55,19 @@ def __init__( if self.agent: if not self.agent.app_id: self.agent.app_id = self.app_id - if not self.agent.agent_id: - self.agent.agent_id = generate_id(self.agent.name) self.agent.initialize_agent() if self.team: if not self.team.app_id: self.team.app_id = self.app_id - if not self.team.team_id: - self.team.team_id = generate_id(self.team.name) self.team.initialize_team() for member in self.team.members: if isinstance(member, Agent): if not member.app_id: member.app_id = self.app_id - if not member.agent_id: - member.agent_id = generate_id(member.name) member.team_id = None member.initialize_agent() elif isinstance(member, Team): - if not member.app_id: - member.app_id = self.app_id member.initialize_team() self.endpoints_created: Set[str] = set() @@ -152,7 +144,7 @@ async def general_exception_handler(request: Request, call_next): ) return self.api_app - def serve_whatsapp_app( + def serve( self, app: Union[str, FastAPI], *, @@ -165,9 +157,9 @@ def serve_whatsapp_app( self.register_app_on_platform() if self.agent: - self.agent._register_agent() + self.agent.register_agent() if self.team: - self.team._register_team() + self.team.register_team() logger.info(f"Starting Whatsapp API on {host}:{port}") uvicorn.run(app=app, host=host, port=port, reload=reload, **kwargs) diff --git a/libs/agno/agno/team/team.py b/libs/agno/agno/team/team.py index 48d6238cf0..c9ff5efe36 100644 --- a/libs/agno/agno/team/team.py +++ b/libs/agno/agno/team/team.py @@ -640,7 +640,7 @@ def run( self._set_default_model() # Register the team on the platform - thread = threading.Thread(target=self._register_team) + thread = threading.Thread(target=self.register_team) thread.start() # Run the team @@ -7027,7 +7027,7 @@ def _get_agentic_or_user_search_filters( log_info(f"Filters used by Agent: {search_filters}") return search_filters - def _register_team(self) -> None: + def register_team(self) -> None: self._set_monitoring() if not self.monitoring: return diff --git a/libs/agno/agno/workflow/workflow.py b/libs/agno/agno/workflow/workflow.py index eb7aaee01d..0467ffae80 100644 --- a/libs/agno/agno/workflow/workflow.py +++ b/libs/agno/agno/workflow/workflow.py @@ -154,18 +154,17 @@ def run_workflow(self, **kwargs: Any): self.initialize_memory() # Update workflow_id for all agents before registration - for field_name, value in self.__class__.__dict__.items(): + for value in self.__class__.__dict__.items(): if isinstance(value, Agent): value.initialize_agent() value.workflow_id = self.workflow_id - print(value.agent_id) + if isinstance(value, Team): value.initialize_team() value.workflow_id = self.workflow_id - print(value.team_id) # Register the workflow, which will also register agents and teams - self._register_workflow() + self.register_workflow() # Create a run_id self.run_id = str(uuid4()) @@ -663,7 +662,7 @@ def _deep_copy_field(self, field_name: str, field_value: Any) -> Any: # For other types, return as is return field_value - def _register_workflow(self, force: bool = False) -> None: + def register_workflow(self, force: bool = False) -> None: """Register this workflow with Agno's platform. Args: @@ -682,7 +681,6 @@ def _register_workflow(self, force: bool = False) -> None: workflow_config = self.to_config_dict() log_debug(f"Registering workflow: {self.name} (ID: {self.workflow_id})") - print(f"Workflow config: {workflow_config}") # Register the workflow as an app create_workflow( workflow=WorkflowCreate( From c73c6b04027fb3d8e1bd13fcbe1e436d736b39ac Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Mon, 26 May 2025 13:34:55 +0530 Subject: [PATCH 51/55] update --- libs/agno/agno/agent/agent.py | 8 +++++++- libs/agno/agno/team/team.py | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/libs/agno/agno/agent/agent.py b/libs/agno/agno/agent/agent.py index e15b4b5ddb..b63e38ad55 100644 --- a/libs/agno/agno/agent/agent.py +++ b/libs/agno/agno/agent/agent.py @@ -7346,7 +7346,13 @@ def get_agent_config_dict(self) -> Dict[str, Any]: "model": self.model.id, "provider": self.model.provider, }, - "db": self.memory.db.__dict__() if self.memory.db else None, + "db": { + "name": self.memory.db.__class__.__name__, + "table_name": self.memory.db.table_name if hasattr(self.memory.db, "table_name") else None, + "db_url": self.memory.db.db_url if hasattr(self.memory.db, "db_url") else None, + } + if self.memory.db + else None, } if self.memory and self.memory.db else None diff --git a/libs/agno/agno/team/team.py b/libs/agno/agno/team/team.py index 4e6e4d21aa..b297109156 100644 --- a/libs/agno/agno/team/team.py +++ b/libs/agno/agno/team/team.py @@ -7153,7 +7153,13 @@ def to_platform_dict(self) -> Dict[str, Any]: "model": self.model.id, "provider": self.model.provider, }, - "db": self.memory.db.__dict__() if self.memory.db else None, + "db": { + "name": self.memory.db.__class__.__name__, + "table_name": self.memory.db.table_name if hasattr(self.memory.db, "table_name") else None, + "db_url": self.memory.db.db_url if hasattr(self.memory.db, "db_url") else None, + } + if self.memory.db + else None, } if self.memory and self.memory.db else None From 2fd75728923fd57ec9e2ac8d1a41b2f0b046ecfe Mon Sep 17 00:00:00 2001 From: Dirk Brand Date: Mon, 26 May 2025 14:21:07 +0200 Subject: [PATCH 52/55] UpdatE --- libs/agno/agno/app/fastapi/app.py | 3 +-- libs/agno/agno/app/playground/app.py | 4 +--- libs/agno/agno/app/whatsapp/app.py | 3 +-- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/libs/agno/agno/app/fastapi/app.py b/libs/agno/agno/app/fastapi/app.py index 139ace5dd4..0e33f14e51 100644 --- a/libs/agno/agno/app/fastapi/app.py +++ b/libs/agno/agno/app/fastapi/app.py @@ -1,6 +1,6 @@ import logging from os import getenv -from typing import Any, Dict, List, Optional +from typing import Any, Dict, Optional from uuid import uuid4 import uvicorn @@ -16,7 +16,6 @@ from agno.app.fastapi.async_router import get_async_router from agno.app.fastapi.sync_router import get_sync_router from agno.app.settings import APIAppSettings -from agno.app.utils import generate_id from agno.team.team import Team from agno.utils.log import log_debug diff --git a/libs/agno/agno/app/playground/app.py b/libs/agno/agno/app/playground/app.py index 20b2ef05bf..006662558c 100644 --- a/libs/agno/agno/app/playground/app.py +++ b/libs/agno/agno/app/playground/app.py @@ -1,7 +1,5 @@ -import asyncio -import threading from os import getenv -from typing import Any, Dict, List, Optional, Set, Union +from typing import Any, Dict, List, Optional, Union from urllib.parse import quote from uuid import uuid4 diff --git a/libs/agno/agno/app/whatsapp/app.py b/libs/agno/agno/app/whatsapp/app.py index 3d93bd0001..b9e2edd6f9 100644 --- a/libs/agno/agno/app/whatsapp/app.py +++ b/libs/agno/agno/app/whatsapp/app.py @@ -1,6 +1,6 @@ import logging from os import getenv -from typing import Any, Dict, List, Optional, Set, Union +from typing import Any, Dict, Optional, Set, Union from uuid import uuid4 import uvicorn @@ -13,7 +13,6 @@ from agno.agent.agent import Agent from agno.api.app import AppCreate, create_app from agno.app.settings import APIAppSettings -from agno.app.utils import generate_id from agno.app.whatsapp.async_router import get_async_router from agno.app.whatsapp.sync_router import get_sync_router from agno.team.team import Team From 48379d6595ccd061198b9b97c93306cf4ae1eff5 Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Mon, 26 May 2025 19:09:57 +0530 Subject: [PATCH 53/55] update --- libs/agno/agno/agent/agent.py | 14 +++++++++----- libs/agno/agno/team/team.py | 11 +++++++++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/libs/agno/agno/agent/agent.py b/libs/agno/agno/agent/agent.py index b63e38ad55..d60c890321 100644 --- a/libs/agno/agno/agent/agent.py +++ b/libs/agno/agno/agent/agent.py @@ -7315,11 +7315,15 @@ def cli_app( def get_agent_config_dict(self) -> Dict[str, Any]: tools = [] if self.tools is not None: - for tool in self.tools: - functions = [] - for function in tool.functions.keys(): - functions.append({"name": function, "parameters": tool.functions[function].to_dict()}) - tools.append({"name": tool.name, "functions": functions}) + if not hasattr(self, "_tools_for_model") or self._tools_for_model is None: + model = self.model + session_id = self.session_id + self.determine_tools_for_model(model=model, session_id=session_id) + + tools = [] + for tool in self._tools_for_model: + if isinstance(tool, dict) and tool.get("type") == "function": + tools.append(tool["function"]) model = None if self.model is not None: diff --git a/libs/agno/agno/team/team.py b/libs/agno/agno/team/team.py index b297109156..505a6cf480 100644 --- a/libs/agno/agno/team/team.py +++ b/libs/agno/agno/team/team.py @@ -7092,7 +7092,17 @@ def to_platform_dict(self) -> Dict[str, Any]: "model": self.model.id, "provider": self.model.provider, } + tools = [] + if self.tools is not None: + if not hasattr(self, "_tools_for_model") or self._tools_for_model is None: + model = self.model + session_id = self.session_id + self.determine_tools_for_model(model=model, session_id=session_id) + tools = [] + for tool in self._tools_for_model: + if isinstance(tool, dict) and tool.get("type") == "function": + tools.append(tool["function"]) payload = { "members": [ { @@ -7130,6 +7140,7 @@ def to_platform_dict(self) -> Dict[str, Any]: ], "mode": self.mode, "model": model, + "tools": tools, "name": self.name, "instructions": self.instructions, "description": self.description, From 2e9ed46a16fb0e4b270e72b2f4e2b2cce231b243 Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Mon, 26 May 2025 21:08:02 +0530 Subject: [PATCH 54/55] update --- libs/agno/agno/agent/agent.py | 52 +++++++++++++++++------------ libs/agno/agno/team/team.py | 46 ++++++++++++++----------- libs/agno/agno/workflow/workflow.py | 17 +--------- 3 files changed, 58 insertions(+), 57 deletions(-) diff --git a/libs/agno/agno/agent/agent.py b/libs/agno/agno/agent/agent.py index d60c890321..5c9429748d 100644 --- a/libs/agno/agno/agent/agent.py +++ b/libs/agno/agno/agent/agent.py @@ -7328,9 +7328,9 @@ def get_agent_config_dict(self) -> Dict[str, Any]: model = None if self.model is not None: model = { - "name": self.model.__class__.__name__, - "model": self.model.id, - "provider": self.model.provider, + "name": str(self.model.__class__.__name__), + "model": str(self.model.id), + "provider": str(self.model.provider), } payload = { @@ -7339,26 +7339,34 @@ def get_agent_config_dict(self) -> Dict[str, Any]: "memory": ( { "name": self.memory.__class__.__name__, - "model": { - "name": self.memory.model.__class__.__name__, - "model": self.memory.model.id, - "provider": self.memory.model.provider, - } - if self.memory.model - else { - "name": self.model.__class__.__name__, - "model": self.model.id, - "provider": self.model.provider, - }, - "db": { - "name": self.memory.db.__class__.__name__, - "table_name": self.memory.db.table_name if hasattr(self.memory.db, "table_name") else None, - "db_url": self.memory.db.db_url if hasattr(self.memory.db, "db_url") else None, - } - if self.memory.db - else None, + "model": ( + { + "name": self.memory.model.__class__.__name__, + "model": self.memory.model.id, + "provider": self.memory.model.provider, + } + if hasattr(self.memory, "model") and self.memory.model is not None + else ( + { + "name": self.model.__class__.__name__, + "model": self.model.id, + "provider": self.model.provider, + } + if self.model is not None + else None + ) + ), + "db": ( + { + "name": self.memory.db.__class__.__name__, + "table_name": self.memory.db.table_name if hasattr(self.memory.db, "table_name") else None, + "db_url": self.memory.db.db_url if hasattr(self.memory.db, "db_url") else None, + } + if hasattr(self.memory, "db") and self.memory.db is not None + else None + ), } - if self.memory and self.memory.db + if self.memory is not None and hasattr(self.memory, "db") and self.memory.db is not None else None ), "storage": { diff --git a/libs/agno/agno/team/team.py b/libs/agno/agno/team/team.py index 505a6cf480..edbd8fa53f 100644 --- a/libs/agno/agno/team/team.py +++ b/libs/agno/agno/team/team.py @@ -7153,26 +7153,34 @@ def to_platform_dict(self) -> Dict[str, Any]: "memory": ( { "name": self.memory.__class__.__name__, - "model": { - "name": self.memory.model.__class__.__name__, - "model": self.memory.model.id, - "provider": self.memory.model.provider, - } - if self.memory.model - else { - "name": self.model.__class__.__name__, - "model": self.model.id, - "provider": self.model.provider, - }, - "db": { - "name": self.memory.db.__class__.__name__, - "table_name": self.memory.db.table_name if hasattr(self.memory.db, "table_name") else None, - "db_url": self.memory.db.db_url if hasattr(self.memory.db, "db_url") else None, - } - if self.memory.db - else None, + "model": ( + { + "name": self.memory.model.__class__.__name__, + "model": self.memory.model.id, + "provider": self.memory.model.provider, + } + if hasattr(self.memory, "model") and self.memory.model is not None + else ( + { + "name": self.model.__class__.__name__, + "model": self.model.id, + "provider": self.model.provider, + } + if self.model is not None + else None + ) + ), + "db": ( + { + "name": self.memory.db.__class__.__name__, + "table_name": self.memory.db.table_name if hasattr(self.memory.db, "table_name") else None, + "db_url": self.memory.db.db_url if hasattr(self.memory.db, "db_url") else None, + } + if hasattr(self.memory, "db") and self.memory.db is not None + else None + ), } - if self.memory and self.memory.db + if self.memory is not None and hasattr(self.memory, "db") and self.memory.db is not None else None ), } diff --git a/libs/agno/agno/workflow/workflow.py b/libs/agno/agno/workflow/workflow.py index 0467ffae80..6960e27248 100644 --- a/libs/agno/agno/workflow/workflow.py +++ b/libs/agno/agno/workflow/workflow.py @@ -154,7 +154,7 @@ def run_workflow(self, **kwargs: Any): self.initialize_memory() # Update workflow_id for all agents before registration - for value in self.__class__.__dict__.items(): + for field_name, value in self.__class__.__dict__.items(): if isinstance(value, Agent): value.initialize_agent() value.workflow_id = self.workflow_id @@ -709,21 +709,6 @@ def to_config_dict(self) -> Dict[str, Any]: "storage": { "name": self.storage.__class__.__name__ if self.storage is not None else None, }, - "memory": ( - { - "name": self.memory.__class__.__name__, - "model": { - "name": self.memory.model.__class__.__name__, - "model": self.memory.model.id, - "provider": self.memory.model.provider, - } - if self.memory.model - else None, - "db": self.memory.db.__dict__() if self.memory.db else None, - } - if self.memory and self.memory.db - else None - ), } agents = [] From 6fa43c303c0cb03b29c9b9e8de03064ce806fa89 Mon Sep 17 00:00:00 2001 From: ayush0054 Date: Mon, 26 May 2025 21:32:12 +0530 Subject: [PATCH 55/55] FIX THE VALIDATION ERROR --- libs/agno/agno/agent/agent.py | 18 +++++++++--------- libs/agno/agno/app/playground/app.py | 4 ++-- libs/agno/agno/team/team.py | 18 +++++++++--------- libs/agno/agno/workflow/workflow.py | 8 +++----- 4 files changed, 23 insertions(+), 25 deletions(-) diff --git a/libs/agno/agno/agent/agent.py b/libs/agno/agno/agent/agent.py index 5c9429748d..df6e8d254a 100644 --- a/libs/agno/agno/agent/agent.py +++ b/libs/agno/agno/agent/agent.py @@ -7309,22 +7309,22 @@ def cli_app( break self.print_response( - message=message, stream=stream, markdown=markdown, user_id=user_id, session_id=session_id**kwargs + message=message, stream=stream, markdown=markdown, user_id=user_id, session_id=session_id, **kwargs ) def get_agent_config_dict(self) -> Dict[str, Any]: - tools = [] + tools: List[Dict[str, Any]] = [] if self.tools is not None: if not hasattr(self, "_tools_for_model") or self._tools_for_model is None: - model = self.model + team_model = self.model session_id = self.session_id - self.determine_tools_for_model(model=model, session_id=session_id) - - tools = [] - for tool in self._tools_for_model: - if isinstance(tool, dict) and tool.get("type") == "function": - tools.append(tool["function"]) + if team_model and session_id is not None: + self.determine_tools_for_model(model=team_model, session_id=session_id) + if self._tools_for_model is not None: + for tool in self._tools_for_model: + if isinstance(tool, dict) and tool.get("type") == "function": + tools.append(tool["function"]) model = None if self.model is not None: model = { diff --git a/libs/agno/agno/app/playground/app.py b/libs/agno/agno/app/playground/app.py index 006662558c..461cb02e91 100644 --- a/libs/agno/agno/app/playground/app.py +++ b/libs/agno/agno/app/playground/app.py @@ -46,7 +46,7 @@ def __init__( self.settings: PlaygroundSettings = settings or PlaygroundSettings() self.api_app: Optional[FastAPI] = api_app self.router: Optional[APIRouter] = router - self.endpoints_created: Dict[str, Dict[str, str]] = {} + self.endpoints_created: Optional[PlaygroundEndpointCreate] = None self.app_id: Optional[str] = app_id self.name: Optional[str] = name self.monitoring = monitoring @@ -231,7 +231,7 @@ def to_dict(self) -> Dict[str, Any]: ] if self.workflows else [], - "endpointData": self.endpoints_created, + "endpointData": self.endpoints_created.model_dump(exclude_none=True) if self.endpoints_created else {}, "type": "playground", "description": self.description, } diff --git a/libs/agno/agno/team/team.py b/libs/agno/agno/team/team.py index edbd8fa53f..05026c70f0 100644 --- a/libs/agno/agno/team/team.py +++ b/libs/agno/agno/team/team.py @@ -7092,17 +7092,17 @@ def to_platform_dict(self) -> Dict[str, Any]: "model": self.model.id, "provider": self.model.provider, } - tools = [] + tools: List[Dict[str, Any]] = [] if self.tools is not None: if not hasattr(self, "_tools_for_model") or self._tools_for_model is None: - model = self.model - session_id = self.session_id - self.determine_tools_for_model(model=model, session_id=session_id) - - tools = [] - for tool in self._tools_for_model: - if isinstance(tool, dict) and tool.get("type") == "function": - tools.append(tool["function"]) + team_model = self.model + if team_model is not None: + self.determine_tools_for_model(model=team_model, tools=self.tools) + + if self._tools_for_model is not None: + for tool in self._tools_for_model: + if isinstance(tool, dict) and tool.get("type") == "function": + tools.append(tool["function"]) payload = { "members": [ { diff --git a/libs/agno/agno/workflow/workflow.py b/libs/agno/agno/workflow/workflow.py index 6960e27248..29fed85e32 100644 --- a/libs/agno/agno/workflow/workflow.py +++ b/libs/agno/agno/workflow/workflow.py @@ -689,10 +689,8 @@ def register_workflow(self, force: bool = False) -> None: ) log_debug(f"Successfully registered workflow: {self.name} (ID: {self.workflow_id})") - return True except Exception as e: log_warning(f"Failed to register workflow: {e}") - return False def to_config_dict(self) -> Dict[str, Any]: """Convert the workflow to a config dictionary including all agents and teams. @@ -701,7 +699,7 @@ def to_config_dict(self) -> Dict[str, Any]: Dict[str, Any]: Dictionary representation of the workflow config. """ # Basic workflow information - config = { + config: Dict[str, Any] = { "name": self.name, "description": self.description, "type": "workflow", @@ -711,8 +709,8 @@ def to_config_dict(self) -> Dict[str, Any]: }, } - agents = [] - teams = [] + agents: List[Dict[str, Any]] = [] + teams: List[Dict[str, Any]] = [] for attr_name in dir(self.__class__): # Skip private/special attributes and methods