code-puppy 0.0.182__py3-none-any.whl → 0.0.184__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.
@@ -33,7 +33,7 @@ from code_puppy.config import (
33
33
  get_global_model_name,
34
34
  get_protected_token_count,
35
35
  get_value,
36
- load_mcp_server_configs,
36
+ load_mcp_server_configs, get_message_limit,
37
37
  )
38
38
  from code_puppy.mcp_ import ServerConfig, get_mcp_manager
39
39
  from code_puppy.messaging import (
@@ -729,6 +729,63 @@ class BaseAgent(ABC):
729
729
  manager = get_mcp_manager()
730
730
  return manager.get_servers_for_agent()
731
731
 
732
+ def _load_model_with_fallback(
733
+ self,
734
+ requested_model_name: str,
735
+ models_config: Dict[str, Any],
736
+ message_group: str,
737
+ ) -> Tuple[Any, str]:
738
+ """Load the requested model, applying a friendly fallback when unavailable."""
739
+ try:
740
+ model = ModelFactory.get_model(requested_model_name, models_config)
741
+ return model, requested_model_name
742
+ except ValueError as exc:
743
+ available_models = list(models_config.keys())
744
+ available_str = (
745
+ ", ".join(sorted(available_models))
746
+ if available_models
747
+ else "no configured models"
748
+ )
749
+ emit_warning(
750
+ (
751
+ f"[yellow]Model '{requested_model_name}' not found. "
752
+ f"Available models: {available_str}[/yellow]"
753
+ ),
754
+ message_group=message_group,
755
+ )
756
+
757
+ fallback_candidates: List[str] = []
758
+ global_candidate = get_global_model_name()
759
+ if global_candidate:
760
+ fallback_candidates.append(global_candidate)
761
+
762
+ for candidate in available_models:
763
+ if candidate not in fallback_candidates:
764
+ fallback_candidates.append(candidate)
765
+
766
+ for candidate in fallback_candidates:
767
+ if not candidate or candidate == requested_model_name:
768
+ continue
769
+ try:
770
+ model = ModelFactory.get_model(candidate, models_config)
771
+ emit_info(
772
+ f"[bold cyan]Using fallback model: {candidate}[/bold cyan]",
773
+ message_group=message_group,
774
+ )
775
+ return model, candidate
776
+ except ValueError:
777
+ continue
778
+
779
+ friendly_message = (
780
+ "No valid model could be loaded. Update the model configuration or set "
781
+ "a valid model with `config set`."
782
+ )
783
+ emit_error(
784
+ f"[bold red]{friendly_message}[/bold red]",
785
+ message_group=message_group,
786
+ )
787
+ raise ValueError(friendly_message) from exc
788
+
732
789
  def reload_code_generation_agent(self, message_group: Optional[str] = None):
733
790
  """Force-reload the pydantic-ai Agent based on current config and model."""
734
791
  from code_puppy.tools import register_tools_for_agent
@@ -743,7 +800,11 @@ class BaseAgent(ABC):
743
800
  message_group=message_group,
744
801
  )
745
802
  models_config = ModelFactory.load_config()
746
- model = ModelFactory.get_model(model_name, models_config)
803
+ model, resolved_model_name = self._load_model_with_fallback(
804
+ model_name,
805
+ models_config,
806
+ message_group,
807
+ )
747
808
 
748
809
  emit_info(
749
810
  f"[bold magenta]Loading Agent: {self.name}[/bold magenta]",
@@ -786,7 +847,7 @@ class BaseAgent(ABC):
786
847
  register_tools_for_agent(p_agent, agent_tools)
787
848
 
788
849
  self._code_generation_agent = p_agent
789
- self._last_model_name = model_name
850
+ self._last_model_name = resolved_model_name
790
851
  # expose for run_with_mcp
791
852
  self.pydantic_agent = p_agent
792
853
  return self._code_generation_agent
@@ -806,7 +867,7 @@ class BaseAgent(ABC):
806
867
  self.message_history_processor(ctx, _message_history)
807
868
  return self.get_message_history()
808
869
 
809
- async def run_with_mcp(self, prompt: str, usage_limits=None, **kwargs) -> Any:
870
+ async def run_with_mcp(self, prompt: str, **kwargs) -> Any:
810
871
  """
811
872
  Run the agent with MCP servers and full cancellation support.
812
873
 
@@ -832,6 +893,7 @@ class BaseAgent(ABC):
832
893
  self.set_message_history(
833
894
  self.prune_interrupted_tool_calls(self.get_message_history())
834
895
  )
896
+ usage_limits = pydantic_ai.agent._usage.UsageLimits(request_limit=get_message_limit())
835
897
  result_ = await pydantic_agent.run(
836
898
  prompt,
837
899
  message_history=self.get_message_history(),
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-puppy
3
- Version: 0.0.182
3
+ Version: 0.0.184
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 @@ code_puppy/agents/agent_qa_expert.py,sha256=wCGXzuAVElT5c-QigQVb8JX9Gw0JmViCUQQn
26
26
  code_puppy/agents/agent_qa_kitten.py,sha256=5PeFFSwCFlTUvP6h5bGntx0xv5NmRwBiw0HnMqY8nLI,9107
27
27
  code_puppy/agents/agent_security_auditor.py,sha256=ADafi2x4gqXw6m-Nch5vjiKjO0Urcbj0x4zxHti3gDw,3712
28
28
  code_puppy/agents/agent_typescript_reviewer.py,sha256=EDY1mFkVpuJ1BPXsJFu2wQ2pfAV-90ipc_8w9ymrKPg,4054
29
- code_puppy/agents/base_agent.py,sha256=MFyC4YSxlQ1xzQRBnSXgtyO7XPpHZuSJVzRATU8j7J0,36992
29
+ code_puppy/agents/base_agent.py,sha256=lIHy3j5lN6_u6gAMbKFVPo1pODz7-BoxIRjqwim2so0,39426
30
30
  code_puppy/agents/json_agent.py,sha256=KPS1q-Rr3b5ekem4i3wtu8eLJRDd5nSPiZ8duJ_tn0U,4630
31
31
  code_puppy/command_line/__init__.py,sha256=y7WeRemfYppk8KVbCGeAIiTuiOszIURCDjOMZv_YRmU,45
32
32
  code_puppy/command_line/command_handler.py,sha256=JeJo6kc9-4B7S0_pbMp1LO7jtAT6XMXtSSnOShfoG-Y,27237
@@ -119,9 +119,9 @@ code_puppy/tui/screens/help.py,sha256=eJuPaOOCp7ZSUlecearqsuX6caxWv7NQszUh0tZJjB
119
119
  code_puppy/tui/screens/mcp_install_wizard.py,sha256=vObpQwLbXjQsxmSg-WCasoev1usEi0pollKnL0SHu9U,27693
120
120
  code_puppy/tui/screens/settings.py,sha256=-WLldnKyWVKUYVPJcfOn1UU6eP9t8lLPUAVI317SOOM,10685
121
121
  code_puppy/tui/screens/tools.py,sha256=3pr2Xkpa9Js6Yhf1A3_wQVRzFOui-KDB82LwrsdBtyk,1715
122
- code_puppy-0.0.182.data/data/code_puppy/models.json,sha256=iXmLZGflnQcu2DRh4WUlgAhoXdvoxUc7KBhB8YxawXM,3088
123
- code_puppy-0.0.182.dist-info/METADATA,sha256=W7GR68g_PVcOx0lC0bvdIH8mdmN5mkBgmYnQsqVjELY,20079
124
- code_puppy-0.0.182.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
125
- code_puppy-0.0.182.dist-info/entry_points.txt,sha256=Tp4eQC99WY3HOKd3sdvb22vZODRq0XkZVNpXOag_KdI,91
126
- code_puppy-0.0.182.dist-info/licenses/LICENSE,sha256=31u8x0SPgdOq3izJX41kgFazWsM43zPEF9eskzqbJMY,1075
127
- code_puppy-0.0.182.dist-info/RECORD,,
122
+ code_puppy-0.0.184.data/data/code_puppy/models.json,sha256=iXmLZGflnQcu2DRh4WUlgAhoXdvoxUc7KBhB8YxawXM,3088
123
+ code_puppy-0.0.184.dist-info/METADATA,sha256=ZkHxBwyThIm0dxsILQI4NS_KiDOeKOwYFhR-cjCbSTE,20079
124
+ code_puppy-0.0.184.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
125
+ code_puppy-0.0.184.dist-info/entry_points.txt,sha256=Tp4eQC99WY3HOKd3sdvb22vZODRq0XkZVNpXOag_KdI,91
126
+ code_puppy-0.0.184.dist-info/licenses/LICENSE,sha256=31u8x0SPgdOq3izJX41kgFazWsM43zPEF9eskzqbJMY,1075
127
+ code_puppy-0.0.184.dist-info/RECORD,,