code-puppy 0.0.59__py3-none-any.whl → 0.0.61__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 +15 -4
- code_puppy/agent_prompts.py +2 -1
- code_puppy/command_line/meta_command_handler.py +17 -12
- code_puppy/command_line/prompt_toolkit_completion.py +43 -36
- code_puppy/model_factory.py +0 -108
- code_puppy/models.json +4 -31
- code_puppy/tools/command_runner.py +7 -2
- code_puppy/tools/common.py +51 -0
- code_puppy/tools/file_modifications.py +137 -130
- code_puppy/tools/file_operations.py +19 -28
- code_puppy/tools/ts_code_map.py +393 -0
- {code_puppy-0.0.59.data → code_puppy-0.0.61.data}/data/code_puppy/models.json +4 -31
- {code_puppy-0.0.59.dist-info → code_puppy-0.0.61.dist-info}/METADATA +3 -1
- code_puppy-0.0.61.dist-info/RECORD +28 -0
- code_puppy/tools/code_map.py +0 -92
- code_puppy-0.0.59.dist-info/RECORD +0 -28
- {code_puppy-0.0.59.dist-info → code_puppy-0.0.61.dist-info}/WHEEL +0 -0
- {code_puppy-0.0.59.dist-info → code_puppy-0.0.61.dist-info}/entry_points.txt +0 -0
- {code_puppy-0.0.59.dist-info → code_puppy-0.0.61.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from code_puppy.tools.common import should_ignore_path
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from rich.text import Text
|
|
5
|
+
from rich.tree import Tree as RichTree
|
|
6
|
+
from rich.console import Console
|
|
7
|
+
from tree_sitter_language_pack import get_parser
|
|
8
|
+
|
|
9
|
+
from functools import partial, wraps
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _f(fmt): # helper to keep the table tidy
|
|
13
|
+
return lambda name, _fmt=fmt: _fmt.format(name=name)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def mark_export(label_fn, default=False):
|
|
17
|
+
"""Decorator to prefix 'export ' (or 'export default ') when requested."""
|
|
18
|
+
|
|
19
|
+
@wraps(label_fn)
|
|
20
|
+
def _wrap(name, *, exported=False):
|
|
21
|
+
prefix = "export default " if default else "export " if exported else ""
|
|
22
|
+
return prefix + label_fn(name)
|
|
23
|
+
|
|
24
|
+
return _wrap
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
LANGS = {
|
|
28
|
+
".py": {
|
|
29
|
+
"lang": "python",
|
|
30
|
+
"name_field": "name",
|
|
31
|
+
"nodes": {
|
|
32
|
+
"function_definition": partial(_f("def {name}()"), style="green"),
|
|
33
|
+
"class_definition": partial(_f("class {name}"), style="magenta"),
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
".rb": {
|
|
37
|
+
"lang": "ruby",
|
|
38
|
+
"name_field": "name",
|
|
39
|
+
"nodes": {
|
|
40
|
+
"method": partial(_f("def {name}"), style="green"),
|
|
41
|
+
"class": partial(_f("class {name}"), style="magenta"),
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
".php": {
|
|
45
|
+
"lang": "php",
|
|
46
|
+
"name_field": "name",
|
|
47
|
+
"nodes": {
|
|
48
|
+
"function_definition": partial(_f("function {name}()"), style="green"),
|
|
49
|
+
"class_declaration": partial(_f("class {name}"), style="magenta"),
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
".lua": {
|
|
53
|
+
"lang": "lua",
|
|
54
|
+
"name_field": "name",
|
|
55
|
+
"nodes": {
|
|
56
|
+
"function_declaration": partial(_f("function {name}()"), style="green")
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
".pl": {
|
|
60
|
+
"lang": "perl",
|
|
61
|
+
"name_field": "name",
|
|
62
|
+
"nodes": {"sub_definition": partial(_f("sub {name}()"), style="green")},
|
|
63
|
+
},
|
|
64
|
+
".r": {
|
|
65
|
+
"lang": "r",
|
|
66
|
+
"name_field": "name",
|
|
67
|
+
"nodes": {"function_definition": partial(_f("func {name}()"), style="green")},
|
|
68
|
+
},
|
|
69
|
+
".js": {
|
|
70
|
+
"lang": "javascript",
|
|
71
|
+
"name_field": "name",
|
|
72
|
+
"nodes": {
|
|
73
|
+
"function_declaration": partial(_f("function {name}()"), style="green"),
|
|
74
|
+
"class_declaration": partial(_f("class {name}"), style="magenta"),
|
|
75
|
+
"export_statement": partial(_f("export {name}"), style="yellow"),
|
|
76
|
+
"export_default_statement": partial(
|
|
77
|
+
_f("export default {name}"), style="yellow"
|
|
78
|
+
),
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
".mjs": {
|
|
82
|
+
"lang": "javascript",
|
|
83
|
+
"name_field": "name",
|
|
84
|
+
"nodes": {
|
|
85
|
+
"function_declaration": partial(_f("function {name}()"), style="green"),
|
|
86
|
+
"class_declaration": partial(_f("class {name}"), style="magenta"),
|
|
87
|
+
"export_statement": partial(_f("export {name}"), style="yellow"),
|
|
88
|
+
"export_default_statement": partial(
|
|
89
|
+
_f("export default {name}"), style="yellow"
|
|
90
|
+
),
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
".cjs": {
|
|
94
|
+
"lang": "javascript",
|
|
95
|
+
"name_field": "name",
|
|
96
|
+
"nodes": {
|
|
97
|
+
"function_declaration": partial(_f("function {name}()"), style="green"),
|
|
98
|
+
"class_declaration": partial(_f("class {name}"), style="magenta"),
|
|
99
|
+
"export_statement": partial(_f("export {name}"), style="yellow"),
|
|
100
|
+
"export_default_statement": partial(
|
|
101
|
+
_f("export default {name}"), style="yellow"
|
|
102
|
+
),
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
".jsx": {
|
|
106
|
+
"lang": "jsx",
|
|
107
|
+
"name_field": None,
|
|
108
|
+
"nodes": {
|
|
109
|
+
"function_declaration": partial(_f("function {name}()"), style="green"),
|
|
110
|
+
"class_declaration": partial(_f("class {name}"), style="magenta"),
|
|
111
|
+
"export_statement": partial(_f("export {name}"), style="yellow"),
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
".ts": {
|
|
115
|
+
"lang": "tsx",
|
|
116
|
+
"name_field": None,
|
|
117
|
+
"nodes": {
|
|
118
|
+
"function_declaration": partial(_f("function {name}()"), style="green"),
|
|
119
|
+
"class_declaration": partial(_f("class {name}"), style="magenta"),
|
|
120
|
+
"export_statement": partial(_f("export {name}"), style="yellow"),
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
".tsx": {
|
|
124
|
+
"lang": "tsx",
|
|
125
|
+
"name_field": None,
|
|
126
|
+
"nodes": {
|
|
127
|
+
"function_declaration": partial(_f("function {name}()"), style="green"),
|
|
128
|
+
"class_declaration": partial(_f("class {name}"), style="magenta"),
|
|
129
|
+
"export_statement": partial(_f("export {name}"), style="yellow"),
|
|
130
|
+
"interface_declaration": partial(_f("interface {name}"), style="green"),
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
# ───────── systems / compiled ────────────────────────────────────
|
|
134
|
+
".c": {
|
|
135
|
+
"lang": "c",
|
|
136
|
+
"name_field": "declarator", # struct ident is under declarator
|
|
137
|
+
"nodes": {
|
|
138
|
+
"function_definition": partial(_f("fn {name}()"), style="green"),
|
|
139
|
+
"struct_specifier": partial(_f("struct {name}"), style="magenta"),
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
".h": {
|
|
143
|
+
"lang": "c",
|
|
144
|
+
"name_field": "declarator", # struct ident is under declarator
|
|
145
|
+
"nodes": {
|
|
146
|
+
"function_definition": partial(_f("fn {name}()"), style="green"),
|
|
147
|
+
"struct_specifier": partial(_f("struct {name}"), style="magenta"),
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
".cpp": {
|
|
151
|
+
"lang": "cpp",
|
|
152
|
+
"name_field": "declarator",
|
|
153
|
+
"nodes": {
|
|
154
|
+
"function_definition": partial(_f("fn {name}()"), style="green"),
|
|
155
|
+
"class_specifier": partial(_f("class {name}"), style="magenta"),
|
|
156
|
+
"struct_specifier": partial(_f("struct {name}"), style="magenta"),
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
".hpp": {
|
|
160
|
+
"lang": "cpp",
|
|
161
|
+
"name_field": "declarator",
|
|
162
|
+
"nodes": {
|
|
163
|
+
"function_definition": partial(_f("fn {name}()"), style="green"),
|
|
164
|
+
"class_specifier": partial(_f("class {name}"), style="magenta"),
|
|
165
|
+
"struct_specifier": partial(_f("struct {name}"), style="magenta"),
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
".cc": {
|
|
169
|
+
"lang": "cpp",
|
|
170
|
+
"name_field": "declarator",
|
|
171
|
+
"nodes": {
|
|
172
|
+
"function_definition": partial(_f("fn {name}()"), style="green"),
|
|
173
|
+
"class_specifier": partial(_f("class {name}"), style="magenta"),
|
|
174
|
+
"struct_specifier": partial(_f("struct {name}"), style="magenta"),
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
".hh": {
|
|
178
|
+
"lang": "cpp",
|
|
179
|
+
"name_field": "declarator",
|
|
180
|
+
"nodes": {
|
|
181
|
+
"function_definition": partial(_f("fn {name}()"), style="green"),
|
|
182
|
+
"class_specifier": partial(_f("class {name}"), style="magenta"),
|
|
183
|
+
"struct_specifier": partial(_f("struct {name}"), style="magenta"),
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
".cs": {
|
|
187
|
+
"lang": "c_sharp",
|
|
188
|
+
"name_field": "name",
|
|
189
|
+
"nodes": {
|
|
190
|
+
"method_declaration": partial(_f("method {name}()"), style="green"),
|
|
191
|
+
"class_declaration": partial(_f("class {name}"), style="magenta"),
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
".java": {
|
|
195
|
+
"lang": "java",
|
|
196
|
+
"name_field": "name",
|
|
197
|
+
"nodes": {
|
|
198
|
+
"method_declaration": partial(_f("method {name}()"), style="green"),
|
|
199
|
+
"class_declaration": partial(_f("class {name}"), style="magenta"),
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
".kt": {
|
|
203
|
+
"lang": "kotlin",
|
|
204
|
+
"name_field": "name",
|
|
205
|
+
"nodes": {
|
|
206
|
+
"function_declaration": partial(_f("fun {name}()"), style="green"),
|
|
207
|
+
"class_declaration": partial(_f("class {name}"), style="magenta"),
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
".swift": {
|
|
211
|
+
"lang": "swift",
|
|
212
|
+
"name_field": "name",
|
|
213
|
+
"nodes": {
|
|
214
|
+
"function_declaration": partial(_f("func {name}()"), style="green"),
|
|
215
|
+
"class_declaration": partial(_f("class {name}"), style="magenta"),
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
".go": {
|
|
219
|
+
"lang": "go",
|
|
220
|
+
"name_field": "name",
|
|
221
|
+
"nodes": {
|
|
222
|
+
"function_declaration": partial(_f("func {name}()"), style="green"),
|
|
223
|
+
"type_spec": partial(_f("type {name}"), style="magenta"),
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
".rs": {
|
|
227
|
+
"lang": "rust",
|
|
228
|
+
"name_field": "name",
|
|
229
|
+
"nodes": {
|
|
230
|
+
"function_item": partial(_f("fn {name}()"), style="green"),
|
|
231
|
+
"struct_item": partial(_f("struct {name}"), style="magenta"),
|
|
232
|
+
"trait_item": partial(_f("trait {name}"), style="magenta"),
|
|
233
|
+
},
|
|
234
|
+
},
|
|
235
|
+
".zig": {
|
|
236
|
+
"lang": "zig",
|
|
237
|
+
"name_field": "name",
|
|
238
|
+
"nodes": {
|
|
239
|
+
"fn_proto": partial(_f("fn {name}()"), style="green"),
|
|
240
|
+
"struct_decl": partial(_f("struct {name}"), style="magenta"),
|
|
241
|
+
},
|
|
242
|
+
},
|
|
243
|
+
".scala": {
|
|
244
|
+
"lang": "scala",
|
|
245
|
+
"name_field": "name",
|
|
246
|
+
"nodes": {
|
|
247
|
+
"function_definition": partial(_f("def {name}()"), style="green"),
|
|
248
|
+
"class_definition": partial(_f("class {name}"), style="magenta"),
|
|
249
|
+
"object_definition": partial(_f("object {name}"), style="magenta"),
|
|
250
|
+
},
|
|
251
|
+
},
|
|
252
|
+
".hs": {
|
|
253
|
+
"lang": "haskell",
|
|
254
|
+
"name_field": "name",
|
|
255
|
+
"nodes": {
|
|
256
|
+
"function_declaration": partial(_f("fun {name}"), style="green"),
|
|
257
|
+
"type_declaration": partial(_f("type {name}"), style="magenta"),
|
|
258
|
+
},
|
|
259
|
+
},
|
|
260
|
+
".jl": {
|
|
261
|
+
"lang": "julia",
|
|
262
|
+
"name_field": "name",
|
|
263
|
+
"nodes": {
|
|
264
|
+
"function_definition": partial(_f("function {name}()"), style="green"),
|
|
265
|
+
"abstract_type_definition": partial(_f("abstract {name}"), style="magenta"),
|
|
266
|
+
"struct_definition": partial(_f("struct {name}"), style="magenta"),
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
# ───────── scripting (shell / infra) ─────────────────────────────
|
|
270
|
+
".sh": {
|
|
271
|
+
"lang": "bash",
|
|
272
|
+
"name_field": "name",
|
|
273
|
+
"nodes": {"function_definition": partial(_f("fn {name}()"), style="green")},
|
|
274
|
+
},
|
|
275
|
+
".ps1": {
|
|
276
|
+
"lang": "powershell",
|
|
277
|
+
"name_field": "name",
|
|
278
|
+
"nodes": {
|
|
279
|
+
"function_definition": partial(_f("function {name}()"), style="green")
|
|
280
|
+
},
|
|
281
|
+
},
|
|
282
|
+
# ───────── web / data description (pure-function view) ───────────
|
|
283
|
+
".html": {
|
|
284
|
+
"lang": "html",
|
|
285
|
+
"name_field": "name", # rarely useful, but included for completeness
|
|
286
|
+
"nodes": {"element": partial(_f("<{name}>"), style="yellow")},
|
|
287
|
+
},
|
|
288
|
+
".css": {
|
|
289
|
+
"lang": "css",
|
|
290
|
+
"name_field": "name",
|
|
291
|
+
"nodes": {
|
|
292
|
+
"class_selector": partial(_f(".{name}"), style="yellow"),
|
|
293
|
+
"id_selector": partial(_f("#{name}"), style="yellow"),
|
|
294
|
+
},
|
|
295
|
+
},
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
# Cache parsers so we don’t re-create them file-after-file
|
|
299
|
+
_PARSER_CACHE = {}
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
def parser_for(lang_name):
|
|
303
|
+
if lang_name not in _PARSER_CACHE:
|
|
304
|
+
_PARSER_CACHE[lang_name] = get_parser(lang_name)
|
|
305
|
+
return _PARSER_CACHE[lang_name]
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
# ----------------------------------------------------------------------
|
|
309
|
+
# helper: breadth-first search for an identifier-ish node
|
|
310
|
+
# ----------------------------------------------------------------------
|
|
311
|
+
def _first_identifier(node):
|
|
312
|
+
from collections import deque
|
|
313
|
+
|
|
314
|
+
q = deque([node])
|
|
315
|
+
while q:
|
|
316
|
+
n = q.popleft()
|
|
317
|
+
if n.type in {"identifier", "property_identifier", "type_identifier"}:
|
|
318
|
+
return n
|
|
319
|
+
q.extend(n.children)
|
|
320
|
+
return None
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
def _span(node):
|
|
324
|
+
"""Return "[start:end]" lines (1‑based, inclusive)."""
|
|
325
|
+
start_line = node.start_point[0] + 1
|
|
326
|
+
end_line = node.end_point[0] + 1
|
|
327
|
+
return Text(f" [{start_line}:{end_line}]", style="bold white")
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
def _walk(ts_node, rich_parent, info):
|
|
331
|
+
nodes_cfg = info["nodes"]
|
|
332
|
+
name_field = info["name_field"]
|
|
333
|
+
|
|
334
|
+
for child in ts_node.children:
|
|
335
|
+
t = child.type
|
|
336
|
+
if t in nodes_cfg:
|
|
337
|
+
style = nodes_cfg[t].keywords["style"]
|
|
338
|
+
|
|
339
|
+
if name_field:
|
|
340
|
+
ident = child.child_by_field_name(name_field)
|
|
341
|
+
else:
|
|
342
|
+
ident = _first_identifier(child)
|
|
343
|
+
|
|
344
|
+
label_text = ident.text.decode() if ident else "<anon>"
|
|
345
|
+
label = nodes_cfg[t].func(label_text)
|
|
346
|
+
branch = rich_parent.add(Text(label, style=style) + _span(child))
|
|
347
|
+
_walk(child, branch, info)
|
|
348
|
+
else:
|
|
349
|
+
_walk(child, rich_parent, info)
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
def map_code_file(filepath):
|
|
353
|
+
ext = Path(filepath).suffix
|
|
354
|
+
info = LANGS.get(ext)
|
|
355
|
+
if not info:
|
|
356
|
+
return None
|
|
357
|
+
|
|
358
|
+
code = Path(filepath).read_bytes()
|
|
359
|
+
parser = parser_for(info["lang"])
|
|
360
|
+
tree = parser.parse(code)
|
|
361
|
+
|
|
362
|
+
root_label = Path(filepath).name
|
|
363
|
+
base = RichTree(Text(root_label, style="bold cyan"))
|
|
364
|
+
|
|
365
|
+
if tree.root_node.has_error:
|
|
366
|
+
base.add(Text("⚠️ syntax error", style="bold red"))
|
|
367
|
+
|
|
368
|
+
_walk(tree.root_node, base, info)
|
|
369
|
+
return base
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
def make_code_map(directory: str, ignore_tests: bool = True) -> str:
|
|
373
|
+
base_tree = RichTree(Text(Path(directory).name, style="bold magenta"))
|
|
374
|
+
|
|
375
|
+
for root, dirs, files in os.walk(directory):
|
|
376
|
+
dirs[:] = [d for d in dirs if not d.startswith(".")]
|
|
377
|
+
for f in files:
|
|
378
|
+
if (
|
|
379
|
+
should_ignore_path(os.path.join(root, f))
|
|
380
|
+
or ignore_tests
|
|
381
|
+
and "test" in f
|
|
382
|
+
):
|
|
383
|
+
continue
|
|
384
|
+
try:
|
|
385
|
+
file_tree = map_code_file(os.path.join(root, f))
|
|
386
|
+
if file_tree is not None:
|
|
387
|
+
base_tree.add(file_tree)
|
|
388
|
+
except Exception:
|
|
389
|
+
base_tree.add(Text(f"[error reading {f}]", style="bold red"))
|
|
390
|
+
|
|
391
|
+
buf = Console(record=True, width=120)
|
|
392
|
+
buf.print(base_tree)
|
|
393
|
+
return buf.export_text()
|
|
@@ -1,38 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"gemini-2.5-flash-preview-05-20": {
|
|
3
3
|
"type": "gemini",
|
|
4
|
-
"name": "gemini-2.5-flash-preview-05-20"
|
|
5
|
-
"max_requests_per_minute": 10,
|
|
6
|
-
"max_retries": 3,
|
|
7
|
-
"retry_base_delay": 10
|
|
4
|
+
"name": "gemini-2.5-flash-preview-05-20"
|
|
8
5
|
},
|
|
9
6
|
"gpt-4.1": {
|
|
10
7
|
"type": "openai",
|
|
11
|
-
"name": "gpt-4.1"
|
|
12
|
-
"max_requests_per_minute": 100,
|
|
13
|
-
"max_retries": 3,
|
|
14
|
-
"retry_base_delay": 10
|
|
8
|
+
"name": "gpt-4.1"
|
|
15
9
|
},
|
|
16
10
|
"gpt-4.1-mini": {
|
|
17
11
|
"type": "openai",
|
|
18
|
-
"name": "gpt-4.1-mini"
|
|
19
|
-
"max_requests_per_minute": 100,
|
|
20
|
-
"max_retries": 3,
|
|
21
|
-
"retry_base_delay": 10
|
|
12
|
+
"name": "gpt-4.1-mini"
|
|
22
13
|
},
|
|
23
14
|
"gpt-4.1-nano": {
|
|
24
15
|
"type": "openai",
|
|
25
|
-
"name": "gpt-4.1-nano"
|
|
26
|
-
"max_requests_per_minute": 100,
|
|
27
|
-
"max_retries": 3,
|
|
28
|
-
"retry_base_delay": 10
|
|
16
|
+
"name": "gpt-4.1-nano"
|
|
29
17
|
},
|
|
30
18
|
"gpt-4.1-custom": {
|
|
31
19
|
"type": "custom_openai",
|
|
32
20
|
"name": "gpt-4.1-custom",
|
|
33
|
-
"max_requests_per_minute": 100,
|
|
34
|
-
"max_retries": 3,
|
|
35
|
-
"retry_base_delay": 10,
|
|
36
21
|
"custom_endpoint": {
|
|
37
22
|
"url": "https://my.cute.endpoint:8080",
|
|
38
23
|
"headers": {
|
|
@@ -44,9 +29,6 @@
|
|
|
44
29
|
"ollama-llama3.3": {
|
|
45
30
|
"type": "custom_openai",
|
|
46
31
|
"name": "llama3.3",
|
|
47
|
-
"max_requests_per_minute": 100,
|
|
48
|
-
"max_retries": 3,
|
|
49
|
-
"retry_base_delay": 5,
|
|
50
32
|
"custom_endpoint": {
|
|
51
33
|
"url": "http://localhost:11434/v1"
|
|
52
34
|
}
|
|
@@ -54,9 +36,6 @@
|
|
|
54
36
|
"meta-llama/Llama-3.3-70B-Instruct-Turbo": {
|
|
55
37
|
"type": "custom_openai",
|
|
56
38
|
"name": "meta-llama/Llama-3.3-70B-Instruct-Turbo",
|
|
57
|
-
"max_requests_per_minute": 100,
|
|
58
|
-
"max_retries": 3,
|
|
59
|
-
"retry_base_delay": 5,
|
|
60
39
|
"custom_endpoint": {
|
|
61
40
|
"url": "https://api.together.xyz/v1",
|
|
62
41
|
"api_key": "$TOGETHER_API_KEY"
|
|
@@ -65,9 +44,6 @@
|
|
|
65
44
|
"grok-3-mini-fast": {
|
|
66
45
|
"type": "custom_openai",
|
|
67
46
|
"name": "grok-3-mini-fast",
|
|
68
|
-
"max_requests_per_minute": 100,
|
|
69
|
-
"max_retries": 3,
|
|
70
|
-
"retry_base_delay": 5,
|
|
71
47
|
"custom_endpoint": {
|
|
72
48
|
"url": "https://api.x.ai/v1",
|
|
73
49
|
"api_key": "$XAI_API_KEY"
|
|
@@ -76,9 +52,6 @@
|
|
|
76
52
|
"azure-gpt-4.1": {
|
|
77
53
|
"type": "azure_openai",
|
|
78
54
|
"name": "gpt-4.1",
|
|
79
|
-
"max_requests_per_minute": 100,
|
|
80
|
-
"max_retries": 3,
|
|
81
|
-
"retry_base_delay": 5,
|
|
82
55
|
"api_version": "2024-12-01-preview",
|
|
83
56
|
"api_key": "$AZURE_OPENAI_API_KEY",
|
|
84
57
|
"azure_endpoint": "$AZURE_OPENAI_ENDPOINT"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: code-puppy
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.61
|
|
4
4
|
Summary: Code generation agent
|
|
5
5
|
Author: Michael Pfaffenberger
|
|
6
6
|
License: MIT
|
|
@@ -27,6 +27,8 @@ Requires-Dist: python-dotenv>=1.0.0
|
|
|
27
27
|
Requires-Dist: rapidfuzz>=3.13.0
|
|
28
28
|
Requires-Dist: rich>=13.4.2
|
|
29
29
|
Requires-Dist: ruff>=0.11.11
|
|
30
|
+
Requires-Dist: tree-sitter-language-pack>=0.8.0
|
|
31
|
+
Requires-Dist: tree-sitter-typescript>=0.23.2
|
|
30
32
|
Description-Content-Type: text/markdown
|
|
31
33
|
|
|
32
34
|
# 🐶 Code Puppy 🐶
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
code_puppy/__init__.py,sha256=-ANvE6Xe5NlWDIRCIfL1x-rgtCZ6zM2Ye9NphFoULSY,82
|
|
2
|
+
code_puppy/agent.py,sha256=QRBid--LcJv8fbhS9u6Foavgt3jI1B-K_1Arv-kXQsc,3420
|
|
3
|
+
code_puppy/agent_prompts.py,sha256=DnPNubiFtD6Ot76cIsxedJEaEVYS5AaxR3JWJM5nXNg,6925
|
|
4
|
+
code_puppy/config.py,sha256=LTcZe5eHTT0zq-YJzSeNg8LCwhHb1HGN4tOkITtb7Eo,3941
|
|
5
|
+
code_puppy/main.py,sha256=qDbDB123MAv5r_kH91x1LxUROI9I28y2tvuYo2YxEbQ,10323
|
|
6
|
+
code_puppy/model_factory.py,sha256=jZH96zE5GMTK3RWjUpZB4HjbSO3fSaAzjRoQh8Y8lfg,7711
|
|
7
|
+
code_puppy/models.json,sha256=3tiU7_ra39CK8aOFRsVqG7veZDdzq8hAmI5BcfZEWck,1393
|
|
8
|
+
code_puppy/session_memory.py,sha256=4sgAAjbXdLSi8hETpd56tgtrG6hqMUuZWDlJOu6BQjA,2735
|
|
9
|
+
code_puppy/version_checker.py,sha256=aRGulzuY4C4CdFvU1rITduyL-1xTFsn4GiD1uSfOl_Y,396
|
|
10
|
+
code_puppy/command_line/__init__.py,sha256=y7WeRemfYppk8KVbCGeAIiTuiOszIURCDjOMZv_YRmU,45
|
|
11
|
+
code_puppy/command_line/file_path_completion.py,sha256=gw8NpIxa6GOpczUJRyh7VNZwoXKKn-yvCqit7h2y6Gg,2931
|
|
12
|
+
code_puppy/command_line/meta_command_handler.py,sha256=aKSPu_aB98TAuaFwyI4HmrFd45dk6mrhnvR-WvnQuQA,5713
|
|
13
|
+
code_puppy/command_line/model_picker_completion.py,sha256=NkyZZG7IhcVWSJ3ADytwCA5f8DpNeVs759Qtqs4fQtY,3733
|
|
14
|
+
code_puppy/command_line/prompt_toolkit_completion.py,sha256=_gP0FIOgHDNHTTWLNL0XNzr6sO0ISe7Mec1uQNo9kcM,8337
|
|
15
|
+
code_puppy/command_line/utils.py,sha256=7eyxDHjPjPB9wGDJQQcXV_zOsGdYsFgI0SGCetVmTqE,1251
|
|
16
|
+
code_puppy/tools/__init__.py,sha256=J_HCbkivdr1rP5vfucxttXhGmTBx0S2LNoDMrbaE-Fc,558
|
|
17
|
+
code_puppy/tools/command_runner.py,sha256=cEphrDyr12CoqpKizzaxhMHhG1HiVcqXArTkwc6lvxU,6760
|
|
18
|
+
code_puppy/tools/common.py,sha256=4AmPc_jx45nhJBS1TMhqF-i9pJZzmyOmYBcrqFAhSIE,2275
|
|
19
|
+
code_puppy/tools/file_modifications.py,sha256=nEHvdHJ1ige82gguf7-dybD0_e5AYFVARsYFgaTGLfY,13056
|
|
20
|
+
code_puppy/tools/file_operations.py,sha256=xqj7MiK6sGTaC8NMrMRTybWlXG32S-DjybqJtnufRcI,11715
|
|
21
|
+
code_puppy/tools/ts_code_map.py,sha256=0fSZQdNuikG6W43LQXn2oxim75MsXy0DfSfHt-saSZo,13523
|
|
22
|
+
code_puppy/tools/web_search.py,sha256=sA2ierjuuYA517-uhb5s53SgeVsyOe1nExoZsrU1Fps,1284
|
|
23
|
+
code_puppy-0.0.61.data/data/code_puppy/models.json,sha256=3tiU7_ra39CK8aOFRsVqG7veZDdzq8hAmI5BcfZEWck,1393
|
|
24
|
+
code_puppy-0.0.61.dist-info/METADATA,sha256=aZT117pFif0vTOEZjXSr77kfQ-ek7il-DC6mTvQgkAs,4878
|
|
25
|
+
code_puppy-0.0.61.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
26
|
+
code_puppy-0.0.61.dist-info/entry_points.txt,sha256=d8YkBvIUxF-dHNJAj-x4fPEqizbY5d_TwvYpc01U5kw,58
|
|
27
|
+
code_puppy-0.0.61.dist-info/licenses/LICENSE,sha256=31u8x0SPgdOq3izJX41kgFazWsM43zPEF9eskzqbJMY,1075
|
|
28
|
+
code_puppy-0.0.61.dist-info/RECORD,,
|
code_puppy/tools/code_map.py
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import ast
|
|
2
|
-
import os
|
|
3
|
-
|
|
4
|
-
import pathspec
|
|
5
|
-
from rich.text import Text
|
|
6
|
-
from rich.tree import Tree
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
def summarize_node(node: ast.AST) -> str:
|
|
10
|
-
if isinstance(node, ast.ClassDef):
|
|
11
|
-
return f"class {node.name}"
|
|
12
|
-
if isinstance(node, ast.FunctionDef):
|
|
13
|
-
return f"def {node.name}()"
|
|
14
|
-
return ""
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
def get_docstring(node: ast.AST) -> str:
|
|
18
|
-
doc = ast.get_docstring(node)
|
|
19
|
-
if doc:
|
|
20
|
-
lines = doc.strip().split("\n")
|
|
21
|
-
return lines[0] if lines else doc.strip()
|
|
22
|
-
return ""
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def map_python_file(file_path: str, show_doc: bool = True) -> Tree:
|
|
26
|
-
tree = Tree(Text(file_path, style="bold cyan"))
|
|
27
|
-
with open(file_path, "r", encoding="utf-8") as f:
|
|
28
|
-
root = ast.parse(f.read(), filename=file_path)
|
|
29
|
-
for node in root.body:
|
|
30
|
-
summary = summarize_node(node)
|
|
31
|
-
if summary:
|
|
32
|
-
t = Tree(summary)
|
|
33
|
-
if show_doc:
|
|
34
|
-
doc = get_docstring(node)
|
|
35
|
-
if doc:
|
|
36
|
-
t.add(Text(f'"{doc}"', style="dim"))
|
|
37
|
-
# Add inner functions
|
|
38
|
-
if hasattr(node, "body"):
|
|
39
|
-
for subnode in getattr(node, "body"):
|
|
40
|
-
subsum = summarize_node(subnode)
|
|
41
|
-
if subsum:
|
|
42
|
-
sub_t = Tree(subsum)
|
|
43
|
-
doc2 = get_docstring(subnode)
|
|
44
|
-
if doc2:
|
|
45
|
-
sub_t.add(Text(f'"{doc2}"', style="dim"))
|
|
46
|
-
t.add(sub_t)
|
|
47
|
-
tree.add(t)
|
|
48
|
-
return tree
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
def load_gitignore(directory: str):
|
|
52
|
-
gitignore_file = os.path.join(directory, ".gitignore")
|
|
53
|
-
if os.path.exists(gitignore_file):
|
|
54
|
-
with open(gitignore_file, "r") as f:
|
|
55
|
-
spec = pathspec.PathSpec.from_lines("gitwildmatch", f)
|
|
56
|
-
return spec
|
|
57
|
-
else:
|
|
58
|
-
return pathspec.PathSpec.from_lines("gitwildmatch", [])
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
def make_code_map(directory: str, show_doc: bool = True) -> Tree:
|
|
62
|
-
"""
|
|
63
|
-
Recursively build a Tree displaying the code structure of all .py files in a directory,
|
|
64
|
-
ignoring files listed in .gitignore if present.
|
|
65
|
-
"""
|
|
66
|
-
base_tree = Tree(Text(directory, style="bold magenta"))
|
|
67
|
-
|
|
68
|
-
spec = load_gitignore(directory)
|
|
69
|
-
abs_directory = os.path.abspath(directory)
|
|
70
|
-
|
|
71
|
-
for root, dirs, files in os.walk(directory):
|
|
72
|
-
rel_root = os.path.relpath(root, abs_directory)
|
|
73
|
-
# Remove ignored directories in-place for os.walk to not descend
|
|
74
|
-
dirs[:] = [
|
|
75
|
-
d
|
|
76
|
-
for d in dirs
|
|
77
|
-
if not spec.match_file(os.path.normpath(os.path.join(rel_root, d)))
|
|
78
|
-
]
|
|
79
|
-
for fname in files:
|
|
80
|
-
rel_file = os.path.normpath(os.path.join(rel_root, fname))
|
|
81
|
-
if fname.endswith(".py") and not fname.startswith("__"):
|
|
82
|
-
if not spec.match_file(rel_file):
|
|
83
|
-
fpath = os.path.join(root, fname)
|
|
84
|
-
try:
|
|
85
|
-
file_tree = map_python_file(fpath, show_doc=show_doc)
|
|
86
|
-
base_tree.add(file_tree)
|
|
87
|
-
except Exception as e:
|
|
88
|
-
err = Tree(
|
|
89
|
-
Text(f"[error reading {fname}: {e}]", style="bold red")
|
|
90
|
-
)
|
|
91
|
-
base_tree.add(err)
|
|
92
|
-
return base_tree
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
code_puppy/__init__.py,sha256=-ANvE6Xe5NlWDIRCIfL1x-rgtCZ6zM2Ye9NphFoULSY,82
|
|
2
|
-
code_puppy/agent.py,sha256=e3DBLW6dq30VuQdm5CVfLO81cU4ilyLJIz6rBj5U7pw,3239
|
|
3
|
-
code_puppy/agent_prompts.py,sha256=bT8m7UCFU56yYdMtnB9xeiPtMwU3WA63d265PclCzb4,6774
|
|
4
|
-
code_puppy/config.py,sha256=LTcZe5eHTT0zq-YJzSeNg8LCwhHb1HGN4tOkITtb7Eo,3941
|
|
5
|
-
code_puppy/main.py,sha256=qDbDB123MAv5r_kH91x1LxUROI9I28y2tvuYo2YxEbQ,10323
|
|
6
|
-
code_puppy/model_factory.py,sha256=tPS6lpfBRkTnHPPf_KpejMTtH02ZXiop2OSwaliyZ8g,11946
|
|
7
|
-
code_puppy/models.json,sha256=7H-y97YK9BXhag5wJU19rtg24JtZWYx60RsBLBW3WiI,2162
|
|
8
|
-
code_puppy/session_memory.py,sha256=4sgAAjbXdLSi8hETpd56tgtrG6hqMUuZWDlJOu6BQjA,2735
|
|
9
|
-
code_puppy/version_checker.py,sha256=aRGulzuY4C4CdFvU1rITduyL-1xTFsn4GiD1uSfOl_Y,396
|
|
10
|
-
code_puppy/command_line/__init__.py,sha256=y7WeRemfYppk8KVbCGeAIiTuiOszIURCDjOMZv_YRmU,45
|
|
11
|
-
code_puppy/command_line/file_path_completion.py,sha256=gw8NpIxa6GOpczUJRyh7VNZwoXKKn-yvCqit7h2y6Gg,2931
|
|
12
|
-
code_puppy/command_line/meta_command_handler.py,sha256=5jORzgSEmJBP8ixGIz8ET5Su9taPJZpQibe732LmOsg,5571
|
|
13
|
-
code_puppy/command_line/model_picker_completion.py,sha256=NkyZZG7IhcVWSJ3ADytwCA5f8DpNeVs759Qtqs4fQtY,3733
|
|
14
|
-
code_puppy/command_line/prompt_toolkit_completion.py,sha256=wxz8xCBge__EAxJRXYUCt9FoDpHog1QZ6RqpvoQP7O4,7904
|
|
15
|
-
code_puppy/command_line/utils.py,sha256=7eyxDHjPjPB9wGDJQQcXV_zOsGdYsFgI0SGCetVmTqE,1251
|
|
16
|
-
code_puppy/tools/__init__.py,sha256=J_HCbkivdr1rP5vfucxttXhGmTBx0S2LNoDMrbaE-Fc,558
|
|
17
|
-
code_puppy/tools/code_map.py,sha256=5vzKBUddY0z9kMfHZmLiewUMJofDOONJIaXCWVhbE5E,3201
|
|
18
|
-
code_puppy/tools/command_runner.py,sha256=6Ej2axH-b4ZGPLxOWg9kfW75qbftAecCFqWEtw3wEB8,6540
|
|
19
|
-
code_puppy/tools/common.py,sha256=WAwij4KZ3JVFr9PssLsmIAPE9rlDKg8XSEtdKjNMQF4,1307
|
|
20
|
-
code_puppy/tools/file_modifications.py,sha256=o7meMYjsQ70P1Lgc0XM0pFsh6Nn3XfJb7R5y-bwZp_M,13367
|
|
21
|
-
code_puppy/tools/file_operations.py,sha256=-mo07EB6Rp_eDEFWqdJblj1Unz6flAsSY2ZNIxYzBiM,11595
|
|
22
|
-
code_puppy/tools/web_search.py,sha256=sA2ierjuuYA517-uhb5s53SgeVsyOe1nExoZsrU1Fps,1284
|
|
23
|
-
code_puppy-0.0.59.data/data/code_puppy/models.json,sha256=7H-y97YK9BXhag5wJU19rtg24JtZWYx60RsBLBW3WiI,2162
|
|
24
|
-
code_puppy-0.0.59.dist-info/METADATA,sha256=s85j3wx1XwgNQJrliE5LzbUezX_T7NJcWWAKUA6ZJgg,4784
|
|
25
|
-
code_puppy-0.0.59.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
26
|
-
code_puppy-0.0.59.dist-info/entry_points.txt,sha256=d8YkBvIUxF-dHNJAj-x4fPEqizbY5d_TwvYpc01U5kw,58
|
|
27
|
-
code_puppy-0.0.59.dist-info/licenses/LICENSE,sha256=31u8x0SPgdOq3izJX41kgFazWsM43zPEF9eskzqbJMY,1075
|
|
28
|
-
code_puppy-0.0.59.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|