Skip to content

Commit

Permalink
fix: add local built-in agent support (#22)
Browse files Browse the repository at this point in the history
* Fix 'NoneType' Object Error in Tool Loading

## What Changed
1. **Local Tool Loading**: Added logic to check and load tools from the local directory first.
2. **Fixed NoneType Error**: Resolved the issue where the version was `None`, causing a `'NoneType' object has no attribute 'replace'` error.
3. **Improved Error Messages**: Enhanced error messages for better clarity and debugging.

## How It Works Now
- **Local First**: The system first checks the local tools folder.
- **Use Local Tool**: If a tool is found locally, it uses that version.
- **Remote Fallback**: If not found locally, it downloads the tool.
- **Version Handling**: Retrieves version from local `config.json` to ensure correct versioning.

## Testing
- Tested with `math_agent` using local `wikipedia` tool.
- Tested with `story_teller` agent.
- Confirmed no NoneType errors occur.

* Fix 'NoneType' Object Error in Tool Loading

## What Changed
1. **Local Tool Loading**: Added logic to check and load tools from the local directory first.
2. **Fixed NoneType Error**: Resolved the issue where the version was `None`, causing a `'NoneType' object has no attribute 'replace'` error.
3. **Improved Error Messages**: Enhanced error messages for better clarity and debugging.

## How It Works Now
- **Local First**: The system first checks the local tools folder.
- **Use Local Tool**: If a tool is found locally, it uses that version.
- **Remote Fallback**: If not found locally, it downloads the tool.
- **Version Handling**: Retrieves version from local `config.json` to ensure correct versioning.

* Fix 'NoneType' Object Error in Tool Loading

## What Changed
1. **Local Tool Loading**: Added logic to check and load tools from the local directory first.
2. **Fixed NoneType Error**: Resolved the issue where the version was `None`, causing a `'NoneType' object has no attribute 'replace'` error.
3. **Improved Error Messages**: Enhanced error messages for better clarity and debugging.

## How It Works Now
- **Local First**: The system first checks the local tools folder.
- **Use Local Tool**: If a tool is found locally, it uses that version.
- **Remote Fallback**: If not found locally, it downloads the tool.
- **Version Handling**: Retrieves version from local `config.json` to ensure correct versioning.

* Fix 'NoneType' Object Error in Tool Loading

## What Changed
1. **Local Tool Loading**: Added logic to check and load tools from the local directory first.
2. **Fixed NoneType Error**: Resolved the issue where the version was `None`, causing a `'NoneType' object has no attribute 'replace'` error.
3. **Improved Error Messages**: Enhanced error messages for better clarity and debugging.

## How It Works Now
- **Local First**: The system first checks the local tools folder.
- **Use Local Tool**: If a tool is found locally, it uses that version.
- **Remote Fallback**: If not found locally, it downloads the tool.
- **Version Handling**: Retrieves version from local `config.json` to ensure correct versioning.

* Fix

* Create python-package-conda.yml

* Update python-package-conda.yml

* Update python-package-conda.yml

* Update python-package-conda.yml

* Update python-package-conda.yml

* Update python-package-conda.yml

* Update python-package-conda.yml

* Update python-package-conda.yml

* Update python-package-conda.yml

* fix: improve agent loading and error handling

- Add debug logs to track agent loading
- Fix config handling in agent manager
- Update seeact_demo_agent config format

The code now:
- Shows better error messages
- Loads agents more reliably
- Keeps full config when packaging"

* Add Local Agent Support to run-agent

## What's Changed
- Added `--local_agent` flag to support loading agents from local filesystem
- Added path validation for local agent loading
- Simplified agent execution logic

* Refactor Configuration Management for URLs

This PR refactors the configuration management for Cerebrum by moving the URLs for the Agent and Tool Managers into a centralized configuration file (default.yaml). This change allows for easier management and customization of these URLs across different environments.
Changes:
Added agent_hub_url and tool_hub_url to default.yaml.
2. Updated AutoAgent and AutoTool classes to use URLs from the configuration file.

* Revert "Add Local Agent Support to run-agent"

This reverts commit 1324ed1.

* Reapply "Add Local Agent Support to run-agent"

* Revert "Refactor Configuration Management for URLs"

This reverts commit 53fd503.

* Update run_agent.py

* Update run_agent.py

* fix: LLM API Key Error Handling

## What's Changed
- Added proper error handling for invalid API keys
- Fixed response parsing for LiteLLM completion calls
- Added HTTP status codes for different error types:
  - 402 for API key issues
  - 500 for other errors

* Update

* fix: add local built-in agent support

## What Changed
1. Added `_get_builtin_agent_path` method to find local built-in agents
2. Added dependency check for local built-in agents
3. Fixed agent loading flow for local built-in examples
  • Loading branch information
XiangZhang-zx authored Jan 22, 2025
1 parent bf89343 commit 997d87a
Showing 1 changed file with 82 additions and 14 deletions.
96 changes: 82 additions & 14 deletions cerebrum/manager/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,56 @@ def install_agent_reqs(self, agent_path: Path):

temp_reqs_path.unlink() # Remove temporary requirements file

def _check_and_install_dependencies(self, agent_path: str) -> None:
"""Check and install dependencies for agent"""
# First check meta_requirements.txt
req_file = os.path.join(agent_path, "meta_requirements.txt")

if not os.path.exists(req_file):
# For built-in agents, also check requirements.txt
req_file = os.path.join(agent_path, "requirements.txt")

if os.path.exists(req_file):
logger.info(f"Installing dependencies from {req_file}")
try:
subprocess.check_call([
sys.executable,
"-m",
"pip",
"install",
"-r",
req_file,
"--quiet"
])
logger.info("Dependencies installed successfully")
except Exception as e:
logger.error(f"Failed to install dependencies: {str(e)}")
raise
else:
logger.warning(f"No requirements file found at {req_file}")

def is_builtin_agent(self, name: str) -> bool:
"""Check if an agent is a built-in example agent"""
builtin_paths = [
os.path.join(os.path.dirname(self.base_path), "cerebrum", "example", "agents", name),
os.path.join(os.path.dirname(self.base_path), "example", "agents", name),
]
return any(os.path.exists(path) for path in builtin_paths)

def _get_builtin_agent_path(self, name: str) -> str:
"""Get the path for a built-in agent"""
# Try both possible paths for built-in agents
possible_paths = [
os.path.join(os.path.dirname(self.base_path), "cerebrum", "example", "agents", name),
os.path.join(os.path.dirname(self.base_path), "example", "agents", name),
]

for path in possible_paths:
if os.path.exists(path):
return path

raise FileNotFoundError(f"Built-in agent '{name}' not found in any of the expected paths: {possible_paths}")

def load_agent(self, author: str = '', name: str = '', version: str | None = None,
local: bool = False, path: str | None = None):
try:
Expand All @@ -310,14 +360,17 @@ def load_agent(self, author: str = '', name: str = '', version: str | None = Non
logger.debug(f"local={local}, path={path}")

if local:
# For local agents, check and install dependencies first
self._check_and_install_dependencies(path)

# Handle relative paths
if not os.path.isabs(path):
# Try multiple possible base paths
possible_paths = [
path, # Original path
os.path.join(os.getcwd(), path), # Relative to the current working directory
os.path.join(os.getcwd(), path), # Relative to current working directory
os.path.join(os.path.dirname(self.base_path), path), # Relative to base_path
os.path.join(os.path.dirname(self.base_path), "cerebrum", path), # Relative to the cerebrum directory
os.path.join(os.path.dirname(self.base_path), "cerebrum", path), # Relative to cerebrum directory
]

logger.debug("Trying possible paths:")
Expand All @@ -335,19 +388,8 @@ def load_agent(self, author: str = '', name: str = '', version: str | None = Non
raise FileNotFoundError(f"Could not find agent at any of the attempted paths")

logger.debug(f"Final resolved path: {path}")
# ... The rest of the code remains unchanged ...

if not local:
if version is None:
cached_versions = self._get_cached_versions(author, name)
version = get_newest_version(cached_versions)

agent_path = self._get_cache_path(author, name, version)

if not agent_path.exists():
print(f"Agent {author}/{name} (v{version}) not found in cache. Downloading...")
self.download_agent(author, name, version)
else:
# Package and save local agent
logger.debug("\nPackaging local agent")
logger.debug(f"Agent path: {path}")
logger.debug(f"Path exists: {os.path.exists(path)}")
Expand All @@ -362,7 +404,33 @@ def load_agent(self, author: str = '', name: str = '', version: str | None = Non
self._save_agent_to_cache(local_agent_data, random_path)
agent_path = f"{random_path}"
logger.debug(f"Saved agent to cache: {agent_path}")

elif self.is_builtin_agent(name):
# Handle built-in agent
path = self._get_builtin_agent_path(name)
logger.info(f"Loading built-in agent from {path}")
self._check_and_install_dependencies(path)

# Package and save built-in agent
logger.debug("\nPackaging built-in agent")
local_agent_data = self.package_agent(path)
random_path = self._get_random_cache_path()
self._save_agent_to_cache(local_agent_data, random_path)
agent_path = f"{random_path}"

else:
# Handle remote agent
if version is None:
cached_versions = self._get_cached_versions(author, name)
version = get_newest_version(cached_versions)

agent_path = self._get_cache_path(author, name, version)

if not agent_path.exists():
print(f"Agent {author}/{name} (v{version}) not found in cache. Downloading...")
self.download_agent(author, name, version)

# Common loading code for all agent types
logger.debug(f"\nLoading agent package from: {agent_path}")
agent_package = AgentPackage(agent_path)
agent_package.load()
Expand Down

0 comments on commit 997d87a

Please sign in to comment.