code-puppy 0.0.69__tar.gz → 0.0.71__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.
- {code_puppy-0.0.69 → code_puppy-0.0.71}/PKG-INFO +42 -2
- {code_puppy-0.0.69 → code_puppy-0.0.71}/README.md +40 -0
- {code_puppy-0.0.69 → code_puppy-0.0.71}/code_puppy/agent.py +20 -0
- code_puppy-0.0.71/code_puppy/command_line/motd.py +57 -0
- {code_puppy-0.0.69 → code_puppy-0.0.71}/code_puppy/config.py +20 -0
- {code_puppy-0.0.69 → code_puppy-0.0.71}/code_puppy/main.py +4 -2
- {code_puppy-0.0.69 → code_puppy-0.0.71}/pyproject.toml +2 -2
- {code_puppy-0.0.69 → code_puppy-0.0.71}/.gitignore +0 -0
- {code_puppy-0.0.69 → code_puppy-0.0.71}/LICENSE +0 -0
- {code_puppy-0.0.69 → code_puppy-0.0.71}/code_puppy/__init__.py +0 -0
- {code_puppy-0.0.69 → code_puppy-0.0.71}/code_puppy/agent_prompts.py +0 -0
- {code_puppy-0.0.69 → code_puppy-0.0.71}/code_puppy/command_line/__init__.py +0 -0
- {code_puppy-0.0.69 → code_puppy-0.0.71}/code_puppy/command_line/file_path_completion.py +0 -0
- {code_puppy-0.0.69 → code_puppy-0.0.71}/code_puppy/command_line/meta_command_handler.py +0 -0
- {code_puppy-0.0.69 → code_puppy-0.0.71}/code_puppy/command_line/model_picker_completion.py +0 -0
- {code_puppy-0.0.69 → code_puppy-0.0.71}/code_puppy/command_line/prompt_toolkit_completion.py +0 -0
- {code_puppy-0.0.69 → code_puppy-0.0.71}/code_puppy/command_line/utils.py +0 -0
- {code_puppy-0.0.69 → code_puppy-0.0.71}/code_puppy/model_factory.py +0 -0
- {code_puppy-0.0.69 → code_puppy-0.0.71}/code_puppy/models.json +0 -0
- {code_puppy-0.0.69 → code_puppy-0.0.71}/code_puppy/session_memory.py +0 -0
- {code_puppy-0.0.69 → code_puppy-0.0.71}/code_puppy/tools/__init__.py +0 -0
- {code_puppy-0.0.69 → code_puppy-0.0.71}/code_puppy/tools/command_runner.py +0 -0
- {code_puppy-0.0.69 → code_puppy-0.0.71}/code_puppy/tools/common.py +0 -0
- {code_puppy-0.0.69 → code_puppy-0.0.71}/code_puppy/tools/file_modifications.py +0 -0
- {code_puppy-0.0.69 → code_puppy-0.0.71}/code_puppy/tools/file_operations.py +0 -0
- {code_puppy-0.0.69 → code_puppy-0.0.71}/code_puppy/tools/ts_code_map.py +0 -0
- {code_puppy-0.0.69 → code_puppy-0.0.71}/code_puppy/tools/web_search.py +0 -0
- {code_puppy-0.0.69 → code_puppy-0.0.71}/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.
|
|
3
|
+
Version: 0.0.71
|
|
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.
|
|
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 (Multi-Channel Plugin) 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 (Multi-Channel Plugin) 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
|
-
|
|
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
|
-
|
|
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.
|
|
7
|
+
version = "0.0.71"
|
|
8
8
|
description = "Code generation agent"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
11
11
|
dependencies = [
|
|
12
|
-
"pydantic-ai>=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",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_puppy-0.0.69 → code_puppy-0.0.71}/code_puppy/command_line/prompt_toolkit_completion.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|