code-puppy 0.0.166__py3-none-any.whl → 0.0.167__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/http_utils.py +110 -7
- code_puppy/mcp/managed_server.py +2 -4
- code_puppy/mcp/server_registry_catalog.py +5 -6
- code_puppy/tools/command_runner.py +45 -10
- {code_puppy-0.0.166.dist-info → code_puppy-0.0.167.dist-info}/METADATA +2 -1
- {code_puppy-0.0.166.dist-info → code_puppy-0.0.167.dist-info}/RECORD +10 -10
- {code_puppy-0.0.166.data → code_puppy-0.0.167.data}/data/code_puppy/models.json +0 -0
- {code_puppy-0.0.166.dist-info → code_puppy-0.0.167.dist-info}/WHEEL +0 -0
- {code_puppy-0.0.166.dist-info → code_puppy-0.0.167.dist-info}/entry_points.txt +0 -0
- {code_puppy-0.0.166.dist-info → code_puppy-0.0.167.dist-info}/licenses/LICENSE +0 -0
code_puppy/http_utils.py
CHANGED
|
@@ -10,12 +10,34 @@ from typing import Dict, Optional, Union
|
|
|
10
10
|
|
|
11
11
|
import httpx
|
|
12
12
|
import requests
|
|
13
|
+
from tenacity import retry_if_exception_type, stop_after_attempt, wait_exponential
|
|
14
|
+
|
|
15
|
+
try:
|
|
16
|
+
from pydantic_ai.retries import (
|
|
17
|
+
AsyncTenacityTransport,
|
|
18
|
+
RetryConfig,
|
|
19
|
+
TenacityTransport,
|
|
20
|
+
wait_retry_after,
|
|
21
|
+
)
|
|
22
|
+
except ImportError:
|
|
23
|
+
# Fallback if pydantic_ai.retries is not available
|
|
24
|
+
AsyncTenacityTransport = None
|
|
25
|
+
RetryConfig = None
|
|
26
|
+
TenacityTransport = None
|
|
27
|
+
wait_retry_after = None
|
|
13
28
|
|
|
14
29
|
try:
|
|
15
30
|
from .reopenable_async_client import ReopenableAsyncClient
|
|
16
31
|
except ImportError:
|
|
17
32
|
ReopenableAsyncClient = None
|
|
18
33
|
|
|
34
|
+
try:
|
|
35
|
+
from .messaging import emit_info
|
|
36
|
+
except ImportError:
|
|
37
|
+
# Fallback if messaging system is not available
|
|
38
|
+
def emit_info(content: str, **metadata):
|
|
39
|
+
pass # No-op if messaging system is not available
|
|
40
|
+
|
|
19
41
|
|
|
20
42
|
def get_cert_bundle_path() -> str:
|
|
21
43
|
# First check if SSL_CERT_FILE environment variable is set
|
|
@@ -28,22 +50,72 @@ def create_client(
|
|
|
28
50
|
timeout: int = 180,
|
|
29
51
|
verify: Union[bool, str] = None,
|
|
30
52
|
headers: Optional[Dict[str, str]] = None,
|
|
53
|
+
retry_status_codes: tuple = (429, 502, 503, 504),
|
|
31
54
|
) -> httpx.Client:
|
|
32
55
|
if verify is None:
|
|
33
56
|
verify = get_cert_bundle_path()
|
|
34
57
|
|
|
35
|
-
|
|
58
|
+
# If retry components are available, create a client with retry transport
|
|
59
|
+
if TenacityTransport and RetryConfig and wait_retry_after:
|
|
60
|
+
def should_retry_status(response):
|
|
61
|
+
"""Raise exceptions for retryable HTTP status codes."""
|
|
62
|
+
if response.status_code in retry_status_codes:
|
|
63
|
+
emit_info(f"HTTP retry: Retrying request due to status code {response.status_code}")
|
|
64
|
+
response.raise_for_status()
|
|
65
|
+
|
|
66
|
+
transport = TenacityTransport(
|
|
67
|
+
config=RetryConfig(
|
|
68
|
+
retry=lambda e: isinstance(e, httpx.HTTPStatusError) and e.response.status_code in retry_status_codes,
|
|
69
|
+
wait=wait_retry_after(
|
|
70
|
+
fallback_strategy=wait_exponential(multiplier=1, max=60),
|
|
71
|
+
max_wait=300
|
|
72
|
+
),
|
|
73
|
+
stop=stop_after_attempt(5),
|
|
74
|
+
reraise=True
|
|
75
|
+
),
|
|
76
|
+
validate_response=should_retry_status
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
return httpx.Client(transport=transport, verify=verify, headers=headers or {}, timeout=timeout)
|
|
80
|
+
else:
|
|
81
|
+
# Fallback to regular client if retry components are not available
|
|
82
|
+
return httpx.Client(verify=verify, headers=headers or {}, timeout=timeout)
|
|
36
83
|
|
|
37
84
|
|
|
38
85
|
def create_async_client(
|
|
39
86
|
timeout: int = 180,
|
|
40
87
|
verify: Union[bool, str] = None,
|
|
41
88
|
headers: Optional[Dict[str, str]] = None,
|
|
89
|
+
retry_status_codes: tuple = (429, 502, 503, 504),
|
|
42
90
|
) -> httpx.AsyncClient:
|
|
43
91
|
if verify is None:
|
|
44
92
|
verify = get_cert_bundle_path()
|
|
45
93
|
|
|
46
|
-
|
|
94
|
+
# If retry components are available, create a client with retry transport
|
|
95
|
+
if AsyncTenacityTransport and RetryConfig and wait_retry_after:
|
|
96
|
+
def should_retry_status(response):
|
|
97
|
+
"""Raise exceptions for retryable HTTP status codes."""
|
|
98
|
+
if response.status_code in retry_status_codes:
|
|
99
|
+
emit_info(f"HTTP retry: Retrying request due to status code {response.status_code}")
|
|
100
|
+
response.raise_for_status()
|
|
101
|
+
|
|
102
|
+
transport = AsyncTenacityTransport(
|
|
103
|
+
config=RetryConfig(
|
|
104
|
+
retry=lambda e: isinstance(e, httpx.HTTPStatusError) and e.response.status_code in retry_status_codes,
|
|
105
|
+
wait=wait_retry_after(
|
|
106
|
+
fallback_strategy=wait_exponential(multiplier=1, max=60),
|
|
107
|
+
max_wait=300
|
|
108
|
+
),
|
|
109
|
+
stop=stop_after_attempt(5),
|
|
110
|
+
reraise=True
|
|
111
|
+
),
|
|
112
|
+
validate_response=should_retry_status
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
return httpx.AsyncClient(transport=transport, verify=verify, headers=headers or {}, timeout=timeout)
|
|
116
|
+
else:
|
|
117
|
+
# Fallback to regular client if retry components are not available
|
|
118
|
+
return httpx.AsyncClient(verify=verify, headers=headers or {}, timeout=timeout)
|
|
47
119
|
|
|
48
120
|
|
|
49
121
|
def create_requests_session(
|
|
@@ -90,17 +162,48 @@ def create_reopenable_async_client(
|
|
|
90
162
|
timeout: int = 180,
|
|
91
163
|
verify: Union[bool, str] = None,
|
|
92
164
|
headers: Optional[Dict[str, str]] = None,
|
|
165
|
+
retry_status_codes: tuple = (429, 502, 503, 504),
|
|
93
166
|
) -> Union[ReopenableAsyncClient, httpx.AsyncClient]:
|
|
94
167
|
if verify is None:
|
|
95
168
|
verify = get_cert_bundle_path()
|
|
96
169
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
170
|
+
# If retry components are available, create a client with retry transport
|
|
171
|
+
if AsyncTenacityTransport and RetryConfig and wait_retry_after:
|
|
172
|
+
def should_retry_status(response):
|
|
173
|
+
"""Raise exceptions for retryable HTTP status codes."""
|
|
174
|
+
if response.status_code in retry_status_codes:
|
|
175
|
+
emit_info(f"HTTP retry: Retrying request due to status code {response.status_code}")
|
|
176
|
+
response.raise_for_status()
|
|
177
|
+
|
|
178
|
+
transport = AsyncTenacityTransport(
|
|
179
|
+
config=RetryConfig(
|
|
180
|
+
retry=lambda e: isinstance(e, httpx.HTTPStatusError) and e.response.status_code in retry_status_codes,
|
|
181
|
+
wait=wait_retry_after(
|
|
182
|
+
fallback_strategy=wait_exponential(multiplier=1, max=60),
|
|
183
|
+
max_wait=300
|
|
184
|
+
),
|
|
185
|
+
stop=stop_after_attempt(5),
|
|
186
|
+
reraise=True
|
|
187
|
+
),
|
|
188
|
+
validate_response=should_retry_status
|
|
100
189
|
)
|
|
190
|
+
|
|
191
|
+
if ReopenableAsyncClient is not None:
|
|
192
|
+
return ReopenableAsyncClient(
|
|
193
|
+
transport=transport, verify=verify, headers=headers or {}, timeout=timeout
|
|
194
|
+
)
|
|
195
|
+
else:
|
|
196
|
+
# Fallback to regular AsyncClient if ReopenableAsyncClient is not available
|
|
197
|
+
return httpx.AsyncClient(transport=transport, verify=verify, headers=headers or {}, timeout=timeout)
|
|
101
198
|
else:
|
|
102
|
-
# Fallback to regular
|
|
103
|
-
|
|
199
|
+
# Fallback to regular clients if retry components are not available
|
|
200
|
+
if ReopenableAsyncClient is not None:
|
|
201
|
+
return ReopenableAsyncClient(
|
|
202
|
+
verify=verify, headers=headers or {}, timeout=timeout
|
|
203
|
+
)
|
|
204
|
+
else:
|
|
205
|
+
# Fallback to regular AsyncClient if ReopenableAsyncClient is not available
|
|
206
|
+
return httpx.AsyncClient(verify=verify, headers=headers or {}, timeout=timeout)
|
|
104
207
|
|
|
105
208
|
|
|
106
209
|
def is_cert_bundle_available() -> bool:
|
code_puppy/mcp/managed_server.py
CHANGED
|
@@ -226,11 +226,9 @@ class ManagedMCPServer:
|
|
|
226
226
|
http_kwargs["timeout"] = config["timeout"]
|
|
227
227
|
if "read_timeout" in config:
|
|
228
228
|
http_kwargs["read_timeout"] = config["read_timeout"]
|
|
229
|
-
if "
|
|
230
|
-
http_kwargs["
|
|
231
|
-
elif config.get("headers"):
|
|
229
|
+
if "headers" in config:
|
|
230
|
+
http_kwargs["headers"] = config.get("headers")
|
|
232
231
|
# Create HTTP client if headers are provided but no client specified
|
|
233
|
-
http_kwargs["http_client"] = self._get_http_client()
|
|
234
232
|
|
|
235
233
|
self._pydantic_server = MCPServerStreamableHTTP(
|
|
236
234
|
**http_kwargs, process_tool_call=process_tool_call
|
|
@@ -791,18 +791,17 @@ MCP_SERVER_REGISTRY: List[MCPServerTemplate] = [
|
|
|
791
791
|
description="Search and retrieve documentation from multiple sources with AI-powered context understanding",
|
|
792
792
|
category="Documentation",
|
|
793
793
|
tags=["documentation", "search", "context", "ai", "knowledge", "docs", "cloud"],
|
|
794
|
-
type="
|
|
794
|
+
type="http",
|
|
795
795
|
config={
|
|
796
|
-
"
|
|
797
|
-
|
|
798
|
-
|
|
796
|
+
"url": "https://mcp.context7.com/mcp",
|
|
797
|
+
"headers": {
|
|
798
|
+
"Authorization": "Bearer $CONTEXT7_API_KEY"
|
|
799
|
+
}
|
|
799
800
|
},
|
|
800
801
|
verified=True,
|
|
801
802
|
popular=True,
|
|
802
803
|
requires=MCPServerRequirements(
|
|
803
804
|
environment_vars=["CONTEXT7_API_KEY"],
|
|
804
|
-
required_tools=["node", "npx"],
|
|
805
|
-
package_dependencies=["@upstash/context7-mcp"],
|
|
806
805
|
),
|
|
807
806
|
example_usage="Cloud-based service - no local setup required",
|
|
808
807
|
),
|
|
@@ -22,6 +22,17 @@ from code_puppy.messaging import (
|
|
|
22
22
|
from code_puppy.state_management import is_tui_mode
|
|
23
23
|
from code_puppy.tools.common import generate_group_id
|
|
24
24
|
|
|
25
|
+
# Maximum line length for shell command output to prevent massive token usage
|
|
26
|
+
# This helps avoid exceeding model context limits when commands produce very long lines
|
|
27
|
+
MAX_LINE_LENGTH = 256
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _truncate_line(line: str) -> str:
|
|
31
|
+
"""Truncate a line to MAX_LINE_LENGTH if it exceeds the limit."""
|
|
32
|
+
if len(line) > MAX_LINE_LENGTH:
|
|
33
|
+
return line[:MAX_LINE_LENGTH] + "... [truncated]"
|
|
34
|
+
return line
|
|
35
|
+
|
|
25
36
|
_AWAITING_USER_INPUT = False
|
|
26
37
|
|
|
27
38
|
_CONFIRMATION_LOCK = threading.Lock()
|
|
@@ -188,6 +199,8 @@ def run_shell_command_streaming(
|
|
|
188
199
|
for line in iter(process.stdout.readline, ""):
|
|
189
200
|
if line:
|
|
190
201
|
line = line.rstrip("\n\r")
|
|
202
|
+
# Limit line length to prevent massive token usage
|
|
203
|
+
line = _truncate_line(line)
|
|
191
204
|
stdout_lines.append(line)
|
|
192
205
|
emit_system_message(line, message_group=group_id)
|
|
193
206
|
last_output_time[0] = time.time()
|
|
@@ -199,6 +212,8 @@ def run_shell_command_streaming(
|
|
|
199
212
|
for line in iter(process.stderr.readline, ""):
|
|
200
213
|
if line:
|
|
201
214
|
line = line.rstrip("\n\r")
|
|
215
|
+
# Limit line length to prevent massive token usage
|
|
216
|
+
line = _truncate_line(line)
|
|
202
217
|
stderr_lines.append(line)
|
|
203
218
|
emit_system_message(line, message_group=group_id)
|
|
204
219
|
last_output_time[0] = time.time()
|
|
@@ -252,8 +267,8 @@ def run_shell_command_streaming(
|
|
|
252
267
|
**{
|
|
253
268
|
"success": False,
|
|
254
269
|
"command": command,
|
|
255
|
-
"stdout": "\n".join(stdout_lines[-
|
|
256
|
-
"stderr": "\n".join(stderr_lines[-
|
|
270
|
+
"stdout": "\n".join(stdout_lines[-256:]),
|
|
271
|
+
"stderr": "\n".join(stderr_lines[-256:]),
|
|
257
272
|
"exit_code": -9,
|
|
258
273
|
"execution_time": execution_time,
|
|
259
274
|
"timeout": True,
|
|
@@ -315,23 +330,31 @@ def run_shell_command_streaming(
|
|
|
315
330
|
)
|
|
316
331
|
emit_info(f"Took {execution_time:.2f}s", message_group=group_id)
|
|
317
332
|
time.sleep(1)
|
|
333
|
+
# Apply line length limits to stdout/stderr before returning
|
|
334
|
+
truncated_stdout = [_truncate_line(line) for line in stdout_lines[-256:]]
|
|
335
|
+
truncated_stderr = [_truncate_line(line) for line in stderr_lines[-256:]]
|
|
336
|
+
|
|
318
337
|
return ShellCommandOutput(
|
|
319
338
|
success=False,
|
|
320
339
|
command=command,
|
|
321
340
|
error="""The process didn't exit cleanly! If the user_interrupted flag is true,
|
|
322
341
|
please stop all execution and ask the user for clarification!""",
|
|
323
|
-
stdout="\n".join(
|
|
324
|
-
stderr="\n".join(
|
|
342
|
+
stdout="\n".join(truncated_stdout),
|
|
343
|
+
stderr="\n".join(truncated_stderr),
|
|
325
344
|
exit_code=exit_code,
|
|
326
345
|
execution_time=execution_time,
|
|
327
346
|
timeout=False,
|
|
328
347
|
user_interrupted=process.pid in _USER_KILLED_PROCESSES,
|
|
329
348
|
)
|
|
349
|
+
# Apply line length limits to stdout/stderr before returning
|
|
350
|
+
truncated_stdout = [_truncate_line(line) for line in stdout_lines[-256:]]
|
|
351
|
+
truncated_stderr = [_truncate_line(line) for line in stderr_lines[-256:]]
|
|
352
|
+
|
|
330
353
|
return ShellCommandOutput(
|
|
331
354
|
success=exit_code == 0,
|
|
332
355
|
command=command,
|
|
333
|
-
stdout="\n".join(
|
|
334
|
-
stderr="\n".join(
|
|
356
|
+
stdout="\n".join(truncated_stdout),
|
|
357
|
+
stderr="\n".join(truncated_stderr),
|
|
335
358
|
exit_code=exit_code,
|
|
336
359
|
execution_time=execution_time,
|
|
337
360
|
timeout=False,
|
|
@@ -453,12 +476,24 @@ def run_shell_command(
|
|
|
453
476
|
stdout = None
|
|
454
477
|
if "stderr" not in locals():
|
|
455
478
|
stderr = None
|
|
479
|
+
|
|
480
|
+
# Apply line length limits to stdout/stderr if they exist
|
|
481
|
+
truncated_stdout = None
|
|
482
|
+
if stdout:
|
|
483
|
+
stdout_lines = stdout.split("\n")
|
|
484
|
+
truncated_stdout = "\n".join([_truncate_line(line) for line in stdout_lines[-256:]])
|
|
485
|
+
|
|
486
|
+
truncated_stderr = None
|
|
487
|
+
if stderr:
|
|
488
|
+
stderr_lines = stderr.split("\n")
|
|
489
|
+
truncated_stderr = "\n".join([_truncate_line(line) for line in stderr_lines[-256:]])
|
|
490
|
+
|
|
456
491
|
return ShellCommandOutput(
|
|
457
492
|
success=False,
|
|
458
493
|
command=command,
|
|
459
494
|
error=f"Error executing command {str(e)}",
|
|
460
|
-
stdout=
|
|
461
|
-
stderr=
|
|
495
|
+
stdout=truncated_stdout,
|
|
496
|
+
stderr=truncated_stderr,
|
|
462
497
|
exit_code=-1,
|
|
463
498
|
timeout=False,
|
|
464
499
|
)
|
|
@@ -520,8 +555,8 @@ def register_agent_run_shell_command(agent):
|
|
|
520
555
|
- success (bool): True if command executed successfully (exit code 0)
|
|
521
556
|
- command (str | None): The executed command string
|
|
522
557
|
- error (str | None): Error message if execution failed
|
|
523
|
-
- stdout (str | None): Standard output from the command (last
|
|
524
|
-
- stderr (str | None): Standard error from the command (last
|
|
558
|
+
- stdout (str | None): Standard output from the command (last 256 lines)
|
|
559
|
+
- stderr (str | None): Standard error from the command (last 256 lines)
|
|
525
560
|
- exit_code (int | None): Process exit code
|
|
526
561
|
- execution_time (float | None): Total execution time in seconds
|
|
527
562
|
- timeout (bool | None): True if command was terminated due to timeout
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: code-puppy
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.167
|
|
4
4
|
Summary: Code generation agent
|
|
5
5
|
Project-URL: repository, https://github.com/mpfaffenberger/code_puppy
|
|
6
6
|
Project-URL: HomePage, https://github.com/mpfaffenberger/code_puppy
|
|
@@ -33,6 +33,7 @@ Requires-Dist: rapidfuzz>=3.13.0
|
|
|
33
33
|
Requires-Dist: rich>=13.4.2
|
|
34
34
|
Requires-Dist: ripgrep>=14.1.0
|
|
35
35
|
Requires-Dist: ruff>=0.11.11
|
|
36
|
+
Requires-Dist: tenacity>=8.2.0
|
|
36
37
|
Requires-Dist: termcolor>=3.1.0
|
|
37
38
|
Requires-Dist: textual-dev>=1.7.0
|
|
38
39
|
Requires-Dist: textual>=5.0.0
|
|
@@ -3,7 +3,7 @@ code_puppy/__main__.py,sha256=pDVssJOWP8A83iFkxMLY9YteHYat0EyWDQqMkKHpWp4,203
|
|
|
3
3
|
code_puppy/agent.py,sha256=wCARhq7PcD38c4l83fuXm4Us_6c1TXVa0U7TnBnNPEY,8064
|
|
4
4
|
code_puppy/callbacks.py,sha256=6wYB6K_fGSCkKKEFaYOYkJT45WaV5W_NhUIzcvVH_nU,5060
|
|
5
5
|
code_puppy/config.py,sha256=J8XU0iOPtfzrkDD49b4TdrdHoQmW2kaP-25PPbGGdKU,16386
|
|
6
|
-
code_puppy/http_utils.py,sha256=
|
|
6
|
+
code_puppy/http_utils.py,sha256=JecBdukr9dr1xcjw-Zyx2iD65RDEd183r8e1NMU4HLo,8093
|
|
7
7
|
code_puppy/main.py,sha256=tYLfhUjPTJ-4S1r-pr-jSbn6kIU1iYvt2Z8lxI7zDFY,22220
|
|
8
8
|
code_puppy/message_history_processor.py,sha256=zzeOSUC1Wpsry-z2MD6pQWk2wt1axGSOKaGR2v22_qQ,18825
|
|
9
9
|
code_puppy/model_factory.py,sha256=z9vQbcGllgMwU0On8rPvzYxkygW2Uyd3NJmRzbKv-is,13759
|
|
@@ -59,11 +59,11 @@ code_puppy/mcp/config_wizard.py,sha256=SIsm8uhDInfRYy_2W8wPIZcmoxk24680ikhMT93Vu
|
|
|
59
59
|
code_puppy/mcp/dashboard.py,sha256=y6t6trrBZU-mr8W1_29VN5DeZI8VYvOsKNz1EXxlvUg,9022
|
|
60
60
|
code_puppy/mcp/error_isolation.py,sha256=mpPBiH17zTXPsOEAn9WmkbwQwnt4gmgiaWv87JBJbUo,12426
|
|
61
61
|
code_puppy/mcp/health_monitor.py,sha256=n5R6EeYOYbUucUFe74qGWCU3g6Mep5UEQbLF0wbT0dU,19688
|
|
62
|
-
code_puppy/mcp/managed_server.py,sha256=
|
|
62
|
+
code_puppy/mcp/managed_server.py,sha256=EZwWsQGxzgnjL6TGJTm58Pj6fw7kkYpLuolYQY-GbXY,14256
|
|
63
63
|
code_puppy/mcp/manager.py,sha256=Yx9zxukdXgdPDgeJiiQPYlPae0zQPofHWB-axuoMNc8,26426
|
|
64
64
|
code_puppy/mcp/registry.py,sha256=IvbIL-pETQ7HS7iRgsoT5j7eY8TOJXqYczSiigT2ofU,15752
|
|
65
65
|
code_puppy/mcp/retry_manager.py,sha256=evVxbtrsHNyo8UoI7zpO-NVDegibn82RLlgN8VKewA8,10665
|
|
66
|
-
code_puppy/mcp/server_registry_catalog.py,sha256=
|
|
66
|
+
code_puppy/mcp/server_registry_catalog.py,sha256=U0HJMgEeF8Ntq3ZWepA0Z9t8ZG82Toa9JCGBjiDAzh8,38760
|
|
67
67
|
code_puppy/mcp/status_tracker.py,sha256=uekxrzkzIWrv3OfSVgblaPuoGFcAh_dBYwCcaHZ_CrM,12183
|
|
68
68
|
code_puppy/mcp/system_tools.py,sha256=7_oR8k0c8YjtCcYF9g7A946oAGuKOf_i-92aJH7VmlQ,7331
|
|
69
69
|
code_puppy/mcp/examples/retry_example.py,sha256=En3LiqECYmG00gWaa7K9L9vvGk1VJyYtKWcv3p3gzCc,7220
|
|
@@ -78,7 +78,7 @@ code_puppy/messaging/spinner/textual_spinner.py,sha256=Omx9A-FSPkxYDMYgBXgYMBQnK
|
|
|
78
78
|
code_puppy/plugins/__init__.py,sha256=fksDqMUiXPJ5WNuMsYsVR8ulueQRCXPlvECEyicHPtQ,1312
|
|
79
79
|
code_puppy/tools/__init__.py,sha256=YiiXRqxU1BEJ5t0Oe163lSqOneI9sKtwDW0swCPgBt4,2119
|
|
80
80
|
code_puppy/tools/agent_tools.py,sha256=bHMrFIbYRhuubR41G_XdLsk3cUKWfIPl2O4bVzo2pE0,5591
|
|
81
|
-
code_puppy/tools/command_runner.py,sha256=
|
|
81
|
+
code_puppy/tools/command_runner.py,sha256=TeKbUY1BeHpUEYtBbmEXnYd4ESI-RGNXRlI-7I1UNHU,22427
|
|
82
82
|
code_puppy/tools/common.py,sha256=pL-9xcRs3rxU7Fl9X9EUgbDp2-csh2LLJ5DHH_KAHKY,10596
|
|
83
83
|
code_puppy/tools/file_modifications.py,sha256=EaDWcv6gi8wAvpgyeJdKSKPWg9fTpZoEkxQiLCE6rn4,23218
|
|
84
84
|
code_puppy/tools/file_operations.py,sha256=dEnsGCbDF12ctegCm9Kiu-mgNCrvopf64ij_CQbikW4,32460
|
|
@@ -104,9 +104,9 @@ code_puppy/tui/screens/help.py,sha256=eJuPaOOCp7ZSUlecearqsuX6caxWv7NQszUh0tZJjB
|
|
|
104
104
|
code_puppy/tui/screens/mcp_install_wizard.py,sha256=xqwN5omltMkfxWZwXj3D2PbXbtrxUi1dT0XT77oxOKk,27685
|
|
105
105
|
code_puppy/tui/screens/settings.py,sha256=GMpv-qa08rorAE9mj3AjmqjZFPhmeJ_GWd-DBHG6iAA,10671
|
|
106
106
|
code_puppy/tui/screens/tools.py,sha256=3pr2Xkpa9Js6Yhf1A3_wQVRzFOui-KDB82LwrsdBtyk,1715
|
|
107
|
-
code_puppy-0.0.
|
|
108
|
-
code_puppy-0.0.
|
|
109
|
-
code_puppy-0.0.
|
|
110
|
-
code_puppy-0.0.
|
|
111
|
-
code_puppy-0.0.
|
|
112
|
-
code_puppy-0.0.
|
|
107
|
+
code_puppy-0.0.167.data/data/code_puppy/models.json,sha256=iXmLZGflnQcu2DRh4WUlgAhoXdvoxUc7KBhB8YxawXM,3088
|
|
108
|
+
code_puppy-0.0.167.dist-info/METADATA,sha256=kmno03NP1H0J8qL2UAKHSq200Bsv1XkwCk9GqfwsrXg,19598
|
|
109
|
+
code_puppy-0.0.167.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
110
|
+
code_puppy-0.0.167.dist-info/entry_points.txt,sha256=d8YkBvIUxF-dHNJAj-x4fPEqizbY5d_TwvYpc01U5kw,58
|
|
111
|
+
code_puppy-0.0.167.dist-info/licenses/LICENSE,sha256=31u8x0SPgdOq3izJX41kgFazWsM43zPEF9eskzqbJMY,1075
|
|
112
|
+
code_puppy-0.0.167.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|