Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 15 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -466,8 +466,11 @@ Agents can access these tools based on their configuration:

## File Locations

### JSON Agents Directory
- **All platforms**: `~/.code_puppy/agents/`
### JSON Agents Directories
- **User-level (global)**: `~/.code_puppy/agents/`
- **Project-level (shared via version control)**: `.code_puppy/agents/`

Project-level agents in `.code_puppy/agents/` override user-level agents on name collision. This directory should be committed to version control for team sharing.

### Python Agents Directory
- **Built-in**: `code_puppy/agents/` (in package)
Expand Down Expand Up @@ -501,8 +504,9 @@ Agents can access these tools based on their configuration:
### Agent Discovery
The system automatically discovers agents by:
1. **Python Agents**: Scanning `code_puppy/agents/` for classes inheriting from `BaseAgent`
2. **JSON Agents**: Scanning user's agents directory for `*-agent.json` files
3. Instantiating and registering discovered agents
2. **JSON Agents (user-level)**: Scanning `~/.code_puppy/agents/` for `*.json` files
3. **JSON Agents (project-level)**: Scanning `.code_puppy/agents/` for `*.json` files (overrides user-level on name collision)
4. Instantiating and registering discovered agents

### JSONAgent Implementation
JSON agents are powered by the `JSONAgent` class (`code_puppy/agents/json_agent.py`):
Expand Down Expand Up @@ -647,11 +651,13 @@ The agent system supports future expansion:
- **Testing**: Comprehensive test suite in `tests/test_json_agents.py`

### JSON Agent Loading Process
1. System scans `~/.code_puppy/agents/` for `*-agent.json` files
2. `JSONAgent` class loads and validates each JSON configuration
3. Agents are registered in unified agent registry
4. Users can switch to JSON agents via `/agent <name>` command
5. Tool access and system prompts work identically to Python agents
1. System scans `~/.code_puppy/agents/` for `*.json` agent files (user-level)
2. System scans `.code_puppy/agents/` for `*.json` agent files (project-level)
3. Project-level agents override user-level agents on name collision
4. `JSONAgent` class loads and validates each JSON configuration
5. Agents are registered in unified agent registry
6. Users can switch to JSON agents via `/agent <name>` command
7. Tool access and system prompts work identically to Python agents

### Error Handling
- Invalid JSON syntax: Clear error messages with line numbers
Expand Down
8 changes: 7 additions & 1 deletion code_puppy/agents/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@
clone_agent,
delete_clone_agent,
get_agent_descriptions,
get_agent_shadowed_path,
get_agent_source_path,
get_available_agents,
get_available_agents_with_descriptions,
get_current_agent,
is_clone_agent_name,
load_agent,
Expand All @@ -20,12 +23,15 @@
__all__ = [
"clone_agent",
"delete_clone_agent",
"get_agent_descriptions",
"get_agent_shadowed_path",
"get_agent_source_path",
"get_available_agents",
"get_available_agents_with_descriptions",
"get_current_agent",
"is_clone_agent_name",
"set_current_agent",
"load_agent",
"get_agent_descriptions",
"refresh_agents",
"subagent_stream_handler",
]
91 changes: 40 additions & 51 deletions code_puppy/agents/agent_creator_agent.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
"""Agent Creator - helps users create new JSON agents."""

import json
import os
from typing import Dict, List, Optional

from code_puppy.config import get_user_agents_directory
from code_puppy.config import get_user_agents_directory, get_project_agents_directory
from code_puppy.model_factory import ModelFactory
from code_puppy.tools import get_available_tool_names

Expand All @@ -29,6 +27,7 @@ def description(self) -> str:
def get_system_prompt(self) -> str:
available_tools = get_available_tool_names()
agents_dir = get_user_agents_directory()
project_agents_dir = get_project_agents_directory()

# Also get Universal Constructor tools (custom tools created by users)
uc_tools_info = []
Expand Down Expand Up @@ -65,6 +64,41 @@ def get_system_prompt(self) -> str:

available_models_str = "\n".join(model_descriptions)

# Build the file-creation instructions for the system prompt.
# When a project agents directory exists, ask the user where to save.
# When only the user directory is available, skip the question entirely.
if project_agents_dir:
_file_creation_instructions = f"""**File Creation:**
- BEFORE creating the file, you MUST ask where to save it using `ask_user_question` with this EXACT format:
```json
{{{{
"questions": [
{{{{
"question": "Where should this agent be saved?",
"header": "Location",
"multi_select": false,
"options": [
{{{{
"label": "User directory",
"description": "{agents_dir} (available in all projects)"
}}}},
{{{{
"label": "Project directory",
"description": "{project_agents_dir} (version controlled)"
}}}}
]
}}}}
]
}}}}
```
- THEN use `edit_file` to create the JSON file at the chosen location:
- If user chose "User directory": save to `{agents_dir}/agent-name.json`
- If user chose "Project directory": save to `{project_agents_dir}/agent-name.json`"""
else:
_file_creation_instructions = f"""**File Creation:**
- Do NOT ask the user where to save — save directly to the user agents directory.
- Use `edit_file` to create the JSON file at: `{agents_dir}/agent-name.json`"""

return f"""You are the Agent Creator! 🏗️ Your mission is to help users create awesome JSON agent files through an interactive process.

You specialize in:
Expand Down Expand Up @@ -399,10 +433,9 @@ def get_system_prompt(self) -> str:
- ✅ If changes needed: gather feedback and regenerate
- ✅ NEVER ask permission to create the file after confirmation is given

**File Creation:**
- ALWAYS use the `edit_file` tool to create the JSON file
- Save to the agents directory: `{agents_dir}`
- Always notify user of successful creation with file path
{_file_creation_instructions}
- IMPORTANT: Never use `~` in file paths. Always use the fully expanded paths shown above
- Always notify user of successful creation with full file path
- Explain how to use the new agent with `/agent agent-name`

## Tool Suggestion Examples:
Expand Down Expand Up @@ -581,50 +614,6 @@ def validate_agent_json(self, agent_config: Dict) -> List[str]:

return errors

def get_agent_file_path(self, agent_name: str) -> str:
"""Get the full file path for an agent JSON file.

Args:
agent_name: The agent name

Returns:
Full path to the agent JSON file
"""
agents_dir = get_user_agents_directory()
return os.path.join(agents_dir, f"{agent_name}.json")

def create_agent_json(self, agent_config: Dict) -> tuple[bool, str]:
"""Create a JSON agent file.

Args:
agent_config: The agent configuration dictionary

Returns:
Tuple of (success, message)
"""
# Validate the configuration
errors = self.validate_agent_json(agent_config)
if errors:
return False, "Validation errors:\n" + "\n".join(
f"- {error}" for error in errors
)

# Get file path
agent_name = agent_config["name"]
file_path = self.get_agent_file_path(agent_name)

# Check if file already exists
if os.path.exists(file_path):
return False, f"Agent '{agent_name}' already exists at {file_path}"

# Create the JSON file
try:
with open(file_path, "w", encoding="utf-8") as f:
json.dump(agent_config, f, indent=2, ensure_ascii=False)
return True, f"Successfully created agent '{agent_name}' at {file_path}"
except Exception as e:
return False, f"Failed to create agent file: {e}"

def get_user_prompt(self) -> Optional[str]:
"""Get the initial user prompt."""
return "Hi! I'm the Agent Creator 🏗️ Let's build an awesome agent together!"
Loading