Add multi-agent API functionality in multi-agents-api.py and `multi…#476
Add multi-agent API functionality in multi-agents-api.py and `multi…#476MervinPraison merged 1 commit intomainfrom
multi-agents-api.py and `multi…#476Conversation
…-agents-group-api.py`, increment version to 0.0.80 in `pyproject.toml` and `uv.lock`, and enhance agent launch logic in `agents.py` with improved endpoint management and healthcheck capabilities.
✅ Deploy Preview for praisonai canceled.
|
|
Caution Review failedThe pull request is closed. WalkthroughThis update introduces new scripts for launching multi-agent systems via the Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant FastAPI Server
participant Agents Collection
participant Research Agent
participant Summarise Agent
User->>FastAPI Server: POST /agents with query
FastAPI Server->>Agents Collection: Receive query
Agents Collection->>Research Agent: Process query (e.g., search AI 2024)
Research Agent-->>Agents Collection: Research result
Agents Collection->>Summarise Agent: Summarize research result
Summarise Agent-->>Agents Collection: Summary points
Agents Collection-->>FastAPI Server: Chain of agent results
FastAPI Server-->>User: JSON response with results
Suggested labels
Poem
Tip ⚡️ Faster reviews with caching
Enjoy the performance boost—your workflow just got faster. 📜 Recent review detailsConfiguration used: CodeRabbit UI ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (4)
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Hello @MervinPraison, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
Summary of Changes
This pull request introduces multi-agent API functionality, enhancing the praisonaiagents library. It adds new API endpoints for launching and interacting with groups of agents. Specifically, it creates multi-agents-api.py and multi-agents-group-api.py to define agent configurations and launch them as API services. The agents.py file is modified to include improved endpoint management and health check capabilities. The version number is also incremented from 0.0.79 to 0.0.80 in pyproject.toml and uv.lock.
Highlights
- Multi-Agent API Creation: Introduces
multi-agents-api.pyandmulti-agents-group-api.pyto define and launch groups of agents as API endpoints. - Enhanced Agent Launch Logic: Modifies
agents.pyto include improved endpoint management, health check capabilities, and better handling of FastAPI dependencies. - Version Increment: Increments the library version from 0.0.79 to 0.0.80 in
pyproject.tomlanduv.lock.
Changelog
Click here to see the changelog
- src/praisonai-agents/multi-agents-api.py
- Creates a new file to define and launch a research agent and a summarization agent as a single API endpoint.
- Defines a research agent with internet search tool and a summarization agent.
- Launches the agents on port 3030 at the /agents path.
- src/praisonai-agents/multi-agents-group-api.py
- Creates a new file to define and launch multiple groups of agents as separate API endpoints.
- Defines a research agent and a summarization agent, then creates two agent groups.
- Launches the first group on port 3030 at the /agents path and the second group at the /agents2 path.
- src/praisonai-agents/praisonaiagents/agents/agents.py
- Adds global variables to manage shared servers, registered endpoints, and shared FastAPI apps to handle multiple agent groups.
- Introduces a
launchmethod to launch agents as a single API endpoint, processing queries sequentially through all agents. - Includes error handling, dependency checks (FastAPI, uvicorn), and dynamic endpoint registration.
- Adds health check endpoint at
/health. - Adds root endpoint with welcome message at
/. - Handles both direct JSON and form data for queries.
- Starts the server in a separate thread to avoid blocking the main thread.
- Detects if it's the last launch call in the script and blocks the main thread to keep the server alive.
- src/praisonai-agents/pyproject.toml
- Increments the version number from 0.0.79 to 0.0.80.
- src/praisonai-agents/uv.lock
- Updates the version number from 0.0.79 to 0.0.80 to match the
pyproject.tomlfile.
- Updates the version number from 0.0.79 to 0.0.80 to match the
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.
| Feature | Command | Description |
|---|---|---|
| Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
| Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
| Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments. |
| Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
Agents in code, a digital dance,
Each with a task, a focused trance.
APIs hum, a network's grace,
Solving problems at a rapid pace.
Footnotes
-
Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩
There was a problem hiding this comment.
Code Review
The pull request introduces multi-agent API functionality, enhances agent launch logic, and increments the project version. The new launch method in agents.py is comprehensive, but there are areas where improvements can be made to enhance maintainability and error handling. The addition of new API files is a good step towards providing more accessibility to the agents.
Summary of Findings
- Global Variable Naming: The global variables for managing shared servers could benefit from more descriptive names and explicit type hinting using
typing.Dict. - Exception Handling: The
exceptblock in thehandle_queryfunction is too broad and should catch specific exceptions for better error handling. - Path Conflict Resolution: The path conflict resolution strategy is basic. Consider suggesting available paths or providing a configuration option for specifying a different path.
- Agent Error Handling: The error handling within the agent processing loop could be improved to allow for halting or retrying agents instead of always continuing with the original input.
- Launch Detection Logic: The logic for detecting the last
launch()call is complex and potentially unreliable. A more explicit method for signaling completion should be considered.
Merge Readiness
The pull request introduces valuable functionality but requires attention to error handling, naming conventions, and conflict resolution. Addressing these points will improve the code's robustness and maintainability. I am unable to directly approve this pull request, and recommend that others review and approve this code before merging. At a minimum, the HIGH severity comments should be addressed before merging.
| _agents_server_started = {} # Dict of port -> started boolean | ||
| _agents_registered_endpoints = {} # Dict of port -> Dict of path -> endpoint_id | ||
| _agents_shared_apps = {} # Dict of port -> FastAPI app |
There was a problem hiding this comment.
Consider using a more descriptive name for these global variables to improve readability and avoid potential naming conflicts. Also, consider using typing.Dict for type hinting to be more explicit about the types involved.1
Style Guide References
| _agents_server_started = {} # Dict of port -> started boolean | |
| _agents_registered_endpoints = {} # Dict of port -> Dict of path -> endpoint_id | |
| _agents_shared_apps = {} # Dict of port -> FastAPI app | |
| agent_servers_started: typing.Dict[int, bool] = {} | |
| agent_registered_endpoints: typing.Dict[int, typing.Dict[str, str]] = {} | |
| agent_shared_apps: typing.Dict[int, FastAPI] = {} |
Footnotes
-
Use descriptive names for variables to improve readability and maintainability. Use
typing.Dictfor explicit type hinting. ↩
|
|
||
| # Check if path is already registered for this port | ||
| if path in _agents_registered_endpoints[port]: | ||
| logging.warning(f"Path '{path}' is already registered on port {port}. Please use a different path.") | ||
| print(f"⚠️ Warning: Path '{path}' is already registered on port {port}.") | ||
| # Use a modified path to avoid conflicts | ||
| original_path = path | ||
| instance_id = str(uuid.uuid4())[:6] | ||
| path = f"{path}_{instance_id}" | ||
| logging.warning(f"Using '{path}' instead of '{original_path}'") |
There was a problem hiding this comment.
The logic for handling path conflicts could be improved. Instead of simply appending a UUID, consider implementing a more user-friendly approach, such as suggesting available paths or providing a configuration option to specify a different path.1
# Suggest available paths or provide a configuration option
logging.warning(f"Path '{path}' is already registered on port {port}. Please use a different path or configure a unique path.")
print(f"⚠️ Warning: Path '{path}' is already registered on port {port}. Please use a different path or configure a unique path.")
return # Stop further execution to avoid conflictsStyle Guide References
Footnotes
-
Implement user-friendly conflict resolution strategies. ↩
| query = request_data["query"] | ||
| except: | ||
| # Fallback to form data or query params | ||
| form_data = await request.form() | ||
| if "query" in form_data: | ||
| query = form_data["query"] | ||
| else: |
There was a problem hiding this comment.
The except block is too broad. It should catch specific exceptions like json.JSONDecodeError and KeyError to handle different error scenarios more precisely. This will help in debugging and prevent masking unexpected errors.1
except json.JSONDecodeError:
logging.error("Invalid JSON format in request", exc_info=True)
raise HTTPException(status_code=400, detail="Invalid JSON format in request")
except KeyError:
logging.error("Missing 'query' field in request", exc_info=True)
raise HTTPException(status_code=400, detail="Missing 'query' field in request")Style Guide References
Footnotes
-
Catch specific exceptions to handle different error scenarios more precisely. ↩
| current_input = response | ||
| except Exception as e: | ||
| logging.error(f"Error with agent {agent.name}: {str(e)}", exc_info=True) | ||
| results.append({ | ||
| "agent": agent.name, | ||
| "error": str(e) | ||
| }) |
There was a problem hiding this comment.
Instead of continuing with the original input when an agent encounters an error, consider adding a mechanism to halt the sequence or retry the agent with a modified input. This could prevent cascading errors and improve the overall reliability of the multi-agent system.1
except Exception as e:
logging.error(f"Error with agent {agent.name}: {str(e)}", exc_info=True)
results.append({
"agent": agent.name,
"error": str(e)
})
# Option to halt or retry instead of continuing
break # Example: Halt on errorStyle Guide References
Footnotes
-
Implement mechanisms to handle agent errors and prevent cascading failures. ↩
|
|
||
| # If this is called from a Python script (not interactive), try to detect if it's the last launch call | ||
| if len(stack) > 1 and stack[1].filename.endswith('.py'): | ||
| caller_frame = stack[1] | ||
| caller_line = caller_frame.lineno | ||
|
|
||
| try: | ||
| # Read the file to check if there are more launch calls after this one | ||
| with open(caller_frame.filename, 'r') as f: | ||
| lines = f.readlines() | ||
|
|
||
| # Check if there are more launch() calls after the current line | ||
| has_more_launches = False | ||
| for line in lines[caller_line:]: | ||
| if '.launch(' in line and not line.strip().startswith('#'): | ||
| has_more_launches = True | ||
| break | ||
|
|
||
| # If this is the last launch call, block the main thread | ||
| if not has_more_launches: | ||
| try: | ||
| print("\nAll agents registered. Press Ctrl+C to stop the servers.") | ||
| while True: | ||
| time.sleep(1) | ||
| except KeyboardInterrupt: | ||
| print("\nServers stopped") | ||
| except Exception as e: | ||
| # If something goes wrong with detection, block anyway to be safe | ||
| logging.error(f"Error in launch detection: {e}") | ||
| try: | ||
| print("\nKeeping servers alive. Press Ctrl+C to stop.") | ||
| while True: | ||
| time.sleep(1) | ||
| except KeyboardInterrupt: |
There was a problem hiding this comment.
The logic for detecting the last launch() call is complex and might not be reliable in all scenarios. Consider providing a more explicit way for the user to signal that all agents have been registered, such as a dedicated function call or a configuration option. This would make the code more robust and easier to understand.1
# Provide a dedicated function or configuration option
print("\nAll agents registered. Press Ctrl+C to stop the servers.")
while True:
time.sleep(1)Style Guide References
Footnotes
-
Provide explicit mechanisms for signaling the completion of agent registration. ↩
Add multi-agent API functionality in `multi-agents-api.py` and `multi…
…-agents-group-api.py
, increment version to 0.0.80 inpyproject.tomlanduv.lock, and enhance agent launch logic inagents.py` with improved endpoint management and healthcheck capabilities.Summary by CodeRabbit