code-puppy 0.0.70__tar.gz → 0.0.72__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 (29) hide show
  1. {code_puppy-0.0.70 → code_puppy-0.0.72}/PKG-INFO +42 -2
  2. {code_puppy-0.0.70 → code_puppy-0.0.72}/README.md +40 -0
  3. {code_puppy-0.0.70 → code_puppy-0.0.72}/code_puppy/agent.py +20 -0
  4. code_puppy-0.0.72/code_puppy/command_line/motd.py +57 -0
  5. {code_puppy-0.0.70 → code_puppy-0.0.72}/code_puppy/config.py +20 -0
  6. {code_puppy-0.0.70 → code_puppy-0.0.72}/code_puppy/main.py +4 -2
  7. {code_puppy-0.0.70 → code_puppy-0.0.72}/pyproject.toml +2 -2
  8. code_puppy-0.0.70/code_puppy/command_line/motd.py +0 -45
  9. {code_puppy-0.0.70 → code_puppy-0.0.72}/.gitignore +0 -0
  10. {code_puppy-0.0.70 → code_puppy-0.0.72}/LICENSE +0 -0
  11. {code_puppy-0.0.70 → code_puppy-0.0.72}/code_puppy/__init__.py +0 -0
  12. {code_puppy-0.0.70 → code_puppy-0.0.72}/code_puppy/agent_prompts.py +0 -0
  13. {code_puppy-0.0.70 → code_puppy-0.0.72}/code_puppy/command_line/__init__.py +0 -0
  14. {code_puppy-0.0.70 → code_puppy-0.0.72}/code_puppy/command_line/file_path_completion.py +0 -0
  15. {code_puppy-0.0.70 → code_puppy-0.0.72}/code_puppy/command_line/meta_command_handler.py +0 -0
  16. {code_puppy-0.0.70 → code_puppy-0.0.72}/code_puppy/command_line/model_picker_completion.py +0 -0
  17. {code_puppy-0.0.70 → code_puppy-0.0.72}/code_puppy/command_line/prompt_toolkit_completion.py +0 -0
  18. {code_puppy-0.0.70 → code_puppy-0.0.72}/code_puppy/command_line/utils.py +0 -0
  19. {code_puppy-0.0.70 → code_puppy-0.0.72}/code_puppy/model_factory.py +0 -0
  20. {code_puppy-0.0.70 → code_puppy-0.0.72}/code_puppy/models.json +0 -0
  21. {code_puppy-0.0.70 → code_puppy-0.0.72}/code_puppy/session_memory.py +0 -0
  22. {code_puppy-0.0.70 → code_puppy-0.0.72}/code_puppy/tools/__init__.py +0 -0
  23. {code_puppy-0.0.70 → code_puppy-0.0.72}/code_puppy/tools/command_runner.py +0 -0
  24. {code_puppy-0.0.70 → code_puppy-0.0.72}/code_puppy/tools/common.py +0 -0
  25. {code_puppy-0.0.70 → code_puppy-0.0.72}/code_puppy/tools/file_modifications.py +0 -0
  26. {code_puppy-0.0.70 → code_puppy-0.0.72}/code_puppy/tools/file_operations.py +0 -0
  27. {code_puppy-0.0.70 → code_puppy-0.0.72}/code_puppy/tools/ts_code_map.py +0 -0
  28. {code_puppy-0.0.70 → code_puppy-0.0.72}/code_puppy/tools/web_search.py +0 -0
  29. {code_puppy-0.0.70 → code_puppy-0.0.72}/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.70
3
+ Version: 0.0.72
4
4
  Summary: Code generation agent
5
5
  Author: Michael Pfaffenberger
6
6
  License: MIT
@@ -20,7 +20,7 @@ Requires-Dist: json-repair>=0.46.2
20
20
  Requires-Dist: logfire>=0.7.1
21
21
  Requires-Dist: pathspec>=0.11.0
22
22
  Requires-Dist: prompt-toolkit>=3.0.38
23
- Requires-Dist: pydantic-ai>=0.1.0
23
+ Requires-Dist: pydantic-ai>=0.3.2
24
24
  Requires-Dist: pydantic>=2.4.0
25
25
  Requires-Dist: pytest-cov>=6.1.1
26
26
  Requires-Dist: python-dotenv>=1.0.0
@@ -144,5 +144,45 @@ For instance, if you want to ensure that your application follows a specific des
144
144
  Ensure that all components follow these color schemes to promote consistency in design.
145
145
  ```
146
146
 
147
+ ## Using MCP Servers for External Tools
148
+
149
+ Code Puppy supports **MCP (Model Context Protocol) servers** to give you access to external code tools and advanced features like code search, documentation lookups, and more—including Context7 integration for deep docs and search!
150
+
151
+ ### What is an MCP Server?
152
+ An MCP server is a standalone process (can be local or remote) that offers specialized functionality (plugins, doc search, code analysis, etc.). Code Puppy can connect to one or more MCP servers at startup, unlocking these extra commands inside your coding agent.
153
+
154
+ ### Configuration
155
+ Create a config file at `~/.code_puppy/mcp_servers.json`. Here’s an example that connects to a local Context7 MCP server:
156
+
157
+ ```json
158
+ {
159
+ "mcp_servers": {
160
+ "context7": {
161
+ "url": "https://mcp.context7.com/sse"
162
+ }
163
+ }
164
+ }
165
+ ```
166
+
167
+ You can list multiple objects (one per server).
168
+
169
+ ### How to Use
170
+ - Drop the config file in `~/.code_puppy/mcp_servers.json`.
171
+ - Start your MCP (like context7, or anything compatible).
172
+ - Run Code Puppy as usual. It’ll discover and use all configured MCP servers.
173
+
174
+ #### Example usage
175
+ ```bash
176
+ code-puppy --interactive
177
+ # Then ask: Use context7 to look up FastAPI docs!
178
+ ```
179
+
180
+ That’s it!
181
+ If you need to run more exotic setups or connect to remote MCPs, just update your `mcp_servers.json` accordingly.
182
+
183
+ **NOTE:** Want to add your own server or tool? Just follow the config pattern above—no code changes needed!
184
+
185
+ ---
186
+
147
187
  ## Conclusion
148
188
  By using Code Puppy, you can maintain code quality and adhere to design guidelines with ease.
@@ -111,5 +111,45 @@ For instance, if you want to ensure that your application follows a specific des
111
111
  Ensure that all components follow these color schemes to promote consistency in design.
112
112
  ```
113
113
 
114
+ ## Using MCP Servers for External Tools
115
+
116
+ Code Puppy supports **MCP (Model Context Protocol) servers** to give you access to external code tools and advanced features like code search, documentation lookups, and more—including Context7 integration for deep docs and search!
117
+
118
+ ### What is an MCP Server?
119
+ An MCP server is a standalone process (can be local or remote) that offers specialized functionality (plugins, doc search, code analysis, etc.). Code Puppy can connect to one or more MCP servers at startup, unlocking these extra commands inside your coding agent.
120
+
121
+ ### Configuration
122
+ Create a config file at `~/.code_puppy/mcp_servers.json`. Here’s an example that connects to a local Context7 MCP server:
123
+
124
+ ```json
125
+ {
126
+ "mcp_servers": {
127
+ "context7": {
128
+ "url": "https://mcp.context7.com/sse"
129
+ }
130
+ }
131
+ }
132
+ ```
133
+
134
+ You can list multiple objects (one per server).
135
+
136
+ ### How to Use
137
+ - Drop the config file in `~/.code_puppy/mcp_servers.json`.
138
+ - Start your MCP (like context7, or anything compatible).
139
+ - Run Code Puppy as usual. It’ll discover and use all configured MCP servers.
140
+
141
+ #### Example usage
142
+ ```bash
143
+ code-puppy --interactive
144
+ # Then ask: Use context7 to look up FastAPI docs!
145
+ ```
146
+
147
+ That’s it!
148
+ If you need to run more exotic setups or connect to remote MCPs, just update your `mcp_servers.json` accordingly.
149
+
150
+ **NOTE:** Want to add your own server or tool? Just follow the config pattern above—no code changes needed!
151
+
152
+ ---
153
+
114
154
  ## Conclusion
115
155
  By using Code Puppy, you can maintain code quality and adhere to design guidelines with ease.
@@ -3,6 +3,7 @@ from pathlib import Path
3
3
 
4
4
  import pydantic
5
5
  from pydantic_ai import Agent
6
+ from pydantic_ai.mcp import MCPServerSSE
6
7
 
7
8
  from code_puppy.agent_prompts import get_system_prompt
8
9
  from code_puppy.model_factory import ModelFactory
@@ -64,11 +65,27 @@ def session_memory():
64
65
  return _session_memory
65
66
 
66
67
 
68
+ def _load_mcp_servers():
69
+ from code_puppy.config import load_mcp_server_configs
70
+ configs = load_mcp_server_configs()
71
+ servers = []
72
+ for name, conf in configs.items():
73
+ url = conf.get("url")
74
+ if url:
75
+ console.print(f"Registering MCP Server - {url}")
76
+ servers.append(MCPServerSSE(url))
77
+ return servers
78
+
67
79
  def reload_code_generation_agent():
68
80
  """Force-reload the agent, usually after a model change."""
69
81
  global _code_generation_agent, _LAST_MODEL_NAME
70
82
  from code_puppy.config import get_model_name
71
83
 
84
+ model_name = get_model_name()
85
+ console.print(f"[bold cyan]Loading Model: {model_name}")
86
+ global _code_generation_agent, _LAST_MODEL_NAME
87
+ from code_puppy.config import get_model_name
88
+
72
89
  model_name = get_model_name()
73
90
  console.print(f"[bold cyan]Loading Model: {model_name}[/bold cyan]")
74
91
  models_path = (
@@ -80,11 +97,14 @@ def reload_code_generation_agent():
80
97
  instructions = get_system_prompt()
81
98
  if PUPPY_RULES:
82
99
  instructions += f"\n{PUPPY_RULES}"
100
+
101
+ mcp_servers = _load_mcp_servers()
83
102
  agent = Agent(
84
103
  model=model,
85
104
  instructions=instructions,
86
105
  output_type=AgentResponse,
87
106
  retries=3,
107
+ mcp_servers=mcp_servers
88
108
  )
89
109
  register_all_tools(agent)
90
110
  _code_generation_agent = agent
@@ -0,0 +1,57 @@
1
+ """
2
+ MOTD (Message of the Day) feature for code-puppy.
3
+ Stores seen versions in ~/.puppy_cfg/motd.txt.
4
+ """
5
+ import os
6
+ from typing import Optional
7
+
8
+ MOTD_VERSION = "20240621"
9
+ MOTD_MESSAGE = """
10
+ June 21th, 2025 - 🚀 Woof-tastic news! Code Puppy now supports **MCP (Model Context Protocol) servers** for EXTREME PUPPY POWER!!!!.
11
+
12
+ You can now connect plugins like doc search, Context7 integration, and more by simply dropping their info in your `~/.code_puppy/mcp_servers.json`. I’ll bark at remote docs or wrangle code tools for you—no extra fetches needed.
13
+
14
+ Setup is easy:
15
+ 1. Add your MCP config to `~/.code_puppy/mcp_servers.json`.
16
+ 2. Fire up something like Context7, or any MCP server you want.
17
+ 3. Ask me to search docs, analyze, and more.
18
+
19
+ The following example will let code_puppy use Context7!
20
+ Example config (+ more details in the README):
21
+
22
+ {
23
+ "mcp_servers": {
24
+ "context7": {
25
+ "url": "https://mcp.context7.com/sse"
26
+ }
27
+ }
28
+ }
29
+
30
+ I fetch docs and power-ups via those servers. If you break stuff, please file an issue—bonus treat for reproducible bugs! 🦴
31
+
32
+ This message-of-the-day won’t bug you again unless you run ~motd. Stay fluffy!
33
+
34
+ """
35
+ MOTD_TRACK_FILE = os.path.expanduser("~/.puppy_cfg/motd.txt")
36
+
37
+
38
+ def has_seen_motd(version: str) -> bool:
39
+ if not os.path.exists(MOTD_TRACK_FILE):
40
+ return False
41
+ with open(MOTD_TRACK_FILE, "r") as f:
42
+ seen_versions = {line.strip() for line in f if line.strip()}
43
+ return version in seen_versions
44
+
45
+
46
+ def mark_motd_seen(version: str):
47
+ os.makedirs(os.path.dirname(MOTD_TRACK_FILE), exist_ok=True)
48
+ with open(MOTD_TRACK_FILE, "a") as f:
49
+ f.write(f"{version}\n")
50
+
51
+
52
+ def print_motd(console, force: bool = False) -> bool:
53
+ if force or not has_seen_motd(MOTD_VERSION):
54
+ console.print(MOTD_MESSAGE)
55
+ mark_motd_seen(MOTD_VERSION)
56
+ return True
57
+ return False
@@ -1,8 +1,11 @@
1
1
  import configparser
2
2
  import os
3
+ import json
4
+ import pathlib
3
5
 
4
6
  CONFIG_DIR = os.path.join(os.path.expanduser("~"), ".code_puppy")
5
7
  CONFIG_FILE = os.path.join(CONFIG_DIR, "puppy.cfg")
8
+ MCP_SERVERS_FILE = os.path.join(CONFIG_DIR, "mcp_servers.json")
6
9
 
7
10
  DEFAULT_SECTION = "puppy"
8
11
  REQUIRED_KEYS = ["puppy_name", "owner_name"]
@@ -97,6 +100,23 @@ def set_config_value(key: str, value: str):
97
100
 
98
101
 
99
102
  # --- MODEL STICKY EXTENSION STARTS HERE ---
103
+ def load_mcp_server_configs():
104
+ """
105
+ Loads the MCP server configurations from ~/.code_puppy/mcp_servers.json.
106
+ Returns a dict mapping names to their URL or config dict.
107
+ If file does not exist, returns an empty dict.
108
+ """
109
+ try:
110
+ if not pathlib.Path(MCP_SERVERS_FILE).exists():
111
+ print("No MCP configuration was found")
112
+ return {}
113
+ with open(MCP_SERVERS_FILE, "r") as f:
114
+ conf = json.loads(f.read())
115
+ return conf["mcp_servers"]
116
+ except Exception as e:
117
+ print(f"Failed to load MCP servers - {str(e)}")
118
+ return {}
119
+
100
120
  def get_model_name():
101
121
  """Returns the last used model name stored in config, or None if unset."""
102
122
  return get_value("model") or "gpt-4.1"
@@ -67,7 +67,8 @@ async def main():
67
67
  try:
68
68
  while not shutdown_flag:
69
69
  agent = get_code_generation_agent()
70
- response = await agent.run(command)
70
+ async with agent.run_mcp_servers():
71
+ response = await agent.run(command)
71
72
  agent_response = response.output
72
73
  console.print(agent_response.output_message)
73
74
  # Log to session memory
@@ -210,7 +211,8 @@ async def interactive_mode(history_file_path: str) -> None:
210
211
  agent_response = None
211
212
 
212
213
  agent = get_code_generation_agent()
213
- result = await agent.run(task, message_history=message_history)
214
+ async with agent.run_mcp_servers():
215
+ result = await agent.run(task, message_history=message_history)
214
216
  # Get the structured response
215
217
  agent_response = result.output
216
218
  console.print(agent_response.output_message)
@@ -4,12 +4,12 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "code-puppy"
7
- version = "0.0.70"
7
+ version = "0.0.72"
8
8
  description = "Code generation agent"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
11
11
  dependencies = [
12
- "pydantic-ai>=0.1.0",
12
+ "pydantic-ai>=0.3.2",
13
13
  "httpx>=0.24.1",
14
14
  "rich>=13.4.2",
15
15
  "logfire>=0.7.1",
@@ -1,45 +0,0 @@
1
- """
2
- MOTD (Message of the Day) feature for code-puppy.
3
- Stores seen versions in ~/.puppy_cfg/motd.txt.
4
- """
5
- import os
6
- from typing import Optional
7
-
8
- MOTD_VERSION = "20240601"
9
- MOTD_MESSAGE = """
10
- June 14th, 2025 - Wow... code_puppy has been downloaded 10s of thousands of times.
11
-
12
- This new update has a bug fix where message truncation would sometimes cause tool-calls and tool-replies
13
- to become isolated, and an exception would be raied creating a situation only recoverable by restarting
14
- code-puppy or using the `clear` command to get rid of all message history.
15
-
16
- Thankfully that is fixed. Message truncation max-length is configurable with the following command:
17
- `~set message_history_length 25` if you want to truncate to 25 messages. The default is 40.
18
-
19
- This message-of-the-day will not appear again unless you run ~motd.
20
-
21
- Please open issues on GitHub if you find any bugs! Cheers!
22
- """
23
- MOTD_TRACK_FILE = os.path.expanduser("~/.puppy_cfg/motd.txt")
24
-
25
-
26
- def has_seen_motd(version: str) -> bool:
27
- if not os.path.exists(MOTD_TRACK_FILE):
28
- return False
29
- with open(MOTD_TRACK_FILE, "r") as f:
30
- seen_versions = {line.strip() for line in f if line.strip()}
31
- return version in seen_versions
32
-
33
-
34
- def mark_motd_seen(version: str):
35
- os.makedirs(os.path.dirname(MOTD_TRACK_FILE), exist_ok=True)
36
- with open(MOTD_TRACK_FILE, "a") as f:
37
- f.write(f"{version}\n")
38
-
39
-
40
- def print_motd(console, force: bool = False) -> bool:
41
- if force or not has_seen_motd(MOTD_VERSION):
42
- console.print(MOTD_MESSAGE)
43
- mark_motd_seen(MOTD_VERSION)
44
- return True
45
- return False
File without changes
File without changes