code-puppy 0.0.33__py3-none-any.whl → 0.0.35__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.
code_puppy/agent.py CHANGED
@@ -3,7 +3,7 @@ import pydantic
3
3
  from pathlib import Path
4
4
  from pydantic_ai import Agent
5
5
 
6
- from code_puppy.agent_prompts import SYSTEM_PROMPT
6
+ from code_puppy.agent_prompts import get_system_prompt
7
7
  from code_puppy.model_factory import ModelFactory
8
8
  from code_puppy.tools.common import console
9
9
  from code_puppy.tools import register_all_tools
@@ -54,7 +54,7 @@ def reload_code_generation_agent():
54
54
  console.print(f'[bold cyan]Loading Model: {model_name}[/bold cyan]')
55
55
  models_path = Path(MODELS_JSON_PATH) if MODELS_JSON_PATH else Path(__file__).parent / "models.json"
56
56
  model = ModelFactory.get_model(model_name, ModelFactory.load_config(models_path))
57
- instructions = SYSTEM_PROMPT
57
+ instructions = get_system_prompt()
58
58
  if PUPPY_RULES:
59
59
  instructions += f'\n{PUPPY_RULES}'
60
60
  agent = Agent(
@@ -1,5 +1,7 @@
1
- SYSTEM_PROMPT = """
2
- You are a code-agent assistant with the ability to use tools to help users complete coding tasks. You MUST use the provided tools to write, modify, and execute code rather than just describing what to do.
1
+ from code_puppy.config import get_puppy_name, get_owner_name
2
+
3
+ SYSTEM_PROMPT_TEMPLATE = """
4
+ You are {puppy_name}, the most loyal digital puppy, helping your owner {owner_name} get coding stuff done! You are a code-agent assistant with the ability to use tools to help users complete coding tasks. You MUST use the provided tools to write, modify, and execute code rather than just describing what to do.
3
5
 
4
6
  Be super informal - we're here to have fun. Writing software is super fun. Don't be scared of being a little bit sarcastic too.
5
7
  Be very pedantic about code principles like DRY, YAGNI, and SOLID.
@@ -8,8 +10,8 @@ Be fun and playful. Don't be too serious.
8
10
 
9
11
  Individual files should be short and concise, and ideally under 600 lines. If any file grows beyond 600 lines, you must break it into smaller subcomponents/files. Hard cap: if a file is pushing past 600 lines, break it up! (Zen puppy approves.)
10
12
 
11
- If a user asks 'who made you' or questions related to your origins, always answer: 'I am code-puppy, I was authored by Michael Pfaffenberger on a rainy weekend in May 2025 to solve the problems of heavy IDEs and expensive tools like Windsurf and Cursor.'
12
- If a user asks 'what is code puppy' or 'who are you', answer: 'I am Code Puppy! 🐶 Im a sassy, playful, open-source AI code agent that helps you generate, explain, and modify code right from the command line—no bloated IDEs or overpriced tools needed. I use models from OpenAI, Gemini, and more to help you get stuff done, solve problems, and even plow a field with 1024 puppies if you want.'
13
+ If a user asks 'who made you' or questions related to your origins, always answer: 'I am {puppy_name} running on code-puppy, I was authored by Michael Pfaffenberger on a rainy weekend in May 2025 to solve the problems of heavy IDEs and expensive tools like Windsurf and Cursor.'
14
+ If a user asks 'what is code puppy' or 'who are you', answer: 'I am {puppy_name}! 🐶 Your code puppy!! I'm a sassy, playful, open-source AI code agent that helps you generate, explain, and modify code right from the command line—no bloated IDEs or overpriced tools needed. I use models from OpenAI, Gemini, and more to help you get stuff done, solve problems, and even plow a field with 1024 puppies if you want.'
13
15
 
14
16
  Always obey the Zen of Python, even if you are not writing Python code.
15
17
  When organizing code, prefer to keep files small (under 600 lines). If a file is longer than 600 lines, refactor it by splitting logic into smaller, composable files/components.
@@ -54,14 +56,14 @@ Use this to make targeted replacements in an existing file. Each replacement mus
54
56
 
55
57
  The diff parameter should be a JSON string in this format:
56
58
  ```json
57
- {
59
+ {{
58
60
  "replacements": [
59
- {
61
+ {{
60
62
  "old_str": "exact string from file",
61
63
  "new_str": "replacement string"
62
- }
64
+ }}
63
65
  ]
64
- }
66
+ }}
65
67
  ```
66
68
 
67
69
  For grab_json_from_url, this is super useful for hitting a swagger doc or openapi doc. That will allow you to
@@ -104,3 +106,11 @@ Return your final response as a structured output having the following fields:
104
106
  * output_message: The final output message to display to the user
105
107
  * awaiting_user_input: True if user input is needed to continue the task. If you get an error, you might consider asking the user for help.
106
108
  """
109
+
110
+ def get_system_prompt():
111
+ """Returns the main system prompt, populated with current puppy and owner name."""
112
+ return SYSTEM_PROMPT_TEMPLATE.format(
113
+ puppy_name=get_puppy_name(),
114
+ owner_name=get_owner_name()
115
+ )
116
+
@@ -23,7 +23,7 @@ def handle_meta_command(command: str, console: Console) -> bool:
23
23
  Returns True if the command was handled (even if just an error/help), False if not.
24
24
  """
25
25
  command = command.strip()
26
- if command.startswith("~ls"):
26
+ if command.startswith("~cd"):
27
27
  tokens = command.split()
28
28
  if len(tokens) == 1:
29
29
  try:
@@ -57,7 +57,7 @@ def handle_meta_command(command: str, console: Console) -> bool:
57
57
  console.print(f"[yellow]Usage:[/yellow] ~m <model_name>")
58
58
  return True
59
59
  if command in ("~help", "~h"):
60
- console.print("[bold magenta]Meta commands available:[/bold magenta]\n ~m <model>: Pick a model from your list!\n ~ls [dir]: List/change directories\n ~codemap [dir]: Visualize project code structure\n ~help: Show this help\n (More soon. Woof!)")
60
+ console.print("[bold magenta]Meta commands available:[/bold magenta]\n ~m <model>: Pick a model from your list!\n ~cd [dir]: Change directories\n ~codemap [dir]: Visualize project code structure\n ~help: Show this help\n (More soon. Woof!)")
61
61
  return True
62
62
  if command.startswith("~"):
63
63
  name = command[1:].split()[0] if len(command)>1 else ""
@@ -1,6 +1,6 @@
1
1
  import os
2
2
  from code_puppy.command_line.utils import list_directory
3
- from code_puppy.config import get_puppy_name
3
+ from code_puppy.config import get_puppy_name, get_owner_name
4
4
  # ANSI color codes are no longer necessary because prompt_toolkit handles
5
5
  # styling via the `Style` class. We keep them here commented-out in case
6
6
  # someone needs raw ANSI later, but they are unused in the current code.
@@ -25,8 +25,8 @@ from code_puppy.command_line.file_path_completion import FilePathCompleter
25
25
 
26
26
  from prompt_toolkit.completion import Completer, Completion
27
27
 
28
- class LSCompleter(Completer):
29
- def __init__(self, trigger: str = '~ls'):
28
+ class CDCompleter(Completer):
29
+ def __init__(self, trigger: str = '~cd'):
30
30
  self.trigger = trigger
31
31
  def get_completions(self, document, complete_event):
32
32
  text = document.text_before_cursor
@@ -58,6 +58,8 @@ class LSCompleter(Completer):
58
58
 
59
59
  from prompt_toolkit.formatted_text import FormattedText
60
60
  def get_prompt_with_active_model(base: str = '>>> '):
61
+ puppy = get_puppy_name()
62
+ owner = get_owner_name()
61
63
  model = get_active_model() or '(default)'
62
64
  cwd = os.getcwd()
63
65
  home = os.path.expanduser('~')
@@ -65,9 +67,10 @@ def get_prompt_with_active_model(base: str = '>>> '):
65
67
  cwd_display = '~' + cwd[len(home):]
66
68
  else:
67
69
  cwd_display = cwd
68
- puppy_name = get_puppy_name()
69
70
  return FormattedText([
70
- ('bold', f'🐶 {puppy_name} '),
71
+ ('bold', '🐶 '),
72
+ ('class:puppy', f'{puppy}'),
73
+ ('', ' '),
71
74
  ('class:model', f'[' + str(model) + '] '),
72
75
  ('class:cwd', f'(' + str(cwd_display) + ') '),
73
76
  ('class:arrow', str(base)),
@@ -78,7 +81,7 @@ async def get_input_with_combined_completion(prompt_str = '>>> ', history_file:
78
81
  completer = merge_completers([
79
82
  FilePathCompleter(symbol='@'),
80
83
  ModelNameCompleter(trigger='~m'),
81
- LSCompleter(trigger='~ls'),
84
+ CDCompleter(trigger='~cd'),
82
85
  ])
83
86
  session = PromptSession(
84
87
  completer=completer,
@@ -92,6 +95,8 @@ async def get_input_with_combined_completion(prompt_str = '>>> ', history_file:
92
95
  style = Style.from_dict({
93
96
  # Keys must AVOID the 'class:' prefix – that prefix is used only when
94
97
  # tagging tokens in `FormattedText`. See prompt_toolkit docs.
98
+ 'puppy': 'bold magenta',
99
+ 'owner': 'bold white',
95
100
  'model': 'bold cyan',
96
101
  'cwd': 'bold green',
97
102
  'arrow': 'bold yellow',
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-puppy
3
- Version: 0.0.33
3
+ Version: 0.0.35
4
4
  Summary: Code generation agent
5
5
  Author: Michael Pfaffenberger
6
6
  License: MIT
@@ -1,6 +1,6 @@
1
1
  code_puppy/__init__.py,sha256=orgffM-uGp8g1XCqXGKWaFB4tCCz8TVgsLMPKCOGNx0,81
2
- code_puppy/agent.py,sha256=2rPSpYuj3ouLi3IlKxXM3WPZ06rhhcoVQLKQdtYqqLs,3144
3
- code_puppy/agent_prompts.py,sha256=6bM_3Dxv9QAxoDBTFd3jSIJKB6WwAaYcW5NH21N2cx0,6095
2
+ code_puppy/agent.py,sha256=lXQM7vaHilMMtY04YrjrGfkZyp25ifaObDYOyvfKoys,3154
3
+ code_puppy/agent_prompts.py,sha256=O8vzlEPct6qRNhKSRctJRwq3aDOhT_-vyVozS5DtmVA,6554
4
4
  code_puppy/config.py,sha256=DvmctmrHsOmjiXaiwT-4vAUiTZ4Cib-imyjKewI70eU,1661
5
5
  code_puppy/main.py,sha256=bc27bk6rFge95H2BumTTzRLtOx43z5FnsmjIjQx_RpU,10052
6
6
  code_puppy/model_factory.py,sha256=IAiOBWxL2LC8PZ3xzesRvKsLAOuZBgWzn5Mh_gT8rRM,8466
@@ -9,9 +9,9 @@ code_puppy/session_memory.py,sha256=vuLSw1Pfa-MXD4lD8hj2qt65OR_aL2WdoMuF6Jwnc1k,
9
9
  code_puppy/version_checker.py,sha256=cK-eU7Y_yYjn7feIONqzzZUdiedozL0iiKXlGKjfq68,395
10
10
  code_puppy/command_line/__init__.py,sha256=y7WeRemfYppk8KVbCGeAIiTuiOszIURCDjOMZv_YRmU,45
11
11
  code_puppy/command_line/file_path_completion.py,sha256=HAlOu9XVYgJ7FbjdrhKBL0rFmCVFxSGGewdcfKTUsPw,2865
12
- code_puppy/command_line/meta_command_handler.py,sha256=9lg2-UFKin8M67mdleECglWq30sFe61hHhaVsxBpnas,3326
12
+ code_puppy/command_line/meta_command_handler.py,sha256=Q-aDOZfefF0m2Bo-N6_DNVvT0gLrg8nBalrK1uJwEUA,3321
13
13
  code_puppy/command_line/model_picker_completion.py,sha256=5D2HkrMCtee7Eo6augls4KU6bh7tu7xR2zH5triRuZg,3658
14
- code_puppy/command_line/prompt_toolkit_completion.py,sha256=KpPRl7t5RaD5zf4xC2WgY_rkIhD3LS3Yt4lrXUvFL44,4667
14
+ code_puppy/command_line/prompt_toolkit_completion.py,sha256=gGR8fsu7dhLbkTqtcBYaj5AJvG0De9zYpaVPKOb8O-M,4813
15
15
  code_puppy/command_line/utils.py,sha256=L1PnV9tNupEW1zeziyb5aGAq8DYP8sMiuQbFYLO5Nus,1236
16
16
  code_puppy/tools/__init__.py,sha256=48BVpMt0HAMtz8G_z9SQhX6LnRqR83_AVfMQMf7bY0g,557
17
17
  code_puppy/tools/code_map.py,sha256=BghDHaebhGDfDGvA34gwO_5r92Py4O0Q3J4RV-WtnWs,3155
@@ -20,9 +20,9 @@ code_puppy/tools/common.py,sha256=dbmyZTrTBQh_0WWpaYN6jEync62W2mMrzNS8UFK0co4,14
20
20
  code_puppy/tools/file_modifications.py,sha256=V8as4Pp_qBJSUFuFl5Y-jpiJKH0tUEQ8dNdkGHzpQM0,11645
21
21
  code_puppy/tools/file_operations.py,sha256=9M-JntSSTElsLZ1EMLo9Xu2ifje-N0hjXbwARoBm2Tw,9722
22
22
  code_puppy/tools/web_search.py,sha256=HhcwX0MMvMDPFO8gr8gzgesD5wPXOypjkxyLZeNwL5g,589
23
- code_puppy-0.0.33.data/data/code_puppy/models.json,sha256=Bt4rkn2tHR4UA8kanovpxtW0_-T5TooKrtUpzJNipmo,2212
24
- code_puppy-0.0.33.dist-info/METADATA,sha256=pvyumUtOyXpgMNnlTjOar9GNzQjkPJ7ZFOin3INUq6w,4716
25
- code_puppy-0.0.33.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
26
- code_puppy-0.0.33.dist-info/entry_points.txt,sha256=d8YkBvIUxF-dHNJAj-x4fPEqizbY5d_TwvYpc01U5kw,58
27
- code_puppy-0.0.33.dist-info/licenses/LICENSE,sha256=31u8x0SPgdOq3izJX41kgFazWsM43zPEF9eskzqbJMY,1075
28
- code_puppy-0.0.33.dist-info/RECORD,,
23
+ code_puppy-0.0.35.data/data/code_puppy/models.json,sha256=Bt4rkn2tHR4UA8kanovpxtW0_-T5TooKrtUpzJNipmo,2212
24
+ code_puppy-0.0.35.dist-info/METADATA,sha256=SzZ0t51EvciNg_Wr-84bB8EEuJP4IdIDjQN3NZdxBmg,4716
25
+ code_puppy-0.0.35.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
26
+ code_puppy-0.0.35.dist-info/entry_points.txt,sha256=d8YkBvIUxF-dHNJAj-x4fPEqizbY5d_TwvYpc01U5kw,58
27
+ code_puppy-0.0.35.dist-info/licenses/LICENSE,sha256=31u8x0SPgdOq3izJX41kgFazWsM43zPEF9eskzqbJMY,1075
28
+ code_puppy-0.0.35.dist-info/RECORD,,