code-puppy 0.0.154__py3-none-any.whl → 0.0.155__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 +4 -3
- code_puppy/agents/agent_creator_agent.py +9 -2
- code_puppy/agents/runtime_manager.py +12 -4
- code_puppy/command_line/mcp/install_command.py +50 -1
- code_puppy/command_line/mcp/wizard_utils.py +88 -17
- code_puppy/config.py +8 -2
- code_puppy/main.py +17 -4
- code_puppy/mcp/__init__.py +2 -2
- code_puppy/mcp/config_wizard.py +1 -1
- code_puppy/messaging/spinner/console_spinner.py +1 -1
- code_puppy/model_factory.py +13 -12
- code_puppy/models.json +26 -0
- code_puppy/round_robin_model.py +35 -18
- code_puppy/summarization_agent.py +1 -3
- code_puppy/tools/agent_tools.py +41 -138
- code_puppy/tools/file_operations.py +116 -96
- code_puppy/tui/app.py +1 -1
- {code_puppy-0.0.154.data → code_puppy-0.0.155.data}/data/code_puppy/models.json +26 -0
- {code_puppy-0.0.154.dist-info → code_puppy-0.0.155.dist-info}/METADATA +2 -2
- {code_puppy-0.0.154.dist-info → code_puppy-0.0.155.dist-info}/RECORD +23 -45
- code_puppy/token_utils.py +0 -67
- code_puppy/tools/token_check.py +0 -32
- code_puppy/tui/tests/__init__.py +0 -1
- code_puppy/tui/tests/test_agent_command.py +0 -79
- code_puppy/tui/tests/test_chat_message.py +0 -28
- code_puppy/tui/tests/test_chat_view.py +0 -88
- code_puppy/tui/tests/test_command_history.py +0 -89
- code_puppy/tui/tests/test_copy_button.py +0 -191
- code_puppy/tui/tests/test_custom_widgets.py +0 -27
- code_puppy/tui/tests/test_disclaimer.py +0 -27
- code_puppy/tui/tests/test_enums.py +0 -15
- code_puppy/tui/tests/test_file_browser.py +0 -60
- code_puppy/tui/tests/test_help.py +0 -38
- code_puppy/tui/tests/test_history_file_reader.py +0 -107
- code_puppy/tui/tests/test_input_area.py +0 -33
- code_puppy/tui/tests/test_settings.py +0 -44
- code_puppy/tui/tests/test_sidebar.py +0 -33
- code_puppy/tui/tests/test_sidebar_history.py +0 -153
- code_puppy/tui/tests/test_sidebar_history_navigation.py +0 -132
- code_puppy/tui/tests/test_status_bar.py +0 -54
- code_puppy/tui/tests/test_timestamped_history.py +0 -52
- code_puppy/tui/tests/test_tools.py +0 -82
- {code_puppy-0.0.154.dist-info → code_puppy-0.0.155.dist-info}/WHEEL +0 -0
- {code_puppy-0.0.154.dist-info → code_puppy-0.0.155.dist-info}/entry_points.txt +0 -0
- {code_puppy-0.0.154.dist-info → code_puppy-0.0.155.dist-info}/licenses/LICENSE +0 -0
code_puppy/tools/agent_tools.py
CHANGED
|
@@ -21,213 +21,113 @@ from code_puppy.config import get_model_name
|
|
|
21
21
|
|
|
22
22
|
class AgentInfo(BaseModel):
|
|
23
23
|
"""Information about an available agent."""
|
|
24
|
+
|
|
24
25
|
name: str
|
|
25
26
|
display_name: str
|
|
26
27
|
|
|
27
28
|
|
|
28
29
|
class ListAgentsOutput(BaseModel):
|
|
29
30
|
"""Output for the list_agents tool."""
|
|
31
|
+
|
|
30
32
|
agents: List[AgentInfo]
|
|
31
33
|
error: str | None = None
|
|
32
34
|
|
|
33
35
|
|
|
34
36
|
class AgentInvokeOutput(BaseModel):
|
|
35
37
|
"""Output for the invoke_agent tool."""
|
|
38
|
+
|
|
36
39
|
response: str | None
|
|
37
40
|
agent_name: str
|
|
38
41
|
error: str | None = None
|
|
39
42
|
|
|
40
43
|
|
|
41
|
-
def _list_agents(context: RunContext) -> ListAgentsOutput:
|
|
42
|
-
"""List all available sub-agents that can be invoked.
|
|
43
|
-
|
|
44
|
-
Returns:
|
|
45
|
-
ListAgentsOutput: A list of available agents with their names and display names.
|
|
46
|
-
"""
|
|
47
|
-
group_id = generate_group_id("list_agents")
|
|
48
|
-
|
|
49
|
-
emit_info(
|
|
50
|
-
"\n[bold white on blue] LIST AGENTS [/bold white on blue]",
|
|
51
|
-
message_group=group_id
|
|
52
|
-
)
|
|
53
|
-
emit_divider(message_group=group_id)
|
|
54
|
-
|
|
55
|
-
try:
|
|
56
|
-
# Get available agents from the agent manager
|
|
57
|
-
agents_dict = get_available_agents()
|
|
58
|
-
|
|
59
|
-
# Convert to list of AgentInfo objects
|
|
60
|
-
agents = [
|
|
61
|
-
AgentInfo(name=name, display_name=display_name)
|
|
62
|
-
for name, display_name in agents_dict.items()
|
|
63
|
-
]
|
|
64
|
-
|
|
65
|
-
# Display the agents in the console
|
|
66
|
-
for agent in agents:
|
|
67
|
-
emit_system_message(
|
|
68
|
-
f"- [bold]{agent.name}[/bold]: {agent.display_name}",
|
|
69
|
-
message_group=group_id
|
|
70
|
-
)
|
|
71
|
-
|
|
72
|
-
emit_divider(message_group=group_id)
|
|
73
|
-
return ListAgentsOutput(agents=agents)
|
|
74
|
-
|
|
75
|
-
except Exception as e:
|
|
76
|
-
error_msg = f"Error listing agents: {str(e)}"
|
|
77
|
-
emit_error(error_msg, message_group=group_id)
|
|
78
|
-
emit_divider(message_group=group_id)
|
|
79
|
-
return ListAgentsOutput(agents=[], error=error_msg)
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
def _invoke_agent(context: RunContext, agent_name: str, prompt: str) -> AgentInvokeOutput:
|
|
83
|
-
"""Invoke a specific sub-agent with a given prompt.
|
|
84
|
-
|
|
85
|
-
Args:
|
|
86
|
-
agent_name: The name of the agent to invoke
|
|
87
|
-
prompt: The prompt to send to the agent
|
|
88
|
-
|
|
89
|
-
Returns:
|
|
90
|
-
AgentInvokeOutput: The agent's response to the prompt
|
|
91
|
-
"""
|
|
92
|
-
group_id = generate_group_id("invoke_agent", agent_name)
|
|
93
|
-
|
|
94
|
-
emit_info(
|
|
95
|
-
f"\n[bold white on blue] INVOKE AGENT [/bold white on blue] {agent_name}",
|
|
96
|
-
message_group=group_id
|
|
97
|
-
)
|
|
98
|
-
emit_divider(message_group=group_id)
|
|
99
|
-
emit_system_message(f"Prompt: {prompt}", message_group=group_id)
|
|
100
|
-
emit_divider(message_group=group_id)
|
|
101
|
-
|
|
102
|
-
try:
|
|
103
|
-
# Load the specified agent config
|
|
104
|
-
agent_config = load_agent_config(agent_name)
|
|
105
|
-
|
|
106
|
-
# Get the current model for creating a temporary agent
|
|
107
|
-
model_name = get_model_name()
|
|
108
|
-
models_config = ModelFactory.load_config()
|
|
109
|
-
model = ModelFactory.get_model(model_name, models_config)
|
|
110
|
-
|
|
111
|
-
# Create a temporary agent instance to avoid interfering with current agent state
|
|
112
|
-
instructions = agent_config.get_system_prompt()
|
|
113
|
-
temp_agent = Agent(
|
|
114
|
-
model=model,
|
|
115
|
-
instructions=instructions,
|
|
116
|
-
output_type=str,
|
|
117
|
-
retries=3,
|
|
118
|
-
)
|
|
119
|
-
|
|
120
|
-
# Register the tools that the agent needs
|
|
121
|
-
from code_puppy.tools import register_tools_for_agent
|
|
122
|
-
agent_tools = agent_config.get_available_tools()
|
|
123
|
-
|
|
124
|
-
# Avoid recursive tool registration - if the agent has the same tools
|
|
125
|
-
# as the current agent, skip registration to prevent conflicts
|
|
126
|
-
current_agent_tools = ["list_agents", "invoke_agent"]
|
|
127
|
-
if set(agent_tools) != set(current_agent_tools):
|
|
128
|
-
register_tools_for_agent(temp_agent, agent_tools)
|
|
129
|
-
|
|
130
|
-
# Run the temporary agent with the provided prompt
|
|
131
|
-
result = temp_agent.run_sync(prompt)
|
|
132
|
-
|
|
133
|
-
# Extract the response from the result
|
|
134
|
-
response = result.output
|
|
135
|
-
|
|
136
|
-
emit_system_message(f"Response: {response}", message_group=group_id)
|
|
137
|
-
emit_divider(message_group=group_id)
|
|
138
|
-
|
|
139
|
-
return AgentInvokeOutput(response=response, agent_name=agent_name)
|
|
140
|
-
|
|
141
|
-
except Exception as e:
|
|
142
|
-
error_msg = f"Error invoking agent '{agent_name}': {str(e)}"
|
|
143
|
-
emit_error(error_msg, message_group=group_id)
|
|
144
|
-
emit_divider(message_group=group_id)
|
|
145
|
-
return AgentInvokeOutput(response=None, agent_name=agent_name, error=error_msg)
|
|
146
|
-
|
|
147
|
-
|
|
148
44
|
def register_list_agents(agent):
|
|
149
45
|
"""Register the list_agents tool with the provided agent.
|
|
150
|
-
|
|
46
|
+
|
|
151
47
|
Args:
|
|
152
48
|
agent: The agent to register the tool with
|
|
153
49
|
"""
|
|
50
|
+
|
|
154
51
|
@agent.tool
|
|
155
52
|
def list_agents(context: RunContext) -> ListAgentsOutput:
|
|
156
53
|
"""List all available sub-agents that can be invoked.
|
|
157
|
-
|
|
54
|
+
|
|
158
55
|
Returns:
|
|
159
56
|
ListAgentsOutput: A list of available agents with their names and display names.
|
|
160
57
|
"""
|
|
161
58
|
# Generate a group ID for this tool execution
|
|
162
59
|
group_id = generate_group_id("list_agents")
|
|
163
|
-
|
|
60
|
+
|
|
164
61
|
emit_info(
|
|
165
62
|
"\n[bold white on blue] LIST AGENTS [/bold white on blue]",
|
|
166
|
-
message_group=group_id
|
|
63
|
+
message_group=group_id,
|
|
167
64
|
)
|
|
168
65
|
emit_divider(message_group=group_id)
|
|
169
|
-
|
|
66
|
+
|
|
170
67
|
try:
|
|
171
68
|
# Get available agents from the agent manager
|
|
172
69
|
agents_dict = get_available_agents()
|
|
173
|
-
|
|
70
|
+
|
|
174
71
|
# Convert to list of AgentInfo objects
|
|
175
72
|
agents = [
|
|
176
73
|
AgentInfo(name=name, display_name=display_name)
|
|
177
74
|
for name, display_name in agents_dict.items()
|
|
178
75
|
]
|
|
179
|
-
|
|
76
|
+
|
|
180
77
|
# Display the agents in the console
|
|
181
78
|
for agent_item in agents:
|
|
182
79
|
emit_system_message(
|
|
183
|
-
f"- [bold]{agent_item.name}[/bold]: {agent_item.display_name}",
|
|
184
|
-
message_group=group_id
|
|
80
|
+
f"- [bold]{agent_item.name}[/bold]: {agent_item.display_name}",
|
|
81
|
+
message_group=group_id,
|
|
185
82
|
)
|
|
186
|
-
|
|
83
|
+
|
|
187
84
|
emit_divider(message_group=group_id)
|
|
188
85
|
return ListAgentsOutput(agents=agents)
|
|
189
|
-
|
|
86
|
+
|
|
190
87
|
except Exception as e:
|
|
191
88
|
error_msg = f"Error listing agents: {str(e)}"
|
|
192
89
|
emit_error(error_msg, message_group=group_id)
|
|
193
90
|
emit_divider(message_group=group_id)
|
|
194
91
|
return ListAgentsOutput(agents=[], error=error_msg)
|
|
195
|
-
|
|
92
|
+
|
|
196
93
|
return list_agents
|
|
197
94
|
|
|
198
95
|
|
|
199
96
|
def register_invoke_agent(agent):
|
|
200
97
|
"""Register the invoke_agent tool with the provided agent.
|
|
201
|
-
|
|
98
|
+
|
|
202
99
|
Args:
|
|
203
100
|
agent: The agent to register the tool with
|
|
204
101
|
"""
|
|
102
|
+
|
|
205
103
|
@agent.tool
|
|
206
|
-
def invoke_agent(
|
|
104
|
+
def invoke_agent(
|
|
105
|
+
context: RunContext, agent_name: str, prompt: str
|
|
106
|
+
) -> AgentInvokeOutput:
|
|
207
107
|
"""Invoke a specific sub-agent with a given prompt.
|
|
208
|
-
|
|
108
|
+
|
|
209
109
|
Args:
|
|
210
110
|
agent_name: The name of the agent to invoke
|
|
211
111
|
prompt: The prompt to send to the agent
|
|
212
|
-
|
|
112
|
+
|
|
213
113
|
Returns:
|
|
214
114
|
AgentInvokeOutput: The agent's response to the prompt
|
|
215
115
|
"""
|
|
216
116
|
# Generate a group ID for this tool execution
|
|
217
117
|
group_id = generate_group_id("invoke_agent", agent_name)
|
|
218
|
-
|
|
118
|
+
|
|
219
119
|
emit_info(
|
|
220
120
|
f"\n[bold white on blue] INVOKE AGENT [/bold white on blue] {agent_name}",
|
|
221
|
-
message_group=group_id
|
|
121
|
+
message_group=group_id,
|
|
222
122
|
)
|
|
223
123
|
emit_divider(message_group=group_id)
|
|
224
124
|
emit_system_message(f"Prompt: {prompt}", message_group=group_id)
|
|
225
125
|
emit_divider(message_group=group_id)
|
|
226
|
-
|
|
126
|
+
|
|
227
127
|
try:
|
|
228
128
|
# Load the specified agent config
|
|
229
129
|
agent_config = load_agent_config(agent_name)
|
|
230
|
-
|
|
130
|
+
|
|
231
131
|
# Get the current model for creating a temporary agent
|
|
232
132
|
model_name = get_model_name()
|
|
233
133
|
models_config = ModelFactory.load_config()
|
|
@@ -235,9 +135,9 @@ def register_invoke_agent(agent):
|
|
|
235
135
|
# Only proceed if we have a valid model configuration
|
|
236
136
|
if model_name not in models_config:
|
|
237
137
|
raise ValueError(f"Model '{model_name}' not found in configuration")
|
|
238
|
-
|
|
138
|
+
|
|
239
139
|
model = ModelFactory.get_model(model_name, models_config)
|
|
240
|
-
|
|
140
|
+
|
|
241
141
|
# Create a temporary agent instance to avoid interfering with current agent state
|
|
242
142
|
instructions = agent_config.get_system_prompt()
|
|
243
143
|
temp_agent = Agent(
|
|
@@ -246,27 +146,30 @@ def register_invoke_agent(agent):
|
|
|
246
146
|
output_type=str,
|
|
247
147
|
retries=3,
|
|
248
148
|
)
|
|
249
|
-
|
|
149
|
+
|
|
250
150
|
# Register the tools that the agent needs
|
|
251
151
|
from code_puppy.tools import register_tools_for_agent
|
|
152
|
+
|
|
252
153
|
agent_tools = agent_config.get_available_tools()
|
|
253
154
|
register_tools_for_agent(temp_agent, agent_tools)
|
|
254
|
-
|
|
155
|
+
|
|
255
156
|
# Run the temporary agent with the provided prompt
|
|
256
157
|
result = temp_agent.run_sync(prompt)
|
|
257
|
-
|
|
158
|
+
|
|
258
159
|
# Extract the response from the result
|
|
259
160
|
response = result.output
|
|
260
|
-
|
|
161
|
+
|
|
261
162
|
emit_system_message(f"Response: {response}", message_group=group_id)
|
|
262
163
|
emit_divider(message_group=group_id)
|
|
263
|
-
|
|
164
|
+
|
|
264
165
|
return AgentInvokeOutput(response=response, agent_name=agent_name)
|
|
265
|
-
|
|
166
|
+
|
|
266
167
|
except Exception as e:
|
|
267
168
|
error_msg = f"Error invoking agent '{agent_name}': {str(e)}"
|
|
268
169
|
emit_error(error_msg, message_group=group_id)
|
|
269
170
|
emit_divider(message_group=group_id)
|
|
270
|
-
return AgentInvokeOutput(
|
|
271
|
-
|
|
272
|
-
|
|
171
|
+
return AgentInvokeOutput(
|
|
172
|
+
response=None, agent_name=agent_name, error=error_msg
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
return invoke_agent
|