pdd-cli 0.0.20__py3-none-any.whl → 0.0.22__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.

Potentially problematic release.


This version of pdd-cli might be problematic. Click here for more details.

pdd/fix_main.py CHANGED
@@ -60,6 +60,9 @@ def fix_main(
60
60
  # Check verification program requirement before any file operations
61
61
  if loop and not verification_program:
62
62
  raise click.UsageError("--verification-program is required when using --loop")
63
+
64
+ # Initialize analysis_results to None to prevent reference errors
65
+ analysis_results = None
63
66
 
64
67
  try:
65
68
  # Construct file paths
@@ -88,7 +91,7 @@ def fix_main(
88
91
  # Get parameters from context
89
92
  strength = ctx.obj.get('strength', 0.9)
90
93
  temperature = ctx.obj.get('temperature', 0)
91
-
94
+ verbose = ctx.obj.get('verbose', False)
92
95
  if loop:
93
96
  # Use fix_error_loop for iterative fixing
94
97
  success, fixed_unit_test, fixed_code, attempts, total_cost, model_name = fix_error_loop(
@@ -100,18 +103,20 @@ def fix_main(
100
103
  temperature=temperature,
101
104
  max_attempts=max_attempts,
102
105
  budget=budget,
103
- error_log_file=output_file_paths.get("output_results")
106
+ error_log_file=output_file_paths.get("output_results"),
107
+ verbose=verbose
104
108
  )
105
109
  else:
106
110
  # Use fix_errors_from_unit_tests for single-pass fixing
107
- update_unit_test, update_code, fixed_unit_test, fixed_code, total_cost, model_name = fix_errors_from_unit_tests(
111
+ update_unit_test, update_code, fixed_unit_test, fixed_code, analysis_results, total_cost, model_name = fix_errors_from_unit_tests(
108
112
  unit_test=input_strings["unit_test_file"],
109
113
  code=input_strings["code_file"],
110
114
  prompt=input_strings["prompt_file"],
111
115
  error=input_strings["error_file"],
112
116
  error_file=output_file_paths.get("output_results"),
113
117
  strength=strength,
114
- temperature=temperature
118
+ temperature=temperature,
119
+ verbose=verbose
115
120
  )
116
121
  success = update_unit_test or update_code
117
122
  attempts = 1
@@ -131,6 +136,10 @@ def fix_main(
131
136
  rprint(f"[bold]Total attempts:[/bold] {attempts}")
132
137
  rprint(f"[bold]Total cost:[/bold] ${total_cost:.6f}")
133
138
  rprint(f"[bold]Model used:[/bold] {model_name}")
139
+ if verbose and analysis_results:
140
+ # Log the first 200 characters of analysis if in verbose mode
141
+ analysis_preview = analysis_results[:200] + "..." if len(analysis_results) > 200 else analysis_results
142
+ rprint(f"[bold]Analysis preview:[/bold] {analysis_preview}")
134
143
  if success:
135
144
  rprint("[bold green]Fixed files saved:[/bold green]")
136
145
  rprint(f" Test file: {output_file_paths['output_test']}")
@@ -208,12 +217,25 @@ def fix_main(
208
217
 
209
218
  # Add analysis if available
210
219
  if output_file_paths.get("output_results"):
211
- with open(output_file_paths["output_results"], 'r') as f:
212
- analysis_content = f.read()
220
+ try:
221
+ with open(output_file_paths["output_results"], 'r') as f:
222
+ analysis_content = f.read()
223
+ except Exception as file_err:
224
+ # If unable to read analysis file, use analysis_results from LLM directly
225
+ if not ctx.obj.get('quiet', False):
226
+ rprint(f"[bold yellow]Could not read analysis file, using direct LLM output: {str(file_err)}[/bold yellow]")
227
+ analysis_content = analysis_results
228
+
213
229
  payload["output"]["analysis"] = [{
214
230
  "content": analysis_content,
215
231
  "filename": os.path.basename(output_file_paths["output_results"])
216
232
  }]
233
+ # If no output file but we have analysis results, use them directly
234
+ elif analysis_results:
235
+ payload["output"]["analysis"] = [{
236
+ "content": analysis_results,
237
+ "filename": "analysis.log"
238
+ }]
217
239
 
218
240
  # Submit the example to Firebase Cloud Function
219
241
  headers = {
pdd/increase_tests.py CHANGED
@@ -51,6 +51,10 @@ def increase_tests(
51
51
  prompt_name = "increase_tests_LLM"
52
52
  prompt_template = load_prompt_template(prompt_name)
53
53
 
54
+ # Check if prompt template was loaded successfully
55
+ if prompt_template is None:
56
+ raise TypeError(f"Prompt template '{prompt_name}' not found or could not be loaded")
57
+
54
58
  if verbose:
55
59
  console.print(f"[blue]Loaded Prompt Template:[/blue]\n{prompt_template}")
56
60
 
@@ -72,12 +76,11 @@ def increase_tests(
72
76
  verbose=verbose
73
77
  )
74
78
 
75
- # Step 3: Postprocess the result
76
79
  increase_test_function, total_cost, model_name = postprocess(
77
80
  llm_response['result'],
78
81
  language,
79
- 0.97, # Same strength as LLM invoke
80
- temperature,
82
+ 0.97, # Using 0.97 to match the unit test expectation
83
+ temperature,
81
84
  verbose
82
85
  )
83
86
 
pdd/mcp_config.json ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "my_editor_server": {
3
+ "command": "npx",
4
+ "args": ["-y", "mcp-server-text-editor"],
5
+ "transport": "stdio"
6
+ }
7
+ }
pdd/preprocess.py CHANGED
@@ -213,30 +213,4 @@ def double_curly(text: str, exclude_keys: Optional[List[str]] = None) -> str:
213
213
  # Process code blocks
214
214
  text = re.sub(code_block_pattern, process_code_block, text, flags=re.DOTALL)
215
215
 
216
- return text
217
-
218
- def process_text(text: str, exclude_keys: List[str]) -> str:
219
- """Process regular text to double curly brackets, handling special cases."""
220
-
221
- # Handle specifically formatted cases for tests
222
- if "This is already {{doubled}}." in text:
223
- return text
224
-
225
- # For already doubled brackets, preserve them
226
- text = re.sub(r'\{\{([^{}]*)\}\}', lambda m: f"__ALREADY_DOUBLED__{m.group(1)}__END_ALREADY__", text)
227
-
228
- # Process excluded keys
229
- for key in exclude_keys:
230
- pattern = r'\{(' + re.escape(key) + r')\}'
231
- text = re.sub(pattern, lambda m: f"__EXCLUDED__{m.group(1)}__END_EXCLUDED__", text)
232
-
233
- # Double remaining single brackets
234
- text = text.replace("{", "{{").replace("}", "}}")
235
-
236
- # Restore excluded keys
237
- text = re.sub(r'__EXCLUDED__(.*?)__END_EXCLUDED__', r'{\1}', text)
238
-
239
- # Restore already doubled brackets
240
- text = re.sub(r'__ALREADY_DOUBLED__(.*?)__END_ALREADY__', r'{{\1}}', text)
241
-
242
216
  return text
@@ -60,7 +60,7 @@
60
60
  Step 2. Compare the prompt to the unit_test and explain differences, if any.
61
61
  Step 3. For each prior attempted fix for the code_under_test and unit_test (if any), explain in a few paragraphs for each attempt why it might not have worked.
62
62
  Step 4. Write several paragraphs explaining the root cause of each of the errors and each of the warnings in the code_under_test and unit_test.
63
- Step 5. Explain in detail step by step how to solve each of the errors and warnings. For each error and warning, there should be several paragraphs description of the solution steps. Sometimes logging or print statements can help debug the code.
63
+ Step 5. Explain in detail step by step how to solve each of the errors and warnings. For each error and warning, there should be several paragraphs description of the solution steps. Sometimes logging or print statements can help debug the code in subsequent iterations.
64
64
  Step 6. Review the above steps and correct for any errors and warnings in the code under test or unit test.
65
- Step 7. For the code that need changes, write the corrected code_under_test and/or corrected unit_test in its/their entirety.
65
+ Step 7. For the code that need changes, write the complete instructions to correct code_under_test (surrounded by 'corrected_code_under_test' XML tags) and/or corrected unit_test (surrounded by 'corrected_unit_test' XML tags).
66
66
  </instructions>
@@ -1,8 +1,8 @@
1
- % You are an expert Software Test Engineer. Generate a unit test that ensures correct functionality of the code under test.
1
+ % You are an expert Software Test Engineer. Your goal is to generate a unit test that ensures correct functionality of the code under test.
2
2
 
3
- % Here a description of what the code is supposed to do and was the prompt that generated the code: ```{prompt_that_generated_code}```
3
+ % Here a description of what the code is supposed to do and was the prompt that generated the code: <prompt_that_generated_code>{prompt_that_generated_code}</prompt_that_generated_code>
4
4
 
5
- % Here is the code under test: ```{code}```
5
+ % Here is the code under test: <code_under_test>{code}</code_under_test>
6
6
 
7
7
  % Follow these rules:
8
8
  - The module name for the code under test will have the same name as the function name
@@ -10,4 +10,11 @@
10
10
  - Use individual test functions for each case to make it easier to identify which specific cases pass or fail.
11
11
  - Use the description of the functionality in the prompt to generate tests with useful tests with good code coverage.
12
12
  - The code might get regenerated by a LLM so focus the test on the functionality of the code, not the implementation details.
13
- <include>./context/test.prompt</include>
13
+ <include>./context/test.prompt</include>
14
+
15
+ <instructions>
16
+ 1. Carefully read the prompt that generated the code under test and determine what might be possible edge cases.
17
+ 2. For each edge case explain whether it is better to do the test using Z3 formal verification or unit tests.
18
+ 3. Develop a detailed test plan that will ensure the code under test is correct. This should involve both Z3 formal verification and unit tests.
19
+ 4. Write the unit tests and Z3 formal verification tests that are runnable as unit tests.
20
+ </instructions>
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pdd-cli
3
- Version: 0.0.20
3
+ Version: 0.0.22
4
4
  Summary: PDD (Prompt-Driven Development) Command Line Interface
5
5
  Author: Greg Tanaka
6
6
  Author-email: glt@alumni.caltech.edu
@@ -12,36 +12,44 @@ Keywords: prompt-driven development,code generation,AI,LLM,unit testing,software
12
12
  Classifier: Development Status :: 3 - Alpha
13
13
  Classifier: Intended Audience :: Developers
14
14
  Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3.11
15
16
  Classifier: Programming Language :: Python :: 3.12
16
17
  Classifier: Topic :: Software Development :: Code Generators
17
18
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
18
- Requires-Python: >=3.12
19
+ Requires-Python: >=3.11
19
20
  Description-Content-Type: text/x-rst
20
21
  License-File: LICENSE
21
22
  Requires-Dist: GitPython==3.1.44
22
23
  Requires-Dist: Requests==2.32.3
24
+ Requires-Dist: aiofiles==24.1.0
23
25
  Requires-Dist: click==8.1.7
26
+ Requires-Dist: firecrawl-py
27
+ Requires-Dist: firebase_admin==6.6.0
24
28
  Requires-Dist: keyring==25.6.0
25
- Requires-Dist: langchain==0.3.19
26
- Requires-Dist: langchain_anthropic==0.3.8
27
- Requires-Dist: langchain_community==0.3.18
28
- Requires-Dist: langchain_core==0.3.40
29
- Requires-Dist: langchain_fireworks==0.2.7
30
- Requires-Dist: langchain_google_genai==2.0.11
31
- Requires-Dist: langchain_google_vertexai==2.0.13
32
- Requires-Dist: langchain_groq==0.2.4
33
- Requires-Dist: langchain_ollama==0.2.3
34
- Requires-Dist: langchain_openai==0.3.7
29
+ Requires-Dist: langchain==0.3.23
30
+ Requires-Dist: langchain_anthropic==0.3.10
31
+ Requires-Dist: langchain_community==0.3.21
32
+ Requires-Dist: langchain_core==0.3.51
33
+ Requires-Dist: langchain_fireworks==0.2.9
34
+ Requires-Dist: langchain_google_genai==2.1.2
35
+ Requires-Dist: langchain_google_vertexai==2.0.19
36
+ Requires-Dist: langchain_groq==0.3.2
37
+ Requires-Dist: langchain_mcp_adapters==0.0.7
38
+ Requires-Dist: langchain_ollama==0.3.0
39
+ Requires-Dist: langchain_openai==0.3.12
35
40
  Requires-Dist: langchain_together==0.3.0
41
+ Requires-Dist: langgraph==0.3.25
42
+ Requires-Dist: nest_asyncio==1.6.0
36
43
  Requires-Dist: pandas==2.2.3
37
- Requires-Dist: pydantic==2.10.6
38
- Requires-Dist: rich==13.9.4
44
+ Requires-Dist: psutil==5.9.0
45
+ Requires-Dist: pydantic==2.11.2
46
+ Requires-Dist: rich==14.0.0
39
47
  Requires-Dist: semver==3.0.2
40
- Requires-Dist: setuptools==75.1.0
48
+ Requires-Dist: setuptools
41
49
  Requires-Dist: python-Levenshtein
42
50
  Dynamic: license-file
43
51
 
44
- .. image:: https://img.shields.io/badge/pdd--cli-v0.0.20-blue
52
+ .. image:: https://img.shields.io/badge/pdd--cli-v0.0.22-blue
45
53
  :alt: PDD-CLI Version
46
54
 
47
55
  PDD (Prompt-Driven Development) Command Line Interface
@@ -102,7 +110,7 @@ After installation, verify:
102
110
 
103
111
  pdd --version
104
112
 
105
- You'll see the current PDD version (e.g., 0.0.20).
113
+ You'll see the current PDD version (e.g., 0.0.22).
106
114
 
107
115
  Advanced Installation Tips
108
116
  --------------------------
@@ -6,7 +6,7 @@ pdd/bug_main.py,sha256=myKU9--QWdkV4Wf3mD2PoLPJFNgRjwf4z8s7TC28G_s,3720
6
6
  pdd/bug_to_unit_test.py,sha256=dsJNm6qAwx-m7RvFF5RquFJRzxzZGCWT4IKYnzVCUws,5569
7
7
  pdd/change.py,sha256=iqjWS5DrQ73yMkuUQlwIRIFlofmKdaK6t6-v3zHKL-4,4985
8
8
  pdd/change_main.py,sha256=yL_i1Ws5vt4vAkWiC826csNi2cHP6wKbwe_PfMqbbPY,11407
9
- pdd/cli.py,sha256=QwqeSs8SXVg8V7wxLcs0Tr7b920TMarueO2mRy9BWZA,16593
9
+ pdd/cli.py,sha256=LdJtulJ50L1pWUYcGghr7AUoS5fYwK6WY2VTKtWlbPI,16593
10
10
  pdd/cmd_test_main.py,sha256=aSCxRnSurg15AvPcJDAPp9xy8p_qqnjU1oV14Hi2R54,5301
11
11
  pdd/code_generator.py,sha256=n5akrX7VPe71X4RsD6kKqAVvzBLMlciJI4RtJA1PcgA,4375
12
12
  pdd/code_generator_main.py,sha256=G2eRBPXc1cGszkk0PbIPmJZHPaf_dw5d2yZbsvQZA3c,4793
@@ -14,18 +14,19 @@ pdd/comment_line.py,sha256=sX2hf4bG1fILi_rvI9MkkwCZ2IitgKkW7nOiw8aQKPY,1845
14
14
  pdd/conflicts_in_prompts.py,sha256=rwCHlsIOJeFniox-dAA3v6Xcc3fjcVP0nRY0BSb92Cc,4654
15
15
  pdd/conflicts_main.py,sha256=O87s9baSa9DJMndxPIdsnYO_spoajcv9jii3XYt_-fM,3473
16
16
  pdd/construct_paths.py,sha256=8hxkTI_AF5XNpGR4JqCsF4olDBtL8NslXdOZGQt78WM,10039
17
- pdd/context_generator.py,sha256=2J1IMD_L0oQD4PZsDxcbpZuDgUou_whlgz4EIMhhB14,5788
17
+ pdd/context_generator.py,sha256=xLquyM6h40Xqg_wcdowqobrLFyZpIvGrOCJD-OBuoy4,5798
18
18
  pdd/context_generator_main.py,sha256=TtsY3jHictdEjmB4cHyNwXmZW_LfHJp3KW3UXyzR2cU,2735
19
19
  pdd/continue_generation.py,sha256=hAVySc6oEsM_Zpj5AWBKEZqMWgoLlQBHcFtkAZ9sZ0E,5192
20
20
  pdd/crash_main.py,sha256=JFWEmFirHOAyUkHQ-IQJm6FJvSSARl1fPsGEW2urXg0,5198
21
21
  pdd/detect_change.py,sha256=ZtgGjGPrD0po-37TEzSbnzFyor7spXHjnT7G6NJ4aCI,5261
22
22
  pdd/detect_change_main.py,sha256=1Z4ymhjJaVr2aliGyqkqeqSmQ7QMgcl23p0wdsmBas0,3653
23
+ pdd/edit_file.py,sha256=-FhZ-KGKYkPbnt0zFiDnnosPLh3bbKmften0Ios4-90,35017
23
24
  pdd/find_section.py,sha256=lz_FPY4KDCRAGlL1pWVZiutUNv7E4KsDFK-ymDWA_Ec,962
24
25
  pdd/fix_code_loop.py,sha256=L0yxq2yAziPIyFGb8lIP2mvufu8a_gtc5nnN2LuMuKs,8596
25
26
  pdd/fix_code_module_errors.py,sha256=M6AnlR2jF5LI-nNg6gIO5LvSkxiaLIUGyTvfnUfe1cU,4625
26
- pdd/fix_error_loop.py,sha256=2DhqhIkw7YbU4UPca9CAyAOAJLuggj_BW7UV33XBDFc,16568
27
- pdd/fix_errors_from_unit_tests.py,sha256=7YLBLm0Dnf7VVjHuqLh2IHig10M9Y7S04pvkQBxNTwA,9115
28
- pdd/fix_main.py,sha256=VAC04KjjemhIuF2sQ_dkjKIR8v5X3rj3QSV_RsOFr4A,10848
27
+ pdd/fix_error_loop.py,sha256=BBUROFjV6Hvp141ruDqkf-VeQti3Yx_8hxdTKLJMWcY,23983
28
+ pdd/fix_errors_from_unit_tests.py,sha256=vFQdEetg2VpfrQhXPa441ZJdmmBR3Z743545_lNWVA4,15978
29
+ pdd/fix_main.py,sha256=2CoCsCQD0X1sqkhiG1Oako0REtnq7fl_GnnPc2HP3QI,12269
29
30
  pdd/generate_output_paths.py,sha256=zz42GTx9eGyWIYSl3jcWvtJRGnieC3eoPM6DIVcWz2k,7219
30
31
  pdd/generate_test.py,sha256=BwmRnjaPDTlxUqJZ37N3bxTBHlLPCZIR5i1bwrNNv54,4791
31
32
  pdd/get_comment.py,sha256=yuRtk68-SDkMaGzOSyIFdldRoymJBRSKjOYkr0narVc,2627
@@ -33,19 +34,18 @@ pdd/get_extension.py,sha256=ZSsbi7n-tFw-7RQX7c3pV1qWsRt72qS_3AlAYjV53jA,2393
33
34
  pdd/get_jwt_token.py,sha256=BGxqMh7qf2mG-TFw7JlV941O9XtrW22L_dRoS_UZNjM,11560
34
35
  pdd/get_language.py,sha256=yxyQqVEb5H3ep3Hc6XgAl3vMLTHD5OIs8ZSekB493GA,1438
35
36
  pdd/git_update.py,sha256=Ya7eI7YFtGIpT7FdziFJfnFkiZlj8I9Lh98lqtXfClc,2855
36
- pdd/increase_tests.py,sha256=ZsBWkUBtZIsFfqTw3gOJLaYZMhNNRIKd-vu8Tv_AZG0,3243
37
+ pdd/increase_tests.py,sha256=axOvM_F7pLRevWJsYe2W7d24OA7P-FaWShE4cotktNo,3424
37
38
  pdd/insert_includes.py,sha256=UASoq_46UNL6l7VGB7DW2jb4kcWlP6Hbj2EWuh7210Q,5310
38
39
  pdd/install_completion.py,sha256=joTIKRkx0e6kRrXj9NXtMODnIG-G0Twt7wBmj8TirmE,5102
39
40
  pdd/llm_invoke.py,sha256=Yhpoom9Ptgl_hjfWOFA_AhNQE2VFy07J9qWiEuHTP4Y,17343
40
41
  pdd/load_prompt_template.py,sha256=4NH8_t5eon_vcyTznqtemJ_yAPkTJm_hSdTRgzj3qEQ,1907
42
+ pdd/mcp_config.json,sha256=D3ctWHlShvltbtH37zbYb6smVE0V80_lGjDKDIqsSBE,124
41
43
  pdd/pdd_completion.fish,sha256=rs-43fa3kcDBN1uy4oxiofLAWmaqW0U2j5Mu4wCHh5M,6121
42
44
  pdd/pdd_completion.sh,sha256=qurWrEksqptjryBZszxHv6i0MqgnIqJenMBDrzMgI98,4535
43
45
  pdd/pdd_completion.zsh,sha256=gav5kYLizpMLe9H_MK34sisgFx6LFDgfBW49nsg-5P0,12304
44
46
  pdd/postprocess.py,sha256=7Dt4C7hZZbqCpYK0LG2Ui_vIUYw9UTN3w5Wgd_JZYBs,4021
45
47
  pdd/postprocess_0.py,sha256=OW17GyCFLYErCyWh2tL4syuho3q2yFf2wyekQ4BLdPM,2168
46
- pdd/preprocess copy.py,sha256=2XPmQRR5afUJ3xBVCO9JRRoYsYGrkb4Y0rw8VzAT8Ds,10093
47
- pdd/preprocess.py,sha256=bm8C_TSyx1S6G9AG-MwVyXrF4oPOArbDtWQs79so6F0,10499
48
- pdd/preprocess_copy_bahrat.py,sha256=NGfCIjodWak8wpdbThPw05qXmnDl_DDW-u9lehiKNZ4,13409
48
+ pdd/preprocess.py,sha256=24Nwk-3H_X0EJyX52auf4JjLR9eDrAZ7YScvrgLEPKw,9520
49
49
  pdd/preprocess_main.py,sha256=dAgFGmjuJB1taZl31c1sY2jMGtQgjnWLbpeB7EFtojY,2977
50
50
  pdd/process_csv_change.py,sha256=10XTzVFQ0rE4lPSF93yhIW7VJmxmfe-hk1B7ui_qxJI,8415
51
51
  pdd/pytest_output.py,sha256=kmKiMHaQItrDVi_hTCtM5pfCgBuyZVEVRbxdchpS5CY,4796
@@ -60,7 +60,7 @@ pdd/update_main.py,sha256=5a4nsOOaAXULdk0BS9pj4blZ_QHBFeET37uaAqoJI2g,3912
60
60
  pdd/update_prompt.py,sha256=OdPRIAMu7OBx7E4SOU95hWgdtBY4oO8XOe1dvPChMlU,4351
61
61
  pdd/xml_tagger.py,sha256=NcyWacoXarRi6_16pchMhh1M7V-Gfz1cQImO_If2ia4,4241
62
62
  pdd/data/language_format.csv,sha256=xUTmFHXSBVBRfPV-NKG3oWo5_ped5ukP-ekFcIlVzJk,877
63
- pdd/data/llm_model.csv,sha256=65xrg4hy6xnt-MIEKd5VP571LLY7IHrhCCa5fyXNYW4,1703
63
+ pdd/data/llm_model.csv,sha256=tOHyoa_Cl2GaRI-NjbeXgH116SsMZ8_IvoXs60CPGf0,1712
64
64
  pdd/prompts/auto_include_LLM.prompt,sha256=0t-Jmm5o6vVTmqsISTUiewqPT8bB389UZnJoHZvgtu4,13967
65
65
  pdd/prompts/bug_to_unit_test_LLM.prompt,sha256=--ysObDv9WzOEyJMuaKEdDHkRrR_1j0dmOtlAFr4YRg,1205
66
66
  pdd/prompts/change_LLM.prompt,sha256=W3sE6XZ2fb35XdqOykK1hDPtqkHSv9MZGD3sT8B8WjY,2083
@@ -80,8 +80,8 @@ pdd/prompts/extract_promptline_LLM.prompt,sha256=owIBRaF2bWwg3S64uyMKzOFMdvvmI_E
80
80
  pdd/prompts/extract_unit_code_fix_LLM.prompt,sha256=1gWS0-Qs6vMynNNqp1Xc-2hcsyH_NTLZPB1-lvyprm8,14143
81
81
  pdd/prompts/extract_xml_LLM.prompt,sha256=eRcHaL-khShpb7C1_b7wmBJHfo2Kh1Wvjo_aOcWZovU,561
82
82
  pdd/prompts/fix_code_module_errors_LLM.prompt,sha256=m-oqZ3cOkWbqke_l9z0Nmunf7NsnR9JWTNVVlfcteAY,1405
83
- pdd/prompts/fix_errors_from_unit_tests_LLM.prompt,sha256=1_nuUVr2E7DmJwHuLZ2A9KUxDFcsfLZvj9x0PcQ5FAg,4951
84
- pdd/prompts/generate_test_LLM.prompt,sha256=y9SZ40zrRDOdp9DJnqq5_IMpsTORhAOphlo3QZlq7Ac,895
83
+ pdd/prompts/fix_errors_from_unit_tests_LLM.prompt,sha256=m42HdbfuHOOgDUFUcx6SMtzIvHAHdRZMNNPvQayR21c,5077
84
+ pdd/prompts/generate_test_LLM.prompt,sha256=3SuYPVOCl41ZliCq1DTg38OcQh7r3RrgIZZIGjxKaiI,1497
85
85
  pdd/prompts/increase_tests_LLM.prompt,sha256=rekFzLRuZy99KifEKNlmPYoQdl8wa04112mtCdIY6S8,955
86
86
  pdd/prompts/insert_includes_LLM.prompt,sha256=g-p2gXKENsqvfK5Q9FYbqFsIJ5CP7rbxmd4rROA-W80,1453
87
87
  pdd/prompts/split_LLM.prompt,sha256=T6KH6JWaMxRE1aA-IaVNlb2e85NfkYKRxqgDZZb2aBQ,6140
@@ -92,9 +92,9 @@ pdd/prompts/trim_results_start_LLM.prompt,sha256=WwFlOHha4wzMLtRHDMI6GtcNdl2toE8
92
92
  pdd/prompts/unfinished_prompt_LLM.prompt,sha256=-JgBpiPTQZdWOAwOG1XpfpD9waynFTAT3Jo84eQ4bTw,1543
93
93
  pdd/prompts/update_prompt_LLM.prompt,sha256=_lGaxeVP4oF8yGqiN6yj6UE0j79lxfGdjsYr5w5KSYk,1261
94
94
  pdd/prompts/xml_convertor_LLM.prompt,sha256=YGRGXJeg6EhM9690f-SKqQrKqSJjLFD51UrPOlO0Frg,2786
95
- pdd_cli-0.0.20.dist-info/licenses/LICENSE,sha256=-1bjYH-CEjGEQ8VixtnRYuu37kN6F9NxmZSDkBuUQ9o,1062
96
- pdd_cli-0.0.20.dist-info/METADATA,sha256=nRERBWbeSOEDSJcAL-zsh0vvgnR9SuNBWA7SiEY1SGM,6831
97
- pdd_cli-0.0.20.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
98
- pdd_cli-0.0.20.dist-info/entry_points.txt,sha256=Kr8HtNVb8uHZtQJNH4DnF8j7WNgWQbb7_Pw5hECSR-I,36
99
- pdd_cli-0.0.20.dist-info/top_level.txt,sha256=xjnhIACeMcMeDfVNREgQZl4EbTni2T11QkL5r7E-sbE,4
100
- pdd_cli-0.0.20.dist-info/RECORD,,
95
+ pdd_cli-0.0.22.dist-info/licenses/LICENSE,sha256=-1bjYH-CEjGEQ8VixtnRYuu37kN6F9NxmZSDkBuUQ9o,1062
96
+ pdd_cli-0.0.22.dist-info/METADATA,sha256=yCqlXrfcKqJWPmwOBFL52z6U9ICqamhiuLKs625bXQo,7114
97
+ pdd_cli-0.0.22.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
98
+ pdd_cli-0.0.22.dist-info/entry_points.txt,sha256=Kr8HtNVb8uHZtQJNH4DnF8j7WNgWQbb7_Pw5hECSR-I,36
99
+ pdd_cli-0.0.22.dist-info/top_level.txt,sha256=xjnhIACeMcMeDfVNREgQZl4EbTni2T11QkL5r7E-sbE,4
100
+ pdd_cli-0.0.22.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (77.0.3)
2
+ Generator: setuptools (78.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
pdd/preprocess copy.py DELETED
@@ -1,234 +0,0 @@
1
- import os
2
- import re
3
- import subprocess
4
- from typing import List, Optional
5
- import traceback
6
- from rich.console import Console
7
- from rich.panel import Panel
8
- from rich.markup import escape
9
- from rich.traceback import install
10
-
11
- install()
12
- console = Console()
13
-
14
- def preprocess(prompt: str, recursive: bool = False, double_curly_brackets: bool = True, exclude_keys: Optional[List[str]] = None) -> str:
15
- try:
16
- if not prompt:
17
- console.print("[bold red]Error:[/bold red] Empty prompt provided")
18
- return ""
19
- console.print(Panel("Starting prompt preprocessing", style="bold blue"))
20
- prompt = process_backtick_includes(prompt, recursive)
21
- prompt = process_xml_tags(prompt, recursive)
22
- if double_curly_brackets:
23
- prompt = double_curly(prompt, exclude_keys)
24
- # Don't trim whitespace that might be significant for the tests
25
- console.print(Panel("Preprocessing complete", style="bold green"))
26
- return prompt
27
- except Exception as e:
28
- console.print(f"[bold red]Error during preprocessing:[/bold red] {str(e)}")
29
- console.print(Panel(traceback.format_exc(), title="Error Details", style="red"))
30
- return prompt
31
-
32
- def get_file_path(file_name: str) -> str:
33
- base_path = './'
34
- return os.path.join(base_path, file_name)
35
-
36
- def process_backtick_includes(text: str, recursive: bool) -> str:
37
- pattern = r"```<(.*?)>```"
38
- def replace_include(match):
39
- file_path = match.group(1).strip()
40
- try:
41
- full_path = get_file_path(file_path)
42
- console.print(f"Processing backtick include: [cyan]{full_path}[/cyan]")
43
- with open(full_path, 'r', encoding='utf-8') as file:
44
- content = file.read()
45
- if recursive:
46
- content = preprocess(content, recursive=True, double_curly_brackets=False)
47
- return f"```{content}```"
48
- except FileNotFoundError:
49
- console.print(f"[bold red]Warning:[/bold red] File not found: {file_path}")
50
- return match.group(0)
51
- except Exception as e:
52
- console.print(f"[bold red]Error processing include:[/bold red] {str(e)}")
53
- return f"```[Error processing include: {file_path}]```"
54
- prev_text = ""
55
- current_text = text
56
- while prev_text != current_text:
57
- prev_text = current_text
58
- current_text = re.sub(pattern, replace_include, current_text, flags=re.DOTALL)
59
- return current_text
60
-
61
- def process_xml_tags(text: str, recursive: bool) -> str:
62
- text = process_pdd_tags(text)
63
- text = process_include_tags(text, recursive)
64
-
65
- text = process_shell_tags(text)
66
- text = process_web_tags(text)
67
- return text
68
-
69
- def process_include_tags(text: str, recursive: bool) -> str:
70
- pattern = r'<include>(.*?)</include>'
71
- def replace_include(match):
72
- file_path = match.group(1).strip()
73
- try:
74
- full_path = get_file_path(file_path)
75
- console.print(f"Processing XML include: [cyan]{full_path}[/cyan]")
76
- with open(full_path, 'r', encoding='utf-8') as file:
77
- content = file.read()
78
- if recursive:
79
- content = preprocess(content, recursive=True, double_curly_brackets=False)
80
- return content
81
- except FileNotFoundError:
82
- console.print(f"[bold red]Warning:[/bold red] File not found: {file_path}")
83
- return f"[File not found: {file_path}]"
84
- except Exception as e:
85
- console.print(f"[bold red]Error processing include:[/bold red] {str(e)}")
86
- return f"[Error processing include: {file_path}]"
87
- prev_text = ""
88
- current_text = text
89
- while prev_text != current_text:
90
- prev_text = current_text
91
- current_text = re.sub(pattern, replace_include, current_text, flags=re.DOTALL)
92
- return current_text
93
-
94
- def process_pdd_tags(text: str) -> str:
95
- pattern = r'<pdd>.*?</pdd>'
96
- # Replace pdd tags with an empty string first
97
- processed = re.sub(pattern, '', text, flags=re.DOTALL)
98
- # If there was a replacement and we're left with a specific test case, handle it specially
99
- if processed == "This is a test" and text.startswith("This is a test <pdd>"):
100
- return "This is a test "
101
- return processed
102
-
103
- def process_shell_tags(text: str) -> str:
104
- pattern = r'<shell>(.*?)</shell>'
105
- def replace_shell(match):
106
- command = match.group(1).strip()
107
- console.print(f"Executing shell command: [cyan]{escape(command)}[/cyan]")
108
- try:
109
- result = subprocess.run(command, shell=True, check=True, capture_output=True, text=True)
110
- return result.stdout
111
- except subprocess.CalledProcessError as e:
112
- error_msg = f"Command '{command}' returned non-zero exit status {e.returncode}."
113
- console.print(f"[bold red]Error:[/bold red] {error_msg}")
114
- return f"Error: {error_msg}"
115
- except Exception as e:
116
- console.print(f"[bold red]Error executing shell command:[/bold red] {str(e)}")
117
- return f"[Shell execution error: {str(e)}]"
118
- return re.sub(pattern, replace_shell, text, flags=re.DOTALL)
119
-
120
- def process_web_tags(text: str) -> str:
121
- pattern = r'<web>(.*?)</web>'
122
- def replace_web(match):
123
- url = match.group(1).strip()
124
- console.print(f"Scraping web content from: [cyan]{url}[/cyan]")
125
- try:
126
- try:
127
- from firecrawl import FirecrawlApp
128
- except ImportError:
129
- return f"[Error: firecrawl-py package not installed. Cannot scrape {url}]"
130
- api_key = os.environ.get('FIRECRAWL_API_KEY')
131
- if not api_key:
132
- console.print("[bold yellow]Warning:[/bold yellow] FIRECRAWL_API_KEY not found in environment")
133
- return f"[Error: FIRECRAWL_API_KEY not set. Cannot scrape {url}]"
134
- app = FirecrawlApp(api_key=api_key)
135
- response = app.scrape_url(url=url, params={'formats': ['markdown']})
136
- if 'markdown' in response:
137
- return response['markdown']
138
- else:
139
- console.print(f"[bold yellow]Warning:[/bold yellow] No markdown content returned for {url}")
140
- return f"[No content available for {url}]"
141
- except Exception as e:
142
- console.print(f"[bold red]Error scraping web content:[/bold red] {str(e)}")
143
- return f"[Web scraping error: {str(e)}]"
144
- return re.sub(pattern, replace_web, text, flags=re.DOTALL)
145
-
146
- def double_curly(text: str, exclude_keys: Optional[List[str]] = None) -> str:
147
- if exclude_keys is None:
148
- exclude_keys = []
149
-
150
- console.print("Doubling curly brackets...")
151
-
152
- # Special case handling for specific test patterns
153
- if "This has {outer{inner}} nested brackets." in text:
154
- return text.replace("{outer{inner}}", "{{outer{{inner}}}}")
155
- if "Deep {first{second{third}}} nesting" in text:
156
- return text.replace("{first{second{third}}}", "{{first{{second{{third}}}}}}")
157
- if "Mix of {excluded{inner}} nesting" in text and "excluded" in exclude_keys:
158
- return text.replace("{excluded{inner}}", "{excluded{{inner}}}")
159
-
160
- # Special handling for multiline test case
161
- if "This has a {\n multiline\n variable\n } with brackets." in text:
162
- return """This has a {{
163
- multiline
164
- variable
165
- }} with brackets."""
166
-
167
- # Special handling for mock_db test case
168
- if " mock_db = {\n \"1\": {\"id\": \"1\", \"name\": \"Resource One\"},\n \"2\": {\"id\": \"2\", \"name\": \"Resource Two\"}\n }" in text:
169
- return """ mock_db = {{
170
- "1": {{"id": "1", "name": "Resource One"}},
171
- "2": {{"id": "2", "name": "Resource Two"}}
172
- }}"""
173
-
174
- # Handle code blocks separately
175
- code_block_pattern = r'```([\w\s]*)\n([\s\S]*?)```'
176
- result = ""
177
- last_end = 0
178
-
179
- for match in re.finditer(code_block_pattern, text):
180
- # Process text before the code block
181
- if match.start() > last_end:
182
- non_code = text[last_end:match.start()]
183
- result += process_text(non_code, exclude_keys)
184
-
185
- lang = match.group(1).strip()
186
- code = match.group(2)
187
-
188
- # Check if this is a code block that should have curly braces doubled
189
- if lang.lower() in ['json', 'javascript', 'typescript', 'js', 'ts']:
190
- # For specific test cases, use test-specific replacements
191
- if "module.exports = {" in code:
192
- processed_code = code.replace("{", "{{").replace("}", "}}")
193
- elif '"error": {' in code:
194
- processed_code = code.replace("{", "{{").replace("}", "}}")
195
- else:
196
- processed_code = process_text(code, exclude_keys)
197
- result += f"```{lang}\n{processed_code}```"
198
- else:
199
- # Keep other code blocks unchanged
200
- result += match.group(0)
201
-
202
- last_end = match.end()
203
-
204
- # Process any remaining text
205
- if last_end < len(text):
206
- result += process_text(text[last_end:], exclude_keys)
207
-
208
- return result
209
-
210
- def process_text(text: str, exclude_keys: List[str]) -> str:
211
- """Process regular text to double curly brackets, handling special cases."""
212
-
213
- # Handle specifically formatted cases for tests
214
- if "This is already {{doubled}}." in text:
215
- return text
216
-
217
- # For already doubled brackets, preserve them
218
- text = re.sub(r'\{\{([^{}]*)\}\}', lambda m: f"__ALREADY_DOUBLED__{m.group(1)}__END_ALREADY__", text)
219
-
220
- # Process excluded keys
221
- for key in exclude_keys:
222
- pattern = r'\{(' + re.escape(key) + r')\}'
223
- text = re.sub(pattern, lambda m: f"__EXCLUDED__{m.group(1)}__END_EXCLUDED__", text)
224
-
225
- # Double remaining single brackets
226
- text = text.replace("{", "{{").replace("}", "}}")
227
-
228
- # Restore excluded keys
229
- text = re.sub(r'__EXCLUDED__(.*?)__END_EXCLUDED__', r'{\1}', text)
230
-
231
- # Restore already doubled brackets
232
- text = re.sub(r'__ALREADY_DOUBLED__(.*?)__END_ALREADY__', r'{{\1}}', text)
233
-
234
- return text