pdd-cli 0.0.42__py3-none-any.whl → 0.0.90__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.
- pdd/__init__.py +4 -4
- pdd/agentic_common.py +863 -0
- pdd/agentic_crash.py +534 -0
- pdd/agentic_fix.py +1179 -0
- pdd/agentic_langtest.py +162 -0
- pdd/agentic_update.py +370 -0
- pdd/agentic_verify.py +183 -0
- pdd/auto_deps_main.py +15 -5
- pdd/auto_include.py +63 -5
- pdd/bug_main.py +3 -2
- pdd/bug_to_unit_test.py +2 -0
- pdd/change_main.py +11 -4
- pdd/cli.py +22 -1181
- pdd/cmd_test_main.py +80 -19
- pdd/code_generator.py +58 -18
- pdd/code_generator_main.py +672 -25
- pdd/commands/__init__.py +42 -0
- pdd/commands/analysis.py +248 -0
- pdd/commands/fix.py +140 -0
- pdd/commands/generate.py +257 -0
- pdd/commands/maintenance.py +174 -0
- pdd/commands/misc.py +79 -0
- pdd/commands/modify.py +230 -0
- pdd/commands/report.py +144 -0
- pdd/commands/templates.py +215 -0
- pdd/commands/utility.py +110 -0
- pdd/config_resolution.py +58 -0
- pdd/conflicts_main.py +8 -3
- pdd/construct_paths.py +281 -81
- pdd/context_generator.py +10 -2
- pdd/context_generator_main.py +113 -11
- pdd/continue_generation.py +47 -7
- pdd/core/__init__.py +0 -0
- pdd/core/cli.py +503 -0
- pdd/core/dump.py +554 -0
- pdd/core/errors.py +63 -0
- pdd/core/utils.py +90 -0
- pdd/crash_main.py +44 -11
- pdd/data/language_format.csv +71 -62
- pdd/data/llm_model.csv +20 -18
- pdd/detect_change_main.py +5 -4
- pdd/fix_code_loop.py +331 -77
- pdd/fix_error_loop.py +209 -60
- pdd/fix_errors_from_unit_tests.py +4 -3
- pdd/fix_main.py +75 -18
- pdd/fix_verification_errors.py +12 -100
- pdd/fix_verification_errors_loop.py +319 -272
- pdd/fix_verification_main.py +57 -17
- pdd/generate_output_paths.py +93 -10
- pdd/generate_test.py +16 -5
- pdd/get_jwt_token.py +48 -9
- pdd/get_run_command.py +73 -0
- pdd/get_test_command.py +68 -0
- pdd/git_update.py +70 -19
- pdd/increase_tests.py +7 -0
- pdd/incremental_code_generator.py +2 -2
- pdd/insert_includes.py +11 -3
- pdd/llm_invoke.py +1278 -110
- pdd/load_prompt_template.py +36 -10
- pdd/pdd_completion.fish +25 -2
- pdd/pdd_completion.sh +30 -4
- pdd/pdd_completion.zsh +79 -4
- pdd/postprocess.py +10 -3
- pdd/preprocess.py +228 -15
- pdd/preprocess_main.py +8 -5
- pdd/prompts/agentic_crash_explore_LLM.prompt +49 -0
- pdd/prompts/agentic_fix_explore_LLM.prompt +45 -0
- pdd/prompts/agentic_fix_harvest_only_LLM.prompt +48 -0
- pdd/prompts/agentic_fix_primary_LLM.prompt +85 -0
- pdd/prompts/agentic_update_LLM.prompt +1071 -0
- pdd/prompts/agentic_verify_explore_LLM.prompt +45 -0
- pdd/prompts/auto_include_LLM.prompt +98 -101
- pdd/prompts/change_LLM.prompt +1 -3
- pdd/prompts/detect_change_LLM.prompt +562 -3
- pdd/prompts/example_generator_LLM.prompt +22 -1
- pdd/prompts/extract_code_LLM.prompt +5 -1
- pdd/prompts/extract_program_code_fix_LLM.prompt +14 -2
- pdd/prompts/extract_prompt_update_LLM.prompt +7 -8
- pdd/prompts/extract_promptline_LLM.prompt +17 -11
- pdd/prompts/find_verification_errors_LLM.prompt +6 -0
- pdd/prompts/fix_code_module_errors_LLM.prompt +16 -4
- pdd/prompts/fix_errors_from_unit_tests_LLM.prompt +6 -41
- pdd/prompts/fix_verification_errors_LLM.prompt +22 -0
- pdd/prompts/generate_test_LLM.prompt +21 -6
- pdd/prompts/increase_tests_LLM.prompt +1 -2
- pdd/prompts/insert_includes_LLM.prompt +1181 -6
- pdd/prompts/split_LLM.prompt +1 -62
- pdd/prompts/trace_LLM.prompt +25 -22
- pdd/prompts/unfinished_prompt_LLM.prompt +85 -1
- pdd/prompts/update_prompt_LLM.prompt +22 -1
- pdd/prompts/xml_convertor_LLM.prompt +3246 -7
- pdd/pytest_output.py +188 -21
- pdd/python_env_detector.py +151 -0
- pdd/render_mermaid.py +236 -0
- pdd/setup_tool.py +648 -0
- pdd/simple_math.py +2 -0
- pdd/split_main.py +3 -2
- pdd/summarize_directory.py +56 -7
- pdd/sync_determine_operation.py +918 -186
- pdd/sync_main.py +82 -32
- pdd/sync_orchestration.py +1456 -453
- pdd/sync_tui.py +848 -0
- pdd/template_registry.py +264 -0
- pdd/templates/architecture/architecture_json.prompt +242 -0
- pdd/templates/generic/generate_prompt.prompt +174 -0
- pdd/trace.py +168 -12
- pdd/trace_main.py +4 -3
- pdd/track_cost.py +151 -61
- pdd/unfinished_prompt.py +49 -3
- pdd/update_main.py +549 -67
- pdd/update_model_costs.py +2 -2
- pdd/update_prompt.py +19 -4
- {pdd_cli-0.0.42.dist-info → pdd_cli-0.0.90.dist-info}/METADATA +20 -7
- pdd_cli-0.0.90.dist-info/RECORD +153 -0
- {pdd_cli-0.0.42.dist-info → pdd_cli-0.0.90.dist-info}/licenses/LICENSE +1 -1
- pdd_cli-0.0.42.dist-info/RECORD +0 -115
- {pdd_cli-0.0.42.dist-info → pdd_cli-0.0.90.dist-info}/WHEEL +0 -0
- {pdd_cli-0.0.42.dist-info → pdd_cli-0.0.90.dist-info}/entry_points.txt +0 -0
- {pdd_cli-0.0.42.dist-info → pdd_cli-0.0.90.dist-info}/top_level.txt +0 -0
pdd/git_update.py
CHANGED
|
@@ -4,6 +4,8 @@ from rich import print
|
|
|
4
4
|
from rich.console import Console
|
|
5
5
|
from rich.panel import Panel
|
|
6
6
|
from .update_prompt import update_prompt
|
|
7
|
+
from .agentic_common import get_available_agents
|
|
8
|
+
from .agentic_update import run_agentic_update
|
|
7
9
|
import git
|
|
8
10
|
from . import DEFAULT_TIME
|
|
9
11
|
console = Console()
|
|
@@ -14,21 +16,33 @@ def git_update(
|
|
|
14
16
|
strength: float,
|
|
15
17
|
temperature: float,
|
|
16
18
|
verbose: bool = False,
|
|
17
|
-
time: float = DEFAULT_TIME
|
|
19
|
+
time: float = DEFAULT_TIME,
|
|
20
|
+
simple: bool = False,
|
|
21
|
+
quiet: bool = False,
|
|
22
|
+
prompt_file: Optional[str] = None
|
|
18
23
|
) -> Tuple[Optional[str], float, str]:
|
|
19
24
|
"""
|
|
20
|
-
Read in modified code, restore the prior checked-in version from
|
|
21
|
-
update the prompt, write back the modified code,
|
|
25
|
+
Read in modified code, restore the prior checked-in version from Git,
|
|
26
|
+
update the prompt (via agentic or legacy path), write back the modified code,
|
|
27
|
+
and return outputs.
|
|
22
28
|
|
|
23
29
|
Args:
|
|
24
|
-
input_prompt (str): The prompt
|
|
30
|
+
input_prompt (str): The prompt TEXT content (not a file path).
|
|
25
31
|
modified_code_file (str): Filepath of the modified code.
|
|
26
32
|
strength (float): Strength parameter for the LLM model.
|
|
27
33
|
temperature (float): Temperature parameter for the LLM model.
|
|
34
|
+
verbose (bool): Enable verbose logging.
|
|
35
|
+
time (float): Time parameter for the LLM model.
|
|
36
|
+
simple (bool): If True, skip agentic and use legacy update_prompt().
|
|
37
|
+
quiet (bool): Suppress non-error logging.
|
|
38
|
+
prompt_file (Optional[str]): Path to prompt file (required for agentic path).
|
|
28
39
|
|
|
29
40
|
Returns:
|
|
30
|
-
Tuple[Optional[str], float, str]:
|
|
41
|
+
Tuple[Optional[str], float, str]: Updated prompt content, total cost, and model name.
|
|
31
42
|
"""
|
|
43
|
+
modified_code: Optional[str] = None
|
|
44
|
+
agentic_cost = 0.0
|
|
45
|
+
|
|
32
46
|
try:
|
|
33
47
|
# Check if inputs are valid
|
|
34
48
|
if not input_prompt or not modified_code_file:
|
|
@@ -37,26 +51,57 @@ def git_update(
|
|
|
37
51
|
if not os.path.exists(modified_code_file):
|
|
38
52
|
raise FileNotFoundError(f"Modified code file not found: {modified_code_file}")
|
|
39
53
|
|
|
40
|
-
# Initialize git repository
|
|
41
|
-
repo = git.Repo(search_parent_directories=True)
|
|
54
|
+
# Initialize git repository object once
|
|
55
|
+
repo = git.Repo(modified_code_file, search_parent_directories=True)
|
|
56
|
+
repo_root = repo.working_tree_dir
|
|
42
57
|
|
|
43
58
|
# Get the file's relative path to the repo root
|
|
44
|
-
repo_root = repo.git.rev_parse("--show-toplevel")
|
|
45
59
|
relative_path = os.path.relpath(modified_code_file, repo_root)
|
|
46
60
|
|
|
47
|
-
# Read the modified code
|
|
61
|
+
# Read the modified code FIRST (before any git operations)
|
|
48
62
|
with open(modified_code_file, 'r') as file:
|
|
49
63
|
modified_code = file.read()
|
|
50
64
|
|
|
51
|
-
# Restore the prior checked-in version
|
|
65
|
+
# Restore the prior checked-in version using the relative path
|
|
52
66
|
repo.git.checkout('HEAD', '--', relative_path)
|
|
53
67
|
|
|
54
68
|
# Read the original input code
|
|
55
69
|
with open(modified_code_file, 'r') as file:
|
|
56
70
|
original_input_code = file.read()
|
|
57
71
|
|
|
58
|
-
#
|
|
59
|
-
|
|
72
|
+
# Routing decision: agentic vs legacy
|
|
73
|
+
use_agentic = (
|
|
74
|
+
not simple
|
|
75
|
+
and prompt_file is not None
|
|
76
|
+
and get_available_agents()
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
if use_agentic:
|
|
80
|
+
# Agentic path
|
|
81
|
+
success, message, agentic_cost, provider, changed_files = run_agentic_update(
|
|
82
|
+
prompt_file=prompt_file,
|
|
83
|
+
code_file=modified_code_file,
|
|
84
|
+
verbose=verbose,
|
|
85
|
+
quiet=quiet
|
|
86
|
+
)
|
|
87
|
+
if success:
|
|
88
|
+
# Read updated prompt content from file
|
|
89
|
+
with open(prompt_file, 'r') as file:
|
|
90
|
+
updated_prompt = file.read()
|
|
91
|
+
|
|
92
|
+
# Pretty print the results
|
|
93
|
+
console.print(Panel.fit(
|
|
94
|
+
f"[bold green]Success (agentic):[/bold green]\n"
|
|
95
|
+
f"Provider: {provider}\n"
|
|
96
|
+
f"Total cost: ${agentic_cost:.6f}\n"
|
|
97
|
+
f"Changed files: {', '.join(changed_files)}"
|
|
98
|
+
))
|
|
99
|
+
|
|
100
|
+
return updated_prompt, agentic_cost, provider
|
|
101
|
+
# Fall through to legacy on agentic failure
|
|
102
|
+
|
|
103
|
+
# Legacy path
|
|
104
|
+
result_prompt, legacy_cost, model_name = update_prompt(
|
|
60
105
|
input_prompt=input_prompt,
|
|
61
106
|
input_code=original_input_code,
|
|
62
107
|
modified_code=modified_code,
|
|
@@ -66,21 +111,27 @@ def git_update(
|
|
|
66
111
|
time=time
|
|
67
112
|
)
|
|
68
113
|
|
|
69
|
-
|
|
70
|
-
with open(modified_code_file, 'w') as file:
|
|
71
|
-
file.write(modified_code)
|
|
72
|
-
|
|
114
|
+
total_cost = agentic_cost + legacy_cost
|
|
73
115
|
|
|
74
116
|
# Pretty print the results
|
|
75
117
|
console.print(Panel.fit(
|
|
76
118
|
f"[bold green]Success:[/bold green]\n"
|
|
77
|
-
f"Modified prompt: {
|
|
119
|
+
f"Modified prompt: {result_prompt}\n"
|
|
78
120
|
f"Total cost: ${total_cost:.6f}\n"
|
|
79
121
|
f"Model name: {model_name}"
|
|
80
122
|
))
|
|
81
123
|
|
|
82
|
-
return
|
|
124
|
+
return result_prompt, total_cost, model_name
|
|
83
125
|
|
|
84
126
|
except Exception as e:
|
|
85
127
|
console.print(Panel(f"[bold red]Error:[/bold red] {str(e)}", title="Error", expand=False))
|
|
86
|
-
return None,
|
|
128
|
+
return None, agentic_cost, ""
|
|
129
|
+
|
|
130
|
+
finally:
|
|
131
|
+
# Always restore user's modified code to disk before returning
|
|
132
|
+
if modified_code is not None and modified_code_file:
|
|
133
|
+
try:
|
|
134
|
+
with open(modified_code_file, 'w') as file:
|
|
135
|
+
file.write(modified_code)
|
|
136
|
+
except Exception:
|
|
137
|
+
pass # Best effort restoration
|
pdd/increase_tests.py
CHANGED
|
@@ -78,6 +78,13 @@ def increase_tests(
|
|
|
78
78
|
time=time,
|
|
79
79
|
verbose=verbose
|
|
80
80
|
)
|
|
81
|
+
|
|
82
|
+
# Debug: Check LLM response
|
|
83
|
+
console.print(f"[blue]DEBUG increase_tests: LLM response type: {type(llm_response)}[/blue]")
|
|
84
|
+
console.print(f"[blue]DEBUG increase_tests: LLM response keys: {llm_response.keys() if isinstance(llm_response, dict) else 'Not a dict'}[/blue]")
|
|
85
|
+
console.print(f"[blue]DEBUG increase_tests: LLM result type: {type(llm_response.get('result', 'No result key'))}[/blue]")
|
|
86
|
+
console.print(f"[blue]DEBUG increase_tests: LLM result length: {len(llm_response['result']) if 'result' in llm_response and llm_response['result'] else 0}[/blue]")
|
|
87
|
+
console.print(f"[blue]DEBUG increase_tests: LLM result preview: {repr(llm_response['result'][:300]) if 'result' in llm_response and llm_response['result'] else 'Empty or no result'}[/blue]")
|
|
81
88
|
|
|
82
89
|
increase_test_function, total_cost, model_name = postprocess(
|
|
83
90
|
llm_response['result'],
|
|
@@ -59,8 +59,8 @@ def incremental_code_generator(
|
|
|
59
59
|
if not original_prompt or not new_prompt or not existing_code or not language:
|
|
60
60
|
raise ValueError("All required inputs (original_prompt, new_prompt, existing_code, language) must be provided.")
|
|
61
61
|
|
|
62
|
-
if not 0 <= strength <= 1 or not 0 <= temperature <=
|
|
63
|
-
raise ValueError("Strength
|
|
62
|
+
if not 0 <= strength <= 1 or not 0 <= temperature <= 2 or not 0 <= time <= 1:
|
|
63
|
+
raise ValueError("Strength and time must be between 0 and 1. Temperature must be between 0 and 2.")
|
|
64
64
|
|
|
65
65
|
try:
|
|
66
66
|
total_cost = 0.0
|
pdd/insert_includes.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import Tuple
|
|
1
|
+
from typing import Callable, Optional, Tuple
|
|
2
2
|
from pathlib import Path
|
|
3
3
|
from rich import print
|
|
4
4
|
from pydantic import BaseModel, Field
|
|
@@ -16,10 +16,12 @@ def insert_includes(
|
|
|
16
16
|
input_prompt: str,
|
|
17
17
|
directory_path: str,
|
|
18
18
|
csv_filename: str,
|
|
19
|
+
prompt_filename: Optional[str] = None,
|
|
19
20
|
strength: float = DEFAULT_STRENGTH,
|
|
20
21
|
temperature: float = 0.0,
|
|
21
22
|
time: float = DEFAULT_TIME,
|
|
22
|
-
verbose: bool = False
|
|
23
|
+
verbose: bool = False,
|
|
24
|
+
progress_callback: Optional[Callable[[int, int], None]] = None
|
|
23
25
|
) -> Tuple[str, str, float, str]:
|
|
24
26
|
"""
|
|
25
27
|
Determine needed dependencies and insert them into a prompt.
|
|
@@ -28,10 +30,14 @@ def insert_includes(
|
|
|
28
30
|
input_prompt (str): The prompt to process
|
|
29
31
|
directory_path (str): Directory path where the prompt file is located
|
|
30
32
|
csv_filename (str): Name of the CSV file containing dependencies
|
|
33
|
+
prompt_filename (Optional[str]): The prompt filename being processed,
|
|
34
|
+
used to filter out self-referential example files
|
|
31
35
|
strength (float): Strength parameter for the LLM model
|
|
32
36
|
temperature (float): Temperature parameter for the LLM model
|
|
33
37
|
time (float): Time budget for the LLM model
|
|
34
38
|
verbose (bool, optional): Whether to print detailed information. Defaults to False.
|
|
39
|
+
progress_callback (Optional[Callable[[int, int], None]]): Callback for progress updates.
|
|
40
|
+
Called with (current, total) for each file processed.
|
|
35
41
|
|
|
36
42
|
Returns:
|
|
37
43
|
Tuple[str, str, float, str]: Tuple containing:
|
|
@@ -75,10 +81,12 @@ def insert_includes(
|
|
|
75
81
|
input_prompt=input_prompt,
|
|
76
82
|
directory_path=directory_path,
|
|
77
83
|
csv_file=csv_content,
|
|
84
|
+
prompt_filename=prompt_filename,
|
|
78
85
|
strength=strength,
|
|
79
86
|
temperature=temperature,
|
|
80
87
|
time=time,
|
|
81
|
-
verbose=verbose
|
|
88
|
+
verbose=verbose,
|
|
89
|
+
progress_callback=progress_callback
|
|
82
90
|
)
|
|
83
91
|
|
|
84
92
|
if verbose:
|