code-puppy 0.0.173__py3-none-any.whl → 0.0.175__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 (30) hide show
  1. code_puppy/agents/__init__.py +4 -6
  2. code_puppy/agents/agent_manager.py +22 -189
  3. code_puppy/agents/base_agent.py +471 -63
  4. code_puppy/command_line/command_handler.py +40 -41
  5. code_puppy/command_line/mcp/start_all_command.py +3 -6
  6. code_puppy/command_line/mcp/start_command.py +0 -5
  7. code_puppy/command_line/mcp/stop_all_command.py +3 -6
  8. code_puppy/command_line/mcp/stop_command.py +2 -6
  9. code_puppy/command_line/model_picker_completion.py +2 -2
  10. code_puppy/command_line/prompt_toolkit_completion.py +2 -2
  11. code_puppy/config.py +2 -2
  12. code_puppy/http_utils.py +4 -7
  13. code_puppy/main.py +12 -49
  14. code_puppy/summarization_agent.py +2 -2
  15. code_puppy/tools/agent_tools.py +5 -4
  16. code_puppy/tools/browser/vqa_agent.py +1 -3
  17. code_puppy/tui/app.py +48 -77
  18. code_puppy/tui/screens/settings.py +2 -2
  19. {code_puppy-0.0.173.dist-info → code_puppy-0.0.175.dist-info}/METADATA +2 -2
  20. {code_puppy-0.0.173.dist-info → code_puppy-0.0.175.dist-info}/RECORD +24 -30
  21. code_puppy/agent.py +0 -239
  22. code_puppy/agents/agent_orchestrator.json +0 -26
  23. code_puppy/agents/runtime_manager.py +0 -272
  24. code_puppy/command_line/meta_command_handler.py +0 -153
  25. code_puppy/message_history_processor.py +0 -408
  26. code_puppy/state_management.py +0 -58
  27. {code_puppy-0.0.173.data → code_puppy-0.0.175.data}/data/code_puppy/models.json +0 -0
  28. {code_puppy-0.0.173.dist-info → code_puppy-0.0.175.dist-info}/WHEEL +0 -0
  29. {code_puppy-0.0.173.dist-info → code_puppy-0.0.175.dist-info}/entry_points.txt +0 -0
  30. {code_puppy-0.0.173.dist-info → code_puppy-0.0.175.dist-info}/licenses/LICENSE +0 -0
code_puppy/tui/app.py CHANGED
@@ -12,27 +12,19 @@ from textual.events import Resize
12
12
  from textual.reactive import reactive
13
13
  from textual.widgets import Footer, ListView
14
14
 
15
- from code_puppy.agent import get_code_generation_agent, get_custom_usage_limits
16
- from code_puppy.agents.runtime_manager import get_runtime_agent_manager
17
15
  from code_puppy.command_line.command_handler import handle_command
18
16
  from code_puppy.config import (
19
- get_model_name,
17
+ get_global_model_name,
20
18
  get_puppy_name,
21
19
  initialize_command_history_file,
22
20
  save_command_to_history,
23
21
  )
24
- from code_puppy.message_history_processor import (
25
- message_history_accumulator,
26
- prune_interrupted_tool_calls,
27
- )
22
+ # message_history_accumulator and prune_interrupted_tool_calls have been moved to BaseAgent class
23
+ from code_puppy.agents.agent_manager import get_current_agent
28
24
 
29
25
  # Import our message queue system
30
26
  from code_puppy.messaging import TUIRenderer, get_global_queue
31
- from code_puppy.state_management import (
32
- clear_message_history,
33
- get_message_history,
34
- set_message_history,
35
- )
27
+
36
28
  from code_puppy.tui.components import (
37
29
  ChatView,
38
30
  CustomTextArea,
@@ -41,7 +33,6 @@ from code_puppy.tui.components import (
41
33
  StatusBar,
42
34
  )
43
35
 
44
- from .. import state_management
45
36
 
46
37
  # Import shared message classes
47
38
  from .messages import CommandSelected, HistoryEntrySelected
@@ -112,9 +103,9 @@ class CodePuppyTUI(App):
112
103
  def _on_agent_reload(self, agent_id: str, agent_name: str) -> None:
113
104
  """Callback for when agent is reloaded/changed."""
114
105
  # Get the updated agent configuration
115
- from code_puppy.agents.agent_manager import get_current_agent_config
106
+ from code_puppy.agents.agent_manager import get_current_agent
116
107
 
117
- current_agent_config = get_current_agent_config()
108
+ current_agent_config = get_current_agent()
118
109
  new_agent_display = (
119
110
  current_agent_config.display_name if current_agent_config else "code-puppy"
120
111
  )
@@ -127,7 +118,6 @@ class CodePuppyTUI(App):
127
118
 
128
119
  def __init__(self, initial_command: str = None, **kwargs):
129
120
  super().__init__(**kwargs)
130
- self.agent_manager = None
131
121
  self._current_worker = None
132
122
  self.initial_command = initial_command
133
123
 
@@ -159,13 +149,13 @@ class CodePuppyTUI(App):
159
149
  register_callback("agent_reload", self._on_agent_reload)
160
150
 
161
151
  # Load configuration
162
- self.current_model = get_model_name()
152
+ self.current_model = get_global_model_name()
163
153
  self.puppy_name = get_puppy_name()
164
154
 
165
155
  # Get current agent information
166
- from code_puppy.agents.agent_manager import get_current_agent_config
156
+ from code_puppy.agents.agent_manager import get_current_agent
167
157
 
168
- current_agent_config = get_current_agent_config()
158
+ current_agent_config = get_current_agent()
169
159
  self.current_agent = (
170
160
  current_agent_config.display_name if current_agent_config else "code-puppy"
171
161
  )
@@ -174,8 +164,6 @@ class CodePuppyTUI(App):
174
164
  self._update_title()
175
165
 
176
166
  # Use runtime manager to ensure we always have the current agent
177
- self.agent_manager = get_runtime_agent_manager()
178
-
179
167
  # Update status bar
180
168
  status_bar = self.query_one(StatusBar)
181
169
  status_bar.current_model = self.current_model
@@ -188,7 +176,7 @@ class CodePuppyTUI(App):
188
176
  )
189
177
 
190
178
  # Get current agent and display info
191
- get_code_generation_agent()
179
+ agent = get_current_agent()
192
180
  self.add_system_message(
193
181
  f"🐕 Loaded agent '{self.puppy_name}' with model '{self.current_model}'"
194
182
  )
@@ -430,11 +418,6 @@ class CodePuppyTUI(App):
430
418
  else:
431
419
  # Only cancel the agent task if NO processes were killed
432
420
  self._current_worker.cancel()
433
- state_management.set_message_history(
434
- prune_interrupted_tool_calls(
435
- state_management.get_message_history()
436
- )
437
- )
438
421
  self.add_system_message("⚠️ Processing cancelled by user")
439
422
  # Stop spinner and clear state only when agent is actually cancelled
440
423
  self._current_worker = None
@@ -491,55 +474,44 @@ class CodePuppyTUI(App):
491
474
  return
492
475
 
493
476
  # Process with agent
494
- if self.agent_manager:
495
- try:
496
- self.update_agent_progress("Processing", 25)
497
-
498
- # Use agent_manager's run_with_mcp to handle MCP servers properly
499
- try:
500
- self.update_agent_progress("Processing", 50)
501
- result = await self.agent_manager.run_with_mcp(
502
- message,
503
- message_history=get_message_history(),
504
- usage_limits=get_custom_usage_limits(),
505
- )
506
-
507
- if not result or not hasattr(result, "output"):
508
- self.add_error_message("Invalid response format from agent")
509
- return
510
-
511
- self.update_agent_progress("Processing", 75)
512
- agent_response = result.output
513
- self.add_agent_message(agent_response)
514
-
515
- # Update message history
516
- new_msgs = result.new_messages()
517
- message_history_accumulator(new_msgs)
518
-
519
- # Refresh history display to show new interaction
520
- self.refresh_history_display()
477
+ try:
478
+ self.update_agent_progress("Processing", 25)
521
479
 
522
- except Exception as eg:
523
- # Handle TaskGroup and other exceptions
524
- # BaseExceptionGroup is only available in Python 3.11+
525
- if hasattr(eg, "exceptions"):
526
- # Handle TaskGroup exceptions specifically (Python 3.11+)
527
- for e in eg.exceptions:
528
- self.add_error_message(f"MCP/Agent error: {str(e)}")
529
- else:
530
- # Handle regular exceptions
531
- self.add_error_message(f"MCP/Agent error: {str(eg)}")
532
- finally:
533
- set_message_history(
534
- prune_interrupted_tool_calls(get_message_history())
535
- )
536
- except Exception as agent_error:
537
- # Handle any other errors in agent processing
538
- self.add_error_message(
539
- f"Agent processing failed: {str(agent_error)}"
480
+ # Use agent_manager's run_with_mcp to handle MCP servers properly
481
+ try:
482
+ agent = get_current_agent()
483
+ self.update_agent_progress("Processing", 50)
484
+ result = await agent.run_with_mcp(
485
+ message,
540
486
  )
541
- else:
542
- self.add_error_message("Agent manager not initialized")
487
+
488
+ if not result or not hasattr(result, "output"):
489
+ self.add_error_message("Invalid response format from agent")
490
+ return
491
+
492
+ self.update_agent_progress("Processing", 75)
493
+ agent_response = result.output
494
+ self.add_agent_message(agent_response)
495
+ # Refresh history display to show new interaction
496
+ self.refresh_history_display()
497
+
498
+ except Exception as eg:
499
+ # Handle TaskGroup and other exceptions
500
+ # BaseExceptionGroup is only available in Python 3.11+
501
+ if hasattr(eg, "exceptions"):
502
+ # Handle TaskGroup exceptions specifically (Python 3.11+)
503
+ for e in eg.exceptions:
504
+ self.add_error_message(f"MCP/Agent error: {str(e)}")
505
+ else:
506
+ # Handle regular exceptions
507
+ self.add_error_message(f"MCP/Agent error: {str(eg)}")
508
+ finally:
509
+ pass
510
+ except Exception as agent_error:
511
+ # Handle any other errors in agent processing
512
+ self.add_error_message(
513
+ f"Agent processing failed: {str(agent_error)}"
514
+ )
543
515
 
544
516
  except Exception as e:
545
517
  self.add_error_message(f"Error processing message: {str(e)}")
@@ -553,7 +525,6 @@ class CodePuppyTUI(App):
553
525
  """Clear the chat history."""
554
526
  chat_view = self.query_one("#chat-view", ChatView)
555
527
  chat_view.clear_messages()
556
- clear_message_history()
557
528
  self.add_system_message("Chat history cleared")
558
529
 
559
530
  def action_show_help(self) -> None:
@@ -652,13 +623,13 @@ class CodePuppyTUI(App):
652
623
  def handle_settings_result(result):
653
624
  if result and result.get("success"):
654
625
  # Update reactive variables
655
- from code_puppy.config import get_model_name, get_puppy_name
626
+ from code_puppy.config import get_global_model_name, get_puppy_name
656
627
 
657
628
  self.puppy_name = get_puppy_name()
658
629
 
659
630
  # Handle model change if needed
660
631
  if result.get("model_changed"):
661
- new_model = get_model_name()
632
+ new_model = get_global_model_name()
662
633
  self.current_model = new_model
663
634
  # Reinitialize agent with new model
664
635
  self.agent_manager.reload_agent()
@@ -125,7 +125,7 @@ class SettingsScreen(ModalScreen):
125
125
  def on_mount(self) -> None:
126
126
  """Load current settings when the screen mounts."""
127
127
  from code_puppy.config import (
128
- get_model_name,
128
+ get_global_model_name,
129
129
  get_owner_name,
130
130
  get_protected_token_count,
131
131
  get_puppy_name,
@@ -155,7 +155,7 @@ class SettingsScreen(ModalScreen):
155
155
  self.load_model_options(model_select)
156
156
 
157
157
  # Set current model selection
158
- current_model = get_model_name()
158
+ current_model = get_global_model_name()
159
159
  model_select.value = current_model
160
160
 
161
161
  # YOLO mode is always enabled in TUI mode
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-puppy
3
- Version: 0.0.173
3
+ Version: 0.0.175
4
4
  Summary: Code generation agent
5
5
  Project-URL: repository, https://github.com/mpfaffenberger/code_puppy
6
6
  Project-URL: HomePage, https://github.com/mpfaffenberger/code_puppy
@@ -26,7 +26,7 @@ Requires-Dist: openai>=1.99.1
26
26
  Requires-Dist: pathspec>=0.11.0
27
27
  Requires-Dist: playwright>=1.40.0
28
28
  Requires-Dist: prompt-toolkit>=3.0.38
29
- Requires-Dist: pydantic-ai>=1.0.10
29
+ Requires-Dist: pydantic-ai<=0.8
30
30
  Requires-Dist: pydantic>=2.4.0
31
31
  Requires-Dist: pyjwt>=2.8.0
32
32
  Requires-Dist: pytest-cov>=6.1.1
@@ -1,37 +1,31 @@
1
1
  code_puppy/__init__.py,sha256=ehbM1-wMjNmOXk_DBhhJECFyBv2dRHwwo7ucjHeM68E,107
2
2
  code_puppy/__main__.py,sha256=pDVssJOWP8A83iFkxMLY9YteHYat0EyWDQqMkKHpWp4,203
3
- code_puppy/agent.py,sha256=rBe7OS_ekZvMuteLuIp9lor9zIP7KHBsxZ22pWM9_fg,8526
4
3
  code_puppy/callbacks.py,sha256=6wYB6K_fGSCkKKEFaYOYkJT45WaV5W_NhUIzcvVH_nU,5060
5
- code_puppy/config.py,sha256=A3l5gSJGz9kGXJb2pZVyoksDGclIhMdKmAv-EdDSleY,20625
6
- code_puppy/http_utils.py,sha256=jnElpVNNIK-_gcqwsBYRImDGU-tYNfsLR7Gtme5CYzs,8423
7
- code_puppy/main.py,sha256=VlH8fXPapXblSagOjrezeSTtFij_-X3dzq1cfHPXwDI,22252
8
- code_puppy/message_history_processor.py,sha256=SnVpUCMkbtM4RX5b6ioeG-fh--ri0bh8_yHp7ZQIAPE,16005
4
+ code_puppy/config.py,sha256=ruPGe9f3kFI9F563NQOKuNQY12kw5eXPzbm2utJ0DO8,20639
5
+ code_puppy/http_utils.py,sha256=YLd8Y16idbI32JGeBXG8n5rT4o4X_zxk9FgUvK9XFo8,8248
6
+ code_puppy/main.py,sha256=hVPFNN8QOuct2FFH6OMGQ3E04cmEnmO88ffTbbpfuWY,20516
9
7
  code_puppy/model_factory.py,sha256=z9vQbcGllgMwU0On8rPvzYxkygW2Uyd3NJmRzbKv-is,13759
10
8
  code_puppy/models.json,sha256=iXmLZGflnQcu2DRh4WUlgAhoXdvoxUc7KBhB8YxawXM,3088
11
9
  code_puppy/reopenable_async_client.py,sha256=4UJRaMp5np8cbef9F0zKQ7TPKOfyf5U-Kv-0zYUWDho,8274
12
10
  code_puppy/round_robin_model.py,sha256=SEN3VSwTgC5wHjx2sZsHQLPWOycf4jGwzB-EydgqkdY,5643
13
- code_puppy/state_management.py,sha256=OyBSfdicKN7ObZEGs6Kbyy1JC8R8n4FZBOLIBvQZTBc,1916
14
11
  code_puppy/status_display.py,sha256=F6eEAkGePDp4StM2BWj-uLLQTDGtJrf0IufzCeP1rRg,8336
15
- code_puppy/summarization_agent.py,sha256=kos4_YK-l_YjYRq4Fs4X5YoTUbmAcDhhPqefL-rdenI,3197
12
+ code_puppy/summarization_agent.py,sha256=LnObgtLmM6N4z2553XXQlXAOf8R1BPSNmFSfXkjpivg,3211
16
13
  code_puppy/tui_state.py,sha256=TT76XBVapKj6fKjFzz6oxCONeN_BZwcMILxxZcxu6-Y,1171
17
14
  code_puppy/version_checker.py,sha256=bjLDmgGPrl7XnYwX1u13O8uFlsfikV90PK6nbA9Z9QU,1150
18
- code_puppy/agents/__init__.py,sha256=SwtHGNG1GIgDBv7y3EGIXOXEWrG_Ou7fEknNgFbrHv8,594
15
+ code_puppy/agents/__init__.py,sha256=37co1Xux3E10ynvbCBkyeTZAZpjEb-ci2uUy6nzM1hA,518
19
16
  code_puppy/agents/agent_code_puppy.py,sha256=sbuQxLzlkMbPOyLbILbXOAHecRsxbFdQt13HJ_GEqQo,7972
20
17
  code_puppy/agents/agent_creator_agent.py,sha256=eNOlJssQdyoQm1F7d-TZWcMXpkYmZ-w9WN-NDFXCgtw,23042
21
- code_puppy/agents/agent_manager.py,sha256=nXvro6fpX8KA-NedRoVJuhJW966trrePOrH4eAnqq40,17034
22
- code_puppy/agents/agent_orchestrator.json,sha256=Iqnc0p6ICoAlUTMkEsi1XXMXJi4pdxVnWZUMaih6s5o,1267
18
+ code_puppy/agents/agent_manager.py,sha256=ZT6B7x4hRKdmEzP085_xR8OL8j0YpboWazrs0U7mP1I,11409
23
19
  code_puppy/agents/agent_qa_kitten.py,sha256=5PeFFSwCFlTUvP6h5bGntx0xv5NmRwBiw0HnMqY8nLI,9107
24
- code_puppy/agents/base_agent.py,sha256=XUsziIf0ZGCe6ZLjt-kJqbeYTy9gTQE3_BPq7THQ3X8,19538
20
+ code_puppy/agents/base_agent.py,sha256=Rv1jXxeFsXfwdyGoVWwoZRgovbi_laex6OivLzaGHpQ,36723
25
21
  code_puppy/agents/json_agent.py,sha256=y6AYE3Fx9LhmemcPzt46d7359MNnkGIjU83YBGNer2g,4533
26
- code_puppy/agents/runtime_manager.py,sha256=fUOBpmETo3wTyLc5wWBfGKSX1HFRQWSpuwxYAOyA-_8,10059
27
22
  code_puppy/command_line/__init__.py,sha256=y7WeRemfYppk8KVbCGeAIiTuiOszIURCDjOMZv_YRmU,45
28
- code_puppy/command_line/command_handler.py,sha256=45jUScWIikVi2OgCL7LrcpWoDcrmfWv0do-y_mS4i8U,27248
23
+ code_puppy/command_line/command_handler.py,sha256=z4p62jwdJXUJVVzTHStTOFyzv-PwjjNhu8bziIo8gns,27191
29
24
  code_puppy/command_line/file_path_completion.py,sha256=gw8NpIxa6GOpczUJRyh7VNZwoXKKn-yvCqit7h2y6Gg,2931
30
25
  code_puppy/command_line/load_context_completion.py,sha256=6eZxV6Bs-EFwZjN93V8ZDZUC-6RaWxvtZk-04Wtikyw,2240
31
- code_puppy/command_line/meta_command_handler.py,sha256=80aK5JQOaqjt149qBmSsM02uy2Cikkee8zaQnu5u2KQ,5712
32
- code_puppy/command_line/model_picker_completion.py,sha256=adxp3NZaDV67YqaGv0SG7WVvOTXN0UwkkLqxTsknAvs,4126
26
+ code_puppy/command_line/model_picker_completion.py,sha256=vYNCZS1QWu6fxF__hTwpc7jwH7h_48wUxrnITawc83E,4140
33
27
  code_puppy/command_line/motd.py,sha256=PEdkp3ZnydVfvd7mNJylm8YyFNUKg9jmY6uwkA1em8c,2152
34
- code_puppy/command_line/prompt_toolkit_completion.py,sha256=PLb1Yt_65iQI2mzPEPxPsSaRww5Ur951Qn-K-TLMCGQ,10006
28
+ code_puppy/command_line/prompt_toolkit_completion.py,sha256=O-wTYIGb9J_ONEBa-bWNFeQLnqC6LIFKsKQ7hjMbssM,9992
35
29
  code_puppy/command_line/utils.py,sha256=7eyxDHjPjPB9wGDJQQcXV_zOsGdYsFgI0SGCetVmTqE,1251
36
30
  code_puppy/command_line/mcp/__init__.py,sha256=0-OQuwjq_pLiTVJ1_NrirVwdRerghyKs_MTZkwPC7YY,315
37
31
  code_puppy/command_line/mcp/add_command.py,sha256=lZ09RpFDIeghX1zhc2YIAqBASs5Ra52x5YAasUKvqJg,6409
@@ -44,11 +38,11 @@ code_puppy/command_line/mcp/logs_command.py,sha256=x_QsVGPpI5XY7RCZtiNFegc6R3csi
44
38
  code_puppy/command_line/mcp/remove_command.py,sha256=MrWmXQ9jZTq1wrohFDO3ls0a1faTHCqRZocN-ynTzh8,2753
45
39
  code_puppy/command_line/mcp/restart_command.py,sha256=-arZhayEVjTg3WErQKiBoFxbpbQcFlPXTzUI5o8AQLg,3254
46
40
  code_puppy/command_line/mcp/search_command.py,sha256=k4CGiNJ1MKJ1_dPHd3wlwXo899nzizSUr7PsR0V9y4Y,4113
47
- code_puppy/command_line/mcp/start_all_command.py,sha256=9f8BPTijs7BVBQKKNXjtH3laQVuqhNyfPSgISvBUcfM,4295
48
- code_puppy/command_line/mcp/start_command.py,sha256=r00onOpfSSL-gtJLDOvmD-8G4RZhhmd-nv3TyIWGMUI,3350
41
+ code_puppy/command_line/mcp/start_all_command.py,sha256=cdFi-eEAp4SKTiUvSkCAHaeq3PiujW35a3ZT7UPNlUc,4197
42
+ code_puppy/command_line/mcp/start_command.py,sha256=dFB64MJMHAh8v_Jq07Ux4K74P9CP239l_0BHk7wH_2A,3108
49
43
  code_puppy/command_line/mcp/status_command.py,sha256=tQJrEDlN4DJ3n9jnKW-4kD0vL3TyUQbovb4V3nz-RsA,6640
50
- code_puppy/command_line/mcp/stop_all_command.py,sha256=QioqCPFjIbbdT_P5tyVakB2idUD1rnlhwYXLpa-G4TI,3716
51
- code_puppy/command_line/mcp/stop_command.py,sha256=zuZO8pIP2Ix11LATf-cwwX3fPFIGAbRDaZ6qnfPTqLY,2594
44
+ code_puppy/command_line/mcp/stop_all_command.py,sha256=BcsvkGcSGCexCnWfpirBNxJNHP0HSGrjQP0LslHbano,3618
45
+ code_puppy/command_line/mcp/stop_command.py,sha256=6ruOlABIgGmuFmoakAsaqStaCUctBsA_KbvYNKmlt8U,2456
52
46
  code_puppy/command_line/mcp/test_command.py,sha256=Pjod77DYRcA9WDZcxaCe6AUgpEXKJr42QRkxMhSjXhM,3689
53
47
  code_puppy/command_line/mcp/utils.py,sha256=0Wt4ttYgSlVvtusYmBLKXSkjAjcsDiUxcZQAoFLUNnE,3625
54
48
  code_puppy/command_line/mcp/wizard_utils.py,sha256=mWuE5epVgCxgGoj-VGwPO_XWVkkXjegXoIJpC9LC2TM,11075
@@ -79,7 +73,7 @@ code_puppy/messaging/spinner/spinner_base.py,sha256=474qMrTYpNfWcprFzmhaOJEOC-2r
79
73
  code_puppy/messaging/spinner/textual_spinner.py,sha256=Omx9A-FSPkxYDMYgBXgYMBQnK-DMlyqLOgkFVG8cmo4,3465
80
74
  code_puppy/plugins/__init__.py,sha256=fksDqMUiXPJ5WNuMsYsVR8ulueQRCXPlvECEyicHPtQ,1312
81
75
  code_puppy/tools/__init__.py,sha256=BVTZ85jLHgDANwOnUSOz3UDlp8VQDq4DoGF23BRlyWw,6032
82
- code_puppy/tools/agent_tools.py,sha256=bHMrFIbYRhuubR41G_XdLsk3cUKWfIPl2O4bVzo2pE0,5591
76
+ code_puppy/tools/agent_tools.py,sha256=h3i4c6KOxdjLr-fFjUDJdL0OR_XHo_AWx7uwfvavQJ8,5640
83
77
  code_puppy/tools/browser_control.py,sha256=6E_Kq63cErBk-iM9-03Cq8sTWWLh-Tk2kpdrB_rMmbg,8603
84
78
  code_puppy/tools/browser_interactions.py,sha256=m-bVsAUbdrS-P1GbS0ChO2tMMg4tMIsDX34azn_Olzs,17070
85
79
  code_puppy/tools/browser_locators.py,sha256=ZshjhYuV600vJqXUC23oNX89AZLMvY8rlvj-9oy7GMw,19574
@@ -102,9 +96,9 @@ code_puppy/tools/browser/browser_screenshot.py,sha256=zbOMmN9_9aVDWJkC54-3zv4OEG
102
96
  code_puppy/tools/browser/browser_scripts.py,sha256=BLSx1Q2F_mOOoGCoyXat3HvazTb1XaFYPXAF8CYVeX8,15071
103
97
  code_puppy/tools/browser/browser_workflows.py,sha256=HZ0lPmEyAobPIWR-SK1E0ngW1OfULLqw8XILVT4N8Fg,5979
104
98
  code_puppy/tools/browser/camoufox_manager.py,sha256=E1CJwQtzPFoDQiXSHHk28niWuJhk3soZ-ItxXCXWO0M,6938
105
- code_puppy/tools/browser/vqa_agent.py,sha256=u3EhZQHNBiWUn-XLDK9MnVyd2ChshPnVZbB9iEkEqH4,2118
99
+ code_puppy/tools/browser/vqa_agent.py,sha256=jUvzsk9okOZ9jskuBuij2n8wRTpTkUU2JDaHmfY8PLc,2016
106
100
  code_puppy/tui/__init__.py,sha256=XesAxIn32zLPOmvpR2wIDxDAnnJr81a5pBJB4cZp1Xs,321
107
- code_puppy/tui/app.py,sha256=WW-O8myM_yl05NIdj_aSp7zN56AwimgdMA9TmEOE54Y,39427
101
+ code_puppy/tui/app.py,sha256=gZvg7ZOUp3JurZyKZ7ehpHEhmyC0NnfmQYWF_yZm36o,38163
108
102
  code_puppy/tui/messages.py,sha256=zQoToWI0eWdT36NEsY6RdCFzcDfAmfvoPlHv8jiCbgo,720
109
103
  code_puppy/tui/components/__init__.py,sha256=uj5pnk3s6SEN3SbFI0ZnzaA2KK1NNg8TfUj6U-Z732U,455
110
104
  code_puppy/tui/components/chat_view.py,sha256=NfyNXuN2idPht1rKJB4YhHVXb1AIRNO5q_nLdt8Ocug,19913
@@ -122,11 +116,11 @@ code_puppy/tui/models/enums.py,sha256=1ulsei95Gxy4r1sk-m-Sm5rdmejYCGRI-YtUwJmKFf
122
116
  code_puppy/tui/screens/__init__.py,sha256=tJ00d0aYQ9kzOGHRChqy6cCQ6JUKKXBzLUTEbk_eA2Y,286
123
117
  code_puppy/tui/screens/help.py,sha256=eJuPaOOCp7ZSUlecearqsuX6caxWv7NQszUh0tZJjBM,3232
124
118
  code_puppy/tui/screens/mcp_install_wizard.py,sha256=vObpQwLbXjQsxmSg-WCasoev1usEi0pollKnL0SHu9U,27693
125
- code_puppy/tui/screens/settings.py,sha256=GMpv-qa08rorAE9mj3AjmqjZFPhmeJ_GWd-DBHG6iAA,10671
119
+ code_puppy/tui/screens/settings.py,sha256=W22sevojC1_HZBoeoJTH3HWkehini3bGi_ic0OKgeLI,10685
126
120
  code_puppy/tui/screens/tools.py,sha256=3pr2Xkpa9Js6Yhf1A3_wQVRzFOui-KDB82LwrsdBtyk,1715
127
- code_puppy-0.0.173.data/data/code_puppy/models.json,sha256=iXmLZGflnQcu2DRh4WUlgAhoXdvoxUc7KBhB8YxawXM,3088
128
- code_puppy-0.0.173.dist-info/METADATA,sha256=4qImoiksA3Y_7gc-YlHc7cAdJJa6pnP2xhOUQbQ9vCY,20106
129
- code_puppy-0.0.173.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
130
- code_puppy-0.0.173.dist-info/entry_points.txt,sha256=Tp4eQC99WY3HOKd3sdvb22vZODRq0XkZVNpXOag_KdI,91
131
- code_puppy-0.0.173.dist-info/licenses/LICENSE,sha256=31u8x0SPgdOq3izJX41kgFazWsM43zPEF9eskzqbJMY,1075
132
- code_puppy-0.0.173.dist-info/RECORD,,
121
+ code_puppy-0.0.175.data/data/code_puppy/models.json,sha256=iXmLZGflnQcu2DRh4WUlgAhoXdvoxUc7KBhB8YxawXM,3088
122
+ code_puppy-0.0.175.dist-info/METADATA,sha256=eyUu2t6tGGAB4Urt_lhXVDtSkT0yw8aZ_IJEa2B-BAc,20103
123
+ code_puppy-0.0.175.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
124
+ code_puppy-0.0.175.dist-info/entry_points.txt,sha256=Tp4eQC99WY3HOKd3sdvb22vZODRq0XkZVNpXOag_KdI,91
125
+ code_puppy-0.0.175.dist-info/licenses/LICENSE,sha256=31u8x0SPgdOq3izJX41kgFazWsM43zPEF9eskzqbJMY,1075
126
+ code_puppy-0.0.175.dist-info/RECORD,,
code_puppy/agent.py DELETED
@@ -1,239 +0,0 @@
1
- import uuid
2
- from pathlib import Path
3
- from pydantic_ai.models.openai import OpenAIModelSettings, OpenAIResponsesModelSettings
4
- from typing import Dict, Optional
5
-
6
- from pydantic_ai import Agent
7
- from pydantic_ai.settings import ModelSettings
8
- from pydantic_ai.usage import UsageLimits
9
-
10
- from code_puppy.message_history_processor import message_history_accumulator
11
- from code_puppy.messaging.message_queue import (
12
- emit_error,
13
- emit_info,
14
- emit_system_message,
15
- )
16
- from code_puppy.model_factory import ModelFactory
17
-
18
- # Tool registration is imported on demand
19
- from code_puppy.tools.common import console
20
-
21
-
22
- def load_puppy_rules():
23
- global PUPPY_RULES
24
-
25
- # Check for all 4 combinations of the rules file
26
- possible_paths = ["AGENTS.md", "AGENT.md", "agents.md", "agent.md"]
27
-
28
- for path_str in possible_paths:
29
- puppy_rules_path = Path(path_str)
30
- if puppy_rules_path.exists():
31
- with open(puppy_rules_path, "r") as f:
32
- puppy_rules = f.read()
33
- return puppy_rules
34
-
35
- # If none of the files exist, return None
36
- return None
37
-
38
-
39
- # Load at import
40
- PUPPY_RULES = load_puppy_rules()
41
- _LAST_MODEL_NAME = None
42
- _code_generation_agent = None
43
-
44
-
45
- def _load_mcp_servers(extra_headers: Optional[Dict[str, str]] = None):
46
- """Load MCP servers using the new manager while maintaining backward compatibility."""
47
- from code_puppy.config import get_value, load_mcp_server_configs
48
- from code_puppy.mcp_ import ServerConfig, get_mcp_manager
49
-
50
- # Check if MCP servers are disabled
51
- mcp_disabled = get_value("disable_mcp_servers")
52
- if mcp_disabled and str(mcp_disabled).lower() in ("1", "true", "yes", "on"):
53
- emit_system_message("[dim]MCP servers disabled via config[/dim]")
54
- return []
55
-
56
- # Get the MCP manager singleton
57
- manager = get_mcp_manager()
58
-
59
- # Load configurations from legacy file for backward compatibility
60
- configs = load_mcp_server_configs()
61
- if not configs:
62
- # Check if manager already has servers (could be from new system)
63
- existing_servers = manager.list_servers()
64
- if not existing_servers:
65
- emit_system_message("[dim]No MCP servers configured[/dim]")
66
- return []
67
- else:
68
- # Register servers from legacy config with manager
69
- for name, conf in configs.items():
70
- try:
71
- # Convert legacy format to new ServerConfig
72
- server_config = ServerConfig(
73
- id=conf.get("id", f"{name}_{hash(name)}"),
74
- name=name,
75
- type=conf.get("type", "sse"),
76
- enabled=conf.get("enabled", True),
77
- config=conf,
78
- )
79
-
80
- # Check if server already registered
81
- existing = manager.get_server_by_name(name)
82
- if not existing:
83
- # Register new server
84
- manager.register_server(server_config)
85
- emit_system_message(f"[dim]Registered MCP server: {name}[/dim]")
86
- else:
87
- # Update existing server config if needed
88
- if existing.config != server_config.config:
89
- manager.update_server(existing.id, server_config)
90
- emit_system_message(f"[dim]Updated MCP server: {name}[/dim]")
91
-
92
- except Exception as e:
93
- emit_error(f"Failed to register MCP server '{name}': {str(e)}")
94
- continue
95
-
96
- # Get pydantic-ai compatible servers from manager
97
- servers = manager.get_servers_for_agent()
98
-
99
- if servers:
100
- emit_system_message(
101
- f"[green]Successfully loaded {len(servers)} MCP server(s)[/green]"
102
- )
103
- else:
104
- emit_system_message(
105
- "[yellow]No MCP servers available (check if servers are enabled)[/yellow]"
106
- )
107
-
108
- return servers
109
-
110
-
111
- def reload_mcp_servers():
112
- """Reload MCP servers without restarting the agent."""
113
- from code_puppy.mcp_ import get_mcp_manager
114
-
115
- manager = get_mcp_manager()
116
- # Reload configurations
117
- _load_mcp_servers()
118
- # Return updated servers
119
- return manager.get_servers_for_agent()
120
-
121
-
122
- def reload_code_generation_agent(message_group: str | None):
123
- """Force-reload the agent, usually after a model change."""
124
- if message_group is None:
125
- message_group = str(uuid.uuid4())
126
- global _code_generation_agent, _LAST_MODEL_NAME
127
- from code_puppy.agents import clear_agent_cache
128
- from code_puppy.config import clear_model_cache, get_model_name
129
-
130
- # Clear both ModelFactory cache and config cache when force reloading
131
- clear_model_cache()
132
- clear_agent_cache()
133
-
134
- # Check if current agent has a pinned model
135
- from code_puppy.agents import get_current_agent_config
136
-
137
- agent_config = get_current_agent_config()
138
- agent_model_name = None
139
- if hasattr(agent_config, "get_model_name"):
140
- agent_model_name = agent_config.get_model_name()
141
-
142
- # Use agent-specific model if pinned, otherwise use global model
143
- model_name = agent_model_name if agent_model_name else get_model_name()
144
- emit_info(
145
- f"[bold cyan]Loading Model: {model_name}[/bold cyan]",
146
- message_group=message_group,
147
- )
148
- models_config = ModelFactory.load_config()
149
- model = ModelFactory.get_model(model_name, models_config)
150
-
151
- # Get agent-specific system prompt
152
- agent_config = get_current_agent_config()
153
- emit_info(
154
- f"[bold magenta]Loading Agent: {agent_config.display_name}[/bold magenta]",
155
- message_group=message_group,
156
- )
157
-
158
- instructions = agent_config.get_system_prompt()
159
-
160
- if PUPPY_RULES:
161
- instructions += f"\n{PUPPY_RULES}"
162
-
163
- mcp_servers = _load_mcp_servers()
164
-
165
- # Configure model settings with max_tokens if set
166
- model_settings_dict = {"seed": 42}
167
- # Get current agent to use its method
168
- from code_puppy.agents import get_current_agent_config
169
- current_agent = get_current_agent_config()
170
- output_tokens = max(2048, min(int(0.05 * current_agent.get_model_context_length()) - 1024, 16384))
171
- console.print(f"Max output tokens per message: {output_tokens}")
172
- model_settings_dict["max_tokens"] = output_tokens
173
-
174
-
175
- model_settings = ModelSettings(**model_settings_dict)
176
- if "gpt-5" in model_name:
177
- model_settings_dict["openai_reasoning_effort"] = "off"
178
- model_settings_dict["extra_body"] = {
179
- "verbosity": "low"
180
- }
181
- model_settings = OpenAIModelSettings(**model_settings_dict)
182
- agent = Agent(
183
- model=model,
184
- instructions=instructions,
185
- output_type=str,
186
- retries=3,
187
- mcp_servers=mcp_servers,
188
- history_processors=[message_history_accumulator],
189
- model_settings=model_settings,
190
- )
191
-
192
- # Register tools specified by the agent
193
- from code_puppy.tools import register_tools_for_agent
194
-
195
- agent_tools = agent_config.get_available_tools()
196
- register_tools_for_agent(agent, agent_tools)
197
- _code_generation_agent = agent
198
- _LAST_MODEL_NAME = model_name
199
- return _code_generation_agent
200
-
201
-
202
- def get_code_generation_agent(force_reload=False, message_group: str | None = None):
203
- """
204
- Retrieve the agent with the currently configured model.
205
- Forces a reload if the model has changed, or if force_reload is passed.
206
- """
207
- global _code_generation_agent, _LAST_MODEL_NAME
208
- if message_group is None:
209
- message_group = str(uuid.uuid4())
210
- from code_puppy.config import get_model_name
211
-
212
- # Get the global model name
213
- global_model_name = get_model_name()
214
-
215
- # Check if current agent has a pinned model
216
- from code_puppy.agents import get_current_agent_config
217
-
218
- agent_config = get_current_agent_config()
219
- agent_model_name = None
220
- if hasattr(agent_config, "get_model_name"):
221
- agent_model_name = agent_config.get_model_name()
222
-
223
- # Use agent-specific model if pinned, otherwise use global model
224
- model_name = agent_model_name if agent_model_name else global_model_name
225
-
226
- if _code_generation_agent is None or _LAST_MODEL_NAME != model_name or force_reload:
227
- return reload_code_generation_agent(message_group)
228
- return _code_generation_agent
229
-
230
-
231
- def get_custom_usage_limits():
232
- """
233
- Returns custom usage limits with configurable request limit.
234
- This centralizes the configuration of rate limiting for the agent.
235
- Default pydantic-ai limit is 50, this increases it to the configured value (default 100).
236
- """
237
- from code_puppy.config import get_message_limit
238
-
239
- return UsageLimits(request_limit=get_message_limit())
@@ -1,26 +0,0 @@
1
- {
2
- "id": "agent-orchestrator-id",
3
- "name": "agent-orchestrator",
4
- "display_name": "Agent Orchestrator 🎭",
5
- "description": "Coordinates and manages various specialized agents to accomplish tasks",
6
- "system_prompt": [
7
- "You are an agent orchestrator that coordinates various specialized agents.",
8
- "When given a task, first list the available agents to understand what's at your disposal.",
9
- "Then, invoke the most appropriate agent to handle the task. If needed, you can invoke multiple agents.",
10
- "",
11
- "#### `list_agents()`",
12
- "Use this to list all available sub-agents that can be invoked",
13
- "",
14
- "#### `invoke_agent(agent_name: str, user_prompt: str)`",
15
- "Use this to invoke another agent with a specific prompt. This allows agents to delegate tasks to specialized sub-agents.",
16
- "Arguments:",
17
- "- agent_name (required): Name of the agent to invoke",
18
- "- user_prompt (required): The prompt to send to the invoked agent",
19
- "Example usage:",
20
- "```python",
21
- "invoke_agent(agent_name=\"python-tutor\", user_prompt=\"Explain how to use list comprehensions\")",
22
- "```"
23
- ],
24
- "tools": ["list_agents", "invoke_agent", "agent_share_your_reasoning"],
25
- "user_prompt": "What would you like me to coordinate for you?"
26
- }