code-puppy 0.0.174__tar.gz → 0.0.175__tar.gz

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 (126) hide show
  1. {code_puppy-0.0.174 → code_puppy-0.0.175}/PKG-INFO +1 -1
  2. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/agents/agent_manager.py +8 -3
  3. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/agents/base_agent.py +1 -0
  4. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/http_utils.py +4 -7
  5. {code_puppy-0.0.174 → code_puppy-0.0.175}/pyproject.toml +1 -1
  6. code_puppy-0.0.174/code_puppy/agent.py +0 -239
  7. {code_puppy-0.0.174 → code_puppy-0.0.175}/.gitignore +0 -0
  8. {code_puppy-0.0.174 → code_puppy-0.0.175}/LICENSE +0 -0
  9. {code_puppy-0.0.174 → code_puppy-0.0.175}/README.md +0 -0
  10. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/__init__.py +0 -0
  11. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/__main__.py +0 -0
  12. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/agents/__init__.py +0 -0
  13. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/agents/agent_code_puppy.py +0 -0
  14. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/agents/agent_creator_agent.py +0 -0
  15. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/agents/agent_qa_kitten.py +0 -0
  16. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/agents/json_agent.py +0 -0
  17. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/callbacks.py +0 -0
  18. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/command_line/__init__.py +0 -0
  19. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/command_line/command_handler.py +0 -0
  20. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/command_line/file_path_completion.py +0 -0
  21. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/command_line/load_context_completion.py +0 -0
  22. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/command_line/mcp/__init__.py +0 -0
  23. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/command_line/mcp/add_command.py +0 -0
  24. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/command_line/mcp/base.py +0 -0
  25. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/command_line/mcp/handler.py +0 -0
  26. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/command_line/mcp/help_command.py +0 -0
  27. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/command_line/mcp/install_command.py +0 -0
  28. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/command_line/mcp/list_command.py +0 -0
  29. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/command_line/mcp/logs_command.py +0 -0
  30. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/command_line/mcp/remove_command.py +0 -0
  31. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/command_line/mcp/restart_command.py +0 -0
  32. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/command_line/mcp/search_command.py +0 -0
  33. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/command_line/mcp/start_all_command.py +0 -0
  34. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/command_line/mcp/start_command.py +0 -0
  35. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/command_line/mcp/status_command.py +0 -0
  36. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/command_line/mcp/stop_all_command.py +0 -0
  37. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/command_line/mcp/stop_command.py +0 -0
  38. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/command_line/mcp/test_command.py +0 -0
  39. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/command_line/mcp/utils.py +0 -0
  40. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/command_line/mcp/wizard_utils.py +0 -0
  41. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/command_line/model_picker_completion.py +0 -0
  42. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/command_line/motd.py +0 -0
  43. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/command_line/prompt_toolkit_completion.py +0 -0
  44. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/command_line/utils.py +0 -0
  45. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/config.py +0 -0
  46. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/main.py +0 -0
  47. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/mcp_/__init__.py +0 -0
  48. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/mcp_/async_lifecycle.py +0 -0
  49. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/mcp_/blocking_startup.py +0 -0
  50. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/mcp_/captured_stdio_server.py +0 -0
  51. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/mcp_/circuit_breaker.py +0 -0
  52. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/mcp_/config_wizard.py +0 -0
  53. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/mcp_/dashboard.py +0 -0
  54. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/mcp_/error_isolation.py +0 -0
  55. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/mcp_/examples/retry_example.py +0 -0
  56. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/mcp_/health_monitor.py +0 -0
  57. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/mcp_/managed_server.py +0 -0
  58. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/mcp_/manager.py +0 -0
  59. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/mcp_/registry.py +0 -0
  60. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/mcp_/retry_manager.py +0 -0
  61. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/mcp_/server_registry_catalog.py +0 -0
  62. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/mcp_/status_tracker.py +0 -0
  63. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/mcp_/system_tools.py +0 -0
  64. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/messaging/__init__.py +0 -0
  65. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/messaging/message_queue.py +0 -0
  66. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/messaging/queue_console.py +0 -0
  67. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/messaging/renderers.py +0 -0
  68. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/messaging/spinner/__init__.py +0 -0
  69. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/messaging/spinner/console_spinner.py +0 -0
  70. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/messaging/spinner/spinner_base.py +0 -0
  71. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/messaging/spinner/textual_spinner.py +0 -0
  72. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/model_factory.py +0 -0
  73. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/models.json +0 -0
  74. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/plugins/__init__.py +0 -0
  75. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/reopenable_async_client.py +0 -0
  76. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/round_robin_model.py +0 -0
  77. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/status_display.py +0 -0
  78. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/summarization_agent.py +0 -0
  79. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tools/__init__.py +0 -0
  80. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tools/agent_tools.py +0 -0
  81. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tools/browser/__init__.py +0 -0
  82. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tools/browser/browser_control.py +0 -0
  83. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tools/browser/browser_interactions.py +0 -0
  84. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tools/browser/browser_locators.py +0 -0
  85. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tools/browser/browser_navigation.py +0 -0
  86. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tools/browser/browser_screenshot.py +0 -0
  87. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tools/browser/browser_scripts.py +0 -0
  88. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tools/browser/browser_workflows.py +0 -0
  89. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tools/browser/camoufox_manager.py +0 -0
  90. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tools/browser/vqa_agent.py +0 -0
  91. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tools/browser_control.py +0 -0
  92. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tools/browser_interactions.py +0 -0
  93. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tools/browser_locators.py +0 -0
  94. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tools/browser_navigation.py +0 -0
  95. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tools/browser_screenshot.py +0 -0
  96. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tools/browser_scripts.py +0 -0
  97. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tools/browser_workflows.py +0 -0
  98. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tools/camoufox_manager.py +0 -0
  99. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tools/command_runner.py +0 -0
  100. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tools/common.py +0 -0
  101. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tools/file_modifications.py +0 -0
  102. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tools/file_operations.py +0 -0
  103. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tools/tools_content.py +0 -0
  104. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tui/__init__.py +0 -0
  105. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tui/app.py +0 -0
  106. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tui/components/__init__.py +0 -0
  107. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tui/components/chat_view.py +0 -0
  108. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tui/components/command_history_modal.py +0 -0
  109. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tui/components/copy_button.py +0 -0
  110. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tui/components/custom_widgets.py +0 -0
  111. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tui/components/human_input_modal.py +0 -0
  112. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tui/components/input_area.py +0 -0
  113. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tui/components/sidebar.py +0 -0
  114. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tui/components/status_bar.py +0 -0
  115. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tui/messages.py +0 -0
  116. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tui/models/__init__.py +0 -0
  117. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tui/models/chat_message.py +0 -0
  118. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tui/models/command_history.py +0 -0
  119. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tui/models/enums.py +0 -0
  120. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tui/screens/__init__.py +0 -0
  121. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tui/screens/help.py +0 -0
  122. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tui/screens/mcp_install_wizard.py +0 -0
  123. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tui/screens/settings.py +0 -0
  124. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tui/screens/tools.py +0 -0
  125. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/tui_state.py +0 -0
  126. {code_puppy-0.0.174 → code_puppy-0.0.175}/code_puppy/version_checker.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-puppy
3
- Version: 0.0.174
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
@@ -6,7 +6,8 @@ import os
6
6
  import pkgutil
7
7
  import uuid
8
8
  from pathlib import Path
9
- from typing import Dict, Optional, Type, Union
9
+ from pydantic_ai.messages import ModelMessage
10
+ from typing import Dict, Optional, Type, Union, List
10
11
 
11
12
  from code_puppy.callbacks import on_agent_reload
12
13
  from code_puppy.messaging import emit_warning
@@ -15,6 +16,7 @@ from code_puppy.agents.json_agent import JSONAgent, discover_json_agents
15
16
 
16
17
  # Registry of available agents (Python classes and JSON file paths)
17
18
  _AGENT_REGISTRY: Dict[str, Union[Type[BaseAgent], str]] = {}
19
+ _AGENT_HISTORIES: Dict[str, List[ModelMessage]] = {}
18
20
  _CURRENT_AGENT: Optional[BaseAgent] = None
19
21
 
20
22
  # Terminal session-based agent selection
@@ -248,7 +250,9 @@ def set_current_agent(agent_name: str) -> bool:
248
250
  True if the agent was set successfully, False if agent not found.
249
251
  """
250
252
  global _CURRENT_AGENT
251
-
253
+ curr_agent = get_current_agent()
254
+ if curr_agent != None:
255
+ _AGENT_HISTORIES[curr_agent.name] = curr_agent.get_message_history()
252
256
  # Generate a message group ID for agent switching
253
257
  message_group_id = str(uuid.uuid4())
254
258
  _discover_agents(message_group_id=message_group_id)
@@ -264,7 +268,8 @@ def set_current_agent(agent_name: str) -> bool:
264
268
  session_id = get_terminal_session_id()
265
269
  _SESSION_AGENTS_CACHE[session_id] = agent_name
266
270
  _save_session_data(_SESSION_AGENTS_CACHE)
267
-
271
+ if agent_obj.name in _AGENT_HISTORIES:
272
+ agent_obj.set_message_history(_AGENT_HISTORIES[agent_obj.name])
268
273
  on_agent_reload(agent_obj.id, agent_name)
269
274
  return True
270
275
 
@@ -501,6 +501,7 @@ class BaseAgent(ABC):
501
501
  dropped_count += 1
502
502
  continue
503
503
  pruned.append(msg)
504
+ return pruned
504
505
 
505
506
  def message_history_processor(self, messages: List[ModelMessage]) -> List[ModelMessage]:
506
507
  # First, prune any interrupted/mismatched tool-call conversations
@@ -64,7 +64,7 @@ def create_client(
64
64
  emit_info(
65
65
  f"HTTP retry: Retrying request due to status code {response.status_code}"
66
66
  )
67
- response.raise_for_status()
67
+ return True
68
68
 
69
69
  transport = TenacityTransport(
70
70
  config=RetryConfig(
@@ -106,16 +106,13 @@ def create_async_client(
106
106
  emit_info(
107
107
  f"HTTP retry: Retrying request due to status code {response.status_code}"
108
108
  )
109
- response.raise_for_status()
109
+ return True
110
110
 
111
111
  transport = AsyncTenacityTransport(
112
112
  config=RetryConfig(
113
113
  retry=lambda e: isinstance(e, httpx.HTTPStatusError)
114
114
  and e.response.status_code in retry_status_codes,
115
- wait=wait_retry_after(
116
- fallback_strategy=wait_exponential(multiplier=1, max=60),
117
- max_wait=300,
118
- ),
115
+ wait=wait_retry_after(10),
119
116
  stop=stop_after_attempt(10),
120
117
  reraise=True,
121
118
  ),
@@ -188,7 +185,7 @@ def create_reopenable_async_client(
188
185
  emit_info(
189
186
  f"HTTP retry: Retrying request due to status code {response.status_code}"
190
187
  )
191
- response.raise_for_status()
188
+ return True
192
189
 
193
190
  transport = AsyncTenacityTransport(
194
191
  config=RetryConfig(
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "code-puppy"
7
- version = "0.0.174"
7
+ version = "0.0.175"
8
8
  description = "Code generation agent"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -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_global_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
136
-
137
- agent_config = get_current_agent()
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_global_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()
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
169
- current_agent = get_current_agent()
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_global_model_name
211
-
212
- # Get the global model name
213
- global_model_name = get_global_model_name()
214
-
215
- # Check if current agent has a pinned model
216
- from code_puppy.agents import get_current_agent
217
-
218
- agent_config = get_current_agent()
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())
File without changes
File without changes
File without changes