Repository: phidatahq/phidata
File: libs/agno/agno/os/app.py (Python)

Code before:
        self,
        entities: Optional[List[Any]],
    ) -> None:
        """Check for duplicate IDs in a list of entities.

        Args:
            entities: List of agents, teams, or workflows

        Raises:
            ValueError: If duplicate IDs are found
        """
        if not entities:
            return

        seen_ids: List[str] = []

        for entity in entities:
            entity_id = entity.id
            # If id is None, generate it the same way initialization does
            if entity_id is None:
                if hasattr(entity, "name") and entity.name:
                    entity_id = generate_id_from_name(entity.name)
                else:
                    continue  # Will get unique UUID during initialization

            if entity_id in seen_ids:
                raise ValueError(f"Duplicate IDs found in AgentOS: '{entity_id}'")
            seen_ids.append(entity_id)

    def _make_app(self, lifespan: Optional[Any] = None) -> FastAPI:
        # Adjust the FastAPI app lifespan to handle MCP connections if relevant
        app_lifespan = lifespan
        if self.mcp_tools is not None:
            mcp_tools_lifespan = partial(mcp_lifespan, mcp_tools=self.mcp_tools)
            # If there is already a lifespan, combine it with the MCP lifespan
            if lifespan is not None:
                # Combine both lifespans
                @asynccontextmanager
                async def combined_lifespan(app: FastAPI):
                    # Run both lifespans
                    async with lifespan(app):  # type: ignore
                        async with mcp_tools_lifespan(app):  # type: ignore
                            yield

                app_lifespan = combined_lifespan
            else:
                app_lifespan = mcp_tools_lifespan

        return FastAPI(
            title=self.name or "Agno AgentOS",
            version=self.version or "1.0.0",

Review comment (refactor):
Rather raise for all the duplicates at the end. Otherwise the user will get an error, then fix it, then another error on the next try, then fix it, etc. 

Code after:
        """
        duplicate_ids: List[str] = []

        for entities in [self.agents, self.teams, self.workflows]:
            if not entities:
                continue
            seen_ids: set[str] = set()
            for entity in entities:
                entity_id = entity.id
                if entity_id is None:
                    continue
                if entity_id in seen_ids:
                    if entity_id not in duplicate_ids:
                        duplicate_ids.append(entity_id)
                else:
                    seen_ids.add(entity_id)

        if duplicate_ids:
            raise ValueError(f"Duplicate IDs found in AgentOS: {', '.join(repr(id_) for id_ in duplicate_ids)}")

    def _make_app(self, lifespan: Optional[Any] = None) -> FastAPI:
        # Adjust the FastAPI app lifespan to handle MCP connections if relevant
        app_lifespan = lifespan
        if self.mcp_tools is not None:
            mcp_tools_lifespan = partial(mcp_lifespan, mcp_tools=self.mcp_tools)
            # If there is already a lifespan, combine it with the MCP lifespan
            if lifespan is not None:
                # Combine both lifespans
                @asynccontextmanager
                async def combined_lifespan(app: FastAPI):
                    # Run both lifespans
                    async with lifespan(app):  # type: ignore
                        async with mcp_tools_lifespan(app):  # type: ignore
                            yield

                app_lifespan = combined_lifespan
            else:
                app_lifespan = mcp_tools_lifespan

        return FastAPI(
            title=self.name or "Agno AgentOS",
            version=self.version or "1.0.0",
            description=self.description or "An agent operating system.",
            docs_url="/docs" if self.settings.docs_enabled else None,
            redoc_url="/redoc" if self.settings.docs_enabled else None,
            openapi_url="/openapi.json" if self.settings.docs_enabled else None,
            lifespan=app_lifespan,
        )

    def _initialize_agents(self) -> None:
        """Initialize and configure all agents for AgentOS usage."""