code-puppy 0.0.73__py3-none-any.whl → 0.0.74__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
@@ -67,6 +67,7 @@ def session_memory():
67
67
 
68
68
  def _load_mcp_servers():
69
69
  from code_puppy.config import load_mcp_server_configs
70
+
70
71
  configs = load_mcp_server_configs()
71
72
  servers = []
72
73
  for name, conf in configs.items():
@@ -76,6 +77,7 @@ def _load_mcp_servers():
76
77
  servers.append(MCPServerSSE(url))
77
78
  return servers
78
79
 
80
+
79
81
  def reload_code_generation_agent():
80
82
  """Force-reload the agent, usually after a model change."""
81
83
  global _code_generation_agent, _LAST_MODEL_NAME
@@ -104,7 +106,7 @@ def reload_code_generation_agent():
104
106
  instructions=instructions,
105
107
  output_type=AgentResponse,
106
108
  retries=3,
107
- mcp_servers=mcp_servers
109
+ mcp_servers=mcp_servers,
108
110
  )
109
111
  register_all_tools(agent)
110
112
  _code_generation_agent = agent
@@ -8,6 +8,7 @@ from code_puppy.command_line.model_picker_completion import (
8
8
  )
9
9
  from code_puppy.config import get_config_keys
10
10
  from code_puppy.command_line.utils import make_directory_table
11
+ from code_puppy.command_line.motd import print_motd
11
12
 
12
13
  META_COMMANDS_HELP = """
13
14
  [bold magenta]Meta Commands Help[/bold magenta]
@@ -22,8 +23,6 @@ META_COMMANDS_HELP = """
22
23
  """
23
24
 
24
25
 
25
- from code_puppy.command_line.motd import print_motd
26
-
27
26
  def handle_meta_command(command: str, console: Console) -> bool:
28
27
  """
29
28
  Handle meta/config commands prefixed with '~'.
@@ -75,20 +74,26 @@ def handle_meta_command(command: str, console: Console) -> bool:
75
74
 
76
75
  if command.strip().startswith("~show"):
77
76
  from code_puppy.command_line.model_picker_completion import get_active_model
78
- from code_puppy.config import get_owner_name, get_puppy_name, get_yolo_mode, get_message_history_limit
77
+ from code_puppy.config import (
78
+ get_owner_name,
79
+ get_puppy_name,
80
+ get_yolo_mode,
81
+ get_message_history_limit,
82
+ )
83
+
79
84
  puppy_name = get_puppy_name()
80
85
  owner_name = get_owner_name()
81
86
  model = get_active_model()
82
87
  yolo_mode = get_yolo_mode()
83
88
  msg_limit = get_message_history_limit()
84
- console.print(f'''[bold magenta]🐶 Puppy Status[/bold magenta]
89
+ console.print(f"""[bold magenta]🐶 Puppy Status[/bold magenta]
85
90
 
86
91
  [bold]puppy_name:[/bold] [cyan]{puppy_name}[/cyan]
87
92
  [bold]owner_name:[/bold] [cyan]{owner_name}[/cyan]
88
93
  [bold]model:[/bold] [green]{model}[/green]
89
- [bold]YOLO_MODE:[/bold] {'[red]ON[/red]' if yolo_mode else '[yellow]off[/yellow]'}
94
+ [bold]YOLO_MODE:[/bold] {"[red]ON[/red]" if yolo_mode else "[yellow]off[/yellow]"}
90
95
  [bold]message_history_limit:[/bold] Keeping last [cyan]{msg_limit}[/cyan] messages in context
91
- ''')
96
+ """)
92
97
  return True
93
98
 
94
99
  if command.startswith("~set"):
@@ -2,8 +2,8 @@
2
2
  MOTD (Message of the Day) feature for code-puppy.
3
3
  Stores seen versions in ~/.puppy_cfg/motd.txt.
4
4
  """
5
+
5
6
  import os
6
- from typing import Optional
7
7
 
8
8
  MOTD_VERSION = "20240621"
9
9
  MOTD_MESSAGE = """
code_puppy/config.py CHANGED
@@ -72,6 +72,7 @@ def get_message_history_limit():
72
72
  except (ValueError, TypeError):
73
73
  return 40
74
74
 
75
+
75
76
  # --- CONFIG SETTER STARTS HERE ---
76
77
  def get_config_keys():
77
78
  """
@@ -117,6 +118,7 @@ def load_mcp_server_configs():
117
118
  print(f"Failed to load MCP servers - {str(e)}")
118
119
  return {}
119
120
 
121
+
120
122
  def get_model_name():
121
123
  """Returns the last used model name stored in config, or None if unset."""
122
124
  return get_value("model") or "gpt-4.1"
code_puppy/main.py CHANGED
@@ -4,7 +4,6 @@ import os
4
4
  import sys
5
5
 
6
6
  from dotenv import load_dotenv
7
- from pydantic_ai.messages import ToolCallPart, ToolReturnPart
8
7
  from rich.console import Console, ConsoleOptions, RenderResult
9
8
  from rich.markdown import CodeBlock, Markdown
10
9
  from rich.syntax import Syntax
@@ -116,9 +115,10 @@ async def interactive_mode(history_file_path: str) -> None:
116
115
  # Show MOTD if user hasn't seen it after an update
117
116
  try:
118
117
  from code_puppy.command_line.motd import print_motd
118
+
119
119
  print_motd(console, force=False)
120
120
  except Exception as e:
121
- console.print(f'[yellow]MOTD error: {e}[/yellow]')
121
+ console.print(f"[yellow]MOTD error: {e}[/yellow]")
122
122
 
123
123
  # Check if prompt_toolkit is installed
124
124
  try:
@@ -235,19 +235,21 @@ async def interactive_mode(history_file_path: str) -> None:
235
235
  ]
236
236
  # 2. Append to existing history and keep only the most recent set by config
237
237
  from code_puppy.config import get_message_history_limit
238
+
238
239
  message_history.extend(filtered)
239
240
 
240
241
  # --- BEGIN GROUP-AWARE TRUNCATION LOGIC ---
241
242
  limit = get_message_history_limit()
242
243
  if len(message_history) > limit:
244
+
243
245
  def group_by_tool_call_id(msgs):
244
246
  grouped = {}
245
247
  no_group = []
246
248
  for m in msgs:
247
249
  # Find all tool_call_id in message parts
248
250
  tool_call_ids = set()
249
- for part in getattr(m, 'parts', []):
250
- if hasattr(part, 'tool_call_id') and part.tool_call_id:
251
+ for part in getattr(m, "parts", []):
252
+ if hasattr(part, "tool_call_id") and part.tool_call_id:
251
253
  tool_call_ids.add(part.tool_call_id)
252
254
  if tool_call_ids:
253
255
  for tcid in tool_call_ids:
@@ -271,7 +273,6 @@ async def interactive_mode(history_file_path: str) -> None:
271
273
  message_history = truncated
272
274
  # --- END GROUP-AWARE TRUNCATION LOGIC ---
273
275
 
274
-
275
276
  if agent_response and agent_response.awaiting_user_input:
276
277
  console.print(
277
278
  "\n[bold yellow]\u26a0 Agent needs your input to continue.[/bold yellow]"
@@ -110,7 +110,7 @@ def _replace_in_file(
110
110
  orig_lines = modified.splitlines()
111
111
  loc, score = _find_best_window(orig_lines, old_snippet)
112
112
 
113
- if score < 0.95 or loc == None:
113
+ if score < 0.95 or loc is None:
114
114
  return {
115
115
  "error": "No suitable match in file (JW < 0.95)",
116
116
  "jw_score": score,
@@ -392,7 +392,11 @@ def _walk_fix(ts_node, rich_parent, info):
392
392
  n_type = child.type
393
393
  if n_type in nodes_cfg:
394
394
  style = nodes_cfg[n_type].keywords["style"]
395
- ident = child.child_by_field_name(name_field) if name_field else _first_identifier(child)
395
+ ident = (
396
+ child.child_by_field_name(name_field)
397
+ if name_field
398
+ else _first_identifier(child)
399
+ )
396
400
  label_text = ident.text.decode() if ident else "<anon>"
397
401
  label = nodes_cfg[n_type].func(label_text)
398
402
  emoji = _emoji_for_node_type(n_type)
@@ -402,6 +406,8 @@ def _walk_fix(ts_node, rich_parent, info):
402
406
  _walk_fix(child, branch, info)
403
407
  else:
404
408
  _walk_fix(child, rich_parent, info)
409
+
410
+
405
411
  # ----------------------------------------------------------------------
406
412
 
407
413
 
@@ -465,7 +471,9 @@ def make_code_map(directory: str, ignore_tests: bool = True) -> str:
465
471
  base_tree = RichTree(Text(Path(directory).name, style="bold magenta"))
466
472
 
467
473
  # Cache to ensure we reuse RichTree nodes per directory path
468
- dir_nodes: dict[str, RichTree] = {Path(directory).resolve(): base_tree} # key=abs path
474
+ dir_nodes: dict[str, RichTree] = {
475
+ Path(directory).resolve(): base_tree
476
+ } # key=abs path
469
477
 
470
478
  for root, dirs, files in os.walk(directory):
471
479
  # ignore dot-folders early
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-puppy
3
- Version: 0.0.73
3
+ Version: 0.0.74
4
4
  Summary: Code generation agent
5
5
  Author: Michael Pfaffenberger
6
6
  License: MIT
@@ -1,29 +1,29 @@
1
1
  code_puppy/__init__.py,sha256=-ANvE6Xe5NlWDIRCIfL1x-rgtCZ6zM2Ye9NphFoULSY,82
2
- code_puppy/agent.py,sha256=hi064QRtDwMfDSsfW3p31SX4rdsMCRgJMftOK2Nv7_M,4081
2
+ code_puppy/agent.py,sha256=hhVrBhT3MAhzs61cSnZ7Au7lrjoFAewfh6fGkawEQQo,4084
3
3
  code_puppy/agent_prompts.py,sha256=DnPNubiFtD6Ot76cIsxedJEaEVYS5AaxR3JWJM5nXNg,6925
4
- code_puppy/config.py,sha256=3xqEIysX-fV_M3oPDtnYuiH8tMGTZzhHpwzCzx8ghAQ,5011
5
- code_puppy/main.py,sha256=FYqZhne46DCOwC7GdFbfx0reWqRQRI4_JOsq0rHNygo,12538
4
+ code_puppy/config.py,sha256=r5nw5ChOP8xd_K5yo8U5OtO2gy2bFhARiyNtDp1JrwQ,5013
5
+ code_puppy/main.py,sha256=-wC_Bs2vbu9r9kdajKcSjddQ1nHFnpifLUX6nhbATZw,12478
6
6
  code_puppy/model_factory.py,sha256=jZH96zE5GMTK3RWjUpZB4HjbSO3fSaAzjRoQh8Y8lfg,7711
7
7
  code_puppy/models.json,sha256=AY1dcFd3bMFaJBjU_u-PjsrnmcKbjjtGhjL3uYfqpW8,1692
8
8
  code_puppy/session_memory.py,sha256=4sgAAjbXdLSi8hETpd56tgtrG6hqMUuZWDlJOu6BQjA,2735
9
9
  code_puppy/version_checker.py,sha256=aRGulzuY4C4CdFvU1rITduyL-1xTFsn4GiD1uSfOl_Y,396
10
10
  code_puppy/command_line/__init__.py,sha256=y7WeRemfYppk8KVbCGeAIiTuiOszIURCDjOMZv_YRmU,45
11
11
  code_puppy/command_line/file_path_completion.py,sha256=gw8NpIxa6GOpczUJRyh7VNZwoXKKn-yvCqit7h2y6Gg,2931
12
- code_puppy/command_line/meta_command_handler.py,sha256=kP57BU7gH23ten0CHX1XmrCbe89WFxoHzz6ddeRGrCE,6121
12
+ code_puppy/command_line/meta_command_handler.py,sha256=L7qP2g0Faz0V7bMH4YK3s03OWWuQFtK7Sh-Kt2zmmEQ,6182
13
13
  code_puppy/command_line/model_picker_completion.py,sha256=NkyZZG7IhcVWSJ3ADytwCA5f8DpNeVs759Qtqs4fQtY,3733
14
- code_puppy/command_line/motd.py,sha256=TDk5xTe6Atp6tyTFEH3SgK8HWBqsdiffVkhxaoGs-lg,1873
14
+ code_puppy/command_line/motd.py,sha256=3HuwCMuu0_hZa7UCGnOY5EcG103y2jMFWo28NwY-GDQ,1846
15
15
  code_puppy/command_line/prompt_toolkit_completion.py,sha256=_gP0FIOgHDNHTTWLNL0XNzr6sO0ISe7Mec1uQNo9kcM,8337
16
16
  code_puppy/command_line/utils.py,sha256=7eyxDHjPjPB9wGDJQQcXV_zOsGdYsFgI0SGCetVmTqE,1251
17
17
  code_puppy/tools/__init__.py,sha256=J_HCbkivdr1rP5vfucxttXhGmTBx0S2LNoDMrbaE-Fc,558
18
18
  code_puppy/tools/command_runner.py,sha256=cEphrDyr12CoqpKizzaxhMHhG1HiVcqXArTkwc6lvxU,6760
19
19
  code_puppy/tools/common.py,sha256=M53zhiXZAmPdvi1Y_bzCxgvEmifOvRRJvYPARYRZqHw,2253
20
- code_puppy/tools/file_modifications.py,sha256=d0fC2CCnkmv0kEJ8kvKTuUMTww3S_mgF06h9g93212A,13072
20
+ code_puppy/tools/file_modifications.py,sha256=uEUXoB0F4h3Blzgeq4ggejv1GKAc8OdeTvntf58gsrQ,13072
21
21
  code_puppy/tools/file_operations.py,sha256=xqj7MiK6sGTaC8NMrMRTybWlXG32S-DjybqJtnufRcI,11715
22
- code_puppy/tools/ts_code_map.py,sha256=-CXLzFxFMefoYYdWxfPwFugZhkfVxdiftGb3LZnEttk,17567
22
+ code_puppy/tools/ts_code_map.py,sha256=o-u8p5vsYwitfDtVEoPS-7MwWn2xHzwtIQLo1_WMhQs,17647
23
23
  code_puppy/tools/web_search.py,sha256=sA2ierjuuYA517-uhb5s53SgeVsyOe1nExoZsrU1Fps,1284
24
- code_puppy-0.0.73.data/data/code_puppy/models.json,sha256=AY1dcFd3bMFaJBjU_u-PjsrnmcKbjjtGhjL3uYfqpW8,1692
25
- code_puppy-0.0.73.dist-info/METADATA,sha256=zn6uo0kWwpb4-2hi4hhSHJ2QU5mSjym6RyZc9dgnNrI,6417
26
- code_puppy-0.0.73.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
27
- code_puppy-0.0.73.dist-info/entry_points.txt,sha256=d8YkBvIUxF-dHNJAj-x4fPEqizbY5d_TwvYpc01U5kw,58
28
- code_puppy-0.0.73.dist-info/licenses/LICENSE,sha256=31u8x0SPgdOq3izJX41kgFazWsM43zPEF9eskzqbJMY,1075
29
- code_puppy-0.0.73.dist-info/RECORD,,
24
+ code_puppy-0.0.74.data/data/code_puppy/models.json,sha256=AY1dcFd3bMFaJBjU_u-PjsrnmcKbjjtGhjL3uYfqpW8,1692
25
+ code_puppy-0.0.74.dist-info/METADATA,sha256=biL4TR0F1r-BMFHSjpTLvKxNdtYJ3zXhh5_3HQXVzYQ,6417
26
+ code_puppy-0.0.74.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
27
+ code_puppy-0.0.74.dist-info/entry_points.txt,sha256=d8YkBvIUxF-dHNJAj-x4fPEqizbY5d_TwvYpc01U5kw,58
28
+ code_puppy-0.0.74.dist-info/licenses/LICENSE,sha256=31u8x0SPgdOq3izJX41kgFazWsM43zPEF9eskzqbJMY,1075
29
+ code_puppy-0.0.74.dist-info/RECORD,,