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.
Files changed (45) hide show
  1. code_puppy/agent.py +4 -3
  2. code_puppy/agents/agent_creator_agent.py +9 -2
  3. code_puppy/agents/runtime_manager.py +12 -4
  4. code_puppy/command_line/mcp/install_command.py +50 -1
  5. code_puppy/command_line/mcp/wizard_utils.py +88 -17
  6. code_puppy/config.py +8 -2
  7. code_puppy/main.py +17 -4
  8. code_puppy/mcp/__init__.py +2 -2
  9. code_puppy/mcp/config_wizard.py +1 -1
  10. code_puppy/messaging/spinner/console_spinner.py +1 -1
  11. code_puppy/model_factory.py +13 -12
  12. code_puppy/models.json +26 -0
  13. code_puppy/round_robin_model.py +35 -18
  14. code_puppy/summarization_agent.py +1 -3
  15. code_puppy/tools/agent_tools.py +41 -138
  16. code_puppy/tools/file_operations.py +116 -96
  17. code_puppy/tui/app.py +1 -1
  18. {code_puppy-0.0.154.data → code_puppy-0.0.155.data}/data/code_puppy/models.json +26 -0
  19. {code_puppy-0.0.154.dist-info → code_puppy-0.0.155.dist-info}/METADATA +2 -2
  20. {code_puppy-0.0.154.dist-info → code_puppy-0.0.155.dist-info}/RECORD +23 -45
  21. code_puppy/token_utils.py +0 -67
  22. code_puppy/tools/token_check.py +0 -32
  23. code_puppy/tui/tests/__init__.py +0 -1
  24. code_puppy/tui/tests/test_agent_command.py +0 -79
  25. code_puppy/tui/tests/test_chat_message.py +0 -28
  26. code_puppy/tui/tests/test_chat_view.py +0 -88
  27. code_puppy/tui/tests/test_command_history.py +0 -89
  28. code_puppy/tui/tests/test_copy_button.py +0 -191
  29. code_puppy/tui/tests/test_custom_widgets.py +0 -27
  30. code_puppy/tui/tests/test_disclaimer.py +0 -27
  31. code_puppy/tui/tests/test_enums.py +0 -15
  32. code_puppy/tui/tests/test_file_browser.py +0 -60
  33. code_puppy/tui/tests/test_help.py +0 -38
  34. code_puppy/tui/tests/test_history_file_reader.py +0 -107
  35. code_puppy/tui/tests/test_input_area.py +0 -33
  36. code_puppy/tui/tests/test_settings.py +0 -44
  37. code_puppy/tui/tests/test_sidebar.py +0 -33
  38. code_puppy/tui/tests/test_sidebar_history.py +0 -153
  39. code_puppy/tui/tests/test_sidebar_history_navigation.py +0 -132
  40. code_puppy/tui/tests/test_status_bar.py +0 -54
  41. code_puppy/tui/tests/test_timestamped_history.py +0 -52
  42. code_puppy/tui/tests/test_tools.py +0 -82
  43. {code_puppy-0.0.154.dist-info → code_puppy-0.0.155.dist-info}/WHEEL +0 -0
  44. {code_puppy-0.0.154.dist-info → code_puppy-0.0.155.dist-info}/entry_points.txt +0 -0
  45. {code_puppy-0.0.154.dist-info → code_puppy-0.0.155.dist-info}/licenses/LICENSE +0 -0
@@ -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(context: RunContext, agent_name: str, prompt: str) -> AgentInvokeOutput:
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(response=None, agent_name=agent_name, error=error_msg)
271
-
272
- return invoke_agent
171
+ return AgentInvokeOutput(
172
+ response=None, agent_name=agent_name, error=error_msg
173
+ )
174
+
175
+ return invoke_agent