code-puppy 0.0.82__tar.gz → 0.0.84__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 (30) hide show
  1. {code_puppy-0.0.82 → code_puppy-0.0.84}/PKG-INFO +1 -1
  2. {code_puppy-0.0.82 → code_puppy-0.0.84}/code_puppy/agent.py +7 -34
  3. {code_puppy-0.0.82 → code_puppy-0.0.84}/code_puppy/command_line/motd.py +15 -16
  4. {code_puppy-0.0.82 → code_puppy-0.0.84}/code_puppy/main.py +1 -1
  5. {code_puppy-0.0.82 → code_puppy-0.0.84}/code_puppy/message_history_processor.py +3 -1
  6. {code_puppy-0.0.82 → code_puppy-0.0.84}/pyproject.toml +1 -1
  7. code_puppy-0.0.82/code_puppy/session_memory.py +0 -83
  8. {code_puppy-0.0.82 → code_puppy-0.0.84}/.gitignore +0 -0
  9. {code_puppy-0.0.82 → code_puppy-0.0.84}/LICENSE +0 -0
  10. {code_puppy-0.0.82 → code_puppy-0.0.84}/README.md +0 -0
  11. {code_puppy-0.0.82 → code_puppy-0.0.84}/code_puppy/__init__.py +0 -0
  12. {code_puppy-0.0.82 → code_puppy-0.0.84}/code_puppy/agent_prompts.py +0 -0
  13. {code_puppy-0.0.82 → code_puppy-0.0.84}/code_puppy/command_line/__init__.py +0 -0
  14. {code_puppy-0.0.82 → code_puppy-0.0.84}/code_puppy/command_line/file_path_completion.py +0 -0
  15. {code_puppy-0.0.82 → code_puppy-0.0.84}/code_puppy/command_line/meta_command_handler.py +0 -0
  16. {code_puppy-0.0.82 → code_puppy-0.0.84}/code_puppy/command_line/model_picker_completion.py +0 -0
  17. {code_puppy-0.0.82 → code_puppy-0.0.84}/code_puppy/command_line/prompt_toolkit_completion.py +0 -0
  18. {code_puppy-0.0.82 → code_puppy-0.0.84}/code_puppy/command_line/utils.py +0 -0
  19. {code_puppy-0.0.82 → code_puppy-0.0.84}/code_puppy/config.py +0 -0
  20. {code_puppy-0.0.82 → code_puppy-0.0.84}/code_puppy/model_factory.py +0 -0
  21. {code_puppy-0.0.82 → code_puppy-0.0.84}/code_puppy/models.json +0 -0
  22. {code_puppy-0.0.82 → code_puppy-0.0.84}/code_puppy/state_management.py +0 -0
  23. {code_puppy-0.0.82 → code_puppy-0.0.84}/code_puppy/summarization_agent.py +0 -0
  24. {code_puppy-0.0.82 → code_puppy-0.0.84}/code_puppy/tools/__init__.py +0 -0
  25. {code_puppy-0.0.82 → code_puppy-0.0.84}/code_puppy/tools/command_runner.py +0 -0
  26. {code_puppy-0.0.82 → code_puppy-0.0.84}/code_puppy/tools/common.py +0 -0
  27. {code_puppy-0.0.82 → code_puppy-0.0.84}/code_puppy/tools/file_modifications.py +0 -0
  28. {code_puppy-0.0.82 → code_puppy-0.0.84}/code_puppy/tools/file_operations.py +0 -0
  29. {code_puppy-0.0.82 → code_puppy-0.0.84}/code_puppy/tools/ts_code_map.py +0 -0
  30. {code_puppy-0.0.82 → code_puppy-0.0.84}/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.82
3
+ Version: 0.0.84
4
4
  Summary: Code generation agent
5
5
  Author: Michael Pfaffenberger
6
6
  License: MIT
@@ -7,7 +7,6 @@ from pydantic_ai.mcp import MCPServerSSE
7
7
 
8
8
  from code_puppy.agent_prompts import get_system_prompt
9
9
  from code_puppy.model_factory import ModelFactory
10
- from code_puppy.session_memory import SessionMemory
11
10
  from code_puppy.state_management import message_history_accumulator
12
11
  from code_puppy.tools import register_all_tools
13
12
  from code_puppy.tools.common import console
@@ -20,24 +19,16 @@ from code_puppy.tools.common import console
20
19
 
21
20
  MODELS_JSON_PATH = os.environ.get("MODELS_JSON_PATH", None)
22
21
 
23
- # Puppy rules loader
24
- PUPPY_RULES_PATH = Path("AGENT.md")
25
- PUPPY_RULES = None
26
-
27
-
28
- def load_puppy_rules(path=None):
22
+ def load_puppy_rules():
29
23
  global PUPPY_RULES
30
- rules_path = Path(path) if path else PUPPY_RULES_PATH
31
- if rules_path.exists():
32
- with open(rules_path, "r") as f:
33
- PUPPY_RULES = f.read()
34
- else:
35
- PUPPY_RULES = None
36
-
24
+ puppy_rules_path = Path("AGENT.md")
25
+ if puppy_rules_path.exists():
26
+ with open(puppy_rules_path, "r") as f:
27
+ puppy_rules = f.read()
28
+ return puppy_rules
37
29
 
38
30
  # Load at import
39
- load_puppy_rules()
40
-
31
+ PUPPY_RULES = load_puppy_rules()
41
32
 
42
33
  class AgentResponse(pydantic.BaseModel):
43
34
  """Represents a response from the agent."""
@@ -50,20 +41,7 @@ class AgentResponse(pydantic.BaseModel):
50
41
  )
51
42
 
52
43
 
53
- # --- NEW DYNAMIC AGENT LOGIC ---
54
- _LAST_MODEL_NAME = None
55
44
  _code_generation_agent = None
56
- _session_memory = None
57
-
58
-
59
- def session_memory():
60
- """
61
- Returns a singleton SessionMemory instance to allow agent and tools to persist and recall context/history.
62
- """
63
- global _session_memory
64
- if _session_memory is None:
65
- _session_memory = SessionMemory()
66
- return _session_memory
67
45
 
68
46
 
69
47
  def _load_mcp_servers():
@@ -106,11 +84,6 @@ def reload_code_generation_agent():
106
84
  register_all_tools(agent)
107
85
  _code_generation_agent = agent
108
86
  _LAST_MODEL_NAME = model_name
109
- # NEW: Log session event
110
- try:
111
- session_memory().log_task(f"Agent loaded with model: {model_name}")
112
- except Exception:
113
- pass
114
87
  return _code_generation_agent
115
88
 
116
89
 
@@ -5,26 +5,25 @@ Stores seen versions in ~/.puppy_cfg/motd.txt.
5
5
 
6
6
  import os
7
7
 
8
- MOTD_VERSION = "20250815"
8
+ MOTD_VERSION = "20250817"
9
9
  MOTD_MESSAGE = """
10
10
 
11
- 🐾 Happy Friday, Aug 15, 2025!
11
+ 🐾 Happy Sunday, Aug 17, 2025!
12
12
 
13
- Biscuit the code puppy is on full zoomie mode!
13
+ Biscuit the code puppy learned two new tricks!
14
14
  Major paws-ups:
15
- 1. We now integrate Cerebras gpt-oss-120b!
16
- It's a bit underwhelming compared to Qwen3-Coder-480b (obviously), but it's still good for basic fetches.
17
- 2. We also added support for OpenAI gpt-5!
18
- It's so good, it'll make you want to teach it to sit!
19
-
20
- To use one of the Cerebras models just have a CEREBRAS_API_KEY set in the environment variables.
21
- Use ~m to swap models in the middle of your session!
22
- Take stretch breaks you'll need 'em!
23
- • DRY your code, but keep your pup hydrated.
24
- • If you hit a bug, treat yourself for finding it!
25
-
26
- Today: sniff, code, roll over, and let these fancy AI models do the heavy lifting. Fire up a ~motd anytime
27
- you need some puppy hype!
15
+ 1. On-the-fly summarization: when your model's context hits 90%,
16
+ Biscuit auto-summarizes older messages to keep you cruising. No sweat, no tokens spilled.
17
+ 2. AGENT.md support: ship your project rules and style guide,
18
+ and Biscuit will obey them like the good pup he is.
19
+
20
+ Use ~m to swap models mid-session.
21
+ YOLO_MODE=true skips command confirmations (danger, zoomies!).
22
+ Keep files under 600 lines; split big ones like a responsible hooman.
23
+ • DRY code, happy pup.
24
+
25
+ Today's vibe: sniff context, summarize smartly, obey AGENT.md, and ship.
26
+ Run ~motd anytime you need more puppy hype!
28
27
 
29
28
  """
30
29
  MOTD_TRACK_FILE = os.path.expanduser("~/.puppy_cfg/motd.txt")
@@ -10,7 +10,7 @@ from rich.syntax import Syntax
10
10
  from rich.text import Text
11
11
 
12
12
  from code_puppy import __version__, state_management
13
- from code_puppy.agent import get_code_generation_agent, session_memory
13
+ from code_puppy.agent import get_code_generation_agent
14
14
  from code_puppy.command_line.prompt_toolkit_completion import (
15
15
  get_input_with_combined_completion,
16
16
  get_prompt_with_active_model,
@@ -158,7 +158,9 @@ def message_history_processor(messages: List[ModelMessage]) -> List[ModelMessage
158
158
  model_max = get_model_context_length()
159
159
 
160
160
  proportion_used = total_current_tokens / model_max
161
- console.print(f"[bold white on blue] Tokens in context: {total_current_tokens}, total model capacity: {model_max}, proportion used: {proportion_used}")
161
+ console.print(f"""
162
+ [bold white on blue] Tokens in context: {total_current_tokens}, total model capacity: {model_max}, proportion used: {proportion_used}
163
+ """)
162
164
 
163
165
  if proportion_used > 0.9:
164
166
  summary = summarize_messages(messages)
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "code-puppy"
7
- version = "0.0.82"
7
+ version = "0.0.84"
8
8
  description = "Code generation agent"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -1,83 +0,0 @@
1
- import json
2
- from datetime import datetime, timedelta
3
- from pathlib import Path
4
- from typing import Any, Dict, List, Optional
5
-
6
- DEFAULT_MEMORY_PATH = Path(".puppy_session_memory.json")
7
-
8
-
9
- class SessionMemory:
10
- """
11
- Simple persistent memory for Code Puppy agent sessions.
12
- Stores short histories of tasks, notes, user preferences, and watched files.
13
- """
14
-
15
- def __init__(
16
- self, storage_path: Path = DEFAULT_MEMORY_PATH, memory_limit: int = 128
17
- ):
18
- self.storage_path = storage_path
19
- self.memory_limit = memory_limit
20
- self._data = {
21
- "history": [], # List of task/event dicts
22
- "user_preferences": {},
23
- "watched_files": [],
24
- }
25
- self._load()
26
-
27
- def _load(self):
28
- if self.storage_path.exists():
29
- try:
30
- self._data = json.loads(self.storage_path.read_text())
31
- except Exception:
32
- self._data = {
33
- "history": [],
34
- "user_preferences": {},
35
- "watched_files": [],
36
- }
37
-
38
- def _save(self):
39
- try:
40
- self.storage_path.write_text(json.dumps(self._data, indent=2))
41
- except Exception:
42
- pass # Don't crash the agent for memory fails
43
-
44
- def log_task(self, description: str, extras: Optional[Dict[str, Any]] = None):
45
- entry = {
46
- "timestamp": datetime.utcnow().isoformat(),
47
- "description": description,
48
- }
49
- if extras:
50
- entry.update(extras)
51
- self._data["history"].append(entry)
52
- # Trim memory
53
- self._data["history"] = self._data["history"][-self.memory_limit :]
54
- self._save()
55
-
56
- def get_history(self, within_minutes: Optional[int] = None) -> List[Dict[str, Any]]:
57
- if not within_minutes:
58
- return list(self._data["history"])
59
- cutoff = datetime.utcnow() - timedelta(minutes=within_minutes)
60
- return [
61
- h
62
- for h in self._data["history"]
63
- if datetime.fromisoformat(h["timestamp"]) >= cutoff
64
- ]
65
-
66
- def set_preference(self, key: str, value: Any):
67
- self._data["user_preferences"][key] = value
68
- self._save()
69
-
70
- def get_preference(self, key: str, default: Any = None) -> Any:
71
- return self._data["user_preferences"].get(key, default)
72
-
73
- def add_watched_file(self, path: str):
74
- if path not in self._data["watched_files"]:
75
- self._data["watched_files"].append(path)
76
- self._save()
77
-
78
- def list_watched_files(self) -> List[str]:
79
- return list(self._data["watched_files"])
80
-
81
- def clear(self):
82
- self._data = {"history": [], "user_preferences": {}, "watched_files": []}
83
- self._save()
File without changes
File without changes
File without changes