♻️ refactor(deep-agent): customize agent memory middleware path display
- Change workspace_root from ~/.deepagents/{bot_id} to projects/robot/{bot_id}
- Refactor CustomSkillsMiddleware to support user and project skills separately
- Update skill path formatting for better visibility in system prompts
- Remove unused symlink_utils module and related setup code
- Clean up imports in fastapi_app.py and utils/__init__.py
This commit is contained in:
parent
8bb8c3fbc8
commit
1233bdda0c
@ -162,7 +162,8 @@ async def init_agent(config: AgentConfig):
|
|||||||
create_start = time.time()
|
create_start = time.time()
|
||||||
if config.robot_type == "deep_agent":
|
if config.robot_type == "deep_agent":
|
||||||
# 使用 DeepAgentX 创建 agent,自定义 workspace_root
|
# 使用 DeepAgentX 创建 agent,自定义 workspace_root
|
||||||
workspace_root = str(Path.home() / ".deepagents" / config.bot_id)
|
workspace_root = f"projects/robot/{config.bot_id}"
|
||||||
|
# workspace_root = str(Path.home() / ".deepagents" / config.bot_id)
|
||||||
agent, composite_backend = create_custom_cli_agent(
|
agent, composite_backend = create_custom_cli_agent(
|
||||||
model=llm_instance,
|
model=llm_instance,
|
||||||
assistant_id=config.bot_id,
|
assistant_id=config.bot_id,
|
||||||
@ -244,7 +245,43 @@ class CustomSkillsMiddleware(SkillsMiddleware):
|
|||||||
assistant_id=assistant_id,
|
assistant_id=assistant_id,
|
||||||
project_skills_dir=project_skills_dir
|
project_skills_dir=project_skills_dir
|
||||||
)
|
)
|
||||||
self.user_skills_display = f"./skills"
|
self.skills_dir = None
|
||||||
|
self.project_skills_display = f"./skills"
|
||||||
|
|
||||||
|
def _format_skills_locations(self) -> str:
|
||||||
|
"""Format skills locations for display in system prompt."""
|
||||||
|
return "**Project Skills**: `{self.project_skills_dir}`"
|
||||||
|
|
||||||
|
def _format_skills_list(self, skills) -> str:
|
||||||
|
"""Format skills metadata for display in system prompt."""
|
||||||
|
if not skills:
|
||||||
|
locations = [f"{self.user_skills_display}/"]
|
||||||
|
if self.project_skills_dir:
|
||||||
|
locations.append(f"{self.project_skills_display}/")
|
||||||
|
return f"(No skills available yet. You can create skills in {' or '.join(locations)})"
|
||||||
|
|
||||||
|
# Group skills by source
|
||||||
|
user_skills = [s for s in skills if s["source"] == "user"]
|
||||||
|
project_skills = [s for s in skills if s["source"] == "project"]
|
||||||
|
|
||||||
|
lines = []
|
||||||
|
|
||||||
|
# Show user skills
|
||||||
|
if user_skills:
|
||||||
|
lines.append("**User Skills:**")
|
||||||
|
for skill in user_skills:
|
||||||
|
lines.append(f"- **{skill['name']}**: {skill['description']}")
|
||||||
|
lines.append(f" → Read `{skill['path']}` for full instructions")
|
||||||
|
lines.append("")
|
||||||
|
|
||||||
|
# Show project skills
|
||||||
|
if project_skills:
|
||||||
|
lines.append("**Project Skills:**")
|
||||||
|
for skill in project_skills:
|
||||||
|
lines.append(f"- **{skill['name']}**: {skill['description']}")
|
||||||
|
lines.append(f" → Read `{skill['path']}` for full instructions")
|
||||||
|
|
||||||
|
return "\n".join(lines)
|
||||||
|
|
||||||
def before_agent(self, state, runtime):
|
def before_agent(self, state, runtime):
|
||||||
"""Load skills metadata before agent execution.
|
"""Load skills metadata before agent execution.
|
||||||
@ -261,7 +298,10 @@ class CustomSkillsMiddleware(SkillsMiddleware):
|
|||||||
"""
|
"""
|
||||||
state = super().before_agent(state, runtime)
|
state = super().before_agent(state, runtime)
|
||||||
for item in state["skills_metadata"]:
|
for item in state["skills_metadata"]:
|
||||||
item["path"] = self.user_skills_display + item["path"].replace(str(self.skills_dir), "")
|
if item["source"] == "project":
|
||||||
|
item["path"] = self.project_skills_display + item["path"].replace(str(self.project_skills_dir), "")
|
||||||
|
else:
|
||||||
|
item["path"] = self.user_skills_display + item["path"].replace(str(self.skills_dir), "")
|
||||||
return state
|
return state
|
||||||
|
|
||||||
def create_custom_cli_agent(
|
def create_custom_cli_agent(
|
||||||
@ -316,11 +356,6 @@ def create_custom_cli_agent(
|
|||||||
source_content = get_default_coding_instructions()
|
source_content = get_default_coding_instructions()
|
||||||
agent_md.write_text(source_content)
|
agent_md.write_text(source_content)
|
||||||
|
|
||||||
# Skills directories (if enabled)
|
|
||||||
skills_dir = none
|
|
||||||
if enable_skills:
|
|
||||||
skills_dir = settings.ensure_user_skills_dir(assistant_id)
|
|
||||||
|
|
||||||
# Build middleware stack based on enabled features
|
# Build middleware stack based on enabled features
|
||||||
agent_middleware = []
|
agent_middleware = []
|
||||||
|
|
||||||
@ -342,7 +377,8 @@ def create_custom_cli_agent(
|
|||||||
if enable_skills:
|
if enable_skills:
|
||||||
agent_middleware.append(
|
agent_middleware.append(
|
||||||
CustomSkillsMiddleware(
|
CustomSkillsMiddleware(
|
||||||
skills_dir=skills_dir,
|
skills_dir=workspace_root,
|
||||||
|
project_skills_dir=workspace_root+"/skills",
|
||||||
assistant_id=assistant_id
|
assistant_id=assistant_id
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -378,7 +414,8 @@ def create_custom_cli_agent(
|
|||||||
if enable_skills:
|
if enable_skills:
|
||||||
agent_middleware.append(
|
agent_middleware.append(
|
||||||
CustomSkillsMiddleware(
|
CustomSkillsMiddleware(
|
||||||
skills_dir=skills_dir,
|
skills_dir=workspace_root,
|
||||||
|
project_skills_dir=workspace_root+"/skills",
|
||||||
assistant_id=assistant_id
|
assistant_id=assistant_id
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@ -13,7 +13,6 @@ from fastapi.middleware.cors import CORSMiddleware
|
|||||||
from routes.file_manager import router as file_manager_router
|
from routes.file_manager import router as file_manager_router
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from utils.symlink_utils import setup_project_directories
|
|
||||||
from utils.log_util.logger import init_with_fastapi
|
from utils.log_util.logger import init_with_fastapi
|
||||||
|
|
||||||
|
|
||||||
@ -63,8 +62,6 @@ init_with_fastapi(app)
|
|||||||
|
|
||||||
logger = logging.getLogger('app')
|
logger = logging.getLogger('app')
|
||||||
|
|
||||||
# Setup project directories and symbolic links
|
|
||||||
setup_project_directories()
|
|
||||||
|
|
||||||
# 挂载public文件夹为静态文件服务
|
# 挂载public文件夹为静态文件服务
|
||||||
app.mount("/public", StaticFiles(directory="public"), name="static")
|
app.mount("/public", StaticFiles(directory="public"), name="static")
|
||||||
|
|||||||
@ -76,10 +76,7 @@ from .multi_project_manager import (
|
|||||||
generate_robot_readme
|
generate_robot_readme
|
||||||
)
|
)
|
||||||
|
|
||||||
from .symlink_utils import (
|
|
||||||
setup_deepagents_symlink,
|
|
||||||
setup_project_directories
|
|
||||||
)
|
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
# file_utils
|
# file_utils
|
||||||
@ -143,7 +140,5 @@ __all__ = [
|
|||||||
'copy_dataset_folder',
|
'copy_dataset_folder',
|
||||||
'generate_robot_readme',
|
'generate_robot_readme',
|
||||||
|
|
||||||
# symlink_utils
|
|
||||||
'setup_deepagents_symlink',
|
|
||||||
'setup_project_directories',
|
|
||||||
]
|
]
|
||||||
|
|||||||
@ -1,71 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
Utilities for managing symbolic links and directory setup.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import os
|
|
||||||
import logging
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
def setup_deepagents_symlink():
|
|
||||||
"""
|
|
||||||
Create a symbolic link from projects/robot to ~/.deepagents
|
|
||||||
if it doesn't already exist.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
# Get paths
|
|
||||||
project_root = Path(__file__).parent.parent
|
|
||||||
robot_dir = project_root / "projects" / "robot"
|
|
||||||
deepagents_dir = Path.home() / ".deepagents"
|
|
||||||
|
|
||||||
# Create robot directory if it doesn't exist
|
|
||||||
robot_dir.mkdir(parents=True, exist_ok=True)
|
|
||||||
|
|
||||||
# If ~/.deepagents already exists, do nothing
|
|
||||||
if deepagents_dir.exists():
|
|
||||||
logger.info(f"~/.deepagents already exists at {deepagents_dir}, skipping symlink creation")
|
|
||||||
return True
|
|
||||||
|
|
||||||
# Create the symbolic link
|
|
||||||
os.symlink(robot_dir, deepagents_dir, target_is_directory=True)
|
|
||||||
logger.info(f"Created symbolic link: {deepagents_dir} -> {robot_dir}")
|
|
||||||
return True
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(f"Failed to create symbolic link: {e}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def setup_project_directories():
|
|
||||||
"""
|
|
||||||
Set up all necessary directories and symbolic links for the project.
|
|
||||||
"""
|
|
||||||
logger.info("Setting up project directories...")
|
|
||||||
|
|
||||||
# Setup ~/.deepagents symlink
|
|
||||||
symlink_success = setup_deepagents_symlink()
|
|
||||||
|
|
||||||
if symlink_success:
|
|
||||||
logger.info("Project directories setup completed successfully")
|
|
||||||
else:
|
|
||||||
logger.warning("Project directories setup completed with warnings")
|
|
||||||
|
|
||||||
return symlink_success
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
# Set up basic logging for standalone testing
|
|
||||||
logging.basicConfig(
|
|
||||||
level=logging.INFO,
|
|
||||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
|
||||||
)
|
|
||||||
|
|
||||||
# Test the function
|
|
||||||
success = setup_deepagents_symlink()
|
|
||||||
if success:
|
|
||||||
print("✅ Symbolic link setup successful")
|
|
||||||
else:
|
|
||||||
print("❌ Symbolic link setup failed")
|
|
||||||
Loading…
Reference in New Issue
Block a user