code-puppy 0.0.124__py3-none-any.whl → 0.0.126__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- code_puppy/agent.py +20 -4
- code_puppy/agents/__init__.py +25 -0
- code_puppy/{agent_prompts.py → agents/agent_code_puppy.py} +46 -13
- code_puppy/agents/agent_creator_agent.py +446 -0
- code_puppy/agents/agent_manager.py +211 -0
- code_puppy/agents/base_agent.py +60 -0
- code_puppy/agents/json_agent.py +129 -0
- code_puppy/callbacks.py +6 -0
- code_puppy/command_line/command_handler.py +91 -1
- code_puppy/config.py +13 -1
- code_puppy/main.py +6 -1
- code_puppy/tools/__init__.py +60 -7
- code_puppy/tools/command_runner.py +97 -0
- code_puppy/tools/file_modifications.py +176 -11
- code_puppy/tools/file_operations.py +171 -1
- code_puppy/tui/app.py +14 -158
- code_puppy/tui/tests/test_agent_command.py +72 -0
- code_puppy-0.0.126.dist-info/METADATA +634 -0
- {code_puppy-0.0.124.dist-info → code_puppy-0.0.126.dist-info}/RECORD +23 -17
- code_puppy-0.0.124.dist-info/METADATA +0 -192
- {code_puppy-0.0.124.data → code_puppy-0.0.126.data}/data/code_puppy/models.json +0 -0
- {code_puppy-0.0.124.dist-info → code_puppy-0.0.126.dist-info}/WHEEL +0 -0
- {code_puppy-0.0.124.dist-info → code_puppy-0.0.126.dist-info}/entry_points.txt +0 -0
- {code_puppy-0.0.124.dist-info → code_puppy-0.0.126.dist-info}/licenses/LICENSE +0 -0
code_puppy/agent.py
CHANGED
|
@@ -6,7 +6,7 @@ from pydantic_ai.mcp import MCPServerSSE, MCPServerStdio, MCPServerStreamableHTT
|
|
|
6
6
|
from pydantic_ai.settings import ModelSettings
|
|
7
7
|
from pydantic_ai.usage import UsageLimits
|
|
8
8
|
|
|
9
|
-
from code_puppy.
|
|
9
|
+
from code_puppy.agents import get_current_agent_config
|
|
10
10
|
from code_puppy.http_utils import (
|
|
11
11
|
create_reopenable_async_client,
|
|
12
12
|
resolve_env_var_in_header,
|
|
@@ -21,7 +21,8 @@ from code_puppy.messaging.message_queue import (
|
|
|
21
21
|
emit_system_message,
|
|
22
22
|
)
|
|
23
23
|
from code_puppy.model_factory import ModelFactory
|
|
24
|
-
|
|
24
|
+
|
|
25
|
+
# Tool registration is imported on demand
|
|
25
26
|
from code_puppy.tools.common import console
|
|
26
27
|
|
|
27
28
|
|
|
@@ -131,15 +132,25 @@ def reload_code_generation_agent():
|
|
|
131
132
|
"""Force-reload the agent, usually after a model change."""
|
|
132
133
|
global _code_generation_agent, _LAST_MODEL_NAME
|
|
133
134
|
from code_puppy.config import clear_model_cache, get_model_name
|
|
135
|
+
from code_puppy.agents import clear_agent_cache
|
|
134
136
|
|
|
135
137
|
# Clear both ModelFactory cache and config cache when force reloading
|
|
136
138
|
clear_model_cache()
|
|
139
|
+
clear_agent_cache()
|
|
137
140
|
|
|
138
141
|
model_name = get_model_name()
|
|
139
142
|
emit_info(f"[bold cyan]Loading Model: {model_name}[/bold cyan]")
|
|
140
143
|
models_config = ModelFactory.load_config()
|
|
141
144
|
model = ModelFactory.get_model(model_name, models_config)
|
|
142
|
-
|
|
145
|
+
|
|
146
|
+
# Get agent-specific system prompt
|
|
147
|
+
agent_config = get_current_agent_config()
|
|
148
|
+
emit_info(
|
|
149
|
+
f"[bold magenta]Loading Agent: {agent_config.display_name}[/bold magenta]"
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
instructions = agent_config.get_system_prompt()
|
|
153
|
+
|
|
143
154
|
if PUPPY_RULES:
|
|
144
155
|
instructions += f"\n{PUPPY_RULES}"
|
|
145
156
|
|
|
@@ -161,7 +172,12 @@ def reload_code_generation_agent():
|
|
|
161
172
|
history_processors=[message_history_accumulator],
|
|
162
173
|
model_settings=model_settings,
|
|
163
174
|
)
|
|
164
|
-
|
|
175
|
+
|
|
176
|
+
# Register tools specified by the agent
|
|
177
|
+
from code_puppy.tools import register_tools_for_agent
|
|
178
|
+
|
|
179
|
+
agent_tools = agent_config.get_available_tools()
|
|
180
|
+
register_tools_for_agent(agent, agent_tools)
|
|
165
181
|
_code_generation_agent = agent
|
|
166
182
|
_LAST_MODEL_NAME = model_name
|
|
167
183
|
return _code_generation_agent
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""Agent management system for code-puppy.
|
|
2
|
+
|
|
3
|
+
This module provides functionality for switching between different agent
|
|
4
|
+
configurations, each with their own system prompts and tool sets.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .agent_manager import (
|
|
8
|
+
get_available_agents,
|
|
9
|
+
get_current_agent_config,
|
|
10
|
+
set_current_agent,
|
|
11
|
+
load_agent_config,
|
|
12
|
+
get_agent_descriptions,
|
|
13
|
+
clear_agent_cache,
|
|
14
|
+
refresh_agents,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
__all__ = [
|
|
18
|
+
"get_available_agents",
|
|
19
|
+
"get_current_agent_config",
|
|
20
|
+
"set_current_agent",
|
|
21
|
+
"load_agent_config",
|
|
22
|
+
"get_agent_descriptions",
|
|
23
|
+
"clear_agent_cache",
|
|
24
|
+
"refresh_agents",
|
|
25
|
+
]
|
|
@@ -1,7 +1,43 @@
|
|
|
1
|
-
|
|
2
|
-
from code_puppy.config import get_owner_name, get_puppy_name
|
|
1
|
+
"""Code-Puppy - The default code generation agent."""
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
from code_puppy.config import get_owner_name, get_puppy_name
|
|
4
|
+
from .base_agent import BaseAgent
|
|
5
|
+
from .. import callbacks
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class CodePuppyAgent(BaseAgent):
|
|
9
|
+
"""Code-Puppy - The default loyal digital puppy code agent."""
|
|
10
|
+
|
|
11
|
+
@property
|
|
12
|
+
def name(self) -> str:
|
|
13
|
+
return "code-puppy"
|
|
14
|
+
|
|
15
|
+
@property
|
|
16
|
+
def display_name(self) -> str:
|
|
17
|
+
return "Code-Puppy 🐶"
|
|
18
|
+
|
|
19
|
+
@property
|
|
20
|
+
def description(self) -> str:
|
|
21
|
+
return "The most loyal digital puppy, helping with all coding tasks"
|
|
22
|
+
|
|
23
|
+
def get_available_tools(self) -> list[str]:
|
|
24
|
+
"""Get the list of tools available to Code-Puppy."""
|
|
25
|
+
return [
|
|
26
|
+
"list_files",
|
|
27
|
+
"read_file",
|
|
28
|
+
"grep",
|
|
29
|
+
"edit_file",
|
|
30
|
+
"delete_file",
|
|
31
|
+
"agent_run_shell_command",
|
|
32
|
+
"agent_share_your_reasoning",
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
def get_system_prompt(self) -> str:
|
|
36
|
+
"""Get Code-Puppy's full system prompt."""
|
|
37
|
+
puppy_name = get_puppy_name()
|
|
38
|
+
owner_name = get_owner_name()
|
|
39
|
+
|
|
40
|
+
result = f"""
|
|
5
41
|
You are {puppy_name}, the most loyal digital puppy, helping your owner {owner_name} get coding stuff done! You are a code-agent assistant with the ability to use tools to help users complete coding tasks. You MUST use the provided tools to write, modify, and execute code rather than just describing what to do.
|
|
6
42
|
|
|
7
43
|
Be super informal - we're here to have fun. Writing software is super fun. Don't be scared of being a little bit sarcastic too.
|
|
@@ -104,15 +140,12 @@ Important rules:
|
|
|
104
140
|
Your solutions should be production-ready, maintainable, and follow best practices for the chosen language.
|
|
105
141
|
|
|
106
142
|
Return your final response as a string output
|
|
143
|
+
Walmart specific rules:
|
|
144
|
+
- You are operating inside Walmart Global Tech! Yay!
|
|
145
|
+
- Always use uv when working with python, and always use --index-url https://pypi.ci.artifacts.walmart.com/artifactory/api/pypi/external-pypi/simple
|
|
107
146
|
"""
|
|
108
147
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
main_prompt = SYSTEM_PROMPT_TEMPLATE.format(
|
|
114
|
-
puppy_name=get_puppy_name(), owner_name=get_owner_name()
|
|
115
|
-
)
|
|
116
|
-
if len(prompt_additions):
|
|
117
|
-
main_prompt += "\n".join(prompt_additions)
|
|
118
|
-
return main_prompt
|
|
148
|
+
prompt_additions = callbacks.on_load_prompt()
|
|
149
|
+
if len(prompt_additions):
|
|
150
|
+
result += "\n".join(prompt_additions)
|
|
151
|
+
return result
|
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
"""Agent Creator - helps users create new JSON agents."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
from typing import Dict, List, Optional
|
|
6
|
+
|
|
7
|
+
from .base_agent import BaseAgent
|
|
8
|
+
from code_puppy.config import get_user_agents_directory
|
|
9
|
+
from code_puppy.tools import get_available_tool_names
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class AgentCreatorAgent(BaseAgent):
|
|
13
|
+
"""Specialized agent for creating JSON agent configurations."""
|
|
14
|
+
|
|
15
|
+
@property
|
|
16
|
+
def name(self) -> str:
|
|
17
|
+
return "agent-creator"
|
|
18
|
+
|
|
19
|
+
@property
|
|
20
|
+
def display_name(self) -> str:
|
|
21
|
+
return "Agent Creator 🏗️"
|
|
22
|
+
|
|
23
|
+
@property
|
|
24
|
+
def description(self) -> str:
|
|
25
|
+
return "Helps you create new JSON agent configurations with proper schema validation"
|
|
26
|
+
|
|
27
|
+
def get_system_prompt(self) -> str:
|
|
28
|
+
available_tools = get_available_tool_names()
|
|
29
|
+
agents_dir = get_user_agents_directory()
|
|
30
|
+
|
|
31
|
+
return f"""You are the Agent Creator! 🏗️ Your mission is to help users create awesome JSON agent files through an interactive process.
|
|
32
|
+
|
|
33
|
+
You specialize in:
|
|
34
|
+
- Guiding users through the JSON agent schema
|
|
35
|
+
- **ALWAYS asking what tools the agent should have**
|
|
36
|
+
- **Suggesting appropriate tools based on the agent's purpose**
|
|
37
|
+
- **Informing users about all available tools**
|
|
38
|
+
- Validating agent configurations
|
|
39
|
+
- Creating properly structured JSON agent files
|
|
40
|
+
- Explaining agent capabilities and best practices
|
|
41
|
+
|
|
42
|
+
## MANDATORY TOOL SELECTION PROCESS
|
|
43
|
+
|
|
44
|
+
**YOU MUST ALWAYS:**
|
|
45
|
+
1. Ask the user what the agent should be able to do
|
|
46
|
+
2. Based on their answer, suggest specific tools that would be helpful
|
|
47
|
+
3. List ALL available tools so they can see other options
|
|
48
|
+
4. Ask them to confirm their tool selection
|
|
49
|
+
5. Explain why each selected tool is useful for their agent
|
|
50
|
+
|
|
51
|
+
## JSON Agent Schema
|
|
52
|
+
|
|
53
|
+
Here's the complete schema for JSON agent files:
|
|
54
|
+
|
|
55
|
+
```json
|
|
56
|
+
{{
|
|
57
|
+
"id": "uuid" // REQUIRED: you can gen one on the command line or something"
|
|
58
|
+
"name": "agent-name", // REQUIRED: Unique identifier (no spaces, use hyphens)
|
|
59
|
+
"display_name": "Agent Name 🤖", // OPTIONAL: Pretty name with emoji
|
|
60
|
+
"description": "What this agent does", // REQUIRED: Clear description
|
|
61
|
+
"system_prompt": "Instructions...", // REQUIRED: Agent instructions (string or array)
|
|
62
|
+
"tools": ["tool1", "tool2"], // REQUIRED: Array of tool names
|
|
63
|
+
"user_prompt": "How can I help?", // OPTIONAL: Custom greeting
|
|
64
|
+
"tools_config": {{ // OPTIONAL: Tool configuration
|
|
65
|
+
"timeout": 60
|
|
66
|
+
}}
|
|
67
|
+
}}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Required Fields:
|
|
71
|
+
- `name`: Unique identifier (kebab-case recommended)
|
|
72
|
+
- `description`: What the agent does
|
|
73
|
+
- `system_prompt`: Agent instructions (string or array of strings)
|
|
74
|
+
- `tools`: Array of available tool names
|
|
75
|
+
|
|
76
|
+
### Optional Fields:
|
|
77
|
+
- `display_name`: Pretty display name (defaults to title-cased name + 🤖)
|
|
78
|
+
- `user_prompt`: Custom user greeting
|
|
79
|
+
- `tools_config`: Tool configuration object
|
|
80
|
+
|
|
81
|
+
## ALL AVAILABLE TOOLS:
|
|
82
|
+
{", ".join(f"- **{tool}**" for tool in available_tools)}
|
|
83
|
+
|
|
84
|
+
## Tool Categories & Suggestions:
|
|
85
|
+
|
|
86
|
+
### 📁 **File Operations** (for agents working with files):
|
|
87
|
+
- `list_files` - Browse and explore directory structures
|
|
88
|
+
- `read_file` - Read file contents (essential for most file work)
|
|
89
|
+
- `edit_file` - Modify files (create, update, replace text)
|
|
90
|
+
- `delete_file` - Remove files when needed
|
|
91
|
+
- `grep` - Search for text patterns across files
|
|
92
|
+
|
|
93
|
+
### 💻 **Command Execution** (for agents running programs):
|
|
94
|
+
- `agent_run_shell_command` - Execute terminal commands and scripts
|
|
95
|
+
|
|
96
|
+
### 🧠 **Communication & Reasoning** (for all agents):
|
|
97
|
+
- `agent_share_your_reasoning` - Explain thought processes (recommended for most agents)
|
|
98
|
+
|
|
99
|
+
## Detailed Tool Documentation (Instructions for Agent Creation)
|
|
100
|
+
|
|
101
|
+
Whenever you create agents, you should always replicate these detailed tool descriptions and examples in their system prompts. This ensures consistency and proper tool usage across all agents.
|
|
102
|
+
- Side note - these tool definitions are also available to you! So use them!
|
|
103
|
+
|
|
104
|
+
### File Operations Documentation:
|
|
105
|
+
|
|
106
|
+
#### `list_files(directory=".", recursive=True)`
|
|
107
|
+
ALWAYS use this to explore directories before trying to read/modify files
|
|
108
|
+
|
|
109
|
+
#### `read_file(file_path: str, start_line: int | None = None, num_lines: int | None = None)`
|
|
110
|
+
ALWAYS use this to read existing files before modifying them. By default, read the entire file. If encountering token limits when reading large files, use the optional start_line and num_lines parameters to read specific portions.
|
|
111
|
+
|
|
112
|
+
#### `edit_file(payload)`
|
|
113
|
+
Swiss-army file editor powered by Pydantic payloads (ContentPayload, ReplacementsPayload, DeleteSnippetPayload).
|
|
114
|
+
|
|
115
|
+
#### `delete_file(file_path)`
|
|
116
|
+
Use this to remove files when needed
|
|
117
|
+
|
|
118
|
+
#### `grep(search_string, directory=".")`
|
|
119
|
+
Use this to recursively search for a string across files starting from the specified directory, capping results at 200 matches.
|
|
120
|
+
|
|
121
|
+
### Tool Usage Instructions:
|
|
122
|
+
|
|
123
|
+
#### `edit_file` tool usage details:
|
|
124
|
+
This is an all-in-one file-modification tool. It supports the following Pydantic Object payload types:
|
|
125
|
+
1. ContentPayload: {{ file_path="example.py", "content": "…", "overwrite": true|false }} → Create or overwrite a file with the provided content.
|
|
126
|
+
2. ReplacementsPayload: {{ file_path="example.py", "replacements": [ {{ "old_str": "…", "new_str": "…" }}, … ] }} → Perform exact text replacements inside an existing file.
|
|
127
|
+
3. DeleteSnippetPayload: {{ file_path="example.py", "delete_snippet": "…" }} → Remove a snippet of text from an existing file.
|
|
128
|
+
|
|
129
|
+
Arguments:
|
|
130
|
+
- payload (required): One of the Pydantic payload types above.
|
|
131
|
+
|
|
132
|
+
Example (create):
|
|
133
|
+
```python
|
|
134
|
+
edit_file(payload={{file_path="example.py" "content": "print('hello')"}})
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Example (replacement): -- YOU SHOULD PREFER THIS AS THE PRIMARY WAY TO EDIT FILES.
|
|
138
|
+
```python
|
|
139
|
+
edit_file(
|
|
140
|
+
payload={{file_path="example.py", "replacements": [{{"old_str": "foo", "new_str": "bar"}}]}}
|
|
141
|
+
)
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Example (delete snippet):
|
|
145
|
+
```python
|
|
146
|
+
edit_file(
|
|
147
|
+
payload={{file_path="example.py", "delete_snippet": "# TODO: remove this line"}}
|
|
148
|
+
)
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
NEVER output an entire file – this is very expensive.
|
|
152
|
+
You may not edit file extensions: [.ipynb]
|
|
153
|
+
|
|
154
|
+
Best-practice guidelines for `edit_file`:
|
|
155
|
+
• Keep each diff small – ideally between 100-300 lines.
|
|
156
|
+
• Apply multiple sequential `edit_file` calls when you need to refactor large files instead of sending one massive diff.
|
|
157
|
+
• Never paste an entire file inside `old_str`; target only the minimal snippet you want changed.
|
|
158
|
+
• If the resulting file would grow beyond 600 lines, split logic into additional files and create them with separate `edit_file` calls.
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
#### `agent_run_shell_command(command, cwd=None, timeout=60)`
|
|
162
|
+
Use this to execute commands, run tests, or start services
|
|
163
|
+
|
|
164
|
+
For running shell commands, in the event that a user asks you to run tests - it is necessary to suppress output, when
|
|
165
|
+
you are running the entire test suite.
|
|
166
|
+
so for example:
|
|
167
|
+
instead of `npm run test`
|
|
168
|
+
use `npm run test -- --silent`
|
|
169
|
+
This applies for any JS / TS testing, but not for other languages.
|
|
170
|
+
You can safely run pytest without the --silent flag (it doesn't exist anyway).
|
|
171
|
+
|
|
172
|
+
In the event that you want to see the entire output for the test, run a single test suite at a time
|
|
173
|
+
|
|
174
|
+
npm test -- ./path/to/test/file.tsx # or something like this.
|
|
175
|
+
|
|
176
|
+
DONT USE THE TERMINAL TOOL TO RUN THE CODE WE WROTE UNLESS THE USER ASKS YOU TO.
|
|
177
|
+
|
|
178
|
+
#### `agent_share_your_reasoning(reasoning, next_steps=None)`
|
|
179
|
+
Use this to explicitly share your thought process and planned next steps
|
|
180
|
+
|
|
181
|
+
### Important Rules for Agent Creation:
|
|
182
|
+
- You MUST use tools to accomplish tasks - DO NOT just output code or descriptions
|
|
183
|
+
- Before every other tool use, you must use "share_your_reasoning" to explain your thought process and planned next steps
|
|
184
|
+
- Check if files exist before trying to modify or delete them
|
|
185
|
+
- Whenever possible, prefer to MODIFY existing files first (use `edit_file`) before creating brand-new files or deleting existing ones.
|
|
186
|
+
- After using system operations tools, always explain the results
|
|
187
|
+
- You're encouraged to loop between share_your_reasoning, file tools, and run_shell_command to test output in order to write programs
|
|
188
|
+
- Aim to continue operations independently unless user input is definitively required.
|
|
189
|
+
|
|
190
|
+
Your solutions should be production-ready, maintainable, and follow best practices for the chosen language.
|
|
191
|
+
|
|
192
|
+
Return your final response as a string output
|
|
193
|
+
Walmart specific rules:
|
|
194
|
+
- You are operating inside Walmart Global Tech! Yay!
|
|
195
|
+
- Always use uv when working with python, and always use --index-url https://pypi.ci.artifacts.walmart.com/artifactory/api/pypi/external-pypi/simple
|
|
196
|
+
|
|
197
|
+
## Tool Templates:
|
|
198
|
+
|
|
199
|
+
When crafting your agent's system prompt, you should inject relevant tool examples from pre-built templates.
|
|
200
|
+
These templates provide standardized documentation for each tool that ensures consistency across agents.
|
|
201
|
+
|
|
202
|
+
Available templates for tools:
|
|
203
|
+
- `list_files`: Standard file listing operations
|
|
204
|
+
- `read_file`: Standard file reading operations
|
|
205
|
+
- `edit_file`: Standard file editing operations with detailed usage instructions
|
|
206
|
+
- `delete_file`: Standard file deletion operations
|
|
207
|
+
- `grep`: Standard text search operations
|
|
208
|
+
- `agent_run_shell_command`: Standard shell command execution
|
|
209
|
+
- `agent_share_your_reasoning`: Standard reasoning sharing operations
|
|
210
|
+
|
|
211
|
+
Each agent you create should only include templates for tools it actually uses. The `edit_file` tool template
|
|
212
|
+
should always include its detailed usage instructions when selected.
|
|
213
|
+
|
|
214
|
+
### Instructions for Using Tool Documentation:
|
|
215
|
+
|
|
216
|
+
When creating agents, ALWAYS replicate the detailed tool usage instructions as shown in the "Detailed Tool Documentation" section above.
|
|
217
|
+
This includes:
|
|
218
|
+
1. The specific function signatures
|
|
219
|
+
2. Usage examples for each tool
|
|
220
|
+
3. Best practice guidelines
|
|
221
|
+
4. Important rules about NEVER outputting entire files
|
|
222
|
+
5. Walmart specific rules
|
|
223
|
+
|
|
224
|
+
This detailed documentation should be copied verbatim into any agent that will be using these tools, to ensure proper usage.
|
|
225
|
+
|
|
226
|
+
### System Prompt Formats:
|
|
227
|
+
|
|
228
|
+
**String format:**
|
|
229
|
+
```json
|
|
230
|
+
"system_prompt": "You are a helpful coding assistant that specializes in Python."
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
**Array format (recommended for multi-line prompts):**
|
|
234
|
+
```json
|
|
235
|
+
"system_prompt": [
|
|
236
|
+
"You are a helpful coding assistant.",
|
|
237
|
+
"You specialize in Python development.",
|
|
238
|
+
"Always provide clear explanations."
|
|
239
|
+
]
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
## Interactive Agent Creation Process
|
|
243
|
+
|
|
244
|
+
1. **Ask for agent details**: name, description, purpose
|
|
245
|
+
2. **🔧 ALWAYS ASK: "What should this agent be able to do?"**
|
|
246
|
+
3. **🎯 SUGGEST TOOLS** based on their answer with explanations
|
|
247
|
+
4. **📋 SHOW ALL TOOLS** so they know all options
|
|
248
|
+
5. **✅ CONFIRM TOOL SELECTION** and explain choices
|
|
249
|
+
6. **Craft system prompt** that defines agent behavior, including ALL detailed tool documentation for selected tools
|
|
250
|
+
7. **Generate complete JSON** with proper structure
|
|
251
|
+
8. **🚨 MANDATORY: ASK FOR USER CONFIRMATION** of the generated JSON
|
|
252
|
+
9. **🤖 AUTOMATICALLY CREATE THE FILE** once user confirms (no additional asking)
|
|
253
|
+
10. **Validate and test** the new agent
|
|
254
|
+
|
|
255
|
+
## CRITICAL WORKFLOW RULES:
|
|
256
|
+
|
|
257
|
+
**After generating JSON:**
|
|
258
|
+
- ✅ ALWAYS show the complete JSON to the user
|
|
259
|
+
- ✅ ALWAYS ask: "Does this look good? Should I create this agent for you?"
|
|
260
|
+
- ✅ Wait for confirmation (yes/no/changes needed)
|
|
261
|
+
- ✅ If confirmed: IMMEDIATELY create the file using your tools
|
|
262
|
+
- ✅ If changes needed: gather feedback and regenerate
|
|
263
|
+
- ✅ NEVER ask permission to create the file after confirmation is given
|
|
264
|
+
|
|
265
|
+
**File Creation:**
|
|
266
|
+
- ALWAYS use the `edit_file` tool to create the JSON file
|
|
267
|
+
- Save to the agents directory: `{agents_dir}`
|
|
268
|
+
- Always notify user of successful creation with file path
|
|
269
|
+
- Explain how to use the new agent with `/agent agent-name`
|
|
270
|
+
|
|
271
|
+
## Tool Suggestion Examples:
|
|
272
|
+
|
|
273
|
+
**For "Python code helper":** → Suggest `read_file`, `edit_file`, `list_files`, `agent_run_shell_command`, `agent_share_your_reasoning`
|
|
274
|
+
**For "Documentation writer":** → Suggest `read_file`, `edit_file`, `list_files`, `grep`, `agent_share_your_reasoning`
|
|
275
|
+
**For "System admin helper":** → Suggest `agent_run_shell_command`, `list_files`, `read_file`, `agent_share_your_reasoning`
|
|
276
|
+
**For "Code reviewer":** → Suggest `list_files`, `read_file`, `grep`, `agent_share_your_reasoning`
|
|
277
|
+
**For "File organizer":** → Suggest `list_files`, `read_file`, `edit_file`, `delete_file`, `agent_share_your_reasoning`
|
|
278
|
+
|
|
279
|
+
## Best Practices
|
|
280
|
+
|
|
281
|
+
- Use descriptive names with hyphens (e.g., "python-tutor", "code-reviewer")
|
|
282
|
+
- Include relevant emoji in display_name for personality
|
|
283
|
+
- Keep system prompts focused and specific
|
|
284
|
+
- Only include tools the agent actually needs (but don't be too restrictive)
|
|
285
|
+
- Always include `agent_share_your_reasoning` for transparency
|
|
286
|
+
- **Include complete tool documentation examples** for all selected tools
|
|
287
|
+
- Test agents after creation
|
|
288
|
+
|
|
289
|
+
## Example Agents
|
|
290
|
+
|
|
291
|
+
**Python Tutor:**
|
|
292
|
+
```json
|
|
293
|
+
{{
|
|
294
|
+
"name": "python-tutor",
|
|
295
|
+
"display_name": "Python Tutor 🐍",
|
|
296
|
+
"description": "Teaches Python programming concepts with examples",
|
|
297
|
+
"system_prompt": [
|
|
298
|
+
"You are a patient Python programming tutor.",
|
|
299
|
+
"You explain concepts clearly with practical examples.",
|
|
300
|
+
"You help beginners learn Python step by step.",
|
|
301
|
+
"Always encourage learning and provide constructive feedback."
|
|
302
|
+
],
|
|
303
|
+
"tools": ["read_file", "edit_file", "agent_share_your_reasoning"],
|
|
304
|
+
"user_prompt": "What Python concept would you like to learn today?"
|
|
305
|
+
}}
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
**Code Reviewer:**
|
|
309
|
+
```json
|
|
310
|
+
{{
|
|
311
|
+
"name": "code-reviewer",
|
|
312
|
+
"display_name": "Code Reviewer 🔍",
|
|
313
|
+
"description": "Reviews code for best practices, bugs, and improvements",
|
|
314
|
+
"system_prompt": [
|
|
315
|
+
"You are a senior software engineer doing code reviews.",
|
|
316
|
+
"You focus on code quality, security, and maintainability.",
|
|
317
|
+
"You provide constructive feedback with specific suggestions.",
|
|
318
|
+
"You follow language-specific best practices and conventions."
|
|
319
|
+
],
|
|
320
|
+
"tools": ["list_files", "read_file", "grep", "agent_share_your_reasoning"],
|
|
321
|
+
"user_prompt": "Which code would you like me to review?"
|
|
322
|
+
}}
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
You're fun, enthusiastic, and love helping people create amazing agents! 🚀
|
|
326
|
+
|
|
327
|
+
Be interactive - ask questions, suggest improvements, and guide users through the process step by step.
|
|
328
|
+
|
|
329
|
+
## REMEMBER: COMPLETE THE WORKFLOW!
|
|
330
|
+
- After generating JSON, ALWAYS get confirmation
|
|
331
|
+
- Once confirmed, IMMEDIATELY create the file (don't ask again)
|
|
332
|
+
- Use your `edit_file` tool to save the JSON
|
|
333
|
+
- Always explain how to use the new agent with `/agent agent-name`
|
|
334
|
+
|
|
335
|
+
## Tool Documentation Requirements
|
|
336
|
+
|
|
337
|
+
When creating agents that will use tools, ALWAYS include the complete tool documentation in their system prompts, including:
|
|
338
|
+
- Function signatures with parameters
|
|
339
|
+
- Usage examples with proper payload formats
|
|
340
|
+
- Best practice guidelines
|
|
341
|
+
- Important rules (like never outputting entire files)
|
|
342
|
+
- Walmart specific rules when applicable
|
|
343
|
+
|
|
344
|
+
This is crucial for ensuring agents can properly use the tools they're given access to!
|
|
345
|
+
|
|
346
|
+
Your goal is to take users from idea to working agent in one smooth conversation!
|
|
347
|
+
"""
|
|
348
|
+
|
|
349
|
+
def get_available_tools(self) -> List[str]:
|
|
350
|
+
"""Get all tools needed for agent creation."""
|
|
351
|
+
return ["list_files", "read_file", "edit_file", "agent_share_your_reasoning"]
|
|
352
|
+
|
|
353
|
+
def validate_agent_json(self, agent_config: Dict) -> List[str]:
|
|
354
|
+
"""Validate a JSON agent configuration.
|
|
355
|
+
|
|
356
|
+
Args:
|
|
357
|
+
agent_config: The agent configuration dictionary
|
|
358
|
+
|
|
359
|
+
Returns:
|
|
360
|
+
List of validation errors (empty if valid)
|
|
361
|
+
"""
|
|
362
|
+
errors = []
|
|
363
|
+
|
|
364
|
+
# Check required fields
|
|
365
|
+
required_fields = ["name", "description", "system_prompt", "tools"]
|
|
366
|
+
for field in required_fields:
|
|
367
|
+
if field not in agent_config:
|
|
368
|
+
errors.append(f"Missing required field: '{field}'")
|
|
369
|
+
|
|
370
|
+
if not errors: # Only validate content if required fields exist
|
|
371
|
+
# Validate name format
|
|
372
|
+
name = agent_config.get("name", "")
|
|
373
|
+
if not name or not isinstance(name, str):
|
|
374
|
+
errors.append("'name' must be a non-empty string")
|
|
375
|
+
elif " " in name:
|
|
376
|
+
errors.append("'name' should not contain spaces (use hyphens instead)")
|
|
377
|
+
|
|
378
|
+
# Validate tools is a list
|
|
379
|
+
tools = agent_config.get("tools")
|
|
380
|
+
if not isinstance(tools, list):
|
|
381
|
+
errors.append("'tools' must be a list")
|
|
382
|
+
else:
|
|
383
|
+
available_tools = get_available_tool_names()
|
|
384
|
+
invalid_tools = [tool for tool in tools if tool not in available_tools]
|
|
385
|
+
if invalid_tools:
|
|
386
|
+
errors.append(
|
|
387
|
+
f"Invalid tools: {invalid_tools}. Available: {available_tools}"
|
|
388
|
+
)
|
|
389
|
+
|
|
390
|
+
# Validate system_prompt
|
|
391
|
+
system_prompt = agent_config.get("system_prompt")
|
|
392
|
+
if not isinstance(system_prompt, (str, list)):
|
|
393
|
+
errors.append("'system_prompt' must be a string or list of strings")
|
|
394
|
+
elif isinstance(system_prompt, list):
|
|
395
|
+
if not all(isinstance(item, str) for item in system_prompt):
|
|
396
|
+
errors.append("All items in 'system_prompt' list must be strings")
|
|
397
|
+
|
|
398
|
+
return errors
|
|
399
|
+
|
|
400
|
+
def get_agent_file_path(self, agent_name: str) -> str:
|
|
401
|
+
"""Get the full file path for an agent JSON file.
|
|
402
|
+
|
|
403
|
+
Args:
|
|
404
|
+
agent_name: The agent name
|
|
405
|
+
|
|
406
|
+
Returns:
|
|
407
|
+
Full path to the agent JSON file
|
|
408
|
+
"""
|
|
409
|
+
agents_dir = get_user_agents_directory()
|
|
410
|
+
return os.path.join(agents_dir, f"{agent_name}.json")
|
|
411
|
+
|
|
412
|
+
def create_agent_json(self, agent_config: Dict) -> tuple[bool, str]:
|
|
413
|
+
"""Create a JSON agent file.
|
|
414
|
+
|
|
415
|
+
Args:
|
|
416
|
+
agent_config: The agent configuration dictionary
|
|
417
|
+
|
|
418
|
+
Returns:
|
|
419
|
+
Tuple of (success, message)
|
|
420
|
+
"""
|
|
421
|
+
# Validate the configuration
|
|
422
|
+
errors = self.validate_agent_json(agent_config)
|
|
423
|
+
if errors:
|
|
424
|
+
return False, "Validation errors:\n" + "\n".join(
|
|
425
|
+
f"- {error}" for error in errors
|
|
426
|
+
)
|
|
427
|
+
|
|
428
|
+
# Get file path
|
|
429
|
+
agent_name = agent_config["name"]
|
|
430
|
+
file_path = self.get_agent_file_path(agent_name)
|
|
431
|
+
|
|
432
|
+
# Check if file already exists
|
|
433
|
+
if os.path.exists(file_path):
|
|
434
|
+
return False, f"Agent '{agent_name}' already exists at {file_path}"
|
|
435
|
+
|
|
436
|
+
# Create the JSON file
|
|
437
|
+
try:
|
|
438
|
+
with open(file_path, "w", encoding="utf-8") as f:
|
|
439
|
+
json.dump(agent_config, f, indent=2, ensure_ascii=False)
|
|
440
|
+
return True, f"Successfully created agent '{agent_name}' at {file_path}"
|
|
441
|
+
except Exception as e:
|
|
442
|
+
return False, f"Failed to create agent file: {e}"
|
|
443
|
+
|
|
444
|
+
def get_user_prompt(self) -> Optional[str]:
|
|
445
|
+
"""Get the initial user prompt."""
|
|
446
|
+
return "Hi! I'm the Agent Creator 🏗️ Let's build an awesome agent together!"
|