feat: Add agent listing functionality (#444)

* Create agent listing functionality

* feat: add agent listing functionality with proper documentation and style

* removed pyopenagi and focusing only on cerebrum
This commit is contained in:
Krish Mehta
2025-02-16 17:08:51 -05:00
committed by GitHub
parent 5282688ea9
commit 21e5f43a85
5 changed files with 228 additions and 27 deletions

5
.gitignore vendored
View File

@@ -206,4 +206,7 @@ workspace
cache
# Ignore configuration files
aios/config/config.yaml
aios/config/config.yaml
# ignore cerebrum
Cerebrum/*

View File

@@ -21,4 +21,4 @@ llm:
server:
host: "localhost"
port: 8000
port: 8000

View File

@@ -60,8 +60,14 @@ python -m pip install --upgrade pip
pip install -r "$INSTALL_DIR/src/requirements.txt"
# Remove non-kernel files
# Remove non-kernel files but preserve necessary scripts
mkdir -p "$INSTALL_DIR/src/scripts_temp"
cp "$INSTALL_DIR/src/scripts/list_agents.py" "$INSTALL_DIR/src/scripts_temp/"
rm -rf "$INSTALL_DIR/src/scripts"
mkdir -p "$INSTALL_DIR/src/scripts"
mv "$INSTALL_DIR/src/scripts_temp/list_agents.py" "$INSTALL_DIR/src/scripts/"
rm -rf "$INSTALL_DIR/src/scripts_temp"
rm -rf "$INSTALL_DIR/src/tests"
rm -rf "$INSTALL_DIR/src/docs"
@@ -99,14 +105,14 @@ start() {
return
fi
source "$INSTALL_DIR/venv/bin/activate"
# Check Python version before starting
PYTHON_VERSION=$(python -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')
if [[ ! "$PYTHON_VERSION" =~ ^3\.(10|11)$ ]]; then
echo "Error: Unsupported Python version $PYTHON_VERSION. Only Python 3.10 or 3.11 are supported."
return 1
fi
load_env
cd "$INSTALL_DIR/src"
nohup uvicorn runtime.kernel:app --reload > "$INSTALL_DIR/server.log" 2>&1 &
@@ -133,13 +139,13 @@ restart() {
update() {
echo "Checking for updates..."
# Stop server if running
if [ -f "$PID_FILE" ]; then
echo "Stopping server for update..."
stop
fi
# Check Python version before updating
source "$INSTALL_DIR/venv/bin/activate"
PYTHON_VERSION=$(python -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')
@@ -147,43 +153,43 @@ update() {
echo "Error: Unsupported Python version $PYTHON_VERSION. Only Python 3.10 or 3.11 are supported."
return 1
fi
# Store current commit hash
cd "$INSTALL_DIR/src"
current_hash=$(git rev-parse HEAD)
# Fetch and pull latest changes
git fetch origin
remote_hash=$(git rev-parse origin/$(git rev-parse --abbrev-ref HEAD))
if [ "$current_hash" = "$remote_hash" ]; then
echo "Already up to date!"
start
return
fi
echo "Updates found, installing..."
# Pull latest changes
git pull
# Activate venv and update dependencies
pip install -r requirements.txt
# Remove any new non-kernel files that might have been added
rm -rf "$INSTALL_DIR/src/scripts"
rm -rf "$INSTALL_DIR/src/tests"
rm -rf "$INSTALL_DIR/src/docs"
rm -f "$INSTALL_DIR/src/requirements-cuda.txt"
rm -f "$INSTALL_DIR/src/.dockerignore"
rm -f "$INSTALL_DIR/src/.env.example"
rm -f "$INSTALL_DIR/src/.precommit-config.yaml"
rm -f "$INSTALL_DIR/src/README.md"
rm -f "$INSTALL_DIR/src/Dockerfile"
echo "Update complete!"
# Restart server
start
}
@@ -191,18 +197,18 @@ update() {
clean() {
# First stop everything
stop
# Deactivate virtual environment if active
if [ -n "$VIRTUAL_ENV" ]; then
deactivate
fi
# Remove the installation directory
rm -rf "$INSTALL_DIR"
# Remove the executable
rm -f "$HOME/.local/bin/aios"
echo "AIOS installation cleaned up successfully"
}
@@ -210,17 +216,17 @@ env_add() {
echo "Adding new environment variable"
echo "Enter variable name (e.g., API_KEY):"
read varname
# Validate variable name
if [[ ! $varname =~ ^[A-Za-z_][A-Za-z0-9_]*$ ]]; then
echo "Invalid variable name. Use only letters, numbers, and underscores, and start with a letter or underscore."
return 1
fi
echo "Enter variable value:"
read -s varvalue # -s flag hides the input (good for sensitive values)
echo # Add newline after hidden input
# Check if variable already exists
if grep -q "^$varname=" "$ENV_FILE" 2>/dev/null; then
echo "Variable $varname already exists. Do you want to update it? (y/n)"
@@ -232,7 +238,7 @@ env_add() {
# Remove old value
sed -i.bak "/^$varname=/d" "$ENV_FILE" && rm "$ENV_FILE.bak"
fi
# Add new value
echo "$varname=$varvalue" >> "$ENV_FILE"
echo "Environment variable added successfully"
@@ -255,7 +261,7 @@ env_remove() {
echo ""
echo "Enter the number of the variable to remove:"
read varnum
if [[ "$varnum" =~ ^[0-9]+$ ]]; then
varname=$(sed -n "${varnum}p" "$ENV_FILE" | cut -d= -f1)
if [ -n "$varname" ]; then
@@ -331,6 +337,31 @@ Subcommands:
- Immediate removal from configuration
Note: Server restart required for environment changes to take effect
HELP
;;
esac
;;
"agents")
case "$2" in
"list")
# Activate virtual environment and run Python script
source "$INSTALL_DIR/venv/bin/activate"
python "$INSTALL_DIR/src/scripts/list_agents.py"
;;
*)
cat << 'HELP'
Agent Management
Usage: aios agents <subcommand>
Subcommands:
list List all available agents
- Shows Cerebrum built-in agents
- Shows cached agents from previous installations
- Shows available agents to install from AIOS foundation
- Displays versions and sources for each agent
Note: Requires active internet connection for online agent listing
HELP
;;
esac
@@ -373,6 +404,14 @@ Commands:
remove - Remove a variable (interactive)
Environment changes require server restart to take effect
agents Manage AIOS agents
Subcommands:
list - List all available agents
• Shows Cerebrum built-in agents
• Shows cached agents from previous installations
• Shows available agents to install from AIOS foundation
• Displays versions and sources for each agent
clean Uninstall AIOS completely
- Stops any running server
- Removes all AIOS files and configurations
@@ -383,6 +422,7 @@ Commands:
Examples:
aios start # Start the server
aios env add # Add a new API key or configuration value
aios agents list # View all available agents
aios update # Update to the latest version
Notes:
@@ -428,4 +468,4 @@ Note: AIOS requires Python 3.10 or 3.11
For more information, visit:
https://github.com/agiresearch/AIOS
COMPLETE
COMPLETE

View File

@@ -1,2 +1,5 @@
# scripts
## list_agents.py
List all agents available to use and install.

155
scripts/list_agents.py Normal file
View File

@@ -0,0 +1,155 @@
# This file provides functionality to list both offline and online AIOS agents.
# It can display locally installed agents as well as agents available for installation
# from the AIOS foundation.
import os
import importlib
from pathlib import Path
from typing import Dict, List
from cerebrum.manager.agent import AgentManager
import platformdirs
def parse_version_from_filename(filename: str) -> str:
"""Extract version from a filename like 'agent_1.2.3.agent'
Args:
filename (str): The filename to parse version from
Returns:
str: The extracted version string
"""
return filename.replace('agent_', '').replace('.agent', '')
def get_offline_agents() -> Dict[str, List[str]]:
"""Get all locally downloaded/installed agents with their versions
This function checks multiple locations for installed agents:
- Cerebrum built-in agents
- User's cache directory
Returns:
Dict[str, List[str]]: A dictionary mapping agent IDs to their available versions
"""
offline_agents = {}
# Check in Cerebrum built-in agents
try:
cerebrum_path = importlib.util.find_spec('cerebrum').submodule_search_locations[0]
example_paths = [
os.path.join(cerebrum_path, "example", "agents"),
os.path.join(cerebrum_path, "cerebrum", "example", "agents")
]
for example_path in example_paths:
if os.path.exists(example_path):
for agent in os.listdir(example_path):
agent_path = os.path.join(example_path, agent)
if os.path.isdir(agent_path) and os.path.exists(os.path.join(agent_path, 'agent.py')):
agent_id = f"example/{agent}"
if agent_id not in offline_agents:
offline_agents[agent_id] = ["built-in"]
except (ImportError, AttributeError):
print("Error getting offline agents: cerebrum package not found")
# Check in cache directory
try:
cache_dir = Path(platformdirs.user_cache_dir("cerebrum"))
if cache_dir.exists():
for author in cache_dir.iterdir():
if author.is_dir():
for agent in author.iterdir():
if agent.is_dir():
agent_id = f"{author.name}/{agent.name}"
versions = []
for version_file in agent.glob("*.agent"):
version = parse_version_from_filename(version_file.stem)
versions.append(version)
if versions:
offline_agents[agent_id] = sorted(versions, key=lambda v: [int(x) for x in v.split('.')])
except Exception as e:
print(f"Error getting offline agents: Could not access cache directory: {str(e)}")
return offline_agents
def get_online_agents() -> Dict[str, List[str]]:
"""Get all available online agents from AIOS foundation with their versions
This function connects to the AIOS foundation server to retrieve a list of
all available agents and their versions.
Returns:
Dict[str, List[str]]: A dictionary mapping agent IDs to their available versions
"""
online_agents = {}
try:
manager = AgentManager("https://app.aios.foundation/")
agent_list = manager.list_available_agents()
for agent_info in agent_list:
# Parse the full agent path which includes version
full_path = agent_info["agent"]
agent_path, version = full_path.rsplit("/", 1)
if agent_path in online_agents:
online_agents[agent_path].append(version)
else:
online_agents[agent_path] = [version]
# Sort versions for each agent
for agent_id in online_agents:
online_agents[agent_id] = sorted(online_agents[agent_id], key=lambda v: [int(x) for x in v.split('.')])
except Exception as e:
print(f"Error getting online agents: {str(e)}")
return online_agents
def main():
"""Main function to list all offline and online AIOS agents
This function retrieves and displays:
- Offline agents that are ready to use (locally installed)
- Online agents that are available to install
Each agent entry shows its latest version and any other available versions.
"""
# Get offline and online agents
offline_agents = get_offline_agents()
online_agents = get_online_agents()
# Print results
print("\n=== List of Agents ===")
print("Offline Agents (Ready to Use):")
print("-" * 50)
if offline_agents:
for agent_id in sorted(offline_agents.keys()):
versions = offline_agents[agent_id]
if len(versions) == 1 and versions[0] in ["local", "built-in"]:
print(f"{agent_id} [{versions[0]}]")
else:
latest_version = versions[-1] if versions else "unknown"
other_versions = versions[:-1] if len(versions) > 1 else []
version_str = f"v{latest_version}"
if other_versions:
version_str += f" (also: {', '.join(f'v{v}' for v in other_versions)})"
print(f"{agent_id} [{version_str}]")
else:
print(" No agents installed locally")
print("-" * 50)
print("\nOnline Agents (Available to Install):")
print("-" * 50)
installable_agents = set(online_agents.keys()) - set(offline_agents.keys())
if installable_agents:
for agent_id in sorted(installable_agents):
versions = online_agents[agent_id]
latest_version = versions[-1] if versions else "unknown"
other_versions = versions[:-1] if len(versions) > 1 else []
version_str = f"v{latest_version}"
if other_versions:
version_str += f" (also: {', '.join(f'v{v}' for v in other_versions)})"
print(f"{agent_id} [{version_str}]")
else:
print(" No additional agents available to install")
print("-" * 50)
if __name__ == "__main__":
main()