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.
Files changed (119) hide show
  1. pdd/__init__.py +4 -4
  2. pdd/agentic_common.py +863 -0
  3. pdd/agentic_crash.py +534 -0
  4. pdd/agentic_fix.py +1179 -0
  5. pdd/agentic_langtest.py +162 -0
  6. pdd/agentic_update.py +370 -0
  7. pdd/agentic_verify.py +183 -0
  8. pdd/auto_deps_main.py +15 -5
  9. pdd/auto_include.py +63 -5
  10. pdd/bug_main.py +3 -2
  11. pdd/bug_to_unit_test.py +2 -0
  12. pdd/change_main.py +11 -4
  13. pdd/cli.py +22 -1181
  14. pdd/cmd_test_main.py +80 -19
  15. pdd/code_generator.py +58 -18
  16. pdd/code_generator_main.py +672 -25
  17. pdd/commands/__init__.py +42 -0
  18. pdd/commands/analysis.py +248 -0
  19. pdd/commands/fix.py +140 -0
  20. pdd/commands/generate.py +257 -0
  21. pdd/commands/maintenance.py +174 -0
  22. pdd/commands/misc.py +79 -0
  23. pdd/commands/modify.py +230 -0
  24. pdd/commands/report.py +144 -0
  25. pdd/commands/templates.py +215 -0
  26. pdd/commands/utility.py +110 -0
  27. pdd/config_resolution.py +58 -0
  28. pdd/conflicts_main.py +8 -3
  29. pdd/construct_paths.py +281 -81
  30. pdd/context_generator.py +10 -2
  31. pdd/context_generator_main.py +113 -11
  32. pdd/continue_generation.py +47 -7
  33. pdd/core/__init__.py +0 -0
  34. pdd/core/cli.py +503 -0
  35. pdd/core/dump.py +554 -0
  36. pdd/core/errors.py +63 -0
  37. pdd/core/utils.py +90 -0
  38. pdd/crash_main.py +44 -11
  39. pdd/data/language_format.csv +71 -62
  40. pdd/data/llm_model.csv +20 -18
  41. pdd/detect_change_main.py +5 -4
  42. pdd/fix_code_loop.py +331 -77
  43. pdd/fix_error_loop.py +209 -60
  44. pdd/fix_errors_from_unit_tests.py +4 -3
  45. pdd/fix_main.py +75 -18
  46. pdd/fix_verification_errors.py +12 -100
  47. pdd/fix_verification_errors_loop.py +319 -272
  48. pdd/fix_verification_main.py +57 -17
  49. pdd/generate_output_paths.py +93 -10
  50. pdd/generate_test.py +16 -5
  51. pdd/get_jwt_token.py +48 -9
  52. pdd/get_run_command.py +73 -0
  53. pdd/get_test_command.py +68 -0
  54. pdd/git_update.py +70 -19
  55. pdd/increase_tests.py +7 -0
  56. pdd/incremental_code_generator.py +2 -2
  57. pdd/insert_includes.py +11 -3
  58. pdd/llm_invoke.py +1278 -110
  59. pdd/load_prompt_template.py +36 -10
  60. pdd/pdd_completion.fish +25 -2
  61. pdd/pdd_completion.sh +30 -4
  62. pdd/pdd_completion.zsh +79 -4
  63. pdd/postprocess.py +10 -3
  64. pdd/preprocess.py +228 -15
  65. pdd/preprocess_main.py +8 -5
  66. pdd/prompts/agentic_crash_explore_LLM.prompt +49 -0
  67. pdd/prompts/agentic_fix_explore_LLM.prompt +45 -0
  68. pdd/prompts/agentic_fix_harvest_only_LLM.prompt +48 -0
  69. pdd/prompts/agentic_fix_primary_LLM.prompt +85 -0
  70. pdd/prompts/agentic_update_LLM.prompt +1071 -0
  71. pdd/prompts/agentic_verify_explore_LLM.prompt +45 -0
  72. pdd/prompts/auto_include_LLM.prompt +98 -101
  73. pdd/prompts/change_LLM.prompt +1 -3
  74. pdd/prompts/detect_change_LLM.prompt +562 -3
  75. pdd/prompts/example_generator_LLM.prompt +22 -1
  76. pdd/prompts/extract_code_LLM.prompt +5 -1
  77. pdd/prompts/extract_program_code_fix_LLM.prompt +14 -2
  78. pdd/prompts/extract_prompt_update_LLM.prompt +7 -8
  79. pdd/prompts/extract_promptline_LLM.prompt +17 -11
  80. pdd/prompts/find_verification_errors_LLM.prompt +6 -0
  81. pdd/prompts/fix_code_module_errors_LLM.prompt +16 -4
  82. pdd/prompts/fix_errors_from_unit_tests_LLM.prompt +6 -41
  83. pdd/prompts/fix_verification_errors_LLM.prompt +22 -0
  84. pdd/prompts/generate_test_LLM.prompt +21 -6
  85. pdd/prompts/increase_tests_LLM.prompt +1 -2
  86. pdd/prompts/insert_includes_LLM.prompt +1181 -6
  87. pdd/prompts/split_LLM.prompt +1 -62
  88. pdd/prompts/trace_LLM.prompt +25 -22
  89. pdd/prompts/unfinished_prompt_LLM.prompt +85 -1
  90. pdd/prompts/update_prompt_LLM.prompt +22 -1
  91. pdd/prompts/xml_convertor_LLM.prompt +3246 -7
  92. pdd/pytest_output.py +188 -21
  93. pdd/python_env_detector.py +151 -0
  94. pdd/render_mermaid.py +236 -0
  95. pdd/setup_tool.py +648 -0
  96. pdd/simple_math.py +2 -0
  97. pdd/split_main.py +3 -2
  98. pdd/summarize_directory.py +56 -7
  99. pdd/sync_determine_operation.py +918 -186
  100. pdd/sync_main.py +82 -32
  101. pdd/sync_orchestration.py +1456 -453
  102. pdd/sync_tui.py +848 -0
  103. pdd/template_registry.py +264 -0
  104. pdd/templates/architecture/architecture_json.prompt +242 -0
  105. pdd/templates/generic/generate_prompt.prompt +174 -0
  106. pdd/trace.py +168 -12
  107. pdd/trace_main.py +4 -3
  108. pdd/track_cost.py +151 -61
  109. pdd/unfinished_prompt.py +49 -3
  110. pdd/update_main.py +549 -67
  111. pdd/update_model_costs.py +2 -2
  112. pdd/update_prompt.py +19 -4
  113. {pdd_cli-0.0.42.dist-info → pdd_cli-0.0.90.dist-info}/METADATA +20 -7
  114. pdd_cli-0.0.90.dist-info/RECORD +153 -0
  115. {pdd_cli-0.0.42.dist-info → pdd_cli-0.0.90.dist-info}/licenses/LICENSE +1 -1
  116. pdd_cli-0.0.42.dist-info/RECORD +0 -115
  117. {pdd_cli-0.0.42.dist-info → pdd_cli-0.0.90.dist-info}/WHEEL +0 -0
  118. {pdd_cli-0.0.42.dist-info → pdd_cli-0.0.90.dist-info}/entry_points.txt +0 -0
  119. {pdd_cli-0.0.42.dist-info → pdd_cli-0.0.90.dist-info}/top_level.txt +0 -0
@@ -3,24 +3,3263 @@
3
3
  <example_1>
4
4
  % Here is an example_raw_prompt that needs XML tagging:
5
5
  <example_raw_prompt>
6
- <include>context/xml/1/split_LLM.prompt</include>
6
+ <examples>
7
+ % Here is example_1 of how to split and generate the sub_prompt and modified_prompt:
8
+ example_1_input_prompt: ```<./context/split/1/initial_pdd_python.prompt>```
9
+ example_1_input_code: ```<./context/split/1/pdd.py>```
10
+ example_1_example_code: ```<./context/split/1/split_get_extension.py>```
11
+ example_1_sub_prompt: ```<./context/split/1/sub_pdd_python.prompt>```
12
+ example_1_modified_prompt: ```<./context/split/1/final_pdd_python.prompt>```
13
+
14
+ % Here is example_2 of how to split and generate the sub_prompt and modified_prompt:
15
+ example_2_input_prompt: ```<./context/split/2/initial_pdd_python.prompt>```
16
+ example_2_input_code: ```<./context/split/2/pdd.py>```
17
+ example_2_example_code: ```<./context/split/2/split_pdd_construct_output_path.py>```
18
+ example_2_sub_prompt: ```<./context/split/2/sub_pdd_python.prompt>```
19
+ example_2_modified_prompt: ```<./context/split/2/final_pdd_python.prompt>```
20
+
21
+ % Here is example_3 of how to split and generate the sub_prompt and modified_prompt:
22
+ example_3_input_prompt: ```<./context/split/3/initial_postprocess_python.prompt>```
23
+ example_3_input_code: ```<./context/split/3/postprocess.py>```
24
+ example_3_example_code: ```<./context/split/3/split_postprocess_find_section.py>```
25
+ example_3_sub_prompt: ```<./context/split/3/sub_postprocess_python.prompt>```
26
+ example_3_modified_prompt: ```<./context/split/3/final_postprocess_python.prompt>```
27
+
28
+ % Here is example_4 of how to split and generate the sub_prompt and modified_prompt:
29
+ example_4_input_prompt: ```<./context/split/4/initial_construct_paths_python.prompt>```
30
+ example_4_input_code: ```<./context/split/4/construct_paths.py>```
31
+ example_4_example_code: ```<./context/split/4/split_construct_paths_generate_output_filename.py>```
32
+ example_4_sub_prompt: ```<./context/split/4/sub_construct_paths_python.prompt>```
33
+ example_4_modified_prompt: ```<./context/split/4/final_construct_paths_python.prompt>```
34
+ </examples>
35
+
36
+ % You are an expert LLM Prompt Engineer. Your goal is to split the input_prompt into a sub_prompt and modified_prompt with no loss of functionality.
37
+
38
+ % Here are the inputs and outputs of this prompt:
39
+ Input:
40
+ 'input_prompt' - A string contains the prompt that will be split into a sub_prompt and modified_prompt.
41
+ 'input_code' - A string that contains the code that was generated from the input_prompt.
42
+ 'example_code' - A string that contains the code example of how the code generated from the sub_prompt would be used by the code generated from the modified_prompt.
43
+ Output:
44
+ 'sub_prompt' - A string that contains the sub_prompt that was split from the input_prompt.
45
+ 'modified_prompt' - A string that contains the modified prompt from input_prompt split from the above sub_prompt.
46
+
47
+ % Here is the input_prompt to split: ```{input_prompt}```
48
+ % Here is the input_code: ```{input_code}```
49
+ % Here is the example_code: ```{example_code}```
50
+
51
+ % Follow these instructions:
52
+ 1. Write out the difficulties in spliting the prompt
53
+ 2. Write out how to overcome the difficulties
54
+ 3. Generate the sub_prompt.
55
+ 4. Generate the modified_prompt.
7
56
  </example_raw_prompt>
8
57
 
9
58
  % Here is an example_tagged_prompt from the example_raw_prompt above:
10
59
  <example_tagged_prompt>
11
- <include>context/xml/1/split_xml_llm.prompt</include>
60
+ <examples>
61
+ <example_1>
62
+ <input_prompt>% You are an expert Python engineer. Your goal is to write a python command line program, "pdd", that will compile a prompt into a code file or a code file into an example code file. All output to the console will be pretty print using the Python rich library.
63
+
64
+ % Here is how the program will be used: pdd <input_prompt_file or input_code_file_to_generate_example_from>
65
+
66
+ % Prompt file names have this format: 'basename_language.prompt' (e.g. pdd_python.prompt, makefile_makefile.prompt, setup_bash.prompt)
67
+
68
+ % There are four possibilities for the output files:
69
+ - File name given without path (e.g. 'output.py'): This will write the 'output.py' file in the same directory as the input file.
70
+ - File name given with path (e.g. './output.py'): This will write the 'output.py' file in the './' directory.
71
+ - Path given without file name (e.g. './context'): This will write the file with the basename and appropriate extension (for generated runnable code and generated example code) in the './context' directory.
72
+ - Nothing specified by user (default): This will write the file with the basename and appropriate extension in the same directory as the input file.
73
+
74
+ % When given a prompt, the program will generate runnable code and example code if selected. When given a code file, an example file will be generated. Here are the options the program will support:
75
+ '--force': When writing the output files, if a file already exists, the program will ask before overwriting it unless a "--force" is present where it will just overwrite the file. It will default to Yes if user presses Enter.
76
+ '-o': Path or filename of the output of the runnable code. All four of the above possibilities are possible meaning for example, the user might just have "-o" or might have "-o ./output.py".
77
+ '-oe': Means program should generate example from runnable code. As will "-o" all four output possibilities are possible here.
78
+
79
+ % Here are example command lines:
80
+ -'pdd context_generator.py' will generate 'context_generator_example.py' in the same directory
81
+ -'pdd context_generator.py -oe context/' will generate 'context_generator_example.py' in the './context' directory
82
+ -'pdd context_generator_python.prompt -o pdd/ -oe context/' will generate 'context_generator.py' in the './pdd' directory and 'context_generator_example.py' in the './context' directory. 'context_generator' is the basename.
83
+ -'pdd makefile_makefile.prompt' will generate 'makefile' in the same directory
84
+ -'pdd pdd_python.prompt -o pdd/pdd_v1.py will generate 'pdd_v1.py' in the './pdd' directory and no example will be generated
85
+
86
+ % Here is an example how to generate code from the prompt from a file: ```<./context/code_generator_example.py>```
87
+
88
+ % Here is an example how to generate an example from a code file: ```<./context/context_generator_example.py>```
89
+
90
+ % This program will do the following:
91
+ Step 1. Read the input file name from the command line.
92
+ Step 2. If file name has no extension, add '.prompt' to the file name.
93
+ Step 3. Extract the basename and language from the file name so the right code file extension (e.g. '.sh' for bash, '' for makefile, '.py' for Python) and language is used for all the subsequent steps.
94
+ Step 4. From the basename and file extension generate the appropriate file paths for the runnable and example output files considering the four possibilities. First determine which possibility for each of the outputs and then construct the proper file paths for each output.
95
+ Step 5. If a prompt input (indicated by a '.prompt' input file extension) do these steps:
96
+ Step 5a. Generate code from the input prompt file name using code_generator.
97
+ Step 5b. The program will write the runnable code to a runnable file path from Step 4.
98
+ Step 6. If a code file (indicated by a input file extension that isn't '.prompt') is provided or a "-oe" option is provided, the program will generate example code from the runnable code of Step 5 or the input code file using context_generator and write the example code to the example file path from Step 4.</input_prompt>
99
+ <input_code># To create the command line program "pdd" as described, we will use Python's `argparse` for command line argument parsing, and the `rich` library for pretty printing. The program will handle both prompt files and code files, generating runnable code and example code as specified.
100
+
101
+ # Here's a complete implementation of the `pdd` program:
102
+
103
+ # ```python
104
+ import os
105
+ import sys
106
+ import argparse
107
+ from rich.console import Console
108
+ from rich.prompt import Confirm
109
+ from code_generator import code_generator
110
+ from context_generator import context_generator
111
+
112
+ console = Console()
113
+
114
+ def get_file_paths(input_file, output_file, example_output_file):
115
+ # Extract basename and language from the input file
116
+ basename, ext = os.path.splitext(os.path.basename(input_file))
117
+ language = ext[1:] # Remove the dot
118
+
119
+ # Determine output file paths
120
+ if output_file:
121
+ runnable_file_path = output_file
122
+ else:
123
+ runnable_file_path = os.path.join(os.path.dirname(input_file), f"{basename}.{get_extension(language)}")
124
+
125
+ if example_output_file:
126
+ example_file_path = example_output_file
127
+ else:
128
+ example_file_path = os.path.join(os.path.dirname(input_file), f"{basename}_example.{get_example_extension(language)}")
129
+
130
+ return runnable_file_path, example_file_path
131
+
132
+ def get_extension(language):
133
+ extensions = {
134
+ 'python': 'py',
135
+ 'bash': 'sh',
136
+ 'makefile': 'mk',
137
+ # Add more languages and their extensions as needed
138
+ }
139
+ return extensions.get(language, '')
140
+
141
+ def get_example_extension(language):
142
+ return 'py' # Assuming example files are always Python files for simplicity
143
+
144
+ def confirm_overwrite(file_path):
145
+ if os.path.exists(file_path):
146
+ return Confirm.ask(f"{file_path} already exists. Do you want to overwrite it?", default=True)
147
+ return True
148
+
149
+ def main():
150
+ parser = argparse.ArgumentParser(description="Compile prompts into code files or generate example code from code files.")
151
+ parser.add_argument('input', help='Input prompt file or code file to generate example from')
152
+ parser.add_argument('-o', '--output', help='Path or filename of the output runnable code')
153
+ parser.add_argument('-oe', '--output-example', help='Path or filename of the output example code')
154
+ parser.add_argument('--force', action='store_true', help='Force overwrite existing files without confirmation')
155
+
156
+ args = parser.parse_args()
157
+
158
+ input_file = args.input
159
+ if not input_file.endswith('.prompt'):
160
+ if not os.path.splitext(input_file)[1]: # No extension, assume it's a code file
161
+ input_file += '.prompt'
162
+
163
+ # Determine if input is a prompt or code file
164
+ is_prompt = input_file.endswith('.prompt')
165
+
166
+ # Get output file paths
167
+ runnable_file_path, example_file_path = get_file_paths(input_file, args.output, args.output_example)
168
+
169
+ # Handle the runnable code generation
170
+ if is_prompt:
171
+ console.print(f"[bold green]Generating runnable code from prompt: {input_file}[/bold green]")
172
+ runnable_code = code_generator(input_file, get_extension(os.path.splitext(input_file)[1][1:]))
173
+
174
+ if not args.force and not confirm_overwrite(runnable_file_path):
175
+ console.print("[bold red]Operation cancelled.[/bold red]")
176
+ return
177
+
178
+ with open(runnable_file_path, 'w') as f:
179
+ f.write(runnable_code)
180
+ console.print(f"[bold blue]Runnable code written to: {runnable_file_path}[/bold blue]")
181
+
182
+ # Handle example code generation
183
+ if not is_prompt or args.output_example:
184
+ console.print(f"[bold green]Generating example code from: {runnable_file_path}[/bold green]")
185
+ success = context_generator(runnable_file_path, example_file_path, force=args.force)
186
+
187
+ if success:
188
+ console.print(f"[bold blue]Example code written to: {example_file_path}[/bold blue]")
189
+ else:
190
+ console.print("[bold red]Example generation failed.[/bold red]")
191
+
192
+ if __name__ == "__main__":
193
+ main()
194
+ # ```
195
+
196
+ # ### Explanation of the Code:
197
+ # 1. **Imports**: We import necessary modules including `argparse` for command line parsing, `os` for file path manipulations, and `rich` for console output.
198
+ # 2. **Functions**:
199
+ # - `get_file_paths`: Determines the output file paths based on the input file and user-specified options.
200
+ # - `get_extension` and `get_example_extension`: Return the appropriate file extensions based on the language.
201
+ # - `confirm_overwrite`: Asks the user for confirmation if a file already exists.
202
+ # 3. **Main Function**:
203
+ # - Parses command line arguments.
204
+ # - Checks if the input file is a prompt or a code file.
205
+ # - Generates runnable code from the prompt file and writes it to the specified output path.
206
+ # - Generates example code from the runnable code if specified.
207
+ # 4. **Execution**: The script runs the `main` function when executed.
208
+
209
+ # ### Usage:
210
+ # - To run the program, save it as `pdd.py` and execute it from the command line:
211
+ # ```bash
212
+ # python pdd.py <input_prompt_file or input_code_file_to_generate_example_from> [options]
213
+ # ```
214
+
215
+ # ### Requirements:
216
+ # - Ensure you have the `rich`, `langchain`, and `tiktoken` libraries installed, along with the `code_generator` and `context_generator` modules available in your environment.</input_code>
217
+ <example_code>file_extension = get_extension(language)</example_code>
218
+ <sub_prompt>% You are an expert Python engineer. Your goal is to write a python function, "get_extension", that will return the file extension associated with a given language.
219
+
220
+ % Here are the inputs and outputs of the function:
221
+ Input: 'language' - A string containing the language (e.g. Bash, Makefile, Python).
222
+ Output: returns a string that is the extension for the langauge
223
+
224
+ % This program will do the following:
225
+ Step 1. Lower case the language string to make the comparison case insensitive.
226
+ Step 2. Look up the file extension for the given language
227
+ Step 3. Return the file extension</sub_prompt>
228
+ <modified_prompt>% You are an expert Python engineer. Your goal is to write a python command line program, "pdd", that will compile a prompt into a code file or a code file into an example code file. All output to the console will be pretty print using the Python rich library.
229
+
230
+ % Here is how the program will be used: pdd <input_prompt_file or input_code_file_to_generate_example_from>
231
+
232
+ % Prompt file names have this format: 'basename_language.prompt' (e.g. pdd_python.prompt, makefile_makefile.prompt, setup_bash.prompt)
233
+
234
+ % There are four possibilities for the output files:
235
+ - File name given without path (e.g. 'output.py'): This will write the 'output.py' file in the same directory as the input file.
236
+ - File name given with path (e.g. './output.py'): This will write the 'output.py' file in the './' directory.
237
+ - Path given without file name (e.g. './context'): This will write the file with the basename and appropriate extension (for generated runnable code and generated example code) in the './context' directory.
238
+ - Nothing specified by user (default): This will write the file with the basename and appropriate extension in the same directory as the input file.
239
+
240
+ % When given a prompt, the program will generate runnable code and example code if selected. When given a code file, an example file will be generated. Here are the options the program will support:
241
+ '--force': When writing the output files, if a file already exists, the program will ask before overwriting it unless a "--force" is present where it will just overwrite the file. It will default to Yes if user presses Enter.
242
+ '-o': Path or filename of the output of the runnable code. All four of the above possibilities are possible meaning for example, the user might just have "-o" or might have "-o ./output.py".
243
+ '-oe': Means program should generate example from runnable code. As will "-o" all four output possibilities are possible here.
244
+
245
+ % Here are example command lines:
246
+ -'pdd context_generator.py' will generate 'context_generator_example.py' in the same directory
247
+ -'pdd context_generator.py -oe context/' will generate 'context_generator_example.py' in the './context' directory
248
+ -'pdd context_generator_python.prompt -o pdd/ -oe context/' will generate 'context_generator.py' in the './pdd' directory and 'context_generator_example.py' in the './context' directory. 'context_generator' is the basename.
249
+ -'pdd makefile_makefile.prompt' will generate 'makefile' in the same directory
250
+ -'pdd pdd_python.prompt -o pdd/pdd_v1.py will generate 'pdd_v1.py' in the './pdd' directory and no example will be generated
251
+
252
+ % Here is an example how to generate code from the prompt from a file: ```<./context/code_generator_example.py>```
253
+
254
+ % Here is an example how to generate an example from a code file: ```<./context/context_generator_example.py>```
255
+
256
+ % Here is an example how to lookup a file extension given a language: ```<./context/get_extension_example.py>```
257
+
258
+ % This program will do the following:
259
+ Step 1. Read the input file name from the command line.
260
+ Step 2. If file name has no extension, add '.prompt' to the file name.
261
+ Step 3. Extract the basename and language from the file name. Use get_extension to get the file extension for the language. The file extension and language is used for all the subsequent steps.
262
+ Step 4. From the basename and file extension generate the appropriate file paths for the runnable and example output files considering the four possibilities. First determine which possibility for each of the outputs and then construct the proper file paths for each output.
263
+ Step 5. If a prompt input (indicated by a '.prompt' input file extension) do these steps:
264
+ Step 5a. Generate code from the input prompt file name using code_generator.
265
+ Step 5b. The program will write the runnable code to a runnable file path from Step 4.
266
+ Step 6. If a code file (indicated by a input file extension that isn't '.prompt') is provided or a "-oe" option is provided, the program will generate example code from the runnable code of Step 5 or the input code file using context_generator and write the example code to the example file path from Step 4.</modified_prompt>
267
+ </example_1>
268
+
269
+ <example_2>
270
+ <input_prompt>% You are an expert Python engineer. Your goal is to write a python command line program, "pdd", that will compile a prompt into a code file or a code file into an example code file. All output to the console will be pretty print using the Python rich library.
271
+
272
+ % Here is how the program will be used: pdd <input_prompt_file or input_code_file_to_generate_example_from>
273
+
274
+ % Prompt file names have this format: 'basename_language.prompt' (e.g. pdd_python.prompt, makefile_makefile.prompt, setup_bash.prompt)
275
+
276
+ % There are four possibilities for the output files:
277
+ - File name given without path (e.g. 'output.py'): This will write the 'output.py' file in the same directory as the input file.
278
+ - File name given with path (e.g. './output.py'): This will write the 'output.py' file in the './' directory.
279
+ - Path given without file name (e.g. './context'): This will write the file with the basename and appropriate extension (for generated runnable code and generated example code) in the './context' directory.
280
+ - Nothing specified by user (default): This will write the file with the basename and appropriate extension in the same directory as the input file.
281
+
282
+ % When given a prompt, the program will generate runnable code and example code if selected. When given a code file, an example file will be generated. Here are the options the program will support:
283
+ '--force': When writing the output files, if a file already exists, the program will ask before overwriting it unless a "--force" is present where it will just overwrite the file. It will default to Yes if user presses Enter.
284
+ '-o': Path or filename of the output of the runnable code. All four of the above possibilities are possible meaning for example, the user might just have "-o" or might have "-o ./output.py".
285
+ '-oe': Means program should generate example from runnable code. As will "-o" all four output possibilities are possible here.
286
+
287
+ % Here are example command lines:
288
+ -'pdd context_generator.py' will generate 'context_generator_example.py' in the same directory
289
+ -'pdd context_generator.py -oe context/' will generate 'context_generator_example.py' in the './context' directory
290
+ -'pdd context_generator_python.prompt -o pdd/ -oe context/' will generate 'context_generator.py' in the './pdd' directory and 'context_generator_example.py' in the './context' directory. 'context_generator' is the basename.
291
+ -'pdd makefile_makefile.prompt' will generate 'makefile' in the same directory
292
+ -'pdd pdd_python.prompt -o pdd/pdd_v1.py will generate 'pdd_v1.py' in the './pdd' directory and no example will be generated
293
+
294
+ % Here is an example how to generate code from the prompt from a file: ```<./context/code_generator_example.py>```
295
+
296
+ % Here is an example how to generate an example from a code file: ```<./context/context_generator_example.py>```
297
+
298
+ % Here is an example how to lookup a file extension given a language: ```<./context/get_extension_example.py>```
299
+
300
+ % This program will do the following:
301
+ Step 1. Read the input file name from the command line.
302
+ Step 2. If file name has no extension, add '.prompt' to the file name.
303
+ Step 3. Extract the basename and language from the file name. Use get_extension to get the file extension for the language. The file extension and language is used for all the subsequent steps.
304
+ Step 4. From the basename and file extension generate the appropriate file paths for the runnable and example output files considering the four possibilities. First determine which possibility for each of the outputs and then construct the proper file paths for each output.
305
+ Step 5. If a prompt input (indicated by a '.prompt' input file extension) do these steps:
306
+ Step 5a. Generate code from the input prompt file name using code_generator.
307
+ Step 5b. The program will write the runnable code to a runnable file path from Step 4.
308
+ Step 6. If a code file (indicated by a input file extension that isn't '.prompt') is provided or a "-oe" option is provided, the program will generate example code from the runnable code of Step 5 or the input code file using context_generator and write the example code to the example file path from Step 4.</input_prompt>
309
+ <input_code># To create the `pdd` command line program as described, we need to follow the steps outlined in the prompt. Below is the implementation of the `pdd` program in Python. This program will use the `rich` library for pretty printing and handle the various input and output scenarios as specified.
310
+
311
+ # First, ensure you have the necessary modules installed:
312
+ # ```sh
313
+ # pip install rich
314
+ # ```
315
+
316
+ # Next, create the `pdd.py` script:
317
+
318
+ # ```python
319
+ import os
320
+ import sys
321
+ import argparse
322
+ from rich.console import Console
323
+ from code_generator import code_generator
324
+ from context_generator import context_generator
325
+ from get_extension import get_extension
326
+
327
+ console = Console()
328
+
329
+ def main():
330
+ parser = argparse.ArgumentParser(description="Compile a prompt into a code file or a code file into an example code file.")
331
+ parser.add_argument('input_file', help="Input prompt file or input code file to generate example from")
332
+ parser.add_argument('-o', '--output', help="Path or filename of the output of the runnable code")
333
+ parser.add_argument('-oe', '--output_example', help="Path or filename of the output example code")
334
+ parser.add_argument('--force', action='store_true', help="Overwrite files without asking")
335
+
336
+ args = parser.parse_args()
337
+ input_file = args.input_file
338
+ output = args.output
339
+ output_example = args.output_example
340
+ force = args.force
341
+
342
+ # Step 1: Read the input file name from the command line
343
+ if not os.path.exists(input_file):
344
+ console.print(f"[bold red]Error:[/bold red] The file '{input_file}' does not exist.")
345
+ sys.exit(1)
346
+
347
+ # Step 2: If file name has no extension, add '.prompt' to the file name
348
+ if '.' not in input_file:
349
+ input_file += '.prompt'
350
+
351
+ # Step 3: Extract the basename and language from the file name
352
+ basename, ext = os.path.splitext(os.path.basename(input_file))
353
+ if ext == '.prompt':
354
+ language = basename.split('_')[-1]
355
+ else:
356
+ language = ext[1:]
357
+
358
+ file_extension = get_extension(language)
359
+
360
+ # Step 4: Generate the appropriate file paths for the runnable and example output files
361
+ def construct_output_path(output, default_name):
362
+ if output is None:
363
+ return os.path.join(os.path.dirname(input_file), default_name)
364
+ elif os.path.isdir(output):
365
+ return os.path.join(output, default_name)
366
+ else:
367
+ return output
368
+
369
+ runnable_output_path = construct_output_path(output, f"{basename}{file_extension}")
370
+ example_output_path = construct_output_path(output_example, f"{basename}_example{file_extension}")
371
+
372
+ # Step 5: If a prompt input, generate code from the input prompt file name using code_generator
373
+ if ext == '.prompt':
374
+ console.print(f"[bold green]Generating runnable code from prompt:[/bold green] {input_file}")
375
+ runnable_code = code_generator(input_file, language)
376
+ write_to_file(runnable_output_path, runnable_code, force)
377
+
378
+ # Step 6: If a code file is provided or a "-oe" option is provided, generate example code
379
+ if ext != '.prompt' or output_example:
380
+ console.print(f"[bold green]Generating example code from runnable code:[/bold green] {runnable_output_path}")
381
+ success = context_generator(runnable_output_path, example_output_path, force)
382
+ if success:
383
+ console.print(f"[bold green]Example code generated successfully:[/bold green] {example_output_path}")
384
+ else:
385
+ console.print(f"[bold red]Failed to generate example code.[/bold red]")
386
+
387
+ def write_to_file(file_path, content, force):
388
+ if os.path.exists(file_path) and not force:
389
+ console.print(f"[bold yellow]Warning:[/bold yellow] The file '{file_path}' already exists. Overwrite? [y/N]")
390
+ response = input().strip().lower()
391
+ if response not in ['y', 'yes', '']:
392
+ console.print(f"[bold red]Aborted:[/bold red] The file '{file_path}' was not overwritten.")
393
+ return
394
+
395
+ with open(file_path, 'w') as f:
396
+ f.write(content)
397
+ console.print(f"[bold green]File written successfully:[/bold green] {file_path}")
398
+
399
+ if __name__ == "__main__":
400
+ main()
401
+ # ```
402
+
403
+ # ### Explanation:
404
+ # 1. **Argument Parsing**: The script uses `argparse` to handle command-line arguments.
405
+ # 2. **File Existence Check**: It checks if the input file exists.
406
+ # 3. **File Extension Handling**: If the input file has no extension, `.prompt` is added.
407
+ # 4. **Basename and Language Extraction**: The script extracts the basename and language from the input file name.
408
+ # 5. **Output Path Construction**: It constructs the appropriate output paths for runnable and example files.
409
+ # 6. **Code Generation**: If the input is a prompt file, it generates runnable code using `code_generator`.
410
+ # 7. **Example Code Generation**: If the input is a code file or the `-oe` option is provided, it generates example code using `context_generator`.
411
+ # 8. **File Writing**: The script writes the generated code to the specified output files, handling overwrites based on the `--force` option.
412
+
413
+ # This script should be placed in a file named `pdd.py` and can be executed from the command line as described in the prompt.</input_code>
414
+ <example_code>runnable_output_path, example_output_path = construct_output_paths(
415
+ basename, # the basename of the file
416
+ file_extension, # the file extension based on the language
417
+ argv_output_path, # string from the '-o' flag
418
+ argv_example_output_path # string from the '-oe' flag
419
+ )</example_code>
420
+ <sub_prompt>% You are an expert Python engineer. Your goal is to write a Python function, "construct_output_paths", that will generate the appropriate file paths for the runnable and example output files that will be called by "pdd", the top-level command line program.
421
+
422
+ % Here are the inputs and outputs of the function:
423
+ Inputs:
424
+ - 'basename': A string containing the basename of the file
425
+ - 'file_extension': A string containing the file extension based on the language
426
+ - 'argv_output_path': A string from the '-o' flag (can be None)
427
+ - 'argv_example_output_path': A string from the '-oe' flag (can be None)
428
+ Outputs:
429
+ - Returns a tuple containing two strings: (runnable_output_path, example_output_path)
430
+
431
+ % Consider the four possibilities for the output files as described in the main prompt:
432
+ - File name given without path
433
+ - File name given with path
434
+ - Path given without file name
435
+ - Nothing specified by user (default)
436
+
437
+ % Prompt file names have this format: 'basename_language.prompt' (e.g. pdd_python.prompt, makefile_makefile.prompt, setup_bash.prompt)
438
+
439
+ % Here are example command lines:
440
+ -'pdd context_generator.py' will generate 'context_generator_example.py' in the same directory
441
+ -'pdd context_generator.py -oe context/' will generate 'context_generator_example.py' in the './context' directory
442
+ -'pdd context_generator_python.prompt -o pdd/ -oe context/' will generate 'context_generator.py' in the './pdd' directory and 'context_generator_example.py' in the './context' directory. 'context_generator' is the basename.
443
+ -'pdd makefile_makefile.prompt' will generate 'makefile' in the same directory
444
+ -'pdd pdd_python.prompt -o pdd/pdd_v1.py will generate 'pdd_v1.py' in the './pdd' directory and no example will be generated
445
+
446
+ % This function will do the following:
447
+ Step 1: Define a helper function to construct the output path based on the given arguments and default name.
448
+ Step 2: Use the helper function to construct the runnable_output_path using basename, file_extension, and argv_output_path.
449
+ Step 3: Use the helper function to construct the example_output_path using basename, file_extension, and argv_example_output_path.
450
+ Step 4: Return the tuple (runnable_output_path, example_output_path).
451
+ </sub_prompt>
452
+ <modified_prompt>% You are an expert Python engineer. Your goal is to write a python command line program, "pdd", that will compile a prompt into a code file or a code file into an example code file. All output to the console will be pretty print using the Python rich library.
453
+
454
+ % Here is how the program will be used: pdd <input_prompt_file or input_code_file_to_generate_example_from>
455
+
456
+ % Prompt file names have this format: 'basename_language.prompt' (e.g. pdd_python.prompt, makefile_makefile.prompt, setup_bash.prompt)
457
+
458
+ % When given a prompt, the program will generate runnable code and example code if selected. When given a code file, an example file will be generated. Here are the options the program will support:
459
+ '--force': When writing the output files, if a file already exists, the program will ask before overwriting it unless a "--force" is present where it will just overwrite the file. It will default to Yes if user presses Enter.
460
+ '-o': Path or filename of the output of the runnable code.
461
+ '-oe': Means program should generate example from runnable code.
462
+
463
+ % Here are example command lines:
464
+ -'pdd context_generator.py' will generate 'context_generator_example.py' in the same directory
465
+ -'pdd context_generator.py -oe context/' will generate 'context_generator_example.py' in the './context' directory
466
+ -'pdd context_generator_python.prompt -o pdd/ -oe context/' will generate 'context_generator.py' in the './pdd' directory and 'context_generator_example.py' in the './context' directory. 'context_generator' is the basename.
467
+ -'pdd makefile_makefile.prompt' will generate 'makefile' in the same directory
468
+ -'pdd pdd_python.prompt -o pdd/pdd_v1.py will generate 'pdd_v1.py' in the './pdd' directory and no example will be generated
469
+
470
+ % Here is an example how to generate code from the prompt from a file: ```<./context/code_generator_example.py>```
471
+
472
+ % Here is an example how to generate an example from a code file: ```<./context/context_generator_example.py>```
473
+
474
+ % Here is an example how to lookup a file extension given a language: ```<./context/get_extension_example.py>```
475
+
476
+ % Here is an example how to construct output paths: ```<./context/construct_output_paths_example.py>```
477
+
478
+ % This program will do the following:
479
+ Step 1. Read the input file name from the command line.
480
+ Step 2. If file name has no extension, add '.prompt' to the file name.
481
+ Step 3. Extract the basename and language from the file name. Use get_extension to get the file extension for the language. The file extension and language is used for all the subsequent steps.
482
+ Step 4. Use construct_output_paths to generate the appropriate file paths for the runnable and example output files.
483
+ Step 5. If a prompt input (indicated by a '.prompt' input file extension) do these steps:
484
+ Step 5a. Generate code from the input prompt file name using code_generator.
485
+ Step 5b. The program will write the runnable code to a runnable file path from Step 4.
486
+ Step 6. If a code file (indicated by a input file extension that isn't '.prompt') is provided or a "-oe" option is provided, the program will generate example code from the runnable code of Step 5 or the input code file using context_generator and write the example code to the example file path from Step 4.</modified_prompt>
487
+ </example_2>
488
+
489
+ <example_3>
490
+ <input_prompt>% You are an expert Python engineer. Your goal is to write a python function called 'postprocess' that will post-process the string output of a LLM so that the code can be run.
491
+
492
+ % Here are the inputs and outputs of the function:
493
+ Input:
494
+ 'llm_output' - A string contains a mix of text and sections of code separated by triple backticks.
495
+ 'language' - A string that is the type (e.g. python, bash) of file that will be outputed by the LLM
496
+ Output: returns a string that is the processed string that contains a properly commented out comments so that code can be run
497
+
498
+ % Here is an example how to get the lookup the comment line characters given a language: ```<./context/get_comment_example.py>```
499
+
500
+ % Here is an example how to comment out a line of code: ```<./context/comment_line_example.py>```
501
+
502
+ % Here is an example of llm_output: '''To implement the `context_generator` function as described, we will follow the steps outlined in your request. Below is the complete implementation of the function, which includes reading a Python file, preprocessing it, generating a prompt for the model, invoking the model, and writing the output to a specified file.
503
+
504
+ ```python
505
+ import os
506
+
507
+ def context_generator(python_filename: str, output_filename: str, force: bool = False) -> bool:
508
+ # Step 1: Read the Python file
509
+ try:
510
+ with open(python_filename, 'r') as file:
511
+ python_code = file.read()
512
+ except FileNotFoundError:
513
+ print(f"Error: The file {python_filename} does not exist.")
514
+ return False
515
+
516
+
517
+ # Step 3: Generate a prompt for GPT-4
518
+ prompt = f"""
519
+ You are an expert Python engineer. Based on the following Python code, generate a concise example of how to use the module properly.
520
+
521
+ Python Code:
522
+ ```python
523
+ {processed_content}
524
+ ```
525
+
526
+ return True
527
+ ```
528
+
529
+ ### Explanation of the Code:
530
+ 1. **File Reading**: The function attempts to read the specified Python file. If the file does not exist, it prints an error message and returns `False`.
531
+ 2. **Preprocessing**: It calls the `preprocess` function to process the content of the Python file.
532
+
533
+ ### Usage:
534
+ You can call this function by providing the necessary arguments, like so:
535
+
536
+ ```python
537
+ context_generator('your_python_file.py', 'output_example.py', force=False)
538
+ ```
539
+
540
+ Make sure to replace `'your_python_file.py'` and `'output_example.py'` with the actual file names you want to use.
541
+ To implement the context_generator function as described, we will follow the steps outlined in
542
+ your request. Below is the complete implementation of the function, which includes reading a
543
+ Python file, preprocessing it, generating a prompt for the model, invoking the model, and writing
544
+ the output to a specified file.'''
545
+
546
+ % Here is an example of the Output string that would be returned: '''#To implement the `context_generator` function as described, we will follow the steps outlined in your request. Below is the complete implementation of the function, which includes reading a Python file, preprocessing it, generating a prompt for the model, invoking the model, and writing the output to a specified file.
547
+ #
548
+ #```python
549
+ import os
550
+
551
+ def context_generator(python_filename: str, output_filename: str, force: bool = False) -> bool:
552
+ # Step 1: Read the Python file
553
+ try:
554
+ with open(python_filename, 'r') as file:
555
+ python_code = file.read()
556
+ except FileNotFoundError:
557
+ print(f"Error: The file {python_filename} does not exist.")
558
+ return False
559
+
560
+
561
+ # Step 3: Generate a prompt for GPT-4
562
+ prompt = f"""
563
+ You are an expert Python engineer. Based on the following Python code, generate a concise example of how to use the module properly.
564
+
565
+ Python Code:
566
+ ```python
567
+ {processed_content}
568
+ ```
569
+
570
+ return True
571
+ #```
572
+ #
573
+ #### Explanation of the Code:
574
+ #1. **File Reading**: The function attempts to read the specified Python file. If the file does not exist, it prints an error message and returns `False`.
575
+ #2. **Preprocessing**: It calls the `preprocess` function to process the content of the Python file.
576
+ #
577
+ #### Usage:
578
+ #You can call this function by providing the necessary arguments, like so:
579
+ #
580
+ #```python
581
+ #context_generator('your_python_file.py', 'output_example.py', force=False)
582
+ #```
583
+ #
584
+ #Make sure to replace `'your_python_file.py'` and `'output_example.py'` with the actual file names you want to use.
585
+ #To implement the context_generator function as described, we will follow the steps outlined in
586
+ #your request. Below is the complete implementation of the function, which includes reading a
587
+ #Python file, preprocessing it, generating a prompt for the model, invoking the model, and writing
588
+ #the output to a specified file.'''
589
+
590
+ % This function will do the following:
591
+ Step 1. For the specified file_type, associate the right comment line character with the programming language using the get_comment function.
592
+ Step 2. Find the top-level code sections via recursive function, 'find_section'. For a code section, the first backtick will always have a string right after it that determines what kind of code it is and the end of a section just has triple backticks. To properly return the list of top level-sections do the following sub-steps by iterating through lines of the string:
593
+ Step 2a. Find the start of a code block
594
+ Step 2b. If another start of another code block is found, call 'find_section' recursively with a sub-section flag True.
595
+ Step 2c. If not, but the end of a code block is found, we should do one of the following steps depending on the sub-section flag:
596
+ Step 2c_i: If it is a sub-section we should return with an empty list
597
+ Step 2c_ii: If it is not a sub-section we should know the end of the code block and we should record the program type and start/end lines into the output list
598
+ Step 2d. If all lines of the string are process, we should return the output list.
599
+ Step 3. For the sections that are the same as file_type, we will determine which section is the largest.
600
+ Step 4. Now using the original llm_output string, comment out, using the comment_line function, all lines of text until the start line of the largest section of the file_type we want and then resume commenting out the lines after end line of the largest section. Be sure the also comment out the triple backticks of the largest section. This will leave the executable part of largest section of code uncommented.
601
+ Step 5. The program will return the post processed string that contains a properly commented out program that can be run.</input_prompt>
602
+ <input_code>from pdd.get_comment import get_comment
603
+ from pdd.comment_line import comment_line
604
+
605
+ def find_section(lines, start_index=0, sub_section=False):
606
+ sections = []
607
+ i = start_index
608
+ while i < len(lines):
609
+ line = lines[i].strip()
610
+ if line.startswith('```'):
611
+ # Start of a code block
612
+ if len(line) > 3:
613
+ # Extract the language from the line
614
+ code_language = line[3:].strip()
615
+ start_line = i
616
+ i += 1
617
+ # Find the end of the code block
618
+ while i < len(lines) and not lines[i].strip().startswith('```'):
619
+ i += 1
620
+ if i < len(lines):
621
+ end_line = i
622
+ if not sub_section:
623
+ sections.append((code_language, start_line, end_line))
624
+ else:
625
+ return []
626
+ else:
627
+ # End of a code block without a language
628
+ if sub_section:
629
+ return []
630
+ i += 1
631
+ return sections
632
+
633
+ def postprocess(llm_output, language):
634
+ # Step 1: Get the comment character for the specified language
635
+ comment_characters = get_comment(language)
636
+
637
+ # Step 2: Find the top-level code sections
638
+ lines = llm_output.splitlines()
639
+ sections = find_section(lines)
640
+
641
+ # Step 3: Find the largest section of the specified file_type
642
+ largest_section = None
643
+ max_length = 0
644
+ for section in sections:
645
+ code_language, start_line, end_line = section
646
+ if code_language.lower() == language.lower():
647
+ length = end_line - start_line
648
+ if length > max_length:
649
+ max_length = length
650
+ largest_section = section
651
+
652
+ # Step 4: Comment out all lines except the largest section
653
+ if largest_section:
654
+ _, start_line, end_line = largest_section
655
+ processed_lines = []
656
+ for i, line in enumerate(lines):
657
+ if i < start_line or i > end_line:
658
+ processed_lines.append(comment_line(line, comment_characters))
659
+ else:
660
+ processed_lines.append(line)
661
+ return '\n'.join(processed_lines)
662
+
663
+ # If no section matches the language, comment out everything
664
+ return '\n'.join(comment_line(line, comment_characters) for line in lines)</input_code>
665
+ <example_code>sections = find_section(
666
+ lines, # splitlines of text, an array of lines of text
667
+ start_index=0, # start index/row of the line, default is row 0
668
+ sub_section=False # boolean to check if it is a sub-section, default is no
669
+ )</example_code>
670
+ <sub_prompt>% You are an expert Python engineer. Your goal is to write a Python function called 'find_section' that will find top-level code sections in a string output from an LLM.
671
+
672
+ % Here are the inputs and outputs of the function:
673
+ Inputs:
674
+ 'lines' - A list of strings, where each string is a line from the LLM output.
675
+ 'start_index' - An integer representing the starting index to begin searching (default is 0).
676
+ 'sub_section' - A boolean flag indicating whether this is a recursive call for a sub-section (default is False).
677
+ Output: returns a list of tuples, where each tuple contains (code_language, start_line, end_line) for each top-level code section found.
678
+
679
+ % Here is an example of how the function might be called:
680
+ ```python
681
+ lines = llm_output.splitlines()
682
+ sections = find_section(lines)
683
+ ```
684
+
685
+ % Here is an example of llm_output: '''To implement the `context_generator` function as described, we will follow the steps outlined in your request. Below is the complete implementation of the function, which includes reading a Python file, preprocessing it, generating a prompt for the model, invoking the model, and writing the output to a specified file.
686
+
687
+ ```python
688
+ import os
689
+
690
+ def context_generator(python_filename: str, output_filename: str, force: bool = False) -> bool:
691
+ # Step 1: Read the Python file
692
+ try:
693
+ with open(python_filename, 'r') as file:
694
+ python_code = file.read()
695
+ except FileNotFoundError:
696
+ print(f"Error: The file {python_filename} does not exist.")
697
+ return False
698
+
699
+
700
+ # Step 3: Generate a prompt for GPT-4
701
+ prompt = f"""
702
+ You are an expert Python engineer. Based on the following Python code, generate a concise example of how to use the module properly.
703
+
704
+ Python Code:
705
+ ```python
706
+ {processed_content}
707
+ ```
708
+
709
+ return True
710
+ ```
711
+
712
+ ### Explanation of the Code:
713
+ 1. **File Reading**: The function attempts to read the specified Python file. If the file does not exist, it prints an error message and returns `False`.
714
+ 2. **Preprocessing**: It calls the `preprocess` function to process the content of the Python file.
715
+
716
+ ### Usage:
717
+ You can call this function by providing the necessary arguments, like so:
718
+
719
+ ```python
720
+ context_generator('your_python_file.py', 'output_example.py', force=False)
721
+ ```
722
+
723
+ Make sure to replace `'your_python_file.py'` and `'output_example.py'` with the actual file names you want to use.
724
+ To implement the context_generator function as described, we will follow the steps outlined in
725
+ your request. Below is the complete implementation of the function, which includes reading a
726
+ Python file, preprocessing it, generating a prompt for the model, invoking the model, and writing
727
+ the output to a specified file.'''
728
+
729
+ % This function will do the following:
730
+ Step 1. Initialize an empty list to store the sections found.
731
+ Step 2. Iterate through the lines starting from start_index:
732
+ Step 2a. Find the start of a code block (line starting with triple backticks).
733
+ Step 2b. If another start of a code block is found, call 'find_section' recursively with sub_section flag set to True.
734
+ Step 2c. If the end of a code block is found (line with just triple backticks), do one of the following steps depending on the sub_section flag:
735
+ Step 2c_i: If it is a sub-section, return an empty list.
736
+ Step 2c_ii: If it is not a sub-section, record the program type and start/end lines into the output list.
737
+ Step 3. Return the list of sections found.</sub_prompt>
738
+ <modified_prompt>% You are an expert Python engineer. Your goal is to write a python function called 'postprocess' that will post-process the string output of a LLM so that the code can be run.
739
+
740
+ % Here are the inputs and outputs of the function:
741
+ Input:
742
+ 'llm_output' - A string contains a mix of text and sections of code separated by triple backticks.
743
+ 'language' - A string that is the type (e.g. python, bash) of file that will be outputed by the LLM
744
+ Output: returns a string that is the processed string that contains a properly commented out comments so that code can be run
745
+
746
+ % Here is an example how to get the lookup the comment line characters given a language: ```<./context/get_comment_example.py>```
747
+
748
+ % Here is an example how to comment out a line of code: ```<./context/comment_line_example.py>```
749
+
750
+ % Here is an example how to find code sections in LLM output: ```<./context/find_section_example.py>```
751
+
752
+ % Here is an example of llm_output: '''To implement the `context_generator` function as described, we will follow the steps outlined in your request. Below is the complete implementation of the function, which includes reading a Python file, preprocessing it, generating a prompt for the model, invoking the model, and writing the output to a specified file.
753
+
754
+ ```python
755
+ import os
756
+
757
+ def context_generator(python_filename: str, output_filename: str, force: bool = False) -> bool:
758
+ # Step 1: Read the Python file
759
+ try:
760
+ with open(python_filename, 'r') as file:
761
+ python_code = file.read()
762
+ except FileNotFoundError:
763
+ print(f"Error: The file {python_filename} does not exist.")
764
+ return False
765
+
766
+
767
+ # Step 3: Generate a prompt for GPT-4
768
+ prompt = f"""
769
+ You are an expert Python engineer. Based on the following Python code, generate a concise example of how to use the module properly.
770
+
771
+ Python Code:
772
+ ```python
773
+ {processed_content}
774
+ ```
775
+
776
+ return True
777
+ ```
778
+
779
+ ### Explanation of the Code:
780
+ 1. **File Reading**: The function attempts to read the specified Python file. If the file does not exist, it prints an error message and returns `False`.
781
+ 2. **Preprocessing**: It calls the `preprocess` function to process the content of the Python file.
782
+
783
+ ### Usage:
784
+ You can call this function by providing the necessary arguments, like so:
785
+
786
+ ```python
787
+ context_generator('your_python_file.py', 'output_example.py', force=False)
788
+ ```
789
+
790
+ Make sure to replace `'your_python_file.py'` and `'output_example.py'` with the actual file names you want to use.
791
+ To implement the context_generator function as described, we will follow the steps outlined in
792
+ your request. Below is the complete implementation of the function, which includes reading a
793
+ Python file, preprocessing it, generating a prompt for the model, invoking the model, and writing
794
+ the output to a specified file.'''
795
+
796
+ % Here is an example of the Output string that would be returned: '''#To implement the `context_generator` function as described, we will follow the steps outlined in your request. Below is the complete implementation of the function, which includes reading a Python file, preprocessing it, generating a prompt for the model, invoking the model, and writing the output to a specified file.
797
+ #
798
+ #```python
799
+ import os
800
+
801
+ def context_generator(python_filename: str, output_filename: str, force: bool = False) -> bool:
802
+ # Step 1: Read the Python file
803
+ try:
804
+ with open(python_filename, 'r') as file:
805
+ python_code = file.read()
806
+ except FileNotFoundError:
807
+ print(f"Error: The file {python_filename} does not exist.")
808
+ return False
809
+
810
+
811
+ # Step 3: Generate a prompt for GPT-4
812
+ prompt = f"""
813
+ You are an expert Python engineer. Based on the following Python code, generate a concise example of how to use the module properly.
814
+
815
+ Python Code:
816
+ ```python
817
+ {processed_content}
818
+ ```
819
+
820
+ return True
821
+ #```
822
+ #
823
+ #### Explanation of the Code:
824
+ #1. **File Reading**: The function attempts to read the specified Python file. If the file does not exist, it prints an error message and returns `False`.
825
+ #2. **Preprocessing**: It calls the `preprocess` function to process the content of the Python file.
826
+ #
827
+ #### Usage:
828
+ #You can call this function by providing the necessary arguments, like so:
829
+ #
830
+ #```python
831
+ #context_generator('your_python_file.py', 'output_example.py', force=False)
832
+ #```
833
+ #
834
+ #Make sure to replace `'your_python_file.py'` and `'output_example.py'` with the actual file names you want to use.
835
+ #To implement the context_generator function as described, we will follow the steps outlined in
836
+ #your request. Below is the complete implementation of the function, which includes reading a
837
+ #Python file, preprocessing it, generating a prompt for the model, invoking the model, and writing
838
+ #the output to a specified file.'''
839
+
840
+ % This function will do the following:
841
+ Step 1. For the specified file_type, associate the right comment line character with the programming language using the get_comment function.
842
+ Step 2. Use the find_section function to find the top-level code sections in the llm_output.
843
+ Step 3. For the sections that are the same as file_type, determine which section is the largest.
844
+ Step 4. Now using the original llm_output string, comment out, using the comment_line function, all lines of text until the start line of the largest section of the file_type we want and then resume commenting out the lines after end line of the largest section. Be sure to also comment out the triple backticks of the largest section. This will leave the executable part of largest section of code uncommented.
845
+ Step 5. The program will return the post processed string that contains a properly commented out program that can be run.</modified_prompt>
846
+ </example_3>
847
+
848
+ <example_4>
849
+ <input_prompt>% You are an expert Python software engineer. Your goal is to write a Python function, "construct_paths", that will generate and check the appropriate input and output file paths and then load the input files. This function will will be used by pdd to do this function. All output to the console will be pretty print using the Python rich library. The CLI will be handled using the Python Click library.
850
+
851
+ % Here is a detailed description of the program functionality: ```<./README.md>```
852
+
853
+ % Here is an example how to lookup a file extension given a language: ```<./context/get_extension_example.py>```
854
+
855
+ % Here are the inputs and outputs of the function:
856
+ Inputs:
857
+ - 'input_file_paths' (dict) - A dictionary to the paths of the input files with the keys being those specified in the examples from the pdd program description.
858
+ - 'force' (boolean) - A flag that indicates whether to overwrite the output files if they already exist.
859
+ - 'quiet' (boolean) - A flag that indicates whether to suppress the output.
860
+ - 'command' (string) - pdd command that was run.
861
+ - 'command_options' (dict) - A dictionary of the command options for the given command.
862
+ Outputs:
863
+ - 'input_strings' (dict) - A dictionary with the keys being the pdd description examples and the values being the input file strings.
864
+ - 'output_file_paths' (dict)- A dictionary with the keys being the loaded input files and output files paths.
865
+ - 'language' (string) - The language of the output file.
866
+
867
+ % If the file name has no extension, add the appropriate file extension (e.g '.prompt' to input file for the 'generate' command) to the file name.
868
+
869
+ % If the command is 'generate' extract the basename and language from the input_file_path. Use get_extension to get the file extension for the language. The file extension and language is used for the subsequent functionality below. Be able to handle files missing a '_' in the file name.
870
+
871
+ % Unless quiet is True, print out the input and output file paths that are being used and the steps being done below.
872
+
873
+ % This function will do the following:
874
+ Step 1. Construct the input file paths using above rules.
875
+ Step 2. Load the input files into the input_strings dictionary with the pdd description examples as the keys. Alert the user of any errors in loading the input files.
876
+ Step 3. Construct the output file paths using the above rules using a separate sub-function. It should construct the full file path including the output file name for the output files following the rules in the "Output Location Specification" section of the pdd program description.
877
+ Step 4. If the output files already exist, and force isn't true, check with the user if the program should overwrite.
878
+ Step 5. Return the outputs</input_prompt>
879
+ <input_code>import os
880
+ import click
881
+ from rich import print
882
+ from get_extension import get_extension
883
+
884
+ def generate_output_filename(command, key, basename, language, file_extension):
885
+ if command == 'generate':
886
+ return f"{basename}{file_extension}"
887
+ elif command == 'example':
888
+ return f"{basename}_example{file_extension}"
889
+ elif command == 'test':
890
+ return f"test_{basename}{file_extension}"
891
+ elif command == 'preprocess':
892
+ return f"{basename}_{language or 'unknown'}_preprocessed.prompt"
893
+ elif command == 'fix':
894
+ if key == 'output-test':
895
+ return f"test_{basename}_fixed{file_extension}"
896
+ else:
897
+ return f"{basename}_fixed{file_extension}"
898
+ else:
899
+ return f"{basename}_output{file_extension}"
900
+
901
+ def construct_paths(input_file_paths, force, quiet, command, command_options):
902
+ input_strings = {}
903
+ output_file_paths = {}
904
+ language = None
905
+
906
+ def print_if_not_quiet(message):
907
+ if not quiet:
908
+ print(message)
909
+
910
+ # Step 1: Construct the input file paths
911
+ for key, path in input_file_paths.items():
912
+ if not os.path.splitext(path)[1]:
913
+ if command == 'generate':
914
+ path += '.prompt'
915
+ input_file_paths[key] = path
916
+
917
+ print_if_not_quiet(f"Input file path for {key}: {path}")
918
+
919
+ # Step 2: Load the input files
920
+ for key, path in input_file_paths.items():
921
+ try:
922
+ with open(path, 'r') as file:
923
+ input_strings[key] = file.read()
924
+ print_if_not_quiet(f"Loaded input file: {path}")
925
+ except IOError as e:
926
+ print(f"[bold red]Error loading input file {path}: {str(e)}[/bold red]")
927
+ return None, None, None
928
+
929
+ # Extract basename and language
930
+ prompt_file = input_file_paths.get('PROMPT_FILE', '')
931
+ basename, ext = os.path.splitext(os.path.basename(prompt_file))
932
+ parts = basename.split('_')
933
+ if len(parts) > 1:
934
+ language = parts[-1]
935
+ basename = '_'.join(parts[:-1])
936
+ else:
937
+ language = ext[1:] # Remove the leading dot
938
+
939
+ if language:
940
+ file_extension = get_extension(language)
941
+ else:
942
+ file_extension = '.txt'
943
+ print(f"[bold yellow]Warning: Could not determine language. Using .txt as default file extension.[/bold yellow]")
944
+
945
+ print_if_not_quiet(f"Extracted basename: {basename}, language: {language}, File extension: {file_extension}")
946
+
947
+ # Step 3: Construct the output file paths
948
+ for key in command_options:
949
+ if key.startswith('output'):
950
+ output_path = command_options[key]
951
+ if output_path:
952
+ if os.path.isdir(output_path):
953
+ filename = generate_output_filename(command, key, basename, language, file_extension)
954
+ output_path = os.path.join(output_path, filename)
955
+ elif not os.path.splitext(output_path)[1]:
956
+ output_path += file_extension
957
+ else:
958
+ output_path = generate_output_filename(command, key, basename, language, file_extension)
959
+
960
+ output_file_paths[key] = os.path.abspath(output_path)
961
+ print_if_not_quiet(f"Output file path for {key}: {output_file_paths[key]}")
962
+
963
+ # Step 4: Check if output files exist and confirm overwrite if necessary
964
+ for key, path in output_file_paths.items():
965
+ if os.path.exists(path) and not force:
966
+ if not click.confirm(f"Output file {path} already exists. Overwrite?"):
967
+ print(f"[bold yellow]Operation cancelled for {key}.[/bold yellow]")
968
+ return None, None, None
969
+
970
+ # Step 5: Return the outputs
971
+ return input_strings, output_file_paths, language</input_code>
972
+ <example_code>filename = generate_output_filename(
973
+ command, # pdd commands like 'generate', etc.
974
+ key, # output dictionary key like 'output', 'output-test', etc.
975
+ basename, # the basename of the file
976
+ language, # the language of the file
977
+ file_extension # the file extension of the file
978
+ )</example_code>
979
+ <sub_prompt>% You are an expert Python software engineer. Your task is to implement a function called `generate_output_filename` that creates appropriate output filenames for different commands in a Python program.
980
+
981
+ % Inputs: The function should take the following parameters:
982
+ - `command` (string): The command being executed (e.g., 'generate', 'example', 'test', 'preprocess', 'fix')
983
+ - `key` (string): The output dictionary key (e.g., 'output', 'output-test')
984
+ - `basename` (string): The base name of the file
985
+ - `language` (string): The programming language of the file
986
+ - `file_extension` (string): The file extension to be used
987
+
988
+ % Outputs: The function should return a string representing the generated output filename.
989
+
990
+ % Follow these rules for generating the output filename:
991
+ 1. For the 'generate' command: Return `f"{basename}{file_extension}"`
992
+ 2. For the 'example' command: Return `f"{basename}_example{file_extension}"`
993
+ 3. For the 'test' command: Return `f"test_{basename}{file_extension}"`
994
+ 4. For the 'preprocess' command: Return `f"{basename}_{language or 'unknown'}_preprocessed.prompt"`
995
+ 5. For the 'fix' command:
996
+ - If the key is 'output-test', return `f"test_{basename}_fixed{file_extension}"`
997
+ - Otherwise, return `f"{basename}_fixed{file_extension}"`
998
+ 6. For any other command: Return `f"{basename}_output{file_extension}"`
999
+
1000
+ % Implement the function to handle all these cases efficiently and return the appropriate filename as a string, accordingly.
1001
+
1002
+ % Ensure the function handles all cases correctly and returns the appropriate filename string, language, and file extension. The function should be robust and able to handle various edge cases, such as missing file extensions or languages.</sub_prompt>
1003
+ <modified_prompt>% You are an expert Python software engineer. Your goal is to write a Python function, "construct_paths", that will generate and check the appropriate input and output file paths and then load the input files. This function will be used by pdd to perform this functionality. All output to the console will be pretty printed using the Python rich library. The CLI will be handled using the Python Click library.
1004
+
1005
+ % Here is a detailed description of the program functionality: ```<./README.md>```
1006
+
1007
+ % Here is an example of how to lookup a file extension given a language: ```<./context/get_extension_example.py>```
1008
+
1009
+ % Here is an example of how to generate the appropriate output filenames based on the command, key, basename, language, and file extension using the `generate_output_filename` function: ```<./context/generate_output_filename_example.py>```
1010
+
1011
+ % Here are the inputs and outputs of the function:
1012
+ Inputs:
1013
+ - 'input_file_paths' (dict) - A dictionary of the paths of the input files with the keys being those specified in the examples from the pdd program description.
1014
+ - 'force' (boolean) - A flag that indicates whether to overwrite the output files if they already exist.
1015
+ - 'quiet' (boolean) - A flag that indicates whether to suppress the output.
1016
+ - 'command' (string) - pdd command that was run.
1017
+ - 'command_options' (dict) - A dictionary of the command options for the given command.
1018
+ Outputs:
1019
+ - 'input_strings' (dict) - A dictionary with the keys being the pdd description examples and the values being the input file strings.
1020
+ - 'output_file_paths' (dict)- A dictionary with the keys being the loaded input files and output files paths.
1021
+ - 'language' (string) - The language of the output file.
1022
+
1023
+ % If the file name has no extension, add the appropriate file extension (e.g '.prompt' to input file for the 'generate' command) to the file name.
1024
+
1025
+ % If the command is 'generate' extract the basename and language from the input_file_path. Use get_extension to get the file extension for the language. The file extension and language is used for the subsequent functionality below. Be able to handle files missing a '_' in the file name.
1026
+
1027
+ % Unless quiet is True, print out the input and output file paths that are being used and the steps being done below.
1028
+
1029
+ % This function will do the following:
1030
+ Step 1. Construct the input file paths using above rules.
1031
+ Step 2. Load the input files into the input_strings dictionary with the pdd description examples as the keys. Alert the user of any errors in loading the input files.
1032
+ Step 3. Construct the output file paths using the above rules using the `generate_output_filename` function. It should construct the full file path including the output file name for the output files following the rules in the "Output Location Specification" section of the pdd program description.
1033
+ Step 4. If the output files already exist, and force isn't true, check with the user if the program should overwrite.
1034
+ Step 5. Return the outputs</modified_prompt>
1035
+ </example_4>
1036
+ </examples>
1037
+
1038
+ <context>
1039
+ % You are an expert LLM Prompt Engineer. Your goal is to split the input_prompt into a sub_prompt and modified_prompt with no loss of functionality.
1040
+
1041
+ % Here are the inputs and outputs of this prompt:
1042
+ <input_definitions>
1043
+ Input:
1044
+ 'input_prompt' - A string contains the prompt that will be split into a sub_prompt and modified_prompt.
1045
+ 'input_code' - A string that contains the code that was generated from the input_prompt.
1046
+ 'example_code' - A string that contains the code example of how the code generated from the sub_prompt would be used by the code generated from the modified_prompt.
1047
+ </input_definitions>
1048
+ <output_definitions>
1049
+ Output:
1050
+ 'sub_prompt' - A string that contains the sub_prompt that was split from the input_prompt.
1051
+ 'modified_prompt' - A string that contains the modified prompt from input_prompt split from the above sub_prompt.
1052
+ </output_definitions>
1053
+ </context>
1054
+
1055
+ <inputs>
1056
+ <input_prompt>{input_prompt}</input_prompt>
1057
+ <input_code>{input_code}</input_code>
1058
+ <example_code>{example_code}</example_code>
1059
+ </inputs>
1060
+
1061
+ <instructions>
1062
+ % Follow these instructions:
1063
+ 1. Write out the difficulties in spliting the prompt.
1064
+ 2. Write out how to overcome the difficulties.
1065
+ 3. Generate the sub_prompt.
1066
+ 4. Generate the modified_prompt.
1067
+ </instructions>
1068
+
12
1069
  </example_tagged_prompt>
13
1070
  </example_1>
14
1071
 
15
1072
  <example_2>
16
1073
  % Here is an example_raw_prompt that needs XML tagging:
17
1074
  <example_raw_prompt>
18
- <include>context/xml/2/xml_convertor_LLM.prompt</include>
19
- </example_raw_prompt>
1075
+ % You are an expert Prompt Engineer. Your goal is to enhance a given prompt by only adding XML tags where necessary to improve its structure and readability. Do not add any additional content or XML tags unless it is clearly required by the structure of the input_raw_prompt.
20
1076
 
21
- % Here is an example_tagged_prompt from the example_raw_prompt above:
22
- <example_tagged_prompt>
23
- <include>context/xml/2/xml_convertor_xml_LLM.prompt</include>
1077
+ % Here is the input_raw_prompt that needs XML tagging to improve its organization: <input_raw_prompt>{raw_prompt}</input_raw_prompt>
1078
+
1079
+ <example>
1080
+ % Here is an example_raw_prompt that needs XML tagging:
1081
+ <example_raw_prompt>
1082
+ <examples>
1083
+ % Here is example_1 of how to split and generate the sub_prompt and modified_prompt:
1084
+ example_1_input_prompt: ```<./context/split/1/initial_pdd_python.prompt>```
1085
+ example_1_input_code: ```<./context/split/1/pdd.py>```
1086
+ example_1_example_code: ```<./context/split/1/split_get_extension.py>```
1087
+ example_1_sub_prompt: ```<./context/split/1/sub_pdd_python.prompt>```
1088
+ example_1_modified_prompt: ```<./context/split/1/final_pdd_python.prompt>```
1089
+
1090
+ % Here is example_2 of how to split and generate the sub_prompt and modified_prompt:
1091
+ example_2_input_prompt: ```<./context/split/2/initial_pdd_python.prompt>```
1092
+ example_2_input_code: ```<./context/split/2/pdd.py>```
1093
+ example_2_example_code: ```<./context/split/2/split_pdd_construct_output_path.py>```
1094
+ example_2_sub_prompt: ```<./context/split/2/sub_pdd_python.prompt>```
1095
+ example_2_modified_prompt: ```<./context/split/2/final_pdd_python.prompt>```
1096
+
1097
+ % Here is example_3 of how to split and generate the sub_prompt and modified_prompt:
1098
+ example_3_input_prompt: ```<./context/split/3/initial_postprocess_python.prompt>```
1099
+ example_3_input_code: ```<./context/split/3/postprocess.py>```
1100
+ example_3_example_code: ```<./context/split/3/split_postprocess_find_section.py>```
1101
+ example_3_sub_prompt: ```<./context/split/3/sub_postprocess_python.prompt>```
1102
+ example_3_modified_prompt: ```<./context/split/3/final_postprocess_python.prompt>```
1103
+
1104
+ % Here is example_4 of how to split and generate the sub_prompt and modified_prompt:
1105
+ example_4_input_prompt: ```<./context/split/4/initial_construct_paths_python.prompt>```
1106
+ example_4_input_code: ```<./context/split/4/construct_paths.py>```
1107
+ example_4_example_code: ```<./context/split/4/split_construct_paths_generate_output_filename.py>```
1108
+ example_4_sub_prompt: ```<./context/split/4/sub_construct_paths_python.prompt>```
1109
+ example_4_modified_prompt: ```<./context/split/4/final_construct_paths_python.prompt>```
1110
+ </examples>
1111
+
1112
+ % You are an expert LLM Prompt Engineer. Your goal is to split the input_prompt into a sub_prompt and modified_prompt with no loss of functionality.
1113
+
1114
+ % Here are the inputs and outputs of this prompt:
1115
+ Input:
1116
+ 'input_prompt' - A string contains the prompt that will be split into a sub_prompt and modified_prompt.
1117
+ 'input_code' - A string that contains the code that was generated from the input_prompt.
1118
+ 'example_code' - A string that contains the code example of how the code generated from the sub_prompt would be used by the code generated from the modified_prompt.
1119
+ Output:
1120
+ 'sub_prompt' - A string that contains the sub_prompt that was split from the input_prompt.
1121
+ 'modified_prompt' - A string that contains the modified prompt from input_prompt split from the above sub_prompt.
1122
+
1123
+ % Here is the input_prompt to split: ```{input_prompt}```
1124
+ % Here is the input_code: ```{input_code}```
1125
+ % Here is the example_code: ```{example_code}```
1126
+
1127
+ % Follow these instructions:
1128
+ 1. Write out the difficulties in spliting the prompt
1129
+ 2. Write out how to overcome the difficulties
1130
+ 3. Generate the sub_prompt.
1131
+ 4. Generate the modified_prompt.
1132
+ </example_raw_prompt>
1133
+
1134
+ % Here is an example_tagged_prompt from the example_raw_prompt above:
1135
+ <example_tagged_prompt>
1136
+ <examples>
1137
+ <example_1>
1138
+ <input_prompt>% You are an expert Python engineer. Your goal is to write a python command line program, "pdd", that will compile a prompt into a code file or a code file into an example code file. All output to the console will be pretty print using the Python rich library.
1139
+
1140
+ % Here is how the program will be used: pdd <input_prompt_file or input_code_file_to_generate_example_from>
1141
+
1142
+ % Prompt file names have this format: 'basename_language.prompt' (e.g. pdd_python.prompt, makefile_makefile.prompt, setup_bash.prompt)
1143
+
1144
+ % There are four possibilities for the output files:
1145
+ - File name given without path (e.g. 'output.py'): This will write the 'output.py' file in the same directory as the input file.
1146
+ - File name given with path (e.g. './output.py'): This will write the 'output.py' file in the './' directory.
1147
+ - Path given without file name (e.g. './context'): This will write the file with the basename and appropriate extension (for generated runnable code and generated example code) in the './context' directory.
1148
+ - Nothing specified by user (default): This will write the file with the basename and appropriate extension in the same directory as the input file.
1149
+
1150
+ % When given a prompt, the program will generate runnable code and example code if selected. When given a code file, an example file will be generated. Here are the options the program will support:
1151
+ '--force': When writing the output files, if a file already exists, the program will ask before overwriting it unless a "--force" is present where it will just overwrite the file. It will default to Yes if user presses Enter.
1152
+ '-o': Path or filename of the output of the runnable code. All four of the above possibilities are possible meaning for example, the user might just have "-o" or might have "-o ./output.py".
1153
+ '-oe': Means program should generate example from runnable code. As will "-o" all four output possibilities are possible here.
1154
+
1155
+ % Here are example command lines:
1156
+ -'pdd context_generator.py' will generate 'context_generator_example.py' in the same directory
1157
+ -'pdd context_generator.py -oe context/' will generate 'context_generator_example.py' in the './context' directory
1158
+ -'pdd context_generator_python.prompt -o pdd/ -oe context/' will generate 'context_generator.py' in the './pdd' directory and 'context_generator_example.py' in the './context' directory. 'context_generator' is the basename.
1159
+ -'pdd makefile_makefile.prompt' will generate 'makefile' in the same directory
1160
+ -'pdd pdd_python.prompt -o pdd/pdd_v1.py will generate 'pdd_v1.py' in the './pdd' directory and no example will be generated
1161
+
1162
+ % Here is an example how to generate code from the prompt from a file: ```<./context/code_generator_example.py>```
1163
+
1164
+ % Here is an example how to generate an example from a code file: ```<./context/context_generator_example.py>```
1165
+
1166
+ % This program will do the following:
1167
+ Step 1. Read the input file name from the command line.
1168
+ Step 2. If file name has no extension, add '.prompt' to the file name.
1169
+ Step 3. Extract the basename and language from the file name so the right code file extension (e.g. '.sh' for bash, '' for makefile, '.py' for Python) and language is used for all the subsequent steps.
1170
+ Step 4. From the basename and file extension generate the appropriate file paths for the runnable and example output files considering the four possibilities. First determine which possibility for each of the outputs and then construct the proper file paths for each output.
1171
+ Step 5. If a prompt input (indicated by a '.prompt' input file extension) do these steps:
1172
+ Step 5a. Generate code from the input prompt file name using code_generator.
1173
+ Step 5b. The program will write the runnable code to a runnable file path from Step 4.
1174
+ Step 6. If a code file (indicated by a input file extension that isn't '.prompt') is provided or a "-oe" option is provided, the program will generate example code from the runnable code of Step 5 or the input code file using context_generator and write the example code to the example file path from Step 4.</input_prompt>
1175
+ <input_code># To create the command line program "pdd" as described, we will use Python's `argparse` for command line argument parsing, and the `rich` library for pretty printing. The program will handle both prompt files and code files, generating runnable code and example code as specified.
1176
+
1177
+ # Here's a complete implementation of the `pdd` program:
1178
+
1179
+ # ```python
1180
+ import os
1181
+ import sys
1182
+ import argparse
1183
+ from rich.console import Console
1184
+ from rich.prompt import Confirm
1185
+ from code_generator import code_generator
1186
+ from context_generator import context_generator
1187
+
1188
+ console = Console()
1189
+
1190
+ def get_file_paths(input_file, output_file, example_output_file):
1191
+ # Extract basename and language from the input file
1192
+ basename, ext = os.path.splitext(os.path.basename(input_file))
1193
+ language = ext[1:] # Remove the dot
1194
+
1195
+ # Determine output file paths
1196
+ if output_file:
1197
+ runnable_file_path = output_file
1198
+ else:
1199
+ runnable_file_path = os.path.join(os.path.dirname(input_file), f"{basename}.{get_extension(language)}")
1200
+
1201
+ if example_output_file:
1202
+ example_file_path = example_output_file
1203
+ else:
1204
+ example_file_path = os.path.join(os.path.dirname(input_file), f"{basename}_example.{get_example_extension(language)}")
1205
+
1206
+ return runnable_file_path, example_file_path
1207
+
1208
+ def get_extension(language):
1209
+ extensions = {
1210
+ 'python': 'py',
1211
+ 'bash': 'sh',
1212
+ 'makefile': 'mk',
1213
+ # Add more languages and their extensions as needed
1214
+ }
1215
+ return extensions.get(language, '')
1216
+
1217
+ def get_example_extension(language):
1218
+ return 'py' # Assuming example files are always Python files for simplicity
1219
+
1220
+ def confirm_overwrite(file_path):
1221
+ if os.path.exists(file_path):
1222
+ return Confirm.ask(f"{file_path} already exists. Do you want to overwrite it?", default=True)
1223
+ return True
1224
+
1225
+ def main():
1226
+ parser = argparse.ArgumentParser(description="Compile prompts into code files or generate example code from code files.")
1227
+ parser.add_argument('input', help='Input prompt file or code file to generate example from')
1228
+ parser.add_argument('-o', '--output', help='Path or filename of the output runnable code')
1229
+ parser.add_argument('-oe', '--output-example', help='Path or filename of the output example code')
1230
+ parser.add_argument('--force', action='store_true', help='Force overwrite existing files without confirmation')
1231
+
1232
+ args = parser.parse_args()
1233
+
1234
+ input_file = args.input
1235
+ if not input_file.endswith('.prompt'):
1236
+ if not os.path.splitext(input_file)[1]: # No extension, assume it's a code file
1237
+ input_file += '.prompt'
1238
+
1239
+ # Determine if input is a prompt or code file
1240
+ is_prompt = input_file.endswith('.prompt')
1241
+
1242
+ # Get output file paths
1243
+ runnable_file_path, example_file_path = get_file_paths(input_file, args.output, args.output_example)
1244
+
1245
+ # Handle the runnable code generation
1246
+ if is_prompt:
1247
+ console.print(f"[bold green]Generating runnable code from prompt: {input_file}[/bold green]")
1248
+ runnable_code = code_generator(input_file, get_extension(os.path.splitext(input_file)[1][1:]))
1249
+
1250
+ if not args.force and not confirm_overwrite(runnable_file_path):
1251
+ console.print("[bold red]Operation cancelled.[/bold red]")
1252
+ return
1253
+
1254
+ with open(runnable_file_path, 'w') as f:
1255
+ f.write(runnable_code)
1256
+ console.print(f"[bold blue]Runnable code written to: {runnable_file_path}[/bold blue]")
1257
+
1258
+ # Handle example code generation
1259
+ if not is_prompt or args.output_example:
1260
+ console.print(f"[bold green]Generating example code from: {runnable_file_path}[/bold green]")
1261
+ success = context_generator(runnable_file_path, example_file_path, force=args.force)
1262
+
1263
+ if success:
1264
+ console.print(f"[bold blue]Example code written to: {example_file_path}[/bold blue]")
1265
+ else:
1266
+ console.print("[bold red]Example generation failed.[/bold red]")
1267
+
1268
+ if __name__ == "__main__":
1269
+ main()
1270
+ # ```
1271
+
1272
+ # ### Explanation of the Code:
1273
+ # 1. **Imports**: We import necessary modules including `argparse` for command line parsing, `os` for file path manipulations, and `rich` for console output.
1274
+ # 2. **Functions**:
1275
+ # - `get_file_paths`: Determines the output file paths based on the input file and user-specified options.
1276
+ # - `get_extension` and `get_example_extension`: Return the appropriate file extensions based on the language.
1277
+ # - `confirm_overwrite`: Asks the user for confirmation if a file already exists.
1278
+ # 3. **Main Function**:
1279
+ # - Parses command line arguments.
1280
+ # - Checks if the input file is a prompt or a code file.
1281
+ # - Generates runnable code from the prompt file and writes it to the specified output path.
1282
+ # - Generates example code from the runnable code if specified.
1283
+ # 4. **Execution**: The script runs the `main` function when executed.
1284
+
1285
+ # ### Usage:
1286
+ # - To run the program, save it as `pdd.py` and execute it from the command line:
1287
+ # ```bash
1288
+ # python pdd.py <input_prompt_file or input_code_file_to_generate_example_from> [options]
1289
+ # ```
1290
+
1291
+ # ### Requirements:
1292
+ # - Ensure you have the `rich`, `langchain`, and `tiktoken` libraries installed, along with the `code_generator` and `context_generator` modules available in your environment.</input_code>
1293
+ <example_code>file_extension = get_extension(language)</example_code>
1294
+ <sub_prompt>% You are an expert Python engineer. Your goal is to write a python function, "get_extension", that will return the file extension associated with a given language.
1295
+
1296
+ % Here are the inputs and outputs of the function:
1297
+ Input: 'language' - A string containing the language (e.g. Bash, Makefile, Python).
1298
+ Output: returns a string that is the extension for the langauge
1299
+
1300
+ % This program will do the following:
1301
+ Step 1. Lower case the language string to make the comparison case insensitive.
1302
+ Step 2. Look up the file extension for the given language
1303
+ Step 3. Return the file extension</sub_prompt>
1304
+ <modified_prompt>% You are an expert Python engineer. Your goal is to write a python command line program, "pdd", that will compile a prompt into a code file or a code file into an example code file. All output to the console will be pretty print using the Python rich library.
1305
+
1306
+ % Here is how the program will be used: pdd <input_prompt_file or input_code_file_to_generate_example_from>
1307
+
1308
+ % Prompt file names have this format: 'basename_language.prompt' (e.g. pdd_python.prompt, makefile_makefile.prompt, setup_bash.prompt)
1309
+
1310
+ % There are four possibilities for the output files:
1311
+ - File name given without path (e.g. 'output.py'): This will write the 'output.py' file in the same directory as the input file.
1312
+ - File name given with path (e.g. './output.py'): This will write the 'output.py' file in the './' directory.
1313
+ - Path given without file name (e.g. './context'): This will write the file with the basename and appropriate extension (for generated runnable code and generated example code) in the './context' directory.
1314
+ - Nothing specified by user (default): This will write the file with the basename and appropriate extension in the same directory as the input file.
1315
+
1316
+ % When given a prompt, the program will generate runnable code and example code if selected. When given a code file, an example file will be generated. Here are the options the program will support:
1317
+ '--force': When writing the output files, if a file already exists, the program will ask before overwriting it unless a "--force" is present where it will just overwrite the file. It will default to Yes if user presses Enter.
1318
+ '-o': Path or filename of the output of the runnable code. All four of the above possibilities are possible meaning for example, the user might just have "-o" or might have "-o ./output.py".
1319
+ '-oe': Means program should generate example from runnable code. As will "-o" all four output possibilities are possible here.
1320
+
1321
+ % Here are example command lines:
1322
+ -'pdd context_generator.py' will generate 'context_generator_example.py' in the same directory
1323
+ -'pdd context_generator.py -oe context/' will generate 'context_generator_example.py' in the './context' directory
1324
+ -'pdd context_generator_python.prompt -o pdd/ -oe context/' will generate 'context_generator.py' in the './pdd' directory and 'context_generator_example.py' in the './context' directory. 'context_generator' is the basename.
1325
+ -'pdd makefile_makefile.prompt' will generate 'makefile' in the same directory
1326
+ -'pdd pdd_python.prompt -o pdd/pdd_v1.py will generate 'pdd_v1.py' in the './pdd' directory and no example will be generated
1327
+
1328
+ % Here is an example how to generate code from the prompt from a file: ```<./context/code_generator_example.py>```
1329
+
1330
+ % Here is an example how to generate an example from a code file: ```<./context/context_generator_example.py>```
1331
+
1332
+ % Here is an example how to lookup a file extension given a language: ```<./context/get_extension_example.py>```
1333
+
1334
+ % This program will do the following:
1335
+ Step 1. Read the input file name from the command line.
1336
+ Step 2. If file name has no extension, add '.prompt' to the file name.
1337
+ Step 3. Extract the basename and language from the file name. Use get_extension to get the file extension for the language. The file extension and language is used for all the subsequent steps.
1338
+ Step 4. From the basename and file extension generate the appropriate file paths for the runnable and example output files considering the four possibilities. First determine which possibility for each of the outputs and then construct the proper file paths for each output.
1339
+ Step 5. If a prompt input (indicated by a '.prompt' input file extension) do these steps:
1340
+ Step 5a. Generate code from the input prompt file name using code_generator.
1341
+ Step 5b. The program will write the runnable code to a runnable file path from Step 4.
1342
+ Step 6. If a code file (indicated by a input file extension that isn't '.prompt') is provided or a "-oe" option is provided, the program will generate example code from the runnable code of Step 5 or the input code file using context_generator and write the example code to the example file path from Step 4.</modified_prompt>
1343
+ </example_1>
1344
+
1345
+ <example_2>
1346
+ <input_prompt>% You are an expert Python engineer. Your goal is to write a python command line program, "pdd", that will compile a prompt into a code file or a code file into an example code file. All output to the console will be pretty print using the Python rich library.
1347
+
1348
+ % Here is how the program will be used: pdd <input_prompt_file or input_code_file_to_generate_example_from>
1349
+
1350
+ % Prompt file names have this format: 'basename_language.prompt' (e.g. pdd_python.prompt, makefile_makefile.prompt, setup_bash.prompt)
1351
+
1352
+ % There are four possibilities for the output files:
1353
+ - File name given without path (e.g. 'output.py'): This will write the 'output.py' file in the same directory as the input file.
1354
+ - File name given with path (e.g. './output.py'): This will write the 'output.py' file in the './' directory.
1355
+ - Path given without file name (e.g. './context'): This will write the file with the basename and appropriate extension (for generated runnable code and generated example code) in the './context' directory.
1356
+ - Nothing specified by user (default): This will write the file with the basename and appropriate extension in the same directory as the input file.
1357
+
1358
+ % When given a prompt, the program will generate runnable code and example code if selected. When given a code file, an example file will be generated. Here are the options the program will support:
1359
+ '--force': When writing the output files, if a file already exists, the program will ask before overwriting it unless a "--force" is present where it will just overwrite the file. It will default to Yes if user presses Enter.
1360
+ '-o': Path or filename of the output of the runnable code. All four of the above possibilities are possible meaning for example, the user might just have "-o" or might have "-o ./output.py".
1361
+ '-oe': Means program should generate example from runnable code. As will "-o" all four output possibilities are possible here.
1362
+
1363
+ % Here are example command lines:
1364
+ -'pdd context_generator.py' will generate 'context_generator_example.py' in the same directory
1365
+ -'pdd context_generator.py -oe context/' will generate 'context_generator_example.py' in the './context' directory
1366
+ -'pdd context_generator_python.prompt -o pdd/ -oe context/' will generate 'context_generator.py' in the './pdd' directory and 'context_generator_example.py' in the './context' directory. 'context_generator' is the basename.
1367
+ -'pdd makefile_makefile.prompt' will generate 'makefile' in the same directory
1368
+ -'pdd pdd_python.prompt -o pdd/pdd_v1.py will generate 'pdd_v1.py' in the './pdd' directory and no example will be generated
1369
+
1370
+ % Here is an example how to generate code from the prompt from a file: ```<./context/code_generator_example.py>```
1371
+
1372
+ % Here is an example how to generate an example from a code file: ```<./context/context_generator_example.py>```
1373
+
1374
+ % Here is an example how to lookup a file extension given a language: ```<./context/get_extension_example.py>```
1375
+
1376
+ % This program will do the following:
1377
+ Step 1. Read the input file name from the command line.
1378
+ Step 2. If file name has no extension, add '.prompt' to the file name.
1379
+ Step 3. Extract the basename and language from the file name. Use get_extension to get the file extension for the language. The file extension and language is used for all the subsequent steps.
1380
+ Step 4. From the basename and file extension generate the appropriate file paths for the runnable and example output files considering the four possibilities. First determine which possibility for each of the outputs and then construct the proper file paths for each output.
1381
+ Step 5. If a prompt input (indicated by a '.prompt' input file extension) do these steps:
1382
+ Step 5a. Generate code from the input prompt file name using code_generator.
1383
+ Step 5b. The program will write the runnable code to a runnable file path from Step 4.
1384
+ Step 6. If a code file (indicated by a input file extension that isn't '.prompt') is provided or a "-oe" option is provided, the program will generate example code from the runnable code of Step 5 or the input code file using context_generator and write the example code to the example file path from Step 4.</input_prompt>
1385
+ <input_code># To create the `pdd` command line program as described, we need to follow the steps outlined in the prompt. Below is the implementation of the `pdd` program in Python. This program will use the `rich` library for pretty printing and handle the various input and output scenarios as specified.
1386
+
1387
+ # First, ensure you have the necessary modules installed:
1388
+ # ```sh
1389
+ # pip install rich
1390
+ # ```
1391
+
1392
+ # Next, create the `pdd.py` script:
1393
+
1394
+ # ```python
1395
+ import os
1396
+ import sys
1397
+ import argparse
1398
+ from rich.console import Console
1399
+ from code_generator import code_generator
1400
+ from context_generator import context_generator
1401
+ from get_extension import get_extension
1402
+
1403
+ console = Console()
1404
+
1405
+ def main():
1406
+ parser = argparse.ArgumentParser(description="Compile a prompt into a code file or a code file into an example code file.")
1407
+ parser.add_argument('input_file', help="Input prompt file or input code file to generate example from")
1408
+ parser.add_argument('-o', '--output', help="Path or filename of the output of the runnable code")
1409
+ parser.add_argument('-oe', '--output_example', help="Path or filename of the output example code")
1410
+ parser.add_argument('--force', action='store_true', help="Overwrite files without asking")
1411
+
1412
+ args = parser.parse_args()
1413
+ input_file = args.input_file
1414
+ output = args.output
1415
+ output_example = args.output_example
1416
+ force = args.force
1417
+
1418
+ # Step 1: Read the input file name from the command line
1419
+ if not os.path.exists(input_file):
1420
+ console.print(f"[bold red]Error:[/bold red] The file '{input_file}' does not exist.")
1421
+ sys.exit(1)
1422
+
1423
+ # Step 2: If file name has no extension, add '.prompt' to the file name
1424
+ if '.' not in input_file:
1425
+ input_file += '.prompt'
1426
+
1427
+ # Step 3: Extract the basename and language from the file name
1428
+ basename, ext = os.path.splitext(os.path.basename(input_file))
1429
+ if ext == '.prompt':
1430
+ language = basename.split('_')[-1]
1431
+ else:
1432
+ language = ext[1:]
1433
+
1434
+ file_extension = get_extension(language)
1435
+
1436
+ # Step 4: Generate the appropriate file paths for the runnable and example output files
1437
+ def construct_output_path(output, default_name):
1438
+ if output is None:
1439
+ return os.path.join(os.path.dirname(input_file), default_name)
1440
+ elif os.path.isdir(output):
1441
+ return os.path.join(output, default_name)
1442
+ else:
1443
+ return output
1444
+
1445
+ runnable_output_path = construct_output_path(output, f"{basename}{file_extension}")
1446
+ example_output_path = construct_output_path(output_example, f"{basename}_example{file_extension}")
1447
+
1448
+ # Step 5: If a prompt input, generate code from the input prompt file name using code_generator
1449
+ if ext == '.prompt':
1450
+ console.print(f"[bold green]Generating runnable code from prompt:[/bold green] {input_file}")
1451
+ runnable_code = code_generator(input_file, language)
1452
+ write_to_file(runnable_output_path, runnable_code, force)
1453
+
1454
+ # Step 6: If a code file is provided or a "-oe" option is provided, generate example code
1455
+ if ext != '.prompt' or output_example:
1456
+ console.print(f"[bold green]Generating example code from runnable code:[/bold green] {runnable_output_path}")
1457
+ success = context_generator(runnable_output_path, example_output_path, force)
1458
+ if success:
1459
+ console.print(f"[bold green]Example code generated successfully:[/bold green] {example_output_path}")
1460
+ else:
1461
+ console.print(f"[bold red]Failed to generate example code.[/bold red]")
1462
+
1463
+ def write_to_file(file_path, content, force):
1464
+ if os.path.exists(file_path) and not force:
1465
+ console.print(f"[bold yellow]Warning:[/bold yellow] The file '{file_path}' already exists. Overwrite? [y/N]")
1466
+ response = input().strip().lower()
1467
+ if response not in ['y', 'yes', '']:
1468
+ console.print(f"[bold red]Aborted:[/bold red] The file '{file_path}' was not overwritten.")
1469
+ return
1470
+
1471
+ with open(file_path, 'w') as f:
1472
+ f.write(content)
1473
+ console.print(f"[bold green]File written successfully:[/bold green] {file_path}")
1474
+
1475
+ if __name__ == "__main__":
1476
+ main()
1477
+ # ```
1478
+
1479
+ # ### Explanation:
1480
+ # 1. **Argument Parsing**: The script uses `argparse` to handle command-line arguments.
1481
+ # 2. **File Existence Check**: It checks if the input file exists.
1482
+ # 3. **File Extension Handling**: If the input file has no extension, `.prompt` is added.
1483
+ # 4. **Basename and Language Extraction**: The script extracts the basename and language from the input file name.
1484
+ # 5. **Output Path Construction**: It constructs the appropriate output paths for runnable and example files.
1485
+ # 6. **Code Generation**: If the input is a prompt file, it generates runnable code using `code_generator`.
1486
+ # 7. **Example Code Generation**: If the input is a code file or the `-oe` option is provided, it generates example code using `context_generator`.
1487
+ # 8. **File Writing**: The script writes the generated code to the specified output files, handling overwrites based on the `--force` option.
1488
+
1489
+ # This script should be placed in a file named `pdd.py` and can be executed from the command line as described in the prompt.</input_code>
1490
+ <example_code>runnable_output_path, example_output_path = construct_output_paths(
1491
+ basename, # the basename of the file
1492
+ file_extension, # the file extension based on the language
1493
+ argv_output_path, # string from the '-o' flag
1494
+ argv_example_output_path # string from the '-oe' flag
1495
+ )</example_code>
1496
+ <sub_prompt>% You are an expert Python engineer. Your goal is to write a Python function, "construct_output_paths", that will generate the appropriate file paths for the runnable and example output files that will be called by "pdd", the top-level command line program.
1497
+
1498
+ % Here are the inputs and outputs of the function:
1499
+ Inputs:
1500
+ - 'basename': A string containing the basename of the file
1501
+ - 'file_extension': A string containing the file extension based on the language
1502
+ - 'argv_output_path': A string from the '-o' flag (can be None)
1503
+ - 'argv_example_output_path': A string from the '-oe' flag (can be None)
1504
+ Outputs:
1505
+ - Returns a tuple containing two strings: (runnable_output_path, example_output_path)
1506
+
1507
+ % Consider the four possibilities for the output files as described in the main prompt:
1508
+ - File name given without path
1509
+ - File name given with path
1510
+ - Path given without file name
1511
+ - Nothing specified by user (default)
1512
+
1513
+ % Prompt file names have this format: 'basename_language.prompt' (e.g. pdd_python.prompt, makefile_makefile.prompt, setup_bash.prompt)
1514
+
1515
+ % Here are example command lines:
1516
+ -'pdd context_generator.py' will generate 'context_generator_example.py' in the same directory
1517
+ -'pdd context_generator.py -oe context/' will generate 'context_generator_example.py' in the './context' directory
1518
+ -'pdd context_generator_python.prompt -o pdd/ -oe context/' will generate 'context_generator.py' in the './pdd' directory and 'context_generator_example.py' in the './context' directory. 'context_generator' is the basename.
1519
+ -'pdd makefile_makefile.prompt' will generate 'makefile' in the same directory
1520
+ -'pdd pdd_python.prompt -o pdd/pdd_v1.py will generate 'pdd_v1.py' in the './pdd' directory and no example will be generated
1521
+
1522
+ % This function will do the following:
1523
+ Step 1: Define a helper function to construct the output path based on the given arguments and default name.
1524
+ Step 2: Use the helper function to construct the runnable_output_path using basename, file_extension, and argv_output_path.
1525
+ Step 3: Use the helper function to construct the example_output_path using basename, file_extension, and argv_example_output_path.
1526
+ Step 4: Return the tuple (runnable_output_path, example_output_path).
1527
+ </sub_prompt>
1528
+ <modified_prompt>% You are an expert Python engineer. Your goal is to write a python command line program, "pdd", that will compile a prompt into a code file or a code file into an example code file. All output to the console will be pretty print using the Python rich library.
1529
+
1530
+ % Here is how the program will be used: pdd <input_prompt_file or input_code_file_to_generate_example_from>
1531
+
1532
+ % Prompt file names have this format: 'basename_language.prompt' (e.g. pdd_python.prompt, makefile_makefile.prompt, setup_bash.prompt)
1533
+
1534
+ % When given a prompt, the program will generate runnable code and example code if selected. When given a code file, an example file will be generated. Here are the options the program will support:
1535
+ '--force': When writing the output files, if a file already exists, the program will ask before overwriting it unless a "--force" is present where it will just overwrite the file. It will default to Yes if user presses Enter.
1536
+ '-o': Path or filename of the output of the runnable code.
1537
+ '-oe': Means program should generate example from runnable code.
1538
+
1539
+ % Here are example command lines:
1540
+ -'pdd context_generator.py' will generate 'context_generator_example.py' in the same directory
1541
+ -'pdd context_generator.py -oe context/' will generate 'context_generator_example.py' in the './context' directory
1542
+ -'pdd context_generator_python.prompt -o pdd/ -oe context/' will generate 'context_generator.py' in the './pdd' directory and 'context_generator_example.py' in the './context' directory. 'context_generator' is the basename.
1543
+ -'pdd makefile_makefile.prompt' will generate 'makefile' in the same directory
1544
+ -'pdd pdd_python.prompt -o pdd/pdd_v1.py will generate 'pdd_v1.py' in the './pdd' directory and no example will be generated
1545
+
1546
+ % Here is an example how to generate code from the prompt from a file: ```<./context/code_generator_example.py>```
1547
+
1548
+ % Here is an example how to generate an example from a code file: ```<./context/context_generator_example.py>```
1549
+
1550
+ % Here is an example how to lookup a file extension given a language: ```<./context/get_extension_example.py>```
1551
+
1552
+ % Here is an example how to construct output paths: ```<./context/construct_output_paths_example.py>```
1553
+
1554
+ % This program will do the following:
1555
+ Step 1. Read the input file name from the command line.
1556
+ Step 2. If file name has no extension, add '.prompt' to the file name.
1557
+ Step 3. Extract the basename and language from the file name. Use get_extension to get the file extension for the language. The file extension and language is used for all the subsequent steps.
1558
+ Step 4. Use construct_output_paths to generate the appropriate file paths for the runnable and example output files.
1559
+ Step 5. If a prompt input (indicated by a '.prompt' input file extension) do these steps:
1560
+ Step 5a. Generate code from the input prompt file name using code_generator.
1561
+ Step 5b. The program will write the runnable code to a runnable file path from Step 4.
1562
+ Step 6. If a code file (indicated by a input file extension that isn't '.prompt') is provided or a "-oe" option is provided, the program will generate example code from the runnable code of Step 5 or the input code file using context_generator and write the example code to the example file path from Step 4.</modified_prompt>
1563
+ </example_2>
1564
+
1565
+ <example_3>
1566
+ <input_prompt>% You are an expert Python engineer. Your goal is to write a python function called 'postprocess' that will post-process the string output of a LLM so that the code can be run.
1567
+
1568
+ % Here are the inputs and outputs of the function:
1569
+ Input:
1570
+ 'llm_output' - A string contains a mix of text and sections of code separated by triple backticks.
1571
+ 'language' - A string that is the type (e.g. python, bash) of file that will be outputed by the LLM
1572
+ Output: returns a string that is the processed string that contains a properly commented out comments so that code can be run
1573
+
1574
+ % Here is an example how to get the lookup the comment line characters given a language: ```<./context/get_comment_example.py>```
1575
+
1576
+ % Here is an example how to comment out a line of code: ```<./context/comment_line_example.py>```
1577
+
1578
+ % Here is an example of llm_output: '''To implement the `context_generator` function as described, we will follow the steps outlined in your request. Below is the complete implementation of the function, which includes reading a Python file, preprocessing it, generating a prompt for the model, invoking the model, and writing the output to a specified file.
1579
+
1580
+ ```python
1581
+ import os
1582
+
1583
+ def context_generator(python_filename: str, output_filename: str, force: bool = False) -> bool:
1584
+ # Step 1: Read the Python file
1585
+ try:
1586
+ with open(python_filename, 'r') as file:
1587
+ python_code = file.read()
1588
+ except FileNotFoundError:
1589
+ print(f"Error: The file {python_filename} does not exist.")
1590
+ return False
1591
+
1592
+
1593
+ # Step 3: Generate a prompt for GPT-4
1594
+ prompt = f"""
1595
+ You are an expert Python engineer. Based on the following Python code, generate a concise example of how to use the module properly.
1596
+
1597
+ Python Code:
1598
+ ```python
1599
+ {processed_content}
1600
+ ```
1601
+
1602
+ return True
1603
+ ```
1604
+
1605
+ ### Explanation of the Code:
1606
+ 1. **File Reading**: The function attempts to read the specified Python file. If the file does not exist, it prints an error message and returns `False`.
1607
+ 2. **Preprocessing**: It calls the `preprocess` function to process the content of the Python file.
1608
+
1609
+ ### Usage:
1610
+ You can call this function by providing the necessary arguments, like so:
1611
+
1612
+ ```python
1613
+ context_generator('your_python_file.py', 'output_example.py', force=False)
1614
+ ```
1615
+
1616
+ Make sure to replace `'your_python_file.py'` and `'output_example.py'` with the actual file names you want to use.
1617
+ To implement the context_generator function as described, we will follow the steps outlined in
1618
+ your request. Below is the complete implementation of the function, which includes reading a
1619
+ Python file, preprocessing it, generating a prompt for the model, invoking the model, and writing
1620
+ the output to a specified file.'''
1621
+
1622
+ % Here is an example of the Output string that would be returned: '''#To implement the `context_generator` function as described, we will follow the steps outlined in your request. Below is the complete implementation of the function, which includes reading a Python file, preprocessing it, generating a prompt for the model, invoking the model, and writing the output to a specified file.
1623
+ #
1624
+ #```python
1625
+ import os
1626
+
1627
+ def context_generator(python_filename: str, output_filename: str, force: bool = False) -> bool:
1628
+ # Step 1: Read the Python file
1629
+ try:
1630
+ with open(python_filename, 'r') as file:
1631
+ python_code = file.read()
1632
+ except FileNotFoundError:
1633
+ print(f"Error: The file {python_filename} does not exist.")
1634
+ return False
1635
+
1636
+
1637
+ # Step 3: Generate a prompt for GPT-4
1638
+ prompt = f"""
1639
+ You are an expert Python engineer. Based on the following Python code, generate a concise example of how to use the module properly.
1640
+
1641
+ Python Code:
1642
+ ```python
1643
+ {processed_content}
1644
+ ```
1645
+
1646
+ return True
1647
+ #```
1648
+ #
1649
+ #### Explanation of the Code:
1650
+ #1. **File Reading**: The function attempts to read the specified Python file. If the file does not exist, it prints an error message and returns `False`.
1651
+ #2. **Preprocessing**: It calls the `preprocess` function to process the content of the Python file.
1652
+ #
1653
+ #### Usage:
1654
+ #You can call this function by providing the necessary arguments, like so:
1655
+ #
1656
+ #```python
1657
+ #context_generator('your_python_file.py', 'output_example.py', force=False)
1658
+ #```
1659
+ #
1660
+ #Make sure to replace `'your_python_file.py'` and `'output_example.py'` with the actual file names you want to use.
1661
+ #To implement the context_generator function as described, we will follow the steps outlined in
1662
+ #your request. Below is the complete implementation of the function, which includes reading a
1663
+ #Python file, preprocessing it, generating a prompt for the model, invoking the model, and writing
1664
+ #the output to a specified file.'''
1665
+
1666
+ % This function will do the following:
1667
+ Step 1. For the specified file_type, associate the right comment line character with the programming language using the get_comment function.
1668
+ Step 2. Find the top-level code sections via recursive function, 'find_section'. For a code section, the first backtick will always have a string right after it that determines what kind of code it is and the end of a section just has triple backticks. To properly return the list of top level-sections do the following sub-steps by iterating through lines of the string:
1669
+ Step 2a. Find the start of a code block
1670
+ Step 2b. If another start of another code block is found, call 'find_section' recursively with a sub-section flag True.
1671
+ Step 2c. If not, but the end of a code block is found, we should do one of the following steps depending on the sub-section flag:
1672
+ Step 2c_i: If it is a sub-section we should return with an empty list
1673
+ Step 2c_ii: If it is not a sub-section we should know the end of the code block and we should record the program type and start/end lines into the output list
1674
+ Step 2d. If all lines of the string are process, we should return the output list.
1675
+ Step 3. For the sections that are the same as file_type, we will determine which section is the largest.
1676
+ Step 4. Now using the original llm_output string, comment out, using the comment_line function, all lines of text until the start line of the largest section of the file_type we want and then resume commenting out the lines after end line of the largest section. Be sure the also comment out the triple backticks of the largest section. This will leave the executable part of largest section of code uncommented.
1677
+ Step 5. The program will return the post processed string that contains a properly commented out program that can be run.</input_prompt>
1678
+ <input_code>from pdd.get_comment import get_comment
1679
+ from pdd.comment_line import comment_line
1680
+
1681
+ def find_section(lines, start_index=0, sub_section=False):
1682
+ sections = []
1683
+ i = start_index
1684
+ while i < len(lines):
1685
+ line = lines[i].strip()
1686
+ if line.startswith('```'):
1687
+ # Start of a code block
1688
+ if len(line) > 3:
1689
+ # Extract the language from the line
1690
+ code_language = line[3:].strip()
1691
+ start_line = i
1692
+ i += 1
1693
+ # Find the end of the code block
1694
+ while i < len(lines) and not lines[i].strip().startswith('```'):
1695
+ i += 1
1696
+ if i < len(lines):
1697
+ end_line = i
1698
+ if not sub_section:
1699
+ sections.append((code_language, start_line, end_line))
1700
+ else:
1701
+ return []
1702
+ else:
1703
+ # End of a code block without a language
1704
+ if sub_section:
1705
+ return []
1706
+ i += 1
1707
+ return sections
1708
+
1709
+ def postprocess(llm_output, language):
1710
+ # Step 1: Get the comment character for the specified language
1711
+ comment_characters = get_comment(language)
1712
+
1713
+ # Step 2: Find the top-level code sections
1714
+ lines = llm_output.splitlines()
1715
+ sections = find_section(lines)
1716
+
1717
+ # Step 3: Find the largest section of the specified file_type
1718
+ largest_section = None
1719
+ max_length = 0
1720
+ for section in sections:
1721
+ code_language, start_line, end_line = section
1722
+ if code_language.lower() == language.lower():
1723
+ length = end_line - start_line
1724
+ if length > max_length:
1725
+ max_length = length
1726
+ largest_section = section
1727
+
1728
+ # Step 4: Comment out all lines except the largest section
1729
+ if largest_section:
1730
+ _, start_line, end_line = largest_section
1731
+ processed_lines = []
1732
+ for i, line in enumerate(lines):
1733
+ if i < start_line or i > end_line:
1734
+ processed_lines.append(comment_line(line, comment_characters))
1735
+ else:
1736
+ processed_lines.append(line)
1737
+ return '\n'.join(processed_lines)
1738
+
1739
+ # If no section matches the language, comment out everything
1740
+ return '\n'.join(comment_line(line, comment_characters) for line in lines)</input_code>
1741
+ <example_code>sections = find_section(
1742
+ lines, # splitlines of text, an array of lines of text
1743
+ start_index=0, # start index/row of the line, default is row 0
1744
+ sub_section=False # boolean to check if it is a sub-section, default is no
1745
+ )</example_code>
1746
+ <sub_prompt>% You are an expert Python engineer. Your goal is to write a Python function called 'find_section' that will find top-level code sections in a string output from an LLM.
1747
+
1748
+ % Here are the inputs and outputs of the function:
1749
+ Inputs:
1750
+ 'lines' - A list of strings, where each string is a line from the LLM output.
1751
+ 'start_index' - An integer representing the starting index to begin searching (default is 0).
1752
+ 'sub_section' - A boolean flag indicating whether this is a recursive call for a sub-section (default is False).
1753
+ Output: returns a list of tuples, where each tuple contains (code_language, start_line, end_line) for each top-level code section found.
1754
+
1755
+ % Here is an example of how the function might be called:
1756
+ ```python
1757
+ lines = llm_output.splitlines()
1758
+ sections = find_section(lines)
1759
+ ```
1760
+
1761
+ % Here is an example of llm_output: '''To implement the `context_generator` function as described, we will follow the steps outlined in your request. Below is the complete implementation of the function, which includes reading a Python file, preprocessing it, generating a prompt for the model, invoking the model, and writing the output to a specified file.
1762
+
1763
+ ```python
1764
+ import os
1765
+
1766
+ def context_generator(python_filename: str, output_filename: str, force: bool = False) -> bool:
1767
+ # Step 1: Read the Python file
1768
+ try:
1769
+ with open(python_filename, 'r') as file:
1770
+ python_code = file.read()
1771
+ except FileNotFoundError:
1772
+ print(f"Error: The file {python_filename} does not exist.")
1773
+ return False
1774
+
1775
+
1776
+ # Step 3: Generate a prompt for GPT-4
1777
+ prompt = f"""
1778
+ You are an expert Python engineer. Based on the following Python code, generate a concise example of how to use the module properly.
1779
+
1780
+ Python Code:
1781
+ ```python
1782
+ {processed_content}
1783
+ ```
1784
+
1785
+ return True
1786
+ ```
1787
+
1788
+ ### Explanation of the Code:
1789
+ 1. **File Reading**: The function attempts to read the specified Python file. If the file does not exist, it prints an error message and returns `False`.
1790
+ 2. **Preprocessing**: It calls the `preprocess` function to process the content of the Python file.
1791
+
1792
+ ### Usage:
1793
+ You can call this function by providing the necessary arguments, like so:
1794
+
1795
+ ```python
1796
+ context_generator('your_python_file.py', 'output_example.py', force=False)
1797
+ ```
1798
+
1799
+ Make sure to replace `'your_python_file.py'` and `'output_example.py'` with the actual file names you want to use.
1800
+ To implement the context_generator function as described, we will follow the steps outlined in
1801
+ your request. Below is the complete implementation of the function, which includes reading a
1802
+ Python file, preprocessing it, generating a prompt for the model, invoking the model, and writing
1803
+ the output to a specified file.'''
1804
+
1805
+ % This function will do the following:
1806
+ Step 1. Initialize an empty list to store the sections found.
1807
+ Step 2. Iterate through the lines starting from start_index:
1808
+ Step 2a. Find the start of a code block (line starting with triple backticks).
1809
+ Step 2b. If another start of a code block is found, call 'find_section' recursively with sub_section flag set to True.
1810
+ Step 2c. If the end of a code block is found (line with just triple backticks), do one of the following steps depending on the sub_section flag:
1811
+ Step 2c_i: If it is a sub-section, return an empty list.
1812
+ Step 2c_ii: If it is not a sub-section, record the program type and start/end lines into the output list.
1813
+ Step 3. Return the list of sections found.</sub_prompt>
1814
+ <modified_prompt>% You are an expert Python engineer. Your goal is to write a python function called 'postprocess' that will post-process the string output of a LLM so that the code can be run.
1815
+
1816
+ % Here are the inputs and outputs of the function:
1817
+ Input:
1818
+ 'llm_output' - A string contains a mix of text and sections of code separated by triple backticks.
1819
+ 'language' - A string that is the type (e.g. python, bash) of file that will be outputed by the LLM
1820
+ Output: returns a string that is the processed string that contains a properly commented out comments so that code can be run
1821
+
1822
+ % Here is an example how to get the lookup the comment line characters given a language: ```<./context/get_comment_example.py>```
1823
+
1824
+ % Here is an example how to comment out a line of code: ```<./context/comment_line_example.py>```
1825
+
1826
+ % Here is an example how to find code sections in LLM output: ```<./context/find_section_example.py>```
1827
+
1828
+ % Here is an example of llm_output: '''To implement the `context_generator` function as described, we will follow the steps outlined in your request. Below is the complete implementation of the function, which includes reading a Python file, preprocessing it, generating a prompt for the model, invoking the model, and writing the output to a specified file.
1829
+
1830
+ ```python
1831
+ import os
1832
+
1833
+ def context_generator(python_filename: str, output_filename: str, force: bool = False) -> bool:
1834
+ # Step 1: Read the Python file
1835
+ try:
1836
+ with open(python_filename, 'r') as file:
1837
+ python_code = file.read()
1838
+ except FileNotFoundError:
1839
+ print(f"Error: The file {python_filename} does not exist.")
1840
+ return False
1841
+
1842
+
1843
+ # Step 3: Generate a prompt for GPT-4
1844
+ prompt = f"""
1845
+ You are an expert Python engineer. Based on the following Python code, generate a concise example of how to use the module properly.
1846
+
1847
+ Python Code:
1848
+ ```python
1849
+ {processed_content}
1850
+ ```
1851
+
1852
+ return True
1853
+ ```
1854
+
1855
+ ### Explanation of the Code:
1856
+ 1. **File Reading**: The function attempts to read the specified Python file. If the file does not exist, it prints an error message and returns `False`.
1857
+ 2. **Preprocessing**: It calls the `preprocess` function to process the content of the Python file.
1858
+
1859
+ ### Usage:
1860
+ You can call this function by providing the necessary arguments, like so:
1861
+
1862
+ ```python
1863
+ context_generator('your_python_file.py', 'output_example.py', force=False)
1864
+ ```
1865
+
1866
+ Make sure to replace `'your_python_file.py'` and `'output_example.py'` with the actual file names you want to use.
1867
+ To implement the context_generator function as described, we will follow the steps outlined in
1868
+ your request. Below is the complete implementation of the function, which includes reading a
1869
+ Python file, preprocessing it, generating a prompt for the model, invoking the model, and writing
1870
+ the output to a specified file.'''
1871
+
1872
+ % Here is an example of the Output string that would be returned: '''#To implement the `context_generator` function as described, we will follow the steps outlined in your request. Below is the complete implementation of the function, which includes reading a Python file, preprocessing it, generating a prompt for the model, invoking the model, and writing the output to a specified file.
1873
+ #
1874
+ #```python
1875
+ import os
1876
+
1877
+ def context_generator(python_filename: str, output_filename: str, force: bool = False) -> bool:
1878
+ # Step 1: Read the Python file
1879
+ try:
1880
+ with open(python_filename, 'r') as file:
1881
+ python_code = file.read()
1882
+ except FileNotFoundError:
1883
+ print(f"Error: The file {python_filename} does not exist.")
1884
+ return False
1885
+
1886
+
1887
+ # Step 3: Generate a prompt for GPT-4
1888
+ prompt = f"""
1889
+ You are an expert Python engineer. Based on the following Python code, generate a concise example of how to use the module properly.
1890
+
1891
+ Python Code:
1892
+ ```python
1893
+ {processed_content}
1894
+ ```
1895
+
1896
+ return True
1897
+ #```
1898
+ #
1899
+ #### Explanation of the Code:
1900
+ #1. **File Reading**: The function attempts to read the specified Python file. If the file does not exist, it prints an error message and returns `False`.
1901
+ #2. **Preprocessing**: It calls the `preprocess` function to process the content of the Python file.
1902
+ #
1903
+ #### Usage:
1904
+ #You can call this function by providing the necessary arguments, like so:
1905
+ #
1906
+ #```python
1907
+ #context_generator('your_python_file.py', 'output_example.py', force=False)
1908
+ #```
1909
+ #
1910
+ #Make sure to replace `'your_python_file.py'` and `'output_example.py'` with the actual file names you want to use.
1911
+ #To implement the context_generator function as described, we will follow the steps outlined in
1912
+ #your request. Below is the complete implementation of the function, which includes reading a
1913
+ #Python file, preprocessing it, generating a prompt for the model, invoking the model, and writing
1914
+ #the output to a specified file.'''
1915
+
1916
+ % This function will do the following:
1917
+ Step 1. For the specified file_type, associate the right comment line character with the programming language using the get_comment function.
1918
+ Step 2. Use the find_section function to find the top-level code sections in the llm_output.
1919
+ Step 3. For the sections that are the same as file_type, determine which section is the largest.
1920
+ Step 4. Now using the original llm_output string, comment out, using the comment_line function, all lines of text until the start line of the largest section of the file_type we want and then resume commenting out the lines after end line of the largest section. Be sure to also comment out the triple backticks of the largest section. This will leave the executable part of largest section of code uncommented.
1921
+ Step 5. The program will return the post processed string that contains a properly commented out program that can be run.</modified_prompt>
1922
+ </example_3>
1923
+
1924
+ <example_4>
1925
+ <input_prompt>% You are an expert Python software engineer. Your goal is to write a Python function, "construct_paths", that will generate and check the appropriate input and output file paths and then load the input files. This function will will be used by pdd to do this function. All output to the console will be pretty print using the Python rich library. The CLI will be handled using the Python Click library.
1926
+
1927
+ % Here is a detailed description of the program functionality: ```<./README.md>```
1928
+
1929
+ % Here is an example how to lookup a file extension given a language: ```<./context/get_extension_example.py>```
1930
+
1931
+ % Here are the inputs and outputs of the function:
1932
+ Inputs:
1933
+ - 'input_file_paths' (dict) - A dictionary to the paths of the input files with the keys being those specified in the examples from the pdd program description.
1934
+ - 'force' (boolean) - A flag that indicates whether to overwrite the output files if they already exist.
1935
+ - 'quiet' (boolean) - A flag that indicates whether to suppress the output.
1936
+ - 'command' (string) - pdd command that was run.
1937
+ - 'command_options' (dict) - A dictionary of the command options for the given command.
1938
+ Outputs:
1939
+ - 'input_strings' (dict) - A dictionary with the keys being the pdd description examples and the values being the input file strings.
1940
+ - 'output_file_paths' (dict)- A dictionary with the keys being the loaded input files and output files paths.
1941
+ - 'language' (string) - The language of the output file.
1942
+
1943
+ % If the file name has no extension, add the appropriate file extension (e.g '.prompt' to input file for the 'generate' command) to the file name.
1944
+
1945
+ % If the command is 'generate' extract the basename and language from the input_file_path. Use get_extension to get the file extension for the language. The file extension and language is used for the subsequent functionality below. Be able to handle files missing a '_' in the file name.
1946
+
1947
+ % Unless quiet is True, print out the input and output file paths that are being used and the steps being done below.
1948
+
1949
+ % This function will do the following:
1950
+ Step 1. Construct the input file paths using above rules.
1951
+ Step 2. Load the input files into the input_strings dictionary with the pdd description examples as the keys. Alert the user of any errors in loading the input files.
1952
+ Step 3. Construct the output file paths using the above rules using a separate sub-function. It should construct the full file path including the output file name for the output files following the rules in the "Output Location Specification" section of the pdd program description.
1953
+ Step 4. If the output files already exist, and force isn't true, check with the user if the program should overwrite.
1954
+ Step 5. Return the outputs</input_prompt>
1955
+ <input_code>import os
1956
+ import click
1957
+ from rich import print
1958
+ from get_extension import get_extension
1959
+
1960
+ def generate_output_filename(command, key, basename, language, file_extension):
1961
+ if command == 'generate':
1962
+ return f"{basename}{file_extension}"
1963
+ elif command == 'example':
1964
+ return f"{basename}_example{file_extension}"
1965
+ elif command == 'test':
1966
+ return f"test_{basename}{file_extension}"
1967
+ elif command == 'preprocess':
1968
+ return f"{basename}_{language or 'unknown'}_preprocessed.prompt"
1969
+ elif command == 'fix':
1970
+ if key == 'output-test':
1971
+ return f"test_{basename}_fixed{file_extension}"
1972
+ else:
1973
+ return f"{basename}_fixed{file_extension}"
1974
+ else:
1975
+ return f"{basename}_output{file_extension}"
1976
+
1977
+ def construct_paths(input_file_paths, force, quiet, command, command_options):
1978
+ input_strings = {}
1979
+ output_file_paths = {}
1980
+ language = None
1981
+
1982
+ def print_if_not_quiet(message):
1983
+ if not quiet:
1984
+ print(message)
1985
+
1986
+ # Step 1: Construct the input file paths
1987
+ for key, path in input_file_paths.items():
1988
+ if not os.path.splitext(path)[1]:
1989
+ if command == 'generate':
1990
+ path += '.prompt'
1991
+ input_file_paths[key] = path
1992
+
1993
+ print_if_not_quiet(f"Input file path for {key}: {path}")
1994
+
1995
+ # Step 2: Load the input files
1996
+ for key, path in input_file_paths.items():
1997
+ try:
1998
+ with open(path, 'r') as file:
1999
+ input_strings[key] = file.read()
2000
+ print_if_not_quiet(f"Loaded input file: {path}")
2001
+ except IOError as e:
2002
+ print(f"[bold red]Error loading input file {path}: {str(e)}[/bold red]")
2003
+ return None, None, None
2004
+
2005
+ # Extract basename and language
2006
+ prompt_file = input_file_paths.get('PROMPT_FILE', '')
2007
+ basename, ext = os.path.splitext(os.path.basename(prompt_file))
2008
+ parts = basename.split('_')
2009
+ if len(parts) > 1:
2010
+ language = parts[-1]
2011
+ basename = '_'.join(parts[:-1])
2012
+ else:
2013
+ language = ext[1:] # Remove the leading dot
2014
+
2015
+ if language:
2016
+ file_extension = get_extension(language)
2017
+ else:
2018
+ file_extension = '.txt'
2019
+ print(f"[bold yellow]Warning: Could not determine language. Using .txt as default file extension.[/bold yellow]")
2020
+
2021
+ print_if_not_quiet(f"Extracted basename: {basename}, language: {language}, File extension: {file_extension}")
2022
+
2023
+ # Step 3: Construct the output file paths
2024
+ for key in command_options:
2025
+ if key.startswith('output'):
2026
+ output_path = command_options[key]
2027
+ if output_path:
2028
+ if os.path.isdir(output_path):
2029
+ filename = generate_output_filename(command, key, basename, language, file_extension)
2030
+ output_path = os.path.join(output_path, filename)
2031
+ elif not os.path.splitext(output_path)[1]:
2032
+ output_path += file_extension
2033
+ else:
2034
+ output_path = generate_output_filename(command, key, basename, language, file_extension)
2035
+
2036
+ output_file_paths[key] = os.path.abspath(output_path)
2037
+ print_if_not_quiet(f"Output file path for {key}: {output_file_paths[key]}")
2038
+
2039
+ # Step 4: Check if output files exist and confirm overwrite if necessary
2040
+ for key, path in output_file_paths.items():
2041
+ if os.path.exists(path) and not force:
2042
+ if not click.confirm(f"Output file {path} already exists. Overwrite?"):
2043
+ print(f"[bold yellow]Operation cancelled for {key}.[/bold yellow]")
2044
+ return None, None, None
2045
+
2046
+ # Step 5: Return the outputs
2047
+ return input_strings, output_file_paths, language</input_code>
2048
+ <example_code>filename = generate_output_filename(
2049
+ command, # pdd commands like 'generate', etc.
2050
+ key, # output dictionary key like 'output', 'output-test', etc.
2051
+ basename, # the basename of the file
2052
+ language, # the language of the file
2053
+ file_extension # the file extension of the file
2054
+ )</example_code>
2055
+ <sub_prompt>% You are an expert Python software engineer. Your task is to implement a function called `generate_output_filename` that creates appropriate output filenames for different commands in a Python program.
2056
+
2057
+ % Inputs: The function should take the following parameters:
2058
+ - `command` (string): The command being executed (e.g., 'generate', 'example', 'test', 'preprocess', 'fix')
2059
+ - `key` (string): The output dictionary key (e.g., 'output', 'output-test')
2060
+ - `basename` (string): The base name of the file
2061
+ - `language` (string): The programming language of the file
2062
+ - `file_extension` (string): The file extension to be used
2063
+
2064
+ % Outputs: The function should return a string representing the generated output filename.
2065
+
2066
+ % Follow these rules for generating the output filename:
2067
+ 1. For the 'generate' command: Return `f"{basename}{file_extension}"`
2068
+ 2. For the 'example' command: Return `f"{basename}_example{file_extension}"`
2069
+ 3. For the 'test' command: Return `f"test_{basename}{file_extension}"`
2070
+ 4. For the 'preprocess' command: Return `f"{basename}_{language or 'unknown'}_preprocessed.prompt"`
2071
+ 5. For the 'fix' command:
2072
+ - If the key is 'output-test', return `f"test_{basename}_fixed{file_extension}"`
2073
+ - Otherwise, return `f"{basename}_fixed{file_extension}"`
2074
+ 6. For any other command: Return `f"{basename}_output{file_extension}"`
2075
+
2076
+ % Implement the function to handle all these cases efficiently and return the appropriate filename as a string, accordingly.
2077
+
2078
+ % Ensure the function handles all cases correctly and returns the appropriate filename string, language, and file extension. The function should be robust and able to handle various edge cases, such as missing file extensions or languages.</sub_prompt>
2079
+ <modified_prompt>% You are an expert Python software engineer. Your goal is to write a Python function, "construct_paths", that will generate and check the appropriate input and output file paths and then load the input files. This function will be used by pdd to perform this functionality. All output to the console will be pretty printed using the Python rich library. The CLI will be handled using the Python Click library.
2080
+
2081
+ % Here is a detailed description of the program functionality: ```<./README.md>```
2082
+
2083
+ % Here is an example of how to lookup a file extension given a language: ```<./context/get_extension_example.py>```
2084
+
2085
+ % Here is an example of how to generate the appropriate output filenames based on the command, key, basename, language, and file extension using the `generate_output_filename` function: ```<./context/generate_output_filename_example.py>```
2086
+
2087
+ % Here are the inputs and outputs of the function:
2088
+ Inputs:
2089
+ - 'input_file_paths' (dict) - A dictionary of the paths of the input files with the keys being those specified in the examples from the pdd program description.
2090
+ - 'force' (boolean) - A flag that indicates whether to overwrite the output files if they already exist.
2091
+ - 'quiet' (boolean) - A flag that indicates whether to suppress the output.
2092
+ - 'command' (string) - pdd command that was run.
2093
+ - 'command_options' (dict) - A dictionary of the command options for the given command.
2094
+ Outputs:
2095
+ - 'input_strings' (dict) - A dictionary with the keys being the pdd description examples and the values being the input file strings.
2096
+ - 'output_file_paths' (dict)- A dictionary with the keys being the loaded input files and output files paths.
2097
+ - 'language' (string) - The language of the output file.
2098
+
2099
+ % If the file name has no extension, add the appropriate file extension (e.g '.prompt' to input file for the 'generate' command) to the file name.
2100
+
2101
+ % If the command is 'generate' extract the basename and language from the input_file_path. Use get_extension to get the file extension for the language. The file extension and language is used for the subsequent functionality below. Be able to handle files missing a '_' in the file name.
2102
+
2103
+ % Unless quiet is True, print out the input and output file paths that are being used and the steps being done below.
2104
+
2105
+ % This function will do the following:
2106
+ Step 1. Construct the input file paths using above rules.
2107
+ Step 2. Load the input files into the input_strings dictionary with the pdd description examples as the keys. Alert the user of any errors in loading the input files.
2108
+ Step 3. Construct the output file paths using the above rules using the `generate_output_filename` function. It should construct the full file path including the output file name for the output files following the rules in the "Output Location Specification" section of the pdd program description.
2109
+ Step 4. If the output files already exist, and force isn't true, check with the user if the program should overwrite.
2110
+ Step 5. Return the outputs</modified_prompt>
2111
+ </example_4>
2112
+ </examples>
2113
+
2114
+ <context>
2115
+ % You are an expert LLM Prompt Engineer. Your goal is to split the input_prompt into a sub_prompt and modified_prompt with no loss of functionality.
2116
+
2117
+ % Here are the inputs and outputs of this prompt:
2118
+ <input_definitions>
2119
+ Input:
2120
+ 'input_prompt' - A string contains the prompt that will be split into a sub_prompt and modified_prompt.
2121
+ 'input_code' - A string that contains the code that was generated from the input_prompt.
2122
+ 'example_code' - A string that contains the code example of how the code generated from the sub_prompt would be used by the code generated from the modified_prompt.
2123
+ </input_definitions>
2124
+ <output_definitions>
2125
+ Output:
2126
+ 'sub_prompt' - A string that contains the sub_prompt that was split from the input_prompt.
2127
+ 'modified_prompt' - A string that contains the modified prompt from input_prompt split from the above sub_prompt.
2128
+ </output_definitions>
2129
+ </context>
2130
+
2131
+ <inputs>
2132
+ <input_prompt>{input_prompt}</input_prompt>
2133
+ <input_code>{input_code}</input_code>
2134
+ <example_code>{example_code}</example_code>
2135
+ </inputs>
2136
+
2137
+ <instructions>
2138
+ % Follow these instructions:
2139
+ 1. Write out the difficulties in spliting the prompt.
2140
+ 2. Write out how to overcome the difficulties.
2141
+ 3. Generate the sub_prompt.
2142
+ 4. Generate the modified_prompt.
2143
+ </instructions>
2144
+
2145
+ </example_tagged_prompt>
2146
+ </example>
2147
+
2148
+ % Output a string with the `input_raw_prompt` properly tagged using XML as metadata and structural elements to enhance clarity and organization. The output may include, but is not limited to:
2149
+ 1. `<instructions>`: Guidelines or directives for the model's output.
2150
+ 2. `<context>`: Background information or relevant data for understanding the task.
2151
+ 3. `<examples>`: Specific instances that guide the model's response.
2152
+ 4. `<formatting>`: Special formatting instructions for the output.
2153
+
2154
+ % Follow these steps to tag the prompt:
2155
+ Step 1. Write out the analysis of the input_raw_prompt by identifying components like instructions, context, and examples.
2156
+ Step 2. Discuss what could be appropriate XML tags for this input_raw_prompt.
2157
+ Step 3. Insert the XML tags at the correct locations in the input_raw_prompt without introducing any new content. Only add tags to existing content. The XML tags should be enhancing the input_raw_prompt's format, structure and readability.
2158
+
2159
+ % General points:
2160
+ - With triple backtick includes and curly bracket placeholders, there could be lots of text in them after preprocessing so XML tags will help to organize the content.
2161
+ - No need to include the initial and ending triple backticks for the XML code block.
2162
+
2163
+ </example_raw_prompt>
2164
+
2165
+ % Here is an example_tagged_prompt from the example_raw_prompt above:
2166
+ <example_tagged_prompt>
2167
+ <role>You are an expert Prompt Engineer.</role>
2168
+
2169
+ <task>Your goal is to enhance a given prompt by only adding XML tags where necessary to improve its structure and readability. Do not add any additional content or XML tags unless it is clearly required by the structure of the input_raw_prompt.</task>
2170
+
2171
+ <context>
2172
+ Here is the input_raw_prompt that needs XML tagging to improve its organization: <input_raw_prompt>{raw_prompt}</input_raw_prompt>
2173
+ </context>
2174
+
2175
+ <example>
2176
+ % Here is an example_raw_prompt that needs XML tagging:
2177
+ <example_raw_prompt>
2178
+ <examples>
2179
+ % Here is example_1 of how to split and generate the sub_prompt and modified_prompt:
2180
+ example_1_input_prompt: ```<./context/split/1/initial_pdd_python.prompt>```
2181
+ example_1_input_code: ```<./context/split/1/pdd.py>```
2182
+ example_1_example_code: ```<./context/split/1/split_get_extension.py>```
2183
+ example_1_sub_prompt: ```<./context/split/1/sub_pdd_python.prompt>```
2184
+ example_1_modified_prompt: ```<./context/split/1/final_pdd_python.prompt>```
2185
+
2186
+ % Here is example_2 of how to split and generate the sub_prompt and modified_prompt:
2187
+ example_2_input_prompt: ```<./context/split/2/initial_pdd_python.prompt>```
2188
+ example_2_input_code: ```<./context/split/2/pdd.py>```
2189
+ example_2_example_code: ```<./context/split/2/split_pdd_construct_output_path.py>```
2190
+ example_2_sub_prompt: ```<./context/split/2/sub_pdd_python.prompt>```
2191
+ example_2_modified_prompt: ```<./context/split/2/final_pdd_python.prompt>```
2192
+
2193
+ % Here is example_3 of how to split and generate the sub_prompt and modified_prompt:
2194
+ example_3_input_prompt: ```<./context/split/3/initial_postprocess_python.prompt>```
2195
+ example_3_input_code: ```<./context/split/3/postprocess.py>```
2196
+ example_3_example_code: ```<./context/split/3/split_postprocess_find_section.py>```
2197
+ example_3_sub_prompt: ```<./context/split/3/sub_postprocess_python.prompt>```
2198
+ example_3_modified_prompt: ```<./context/split/3/final_postprocess_python.prompt>```
2199
+
2200
+ % Here is example_4 of how to split and generate the sub_prompt and modified_prompt:
2201
+ example_4_input_prompt: ```<./context/split/4/initial_construct_paths_python.prompt>```
2202
+ example_4_input_code: ```<./context/split/4/construct_paths.py>```
2203
+ example_4_example_code: ```<./context/split/4/split_construct_paths_generate_output_filename.py>```
2204
+ example_4_sub_prompt: ```<./context/split/4/sub_construct_paths_python.prompt>```
2205
+ example_4_modified_prompt: ```<./context/split/4/final_construct_paths_python.prompt>```
2206
+ </examples>
2207
+
2208
+ % You are an expert LLM Prompt Engineer. Your goal is to split the input_prompt into a sub_prompt and modified_prompt with no loss of functionality.
2209
+
2210
+ % Here are the inputs and outputs of this prompt:
2211
+ Input:
2212
+ 'input_prompt' - A string contains the prompt that will be split into a sub_prompt and modified_prompt.
2213
+ 'input_code' - A string that contains the code that was generated from the input_prompt.
2214
+ 'example_code' - A string that contains the code example of how the code generated from the sub_prompt would be used by the code generated from the modified_prompt.
2215
+ Output:
2216
+ 'sub_prompt' - A string that contains the sub_prompt that was split from the input_prompt.
2217
+ 'modified_prompt' - A string that contains the modified prompt from input_prompt split from the above sub_prompt.
2218
+
2219
+ % Here is the input_prompt to split: ```{input_prompt}```
2220
+ % Here is the input_code: ```{input_code}```
2221
+ % Here is the example_code: ```{example_code}```
2222
+
2223
+ % Follow these instructions:
2224
+ 1. Write out the difficulties in spliting the prompt
2225
+ 2. Write out how to overcome the difficulties
2226
+ 3. Generate the sub_prompt.
2227
+ 4. Generate the modified_prompt.
2228
+ </example_raw_prompt>
2229
+
2230
+ % Here is an example_tagged_prompt from the example_raw_prompt above:
2231
+ <example_tagged_prompt>
2232
+ <examples>
2233
+ <example_1>
2234
+ <input_prompt>% You are an expert Python engineer. Your goal is to write a python command line program, "pdd", that will compile a prompt into a code file or a code file into an example code file. All output to the console will be pretty print using the Python rich library.
2235
+
2236
+ % Here is how the program will be used: pdd <input_prompt_file or input_code_file_to_generate_example_from>
2237
+
2238
+ % Prompt file names have this format: 'basename_language.prompt' (e.g. pdd_python.prompt, makefile_makefile.prompt, setup_bash.prompt)
2239
+
2240
+ % There are four possibilities for the output files:
2241
+ - File name given without path (e.g. 'output.py'): This will write the 'output.py' file in the same directory as the input file.
2242
+ - File name given with path (e.g. './output.py'): This will write the 'output.py' file in the './' directory.
2243
+ - Path given without file name (e.g. './context'): This will write the file with the basename and appropriate extension (for generated runnable code and generated example code) in the './context' directory.
2244
+ - Nothing specified by user (default): This will write the file with the basename and appropriate extension in the same directory as the input file.
2245
+
2246
+ % When given a prompt, the program will generate runnable code and example code if selected. When given a code file, an example file will be generated. Here are the options the program will support:
2247
+ '--force': When writing the output files, if a file already exists, the program will ask before overwriting it unless a "--force" is present where it will just overwrite the file. It will default to Yes if user presses Enter.
2248
+ '-o': Path or filename of the output of the runnable code. All four of the above possibilities are possible meaning for example, the user might just have "-o" or might have "-o ./output.py".
2249
+ '-oe': Means program should generate example from runnable code. As will "-o" all four output possibilities are possible here.
2250
+
2251
+ % Here are example command lines:
2252
+ -'pdd context_generator.py' will generate 'context_generator_example.py' in the same directory
2253
+ -'pdd context_generator.py -oe context/' will generate 'context_generator_example.py' in the './context' directory
2254
+ -'pdd context_generator_python.prompt -o pdd/ -oe context/' will generate 'context_generator.py' in the './pdd' directory and 'context_generator_example.py' in the './context' directory. 'context_generator' is the basename.
2255
+ -'pdd makefile_makefile.prompt' will generate 'makefile' in the same directory
2256
+ -'pdd pdd_python.prompt -o pdd/pdd_v1.py will generate 'pdd_v1.py' in the './pdd' directory and no example will be generated
2257
+
2258
+ % Here is an example how to generate code from the prompt from a file: ```<./context/code_generator_example.py>```
2259
+
2260
+ % Here is an example how to generate an example from a code file: ```<./context/context_generator_example.py>```
2261
+
2262
+ % This program will do the following:
2263
+ Step 1. Read the input file name from the command line.
2264
+ Step 2. If file name has no extension, add '.prompt' to the file name.
2265
+ Step 3. Extract the basename and language from the file name so the right code file extension (e.g. '.sh' for bash, '' for makefile, '.py' for Python) and language is used for all the subsequent steps.
2266
+ Step 4. From the basename and file extension generate the appropriate file paths for the runnable and example output files considering the four possibilities. First determine which possibility for each of the outputs and then construct the proper file paths for each output.
2267
+ Step 5. If a prompt input (indicated by a '.prompt' input file extension) do these steps:
2268
+ Step 5a. Generate code from the input prompt file name using code_generator.
2269
+ Step 5b. The program will write the runnable code to a runnable file path from Step 4.
2270
+ Step 6. If a code file (indicated by a input file extension that isn't '.prompt') is provided or a "-oe" option is provided, the program will generate example code from the runnable code of Step 5 or the input code file using context_generator and write the example code to the example file path from Step 4.</input_prompt>
2271
+ <input_code># To create the command line program "pdd" as described, we will use Python's `argparse` for command line argument parsing, and the `rich` library for pretty printing. The program will handle both prompt files and code files, generating runnable code and example code as specified.
2272
+
2273
+ # Here's a complete implementation of the `pdd` program:
2274
+
2275
+ # ```python
2276
+ import os
2277
+ import sys
2278
+ import argparse
2279
+ from rich.console import Console
2280
+ from rich.prompt import Confirm
2281
+ from code_generator import code_generator
2282
+ from context_generator import context_generator
2283
+
2284
+ console = Console()
2285
+
2286
+ def get_file_paths(input_file, output_file, example_output_file):
2287
+ # Extract basename and language from the input file
2288
+ basename, ext = os.path.splitext(os.path.basename(input_file))
2289
+ language = ext[1:] # Remove the dot
2290
+
2291
+ # Determine output file paths
2292
+ if output_file:
2293
+ runnable_file_path = output_file
2294
+ else:
2295
+ runnable_file_path = os.path.join(os.path.dirname(input_file), f"{basename}.{get_extension(language)}")
2296
+
2297
+ if example_output_file:
2298
+ example_file_path = example_output_file
2299
+ else:
2300
+ example_file_path = os.path.join(os.path.dirname(input_file), f"{basename}_example.{get_example_extension(language)}")
2301
+
2302
+ return runnable_file_path, example_file_path
2303
+
2304
+ def get_extension(language):
2305
+ extensions = {
2306
+ 'python': 'py',
2307
+ 'bash': 'sh',
2308
+ 'makefile': 'mk',
2309
+ # Add more languages and their extensions as needed
2310
+ }
2311
+ return extensions.get(language, '')
2312
+
2313
+ def get_example_extension(language):
2314
+ return 'py' # Assuming example files are always Python files for simplicity
2315
+
2316
+ def confirm_overwrite(file_path):
2317
+ if os.path.exists(file_path):
2318
+ return Confirm.ask(f"{file_path} already exists. Do you want to overwrite it?", default=True)
2319
+ return True
2320
+
2321
+ def main():
2322
+ parser = argparse.ArgumentParser(description="Compile prompts into code files or generate example code from code files.")
2323
+ parser.add_argument('input', help='Input prompt file or code file to generate example from')
2324
+ parser.add_argument('-o', '--output', help='Path or filename of the output runnable code')
2325
+ parser.add_argument('-oe', '--output-example', help='Path or filename of the output example code')
2326
+ parser.add_argument('--force', action='store_true', help='Force overwrite existing files without confirmation')
2327
+
2328
+ args = parser.parse_args()
2329
+
2330
+ input_file = args.input
2331
+ if not input_file.endswith('.prompt'):
2332
+ if not os.path.splitext(input_file)[1]: # No extension, assume it's a code file
2333
+ input_file += '.prompt'
2334
+
2335
+ # Determine if input is a prompt or code file
2336
+ is_prompt = input_file.endswith('.prompt')
2337
+
2338
+ # Get output file paths
2339
+ runnable_file_path, example_file_path = get_file_paths(input_file, args.output, args.output_example)
2340
+
2341
+ # Handle the runnable code generation
2342
+ if is_prompt:
2343
+ console.print(f"[bold green]Generating runnable code from prompt: {input_file}[/bold green]")
2344
+ runnable_code = code_generator(input_file, get_extension(os.path.splitext(input_file)[1][1:]))
2345
+
2346
+ if not args.force and not confirm_overwrite(runnable_file_path):
2347
+ console.print("[bold red]Operation cancelled.[/bold red]")
2348
+ return
2349
+
2350
+ with open(runnable_file_path, 'w') as f:
2351
+ f.write(runnable_code)
2352
+ console.print(f"[bold blue]Runnable code written to: {runnable_file_path}[/bold blue]")
2353
+
2354
+ # Handle example code generation
2355
+ if not is_prompt or args.output_example:
2356
+ console.print(f"[bold green]Generating example code from: {runnable_file_path}[/bold green]")
2357
+ success = context_generator(runnable_file_path, example_file_path, force=args.force)
2358
+
2359
+ if success:
2360
+ console.print(f"[bold blue]Example code written to: {example_file_path}[/bold blue]")
2361
+ else:
2362
+ console.print("[bold red]Example generation failed.[/bold red]")
2363
+
2364
+ if __name__ == "__main__":
2365
+ main()
2366
+ # ```
2367
+
2368
+ # ### Explanation of the Code:
2369
+ # 1. **Imports**: We import necessary modules including `argparse` for command line parsing, `os` for file path manipulations, and `rich` for console output.
2370
+ # 2. **Functions**:
2371
+ # - `get_file_paths`: Determines the output file paths based on the input file and user-specified options.
2372
+ # - `get_extension` and `get_example_extension`: Return the appropriate file extensions based on the language.
2373
+ # - `confirm_overwrite`: Asks the user for confirmation if a file already exists.
2374
+ # 3. **Main Function**:
2375
+ # - Parses command line arguments.
2376
+ # - Checks if the input file is a prompt or a code file.
2377
+ # - Generates runnable code from the prompt file and writes it to the specified output path.
2378
+ # - Generates example code from the runnable code if specified.
2379
+ # 4. **Execution**: The script runs the `main` function when executed.
2380
+
2381
+ # ### Usage:
2382
+ # - To run the program, save it as `pdd.py` and execute it from the command line:
2383
+ # ```bash
2384
+ # python pdd.py <input_prompt_file or input_code_file_to_generate_example_from> [options]
2385
+ # ```
2386
+
2387
+ # ### Requirements:
2388
+ # - Ensure you have the `rich`, `langchain`, and `tiktoken` libraries installed, along with the `code_generator` and `context_generator` modules available in your environment.</input_code>
2389
+ <example_code>file_extension = get_extension(language)</example_code>
2390
+ <sub_prompt>% You are an expert Python engineer. Your goal is to write a python function, "get_extension", that will return the file extension associated with a given language.
2391
+
2392
+ % Here are the inputs and outputs of the function:
2393
+ Input: 'language' - A string containing the language (e.g. Bash, Makefile, Python).
2394
+ Output: returns a string that is the extension for the langauge
2395
+
2396
+ % This program will do the following:
2397
+ Step 1. Lower case the language string to make the comparison case insensitive.
2398
+ Step 2. Look up the file extension for the given language
2399
+ Step 3. Return the file extension</sub_prompt>
2400
+ <modified_prompt>% You are an expert Python engineer. Your goal is to write a python command line program, "pdd", that will compile a prompt into a code file or a code file into an example code file. All output to the console will be pretty print using the Python rich library.
2401
+
2402
+ % Here is how the program will be used: pdd <input_prompt_file or input_code_file_to_generate_example_from>
2403
+
2404
+ % Prompt file names have this format: 'basename_language.prompt' (e.g. pdd_python.prompt, makefile_makefile.prompt, setup_bash.prompt)
2405
+
2406
+ % There are four possibilities for the output files:
2407
+ - File name given without path (e.g. 'output.py'): This will write the 'output.py' file in the same directory as the input file.
2408
+ - File name given with path (e.g. './output.py'): This will write the 'output.py' file in the './' directory.
2409
+ - Path given without file name (e.g. './context'): This will write the file with the basename and appropriate extension (for generated runnable code and generated example code) in the './context' directory.
2410
+ - Nothing specified by user (default): This will write the file with the basename and appropriate extension in the same directory as the input file.
2411
+
2412
+ % When given a prompt, the program will generate runnable code and example code if selected. When given a code file, an example file will be generated. Here are the options the program will support:
2413
+ '--force': When writing the output files, if a file already exists, the program will ask before overwriting it unless a "--force" is present where it will just overwrite the file. It will default to Yes if user presses Enter.
2414
+ '-o': Path or filename of the output of the runnable code. All four of the above possibilities are possible meaning for example, the user might just have "-o" or might have "-o ./output.py".
2415
+ '-oe': Means program should generate example from runnable code. As will "-o" all four output possibilities are possible here.
2416
+
2417
+ % Here are example command lines:
2418
+ -'pdd context_generator.py' will generate 'context_generator_example.py' in the same directory
2419
+ -'pdd context_generator.py -oe context/' will generate 'context_generator_example.py' in the './context' directory
2420
+ -'pdd context_generator_python.prompt -o pdd/ -oe context/' will generate 'context_generator.py' in the './pdd' directory and 'context_generator_example.py' in the './context' directory. 'context_generator' is the basename.
2421
+ -'pdd makefile_makefile.prompt' will generate 'makefile' in the same directory
2422
+ -'pdd pdd_python.prompt -o pdd/pdd_v1.py will generate 'pdd_v1.py' in the './pdd' directory and no example will be generated
2423
+
2424
+ % Here is an example how to generate code from the prompt from a file: ```<./context/code_generator_example.py>```
2425
+
2426
+ % Here is an example how to generate an example from a code file: ```<./context/context_generator_example.py>```
2427
+
2428
+ % Here is an example how to lookup a file extension given a language: ```<./context/get_extension_example.py>```
2429
+
2430
+ % This program will do the following:
2431
+ Step 1. Read the input file name from the command line.
2432
+ Step 2. If file name has no extension, add '.prompt' to the file name.
2433
+ Step 3. Extract the basename and language from the file name. Use get_extension to get the file extension for the language. The file extension and language is used for all the subsequent steps.
2434
+ Step 4. From the basename and file extension generate the appropriate file paths for the runnable and example output files considering the four possibilities. First determine which possibility for each of the outputs and then construct the proper file paths for each output.
2435
+ Step 5. If a prompt input (indicated by a '.prompt' input file extension) do these steps:
2436
+ Step 5a. Generate code from the input prompt file name using code_generator.
2437
+ Step 5b. The program will write the runnable code to a runnable file path from Step 4.
2438
+ Step 6. If a code file (indicated by a input file extension that isn't '.prompt') is provided or a "-oe" option is provided, the program will generate example code from the runnable code of Step 5 or the input code file using context_generator and write the example code to the example file path from Step 4.</modified_prompt>
2439
+ </example_1>
2440
+
2441
+ <example_2>
2442
+ <input_prompt>% You are an expert Python engineer. Your goal is to write a python command line program, "pdd", that will compile a prompt into a code file or a code file into an example code file. All output to the console will be pretty print using the Python rich library.
2443
+
2444
+ % Here is how the program will be used: pdd <input_prompt_file or input_code_file_to_generate_example_from>
2445
+
2446
+ % Prompt file names have this format: 'basename_language.prompt' (e.g. pdd_python.prompt, makefile_makefile.prompt, setup_bash.prompt)
2447
+
2448
+ % There are four possibilities for the output files:
2449
+ - File name given without path (e.g. 'output.py'): This will write the 'output.py' file in the same directory as the input file.
2450
+ - File name given with path (e.g. './output.py'): This will write the 'output.py' file in the './' directory.
2451
+ - Path given without file name (e.g. './context'): This will write the file with the basename and appropriate extension (for generated runnable code and generated example code) in the './context' directory.
2452
+ - Nothing specified by user (default): This will write the file with the basename and appropriate extension in the same directory as the input file.
2453
+
2454
+ % When given a prompt, the program will generate runnable code and example code if selected. When given a code file, an example file will be generated. Here are the options the program will support:
2455
+ '--force': When writing the output files, if a file already exists, the program will ask before overwriting it unless a "--force" is present where it will just overwrite the file. It will default to Yes if user presses Enter.
2456
+ '-o': Path or filename of the output of the runnable code. All four of the above possibilities are possible meaning for example, the user might just have "-o" or might have "-o ./output.py".
2457
+ '-oe': Means program should generate example from runnable code. As will "-o" all four output possibilities are possible here.
2458
+
2459
+ % Here are example command lines:
2460
+ -'pdd context_generator.py' will generate 'context_generator_example.py' in the same directory
2461
+ -'pdd context_generator.py -oe context/' will generate 'context_generator_example.py' in the './context' directory
2462
+ -'pdd context_generator_python.prompt -o pdd/ -oe context/' will generate 'context_generator.py' in the './pdd' directory and 'context_generator_example.py' in the './context' directory. 'context_generator' is the basename.
2463
+ -'pdd makefile_makefile.prompt' will generate 'makefile' in the same directory
2464
+ -'pdd pdd_python.prompt -o pdd/pdd_v1.py will generate 'pdd_v1.py' in the './pdd' directory and no example will be generated
2465
+
2466
+ % Here is an example how to generate code from the prompt from a file: ```<./context/code_generator_example.py>```
2467
+
2468
+ % Here is an example how to generate an example from a code file: ```<./context/context_generator_example.py>```
2469
+
2470
+ % Here is an example how to lookup a file extension given a language: ```<./context/get_extension_example.py>```
2471
+
2472
+ % This program will do the following:
2473
+ Step 1. Read the input file name from the command line.
2474
+ Step 2. If file name has no extension, add '.prompt' to the file name.
2475
+ Step 3. Extract the basename and language from the file name. Use get_extension to get the file extension for the language. The file extension and language is used for all the subsequent steps.
2476
+ Step 4. From the basename and file extension generate the appropriate file paths for the runnable and example output files considering the four possibilities. First determine which possibility for each of the outputs and then construct the proper file paths for each output.
2477
+ Step 5. If a prompt input (indicated by a '.prompt' input file extension) do these steps:
2478
+ Step 5a. Generate code from the input prompt file name using code_generator.
2479
+ Step 5b. The program will write the runnable code to a runnable file path from Step 4.
2480
+ Step 6. If a code file (indicated by a input file extension that isn't '.prompt') is provided or a "-oe" option is provided, the program will generate example code from the runnable code of Step 5 or the input code file using context_generator and write the example code to the example file path from Step 4.</input_prompt>
2481
+ <input_code># To create the `pdd` command line program as described, we need to follow the steps outlined in the prompt. Below is the implementation of the `pdd` program in Python. This program will use the `rich` library for pretty printing and handle the various input and output scenarios as specified.
2482
+
2483
+ # First, ensure you have the necessary modules installed:
2484
+ # ```sh
2485
+ # pip install rich
2486
+ # ```
2487
+
2488
+ # Next, create the `pdd.py` script:
2489
+
2490
+ # ```python
2491
+ import os
2492
+ import sys
2493
+ import argparse
2494
+ from rich.console import Console
2495
+ from code_generator import code_generator
2496
+ from context_generator import context_generator
2497
+ from get_extension import get_extension
2498
+
2499
+ console = Console()
2500
+
2501
+ def main():
2502
+ parser = argparse.ArgumentParser(description="Compile a prompt into a code file or a code file into an example code file.")
2503
+ parser.add_argument('input_file', help="Input prompt file or input code file to generate example from")
2504
+ parser.add_argument('-o', '--output', help="Path or filename of the output of the runnable code")
2505
+ parser.add_argument('-oe', '--output_example', help="Path or filename of the output example code")
2506
+ parser.add_argument('--force', action='store_true', help="Overwrite files without asking")
2507
+
2508
+ args = parser.parse_args()
2509
+ input_file = args.input_file
2510
+ output = args.output
2511
+ output_example = args.output_example
2512
+ force = args.force
2513
+
2514
+ # Step 1: Read the input file name from the command line
2515
+ if not os.path.exists(input_file):
2516
+ console.print(f"[bold red]Error:[/bold red] The file '{input_file}' does not exist.")
2517
+ sys.exit(1)
2518
+
2519
+ # Step 2: If file name has no extension, add '.prompt' to the file name
2520
+ if '.' not in input_file:
2521
+ input_file += '.prompt'
2522
+
2523
+ # Step 3: Extract the basename and language from the file name
2524
+ basename, ext = os.path.splitext(os.path.basename(input_file))
2525
+ if ext == '.prompt':
2526
+ language = basename.split('_')[-1]
2527
+ else:
2528
+ language = ext[1:]
2529
+
2530
+ file_extension = get_extension(language)
2531
+
2532
+ # Step 4: Generate the appropriate file paths for the runnable and example output files
2533
+ def construct_output_path(output, default_name):
2534
+ if output is None:
2535
+ return os.path.join(os.path.dirname(input_file), default_name)
2536
+ elif os.path.isdir(output):
2537
+ return os.path.join(output, default_name)
2538
+ else:
2539
+ return output
2540
+
2541
+ runnable_output_path = construct_output_path(output, f"{basename}{file_extension}")
2542
+ example_output_path = construct_output_path(output_example, f"{basename}_example{file_extension}")
2543
+
2544
+ # Step 5: If a prompt input, generate code from the input prompt file name using code_generator
2545
+ if ext == '.prompt':
2546
+ console.print(f"[bold green]Generating runnable code from prompt:[/bold green] {input_file}")
2547
+ runnable_code = code_generator(input_file, language)
2548
+ write_to_file(runnable_output_path, runnable_code, force)
2549
+
2550
+ # Step 6: If a code file is provided or a "-oe" option is provided, generate example code
2551
+ if ext != '.prompt' or output_example:
2552
+ console.print(f"[bold green]Generating example code from runnable code:[/bold green] {runnable_output_path}")
2553
+ success = context_generator(runnable_output_path, example_output_path, force)
2554
+ if success:
2555
+ console.print(f"[bold green]Example code generated successfully:[/bold green] {example_output_path}")
2556
+ else:
2557
+ console.print(f"[bold red]Failed to generate example code.[/bold red]")
2558
+
2559
+ def write_to_file(file_path, content, force):
2560
+ if os.path.exists(file_path) and not force:
2561
+ console.print(f"[bold yellow]Warning:[/bold yellow] The file '{file_path}' already exists. Overwrite? [y/N]")
2562
+ response = input().strip().lower()
2563
+ if response not in ['y', 'yes', '']:
2564
+ console.print(f"[bold red]Aborted:[/bold red] The file '{file_path}' was not overwritten.")
2565
+ return
2566
+
2567
+ with open(file_path, 'w') as f:
2568
+ f.write(content)
2569
+ console.print(f"[bold green]File written successfully:[/bold green] {file_path}")
2570
+
2571
+ if __name__ == "__main__":
2572
+ main()
2573
+ # ```
2574
+
2575
+ # ### Explanation:
2576
+ # 1. **Argument Parsing**: The script uses `argparse` to handle command-line arguments.
2577
+ # 2. **File Existence Check**: It checks if the input file exists.
2578
+ # 3. **File Extension Handling**: If the input file has no extension, `.prompt` is added.
2579
+ # 4. **Basename and Language Extraction**: The script extracts the basename and language from the input file name.
2580
+ # 5. **Output Path Construction**: It constructs the appropriate output paths for runnable and example files.
2581
+ # 6. **Code Generation**: If the input is a prompt file, it generates runnable code using `code_generator`.
2582
+ # 7. **Example Code Generation**: If the input is a code file or the `-oe` option is provided, it generates example code using `context_generator`.
2583
+ # 8. **File Writing**: The script writes the generated code to the specified output files, handling overwrites based on the `--force` option.
2584
+
2585
+ # This script should be placed in a file named `pdd.py` and can be executed from the command line as described in the prompt.</input_code>
2586
+ <example_code>runnable_output_path, example_output_path = construct_output_paths(
2587
+ basename, # the basename of the file
2588
+ file_extension, # the file extension based on the language
2589
+ argv_output_path, # string from the '-o' flag
2590
+ argv_example_output_path # string from the '-oe' flag
2591
+ )</example_code>
2592
+ <sub_prompt>% You are an expert Python engineer. Your goal is to write a Python function, "construct_output_paths", that will generate the appropriate file paths for the runnable and example output files that will be called by "pdd", the top-level command line program.
2593
+
2594
+ % Here are the inputs and outputs of the function:
2595
+ Inputs:
2596
+ - 'basename': A string containing the basename of the file
2597
+ - 'file_extension': A string containing the file extension based on the language
2598
+ - 'argv_output_path': A string from the '-o' flag (can be None)
2599
+ - 'argv_example_output_path': A string from the '-oe' flag (can be None)
2600
+ Outputs:
2601
+ - Returns a tuple containing two strings: (runnable_output_path, example_output_path)
2602
+
2603
+ % Consider the four possibilities for the output files as described in the main prompt:
2604
+ - File name given without path
2605
+ - File name given with path
2606
+ - Path given without file name
2607
+ - Nothing specified by user (default)
2608
+
2609
+ % Prompt file names have this format: 'basename_language.prompt' (e.g. pdd_python.prompt, makefile_makefile.prompt, setup_bash.prompt)
2610
+
2611
+ % Here are example command lines:
2612
+ -'pdd context_generator.py' will generate 'context_generator_example.py' in the same directory
2613
+ -'pdd context_generator.py -oe context/' will generate 'context_generator_example.py' in the './context' directory
2614
+ -'pdd context_generator_python.prompt -o pdd/ -oe context/' will generate 'context_generator.py' in the './pdd' directory and 'context_generator_example.py' in the './context' directory. 'context_generator' is the basename.
2615
+ -'pdd makefile_makefile.prompt' will generate 'makefile' in the same directory
2616
+ -'pdd pdd_python.prompt -o pdd/pdd_v1.py will generate 'pdd_v1.py' in the './pdd' directory and no example will be generated
2617
+
2618
+ % This function will do the following:
2619
+ Step 1: Define a helper function to construct the output path based on the given arguments and default name.
2620
+ Step 2: Use the helper function to construct the runnable_output_path using basename, file_extension, and argv_output_path.
2621
+ Step 3: Use the helper function to construct the example_output_path using basename, file_extension, and argv_example_output_path.
2622
+ Step 4: Return the tuple (runnable_output_path, example_output_path).
2623
+ </sub_prompt>
2624
+ <modified_prompt>% You are an expert Python engineer. Your goal is to write a python command line program, "pdd", that will compile a prompt into a code file or a code file into an example code file. All output to the console will be pretty print using the Python rich library.
2625
+
2626
+ % Here is how the program will be used: pdd <input_prompt_file or input_code_file_to_generate_example_from>
2627
+
2628
+ % Prompt file names have this format: 'basename_language.prompt' (e.g. pdd_python.prompt, makefile_makefile.prompt, setup_bash.prompt)
2629
+
2630
+ % When given a prompt, the program will generate runnable code and example code if selected. When given a code file, an example file will be generated. Here are the options the program will support:
2631
+ '--force': When writing the output files, if a file already exists, the program will ask before overwriting it unless a "--force" is present where it will just overwrite the file. It will default to Yes if user presses Enter.
2632
+ '-o': Path or filename of the output of the runnable code.
2633
+ '-oe': Means program should generate example from runnable code.
2634
+
2635
+ % Here are example command lines:
2636
+ -'pdd context_generator.py' will generate 'context_generator_example.py' in the same directory
2637
+ -'pdd context_generator.py -oe context/' will generate 'context_generator_example.py' in the './context' directory
2638
+ -'pdd context_generator_python.prompt -o pdd/ -oe context/' will generate 'context_generator.py' in the './pdd' directory and 'context_generator_example.py' in the './context' directory. 'context_generator' is the basename.
2639
+ -'pdd makefile_makefile.prompt' will generate 'makefile' in the same directory
2640
+ -'pdd pdd_python.prompt -o pdd/pdd_v1.py will generate 'pdd_v1.py' in the './pdd' directory and no example will be generated
2641
+
2642
+ % Here is an example how to generate code from the prompt from a file: ```<./context/code_generator_example.py>```
2643
+
2644
+ % Here is an example how to generate an example from a code file: ```<./context/context_generator_example.py>```
2645
+
2646
+ % Here is an example how to lookup a file extension given a language: ```<./context/get_extension_example.py>```
2647
+
2648
+ % Here is an example how to construct output paths: ```<./context/construct_output_paths_example.py>```
2649
+
2650
+ % This program will do the following:
2651
+ Step 1. Read the input file name from the command line.
2652
+ Step 2. If file name has no extension, add '.prompt' to the file name.
2653
+ Step 3. Extract the basename and language from the file name. Use get_extension to get the file extension for the language. The file extension and language is used for all the subsequent steps.
2654
+ Step 4. Use construct_output_paths to generate the appropriate file paths for the runnable and example output files.
2655
+ Step 5. If a prompt input (indicated by a '.prompt' input file extension) do these steps:
2656
+ Step 5a. Generate code from the input prompt file name using code_generator.
2657
+ Step 5b. The program will write the runnable code to a runnable file path from Step 4.
2658
+ Step 6. If a code file (indicated by a input file extension that isn't '.prompt') is provided or a "-oe" option is provided, the program will generate example code from the runnable code of Step 5 or the input code file using context_generator and write the example code to the example file path from Step 4.</modified_prompt>
2659
+ </example_2>
2660
+
2661
+ <example_3>
2662
+ <input_prompt>% You are an expert Python engineer. Your goal is to write a python function called 'postprocess' that will post-process the string output of a LLM so that the code can be run.
2663
+
2664
+ % Here are the inputs and outputs of the function:
2665
+ Input:
2666
+ 'llm_output' - A string contains a mix of text and sections of code separated by triple backticks.
2667
+ 'language' - A string that is the type (e.g. python, bash) of file that will be outputed by the LLM
2668
+ Output: returns a string that is the processed string that contains a properly commented out comments so that code can be run
2669
+
2670
+ % Here is an example how to get the lookup the comment line characters given a language: ```<./context/get_comment_example.py>```
2671
+
2672
+ % Here is an example how to comment out a line of code: ```<./context/comment_line_example.py>```
2673
+
2674
+ % Here is an example of llm_output: '''To implement the `context_generator` function as described, we will follow the steps outlined in your request. Below is the complete implementation of the function, which includes reading a Python file, preprocessing it, generating a prompt for the model, invoking the model, and writing the output to a specified file.
2675
+
2676
+ ```python
2677
+ import os
2678
+
2679
+ def context_generator(python_filename: str, output_filename: str, force: bool = False) -> bool:
2680
+ # Step 1: Read the Python file
2681
+ try:
2682
+ with open(python_filename, 'r') as file:
2683
+ python_code = file.read()
2684
+ except FileNotFoundError:
2685
+ print(f"Error: The file {python_filename} does not exist.")
2686
+ return False
2687
+
2688
+
2689
+ # Step 3: Generate a prompt for GPT-4
2690
+ prompt = f"""
2691
+ You are an expert Python engineer. Based on the following Python code, generate a concise example of how to use the module properly.
2692
+
2693
+ Python Code:
2694
+ ```python
2695
+ {processed_content}
2696
+ ```
2697
+
2698
+ return True
2699
+ ```
2700
+
2701
+ ### Explanation of the Code:
2702
+ 1. **File Reading**: The function attempts to read the specified Python file. If the file does not exist, it prints an error message and returns `False`.
2703
+ 2. **Preprocessing**: It calls the `preprocess` function to process the content of the Python file.
2704
+
2705
+ ### Usage:
2706
+ You can call this function by providing the necessary arguments, like so:
2707
+
2708
+ ```python
2709
+ context_generator('your_python_file.py', 'output_example.py', force=False)
2710
+ ```
2711
+
2712
+ Make sure to replace `'your_python_file.py'` and `'output_example.py'` with the actual file names you want to use.
2713
+ To implement the context_generator function as described, we will follow the steps outlined in
2714
+ your request. Below is the complete implementation of the function, which includes reading a
2715
+ Python file, preprocessing it, generating a prompt for the model, invoking the model, and writing
2716
+ the output to a specified file.'''
2717
+
2718
+ % Here is an example of the Output string that would be returned: '''#To implement the `context_generator` function as described, we will follow the steps outlined in your request. Below is the complete implementation of the function, which includes reading a Python file, preprocessing it, generating a prompt for the model, invoking the model, and writing the output to a specified file.
2719
+ #
2720
+ #```python
2721
+ import os
2722
+
2723
+ def context_generator(python_filename: str, output_filename: str, force: bool = False) -> bool:
2724
+ # Step 1: Read the Python file
2725
+ try:
2726
+ with open(python_filename, 'r') as file:
2727
+ python_code = file.read()
2728
+ except FileNotFoundError:
2729
+ print(f"Error: The file {python_filename} does not exist.")
2730
+ return False
2731
+
2732
+
2733
+ # Step 3: Generate a prompt for GPT-4
2734
+ prompt = f"""
2735
+ You are an expert Python engineer. Based on the following Python code, generate a concise example of how to use the module properly.
2736
+
2737
+ Python Code:
2738
+ ```python
2739
+ {processed_content}
2740
+ ```
2741
+
2742
+ return True
2743
+ #```
2744
+ #
2745
+ #### Explanation of the Code:
2746
+ #1. **File Reading**: The function attempts to read the specified Python file. If the file does not exist, it prints an error message and returns `False`.
2747
+ #2. **Preprocessing**: It calls the `preprocess` function to process the content of the Python file.
2748
+ #
2749
+ #### Usage:
2750
+ #You can call this function by providing the necessary arguments, like so:
2751
+ #
2752
+ #```python
2753
+ #context_generator('your_python_file.py', 'output_example.py', force=False)
2754
+ #```
2755
+ #
2756
+ #Make sure to replace `'your_python_file.py'` and `'output_example.py'` with the actual file names you want to use.
2757
+ #To implement the context_generator function as described, we will follow the steps outlined in
2758
+ #your request. Below is the complete implementation of the function, which includes reading a
2759
+ #Python file, preprocessing it, generating a prompt for the model, invoking the model, and writing
2760
+ #the output to a specified file.'''
2761
+
2762
+ % This function will do the following:
2763
+ Step 1. For the specified file_type, associate the right comment line character with the programming language using the get_comment function.
2764
+ Step 2. Find the top-level code sections via recursive function, 'find_section'. For a code section, the first backtick will always have a string right after it that determines what kind of code it is and the end of a section just has triple backticks. To properly return the list of top level-sections do the following sub-steps by iterating through lines of the string:
2765
+ Step 2a. Find the start of a code block
2766
+ Step 2b. If another start of another code block is found, call 'find_section' recursively with a sub-section flag True.
2767
+ Step 2c. If not, but the end of a code block is found, we should do one of the following steps depending on the sub-section flag:
2768
+ Step 2c_i: If it is a sub-section we should return with an empty list
2769
+ Step 2c_ii: If it is not a sub-section we should know the end of the code block and we should record the program type and start/end lines into the output list
2770
+ Step 2d. If all lines of the string are process, we should return the output list.
2771
+ Step 3. For the sections that are the same as file_type, we will determine which section is the largest.
2772
+ Step 4. Now using the original llm_output string, comment out, using the comment_line function, all lines of text until the start line of the largest section of the file_type we want and then resume commenting out the lines after end line of the largest section. Be sure the also comment out the triple backticks of the largest section. This will leave the executable part of largest section of code uncommented.
2773
+ Step 5. The program will return the post processed string that contains a properly commented out program that can be run.</input_prompt>
2774
+ <input_code>from pdd.get_comment import get_comment
2775
+ from pdd.comment_line import comment_line
2776
+
2777
+ def find_section(lines, start_index=0, sub_section=False):
2778
+ sections = []
2779
+ i = start_index
2780
+ while i < len(lines):
2781
+ line = lines[i].strip()
2782
+ if line.startswith('```'):
2783
+ # Start of a code block
2784
+ if len(line) > 3:
2785
+ # Extract the language from the line
2786
+ code_language = line[3:].strip()
2787
+ start_line = i
2788
+ i += 1
2789
+ # Find the end of the code block
2790
+ while i < len(lines) and not lines[i].strip().startswith('```'):
2791
+ i += 1
2792
+ if i < len(lines):
2793
+ end_line = i
2794
+ if not sub_section:
2795
+ sections.append((code_language, start_line, end_line))
2796
+ else:
2797
+ return []
2798
+ else:
2799
+ # End of a code block without a language
2800
+ if sub_section:
2801
+ return []
2802
+ i += 1
2803
+ return sections
2804
+
2805
+ def postprocess(llm_output, language):
2806
+ # Step 1: Get the comment character for the specified language
2807
+ comment_characters = get_comment(language)
2808
+
2809
+ # Step 2: Find the top-level code sections
2810
+ lines = llm_output.splitlines()
2811
+ sections = find_section(lines)
2812
+
2813
+ # Step 3: Find the largest section of the specified file_type
2814
+ largest_section = None
2815
+ max_length = 0
2816
+ for section in sections:
2817
+ code_language, start_line, end_line = section
2818
+ if code_language.lower() == language.lower():
2819
+ length = end_line - start_line
2820
+ if length > max_length:
2821
+ max_length = length
2822
+ largest_section = section
2823
+
2824
+ # Step 4: Comment out all lines except the largest section
2825
+ if largest_section:
2826
+ _, start_line, end_line = largest_section
2827
+ processed_lines = []
2828
+ for i, line in enumerate(lines):
2829
+ if i < start_line or i > end_line:
2830
+ processed_lines.append(comment_line(line, comment_characters))
2831
+ else:
2832
+ processed_lines.append(line)
2833
+ return '\n'.join(processed_lines)
2834
+
2835
+ # If no section matches the language, comment out everything
2836
+ return '\n'.join(comment_line(line, comment_characters) for line in lines)</input_code>
2837
+ <example_code>sections = find_section(
2838
+ lines, # splitlines of text, an array of lines of text
2839
+ start_index=0, # start index/row of the line, default is row 0
2840
+ sub_section=False # boolean to check if it is a sub-section, default is no
2841
+ )</example_code>
2842
+ <sub_prompt>% You are an expert Python engineer. Your goal is to write a Python function called 'find_section' that will find top-level code sections in a string output from an LLM.
2843
+
2844
+ % Here are the inputs and outputs of the function:
2845
+ Inputs:
2846
+ 'lines' - A list of strings, where each string is a line from the LLM output.
2847
+ 'start_index' - An integer representing the starting index to begin searching (default is 0).
2848
+ 'sub_section' - A boolean flag indicating whether this is a recursive call for a sub-section (default is False).
2849
+ Output: returns a list of tuples, where each tuple contains (code_language, start_line, end_line) for each top-level code section found.
2850
+
2851
+ % Here is an example of how the function might be called:
2852
+ ```python
2853
+ lines = llm_output.splitlines()
2854
+ sections = find_section(lines)
2855
+ ```
2856
+
2857
+ % Here is an example of llm_output: '''To implement the `context_generator` function as described, we will follow the steps outlined in your request. Below is the complete implementation of the function, which includes reading a Python file, preprocessing it, generating a prompt for the model, invoking the model, and writing the output to a specified file.
2858
+
2859
+ ```python
2860
+ import os
2861
+
2862
+ def context_generator(python_filename: str, output_filename: str, force: bool = False) -> bool:
2863
+ # Step 1: Read the Python file
2864
+ try:
2865
+ with open(python_filename, 'r') as file:
2866
+ python_code = file.read()
2867
+ except FileNotFoundError:
2868
+ print(f"Error: The file {python_filename} does not exist.")
2869
+ return False
2870
+
2871
+
2872
+ # Step 3: Generate a prompt for GPT-4
2873
+ prompt = f"""
2874
+ You are an expert Python engineer. Based on the following Python code, generate a concise example of how to use the module properly.
2875
+
2876
+ Python Code:
2877
+ ```python
2878
+ {processed_content}
2879
+ ```
2880
+
2881
+ return True
2882
+ ```
2883
+
2884
+ ### Explanation of the Code:
2885
+ 1. **File Reading**: The function attempts to read the specified Python file. If the file does not exist, it prints an error message and returns `False`.
2886
+ 2. **Preprocessing**: It calls the `preprocess` function to process the content of the Python file.
2887
+
2888
+ ### Usage:
2889
+ You can call this function by providing the necessary arguments, like so:
2890
+
2891
+ ```python
2892
+ context_generator('your_python_file.py', 'output_example.py', force=False)
2893
+ ```
2894
+
2895
+ Make sure to replace `'your_python_file.py'` and `'output_example.py'` with the actual file names you want to use.
2896
+ To implement the context_generator function as described, we will follow the steps outlined in
2897
+ your request. Below is the complete implementation of the function, which includes reading a
2898
+ Python file, preprocessing it, generating a prompt for the model, invoking the model, and writing
2899
+ the output to a specified file.'''
2900
+
2901
+ % This function will do the following:
2902
+ Step 1. Initialize an empty list to store the sections found.
2903
+ Step 2. Iterate through the lines starting from start_index:
2904
+ Step 2a. Find the start of a code block (line starting with triple backticks).
2905
+ Step 2b. If another start of a code block is found, call 'find_section' recursively with sub_section flag set to True.
2906
+ Step 2c. If the end of a code block is found (line with just triple backticks), do one of the following steps depending on the sub_section flag:
2907
+ Step 2c_i: If it is a sub-section, return an empty list.
2908
+ Step 2c_ii: If it is not a sub-section, record the program type and start/end lines into the output list.
2909
+ Step 3. Return the list of sections found.</sub_prompt>
2910
+ <modified_prompt>% You are an expert Python engineer. Your goal is to write a python function called 'postprocess' that will post-process the string output of a LLM so that the code can be run.
2911
+
2912
+ % Here are the inputs and outputs of the function:
2913
+ Input:
2914
+ 'llm_output' - A string contains a mix of text and sections of code separated by triple backticks.
2915
+ 'language' - A string that is the type (e.g. python, bash) of file that will be outputed by the LLM
2916
+ Output: returns a string that is the processed string that contains a properly commented out comments so that code can be run
2917
+
2918
+ % Here is an example how to get the lookup the comment line characters given a language: ```<./context/get_comment_example.py>```
2919
+
2920
+ % Here is an example how to comment out a line of code: ```<./context/comment_line_example.py>```
2921
+
2922
+ % Here is an example how to find code sections in LLM output: ```<./context/find_section_example.py>```
2923
+
2924
+ % Here is an example of llm_output: '''To implement the `context_generator` function as described, we will follow the steps outlined in your request. Below is the complete implementation of the function, which includes reading a Python file, preprocessing it, generating a prompt for the model, invoking the model, and writing the output to a specified file.
2925
+
2926
+ ```python
2927
+ import os
2928
+
2929
+ def context_generator(python_filename: str, output_filename: str, force: bool = False) -> bool:
2930
+ # Step 1: Read the Python file
2931
+ try:
2932
+ with open(python_filename, 'r') as file:
2933
+ python_code = file.read()
2934
+ except FileNotFoundError:
2935
+ print(f"Error: The file {python_filename} does not exist.")
2936
+ return False
2937
+
2938
+
2939
+ # Step 3: Generate a prompt for GPT-4
2940
+ prompt = f"""
2941
+ You are an expert Python engineer. Based on the following Python code, generate a concise example of how to use the module properly.
2942
+
2943
+ Python Code:
2944
+ ```python
2945
+ {processed_content}
2946
+ ```
2947
+
2948
+ return True
2949
+ ```
2950
+
2951
+ ### Explanation of the Code:
2952
+ 1. **File Reading**: The function attempts to read the specified Python file. If the file does not exist, it prints an error message and returns `False`.
2953
+ 2. **Preprocessing**: It calls the `preprocess` function to process the content of the Python file.
2954
+
2955
+ ### Usage:
2956
+ You can call this function by providing the necessary arguments, like so:
2957
+
2958
+ ```python
2959
+ context_generator('your_python_file.py', 'output_example.py', force=False)
2960
+ ```
2961
+
2962
+ Make sure to replace `'your_python_file.py'` and `'output_example.py'` with the actual file names you want to use.
2963
+ To implement the context_generator function as described, we will follow the steps outlined in
2964
+ your request. Below is the complete implementation of the function, which includes reading a
2965
+ Python file, preprocessing it, generating a prompt for the model, invoking the model, and writing
2966
+ the output to a specified file.'''
2967
+
2968
+ % Here is an example of the Output string that would be returned: '''#To implement the `context_generator` function as described, we will follow the steps outlined in your request. Below is the complete implementation of the function, which includes reading a Python file, preprocessing it, generating a prompt for the model, invoking the model, and writing the output to a specified file.
2969
+ #
2970
+ #```python
2971
+ import os
2972
+
2973
+ def context_generator(python_filename: str, output_filename: str, force: bool = False) -> bool:
2974
+ # Step 1: Read the Python file
2975
+ try:
2976
+ with open(python_filename, 'r') as file:
2977
+ python_code = file.read()
2978
+ except FileNotFoundError:
2979
+ print(f"Error: The file {python_filename} does not exist.")
2980
+ return False
2981
+
2982
+
2983
+ # Step 3: Generate a prompt for GPT-4
2984
+ prompt = f"""
2985
+ You are an expert Python engineer. Based on the following Python code, generate a concise example of how to use the module properly.
2986
+
2987
+ Python Code:
2988
+ ```python
2989
+ {processed_content}
2990
+ ```
2991
+
2992
+ return True
2993
+ #```
2994
+ #
2995
+ #### Explanation of the Code:
2996
+ #1. **File Reading**: The function attempts to read the specified Python file. If the file does not exist, it prints an error message and returns `False`.
2997
+ #2. **Preprocessing**: It calls the `preprocess` function to process the content of the Python file.
2998
+ #
2999
+ #### Usage:
3000
+ #You can call this function by providing the necessary arguments, like so:
3001
+ #
3002
+ #```python
3003
+ #context_generator('your_python_file.py', 'output_example.py', force=False)
3004
+ #```
3005
+ #
3006
+ #Make sure to replace `'your_python_file.py'` and `'output_example.py'` with the actual file names you want to use.
3007
+ #To implement the context_generator function as described, we will follow the steps outlined in
3008
+ #your request. Below is the complete implementation of the function, which includes reading a
3009
+ #Python file, preprocessing it, generating a prompt for the model, invoking the model, and writing
3010
+ #the output to a specified file.'''
3011
+
3012
+ % This function will do the following:
3013
+ Step 1. For the specified file_type, associate the right comment line character with the programming language using the get_comment function.
3014
+ Step 2. Use the find_section function to find the top-level code sections in the llm_output.
3015
+ Step 3. For the sections that are the same as file_type, determine which section is the largest.
3016
+ Step 4. Now using the original llm_output string, comment out, using the comment_line function, all lines of text until the start line of the largest section of the file_type we want and then resume commenting out the lines after end line of the largest section. Be sure to also comment out the triple backticks of the largest section. This will leave the executable part of largest section of code uncommented.
3017
+ Step 5. The program will return the post processed string that contains a properly commented out program that can be run.</modified_prompt>
3018
+ </example_3>
3019
+
3020
+ <example_4>
3021
+ <input_prompt>% You are an expert Python software engineer. Your goal is to write a Python function, "construct_paths", that will generate and check the appropriate input and output file paths and then load the input files. This function will will be used by pdd to do this function. All output to the console will be pretty print using the Python rich library. The CLI will be handled using the Python Click library.
3022
+
3023
+ % Here is a detailed description of the program functionality: ```<./README.md>```
3024
+
3025
+ % Here is an example how to lookup a file extension given a language: ```<./context/get_extension_example.py>```
3026
+
3027
+ % Here are the inputs and outputs of the function:
3028
+ Inputs:
3029
+ - 'input_file_paths' (dict) - A dictionary to the paths of the input files with the keys being those specified in the examples from the pdd program description.
3030
+ - 'force' (boolean) - A flag that indicates whether to overwrite the output files if they already exist.
3031
+ - 'quiet' (boolean) - A flag that indicates whether to suppress the output.
3032
+ - 'command' (string) - pdd command that was run.
3033
+ - 'command_options' (dict) - A dictionary of the command options for the given command.
3034
+ Outputs:
3035
+ - 'input_strings' (dict) - A dictionary with the keys being the pdd description examples and the values being the input file strings.
3036
+ - 'output_file_paths' (dict)- A dictionary with the keys being the loaded input files and output files paths.
3037
+ - 'language' (string) - The language of the output file.
3038
+
3039
+ % If the file name has no extension, add the appropriate file extension (e.g '.prompt' to input file for the 'generate' command) to the file name.
3040
+
3041
+ % If the command is 'generate' extract the basename and language from the input_file_path. Use get_extension to get the file extension for the language. The file extension and language is used for the subsequent functionality below. Be able to handle files missing a '_' in the file name.
3042
+
3043
+ % Unless quiet is True, print out the input and output file paths that are being used and the steps being done below.
3044
+
3045
+ % This function will do the following:
3046
+ Step 1. Construct the input file paths using above rules.
3047
+ Step 2. Load the input files into the input_strings dictionary with the pdd description examples as the keys. Alert the user of any errors in loading the input files.
3048
+ Step 3. Construct the output file paths using the above rules using a separate sub-function. It should construct the full file path including the output file name for the output files following the rules in the "Output Location Specification" section of the pdd program description.
3049
+ Step 4. If the output files already exist, and force isn't true, check with the user if the program should overwrite.
3050
+ Step 5. Return the outputs</input_prompt>
3051
+ <input_code>import os
3052
+ import click
3053
+ from rich import print
3054
+ from get_extension import get_extension
3055
+
3056
+ def generate_output_filename(command, key, basename, language, file_extension):
3057
+ if command == 'generate':
3058
+ return f"{basename}{file_extension}"
3059
+ elif command == 'example':
3060
+ return f"{basename}_example{file_extension}"
3061
+ elif command == 'test':
3062
+ return f"test_{basename}{file_extension}"
3063
+ elif command == 'preprocess':
3064
+ return f"{basename}_{language or 'unknown'}_preprocessed.prompt"
3065
+ elif command == 'fix':
3066
+ if key == 'output-test':
3067
+ return f"test_{basename}_fixed{file_extension}"
3068
+ else:
3069
+ return f"{basename}_fixed{file_extension}"
3070
+ else:
3071
+ return f"{basename}_output{file_extension}"
3072
+
3073
+ def construct_paths(input_file_paths, force, quiet, command, command_options):
3074
+ input_strings = {}
3075
+ output_file_paths = {}
3076
+ language = None
3077
+
3078
+ def print_if_not_quiet(message):
3079
+ if not quiet:
3080
+ print(message)
3081
+
3082
+ # Step 1: Construct the input file paths
3083
+ for key, path in input_file_paths.items():
3084
+ if not os.path.splitext(path)[1]:
3085
+ if command == 'generate':
3086
+ path += '.prompt'
3087
+ input_file_paths[key] = path
3088
+
3089
+ print_if_not_quiet(f"Input file path for {key}: {path}")
3090
+
3091
+ # Step 2: Load the input files
3092
+ for key, path in input_file_paths.items():
3093
+ try:
3094
+ with open(path, 'r') as file:
3095
+ input_strings[key] = file.read()
3096
+ print_if_not_quiet(f"Loaded input file: {path}")
3097
+ except IOError as e:
3098
+ print(f"[bold red]Error loading input file {path}: {str(e)}[/bold red]")
3099
+ return None, None, None
3100
+
3101
+ # Extract basename and language
3102
+ prompt_file = input_file_paths.get('PROMPT_FILE', '')
3103
+ basename, ext = os.path.splitext(os.path.basename(prompt_file))
3104
+ parts = basename.split('_')
3105
+ if len(parts) > 1:
3106
+ language = parts[-1]
3107
+ basename = '_'.join(parts[:-1])
3108
+ else:
3109
+ language = ext[1:] # Remove the leading dot
3110
+
3111
+ if language:
3112
+ file_extension = get_extension(language)
3113
+ else:
3114
+ file_extension = '.txt'
3115
+ print(f"[bold yellow]Warning: Could not determine language. Using .txt as default file extension.[/bold yellow]")
3116
+
3117
+ print_if_not_quiet(f"Extracted basename: {basename}, language: {language}, File extension: {file_extension}")
3118
+
3119
+ # Step 3: Construct the output file paths
3120
+ for key in command_options:
3121
+ if key.startswith('output'):
3122
+ output_path = command_options[key]
3123
+ if output_path:
3124
+ if os.path.isdir(output_path):
3125
+ filename = generate_output_filename(command, key, basename, language, file_extension)
3126
+ output_path = os.path.join(output_path, filename)
3127
+ elif not os.path.splitext(output_path)[1]:
3128
+ output_path += file_extension
3129
+ else:
3130
+ output_path = generate_output_filename(command, key, basename, language, file_extension)
3131
+
3132
+ output_file_paths[key] = os.path.abspath(output_path)
3133
+ print_if_not_quiet(f"Output file path for {key}: {output_file_paths[key]}")
3134
+
3135
+ # Step 4: Check if output files exist and confirm overwrite if necessary
3136
+ for key, path in output_file_paths.items():
3137
+ if os.path.exists(path) and not force:
3138
+ if not click.confirm(f"Output file {path} already exists. Overwrite?"):
3139
+ print(f"[bold yellow]Operation cancelled for {key}.[/bold yellow]")
3140
+ return None, None, None
3141
+
3142
+ # Step 5: Return the outputs
3143
+ return input_strings, output_file_paths, language</input_code>
3144
+ <example_code>filename = generate_output_filename(
3145
+ command, # pdd commands like 'generate', etc.
3146
+ key, # output dictionary key like 'output', 'output-test', etc.
3147
+ basename, # the basename of the file
3148
+ language, # the language of the file
3149
+ file_extension # the file extension of the file
3150
+ )</example_code>
3151
+ <sub_prompt>% You are an expert Python software engineer. Your task is to implement a function called `generate_output_filename` that creates appropriate output filenames for different commands in a Python program.
3152
+
3153
+ % Inputs: The function should take the following parameters:
3154
+ - `command` (string): The command being executed (e.g., 'generate', 'example', 'test', 'preprocess', 'fix')
3155
+ - `key` (string): The output dictionary key (e.g., 'output', 'output-test')
3156
+ - `basename` (string): The base name of the file
3157
+ - `language` (string): The programming language of the file
3158
+ - `file_extension` (string): The file extension to be used
3159
+
3160
+ % Outputs: The function should return a string representing the generated output filename.
3161
+
3162
+ % Follow these rules for generating the output filename:
3163
+ 1. For the 'generate' command: Return `f"{basename}{file_extension}"`
3164
+ 2. For the 'example' command: Return `f"{basename}_example{file_extension}"`
3165
+ 3. For the 'test' command: Return `f"test_{basename}{file_extension}"`
3166
+ 4. For the 'preprocess' command: Return `f"{basename}_{language or 'unknown'}_preprocessed.prompt"`
3167
+ 5. For the 'fix' command:
3168
+ - If the key is 'output-test', return `f"test_{basename}_fixed{file_extension}"`
3169
+ - Otherwise, return `f"{basename}_fixed{file_extension}"`
3170
+ 6. For any other command: Return `f"{basename}_output{file_extension}"`
3171
+
3172
+ % Implement the function to handle all these cases efficiently and return the appropriate filename as a string, accordingly.
3173
+
3174
+ % Ensure the function handles all cases correctly and returns the appropriate filename string, language, and file extension. The function should be robust and able to handle various edge cases, such as missing file extensions or languages.</sub_prompt>
3175
+ <modified_prompt>% You are an expert Python software engineer. Your goal is to write a Python function, "construct_paths", that will generate and check the appropriate input and output file paths and then load the input files. This function will be used by pdd to perform this functionality. All output to the console will be pretty printed using the Python rich library. The CLI will be handled using the Python Click library.
3176
+
3177
+ % Here is a detailed description of the program functionality: ```<./README.md>```
3178
+
3179
+ % Here is an example of how to lookup a file extension given a language: ```<./context/get_extension_example.py>```
3180
+
3181
+ % Here is an example of how to generate the appropriate output filenames based on the command, key, basename, language, and file extension using the `generate_output_filename` function: ```<./context/generate_output_filename_example.py>```
3182
+
3183
+ % Here are the inputs and outputs of the function:
3184
+ Inputs:
3185
+ - 'input_file_paths' (dict) - A dictionary of the paths of the input files with the keys being those specified in the examples from the pdd program description.
3186
+ - 'force' (boolean) - A flag that indicates whether to overwrite the output files if they already exist.
3187
+ - 'quiet' (boolean) - A flag that indicates whether to suppress the output.
3188
+ - 'command' (string) - pdd command that was run.
3189
+ - 'command_options' (dict) - A dictionary of the command options for the given command.
3190
+ Outputs:
3191
+ - 'input_strings' (dict) - A dictionary with the keys being the pdd description examples and the values being the input file strings.
3192
+ - 'output_file_paths' (dict)- A dictionary with the keys being the loaded input files and output files paths.
3193
+ - 'language' (string) - The language of the output file.
3194
+
3195
+ % If the file name has no extension, add the appropriate file extension (e.g '.prompt' to input file for the 'generate' command) to the file name.
3196
+
3197
+ % If the command is 'generate' extract the basename and language from the input_file_path. Use get_extension to get the file extension for the language. The file extension and language is used for the subsequent functionality below. Be able to handle files missing a '_' in the file name.
3198
+
3199
+ % Unless quiet is True, print out the input and output file paths that are being used and the steps being done below.
3200
+
3201
+ % This function will do the following:
3202
+ Step 1. Construct the input file paths using above rules.
3203
+ Step 2. Load the input files into the input_strings dictionary with the pdd description examples as the keys. Alert the user of any errors in loading the input files.
3204
+ Step 3. Construct the output file paths using the above rules using the `generate_output_filename` function. It should construct the full file path including the output file name for the output files following the rules in the "Output Location Specification" section of the pdd program description.
3205
+ Step 4. If the output files already exist, and force isn't true, check with the user if the program should overwrite.
3206
+ Step 5. Return the outputs</modified_prompt>
3207
+ </example_4>
3208
+ </examples>
3209
+
3210
+ <context>
3211
+ % You are an expert LLM Prompt Engineer. Your goal is to split the input_prompt into a sub_prompt and modified_prompt with no loss of functionality.
3212
+
3213
+ % Here are the inputs and outputs of this prompt:
3214
+ <input_definitions>
3215
+ Input:
3216
+ 'input_prompt' - A string contains the prompt that will be split into a sub_prompt and modified_prompt.
3217
+ 'input_code' - A string that contains the code that was generated from the input_prompt.
3218
+ 'example_code' - A string that contains the code example of how the code generated from the sub_prompt would be used by the code generated from the modified_prompt.
3219
+ </input_definitions>
3220
+ <output_definitions>
3221
+ Output:
3222
+ 'sub_prompt' - A string that contains the sub_prompt that was split from the input_prompt.
3223
+ 'modified_prompt' - A string that contains the modified prompt from input_prompt split from the above sub_prompt.
3224
+ </output_definitions>
3225
+ </context>
3226
+
3227
+ <inputs>
3228
+ <input_prompt>{input_prompt}</input_prompt>
3229
+ <input_code>{input_code}</input_code>
3230
+ <example_code>{example_code}</example_code>
3231
+ </inputs>
3232
+
3233
+ <instructions>
3234
+ % Follow these instructions:
3235
+ 1. Write out the difficulties in spliting the prompt.
3236
+ 2. Write out how to overcome the difficulties.
3237
+ 3. Generate the sub_prompt.
3238
+ 4. Generate the modified_prompt.
3239
+ </instructions>
3240
+
3241
+ </example_tagged_prompt>
3242
+ </example>
3243
+
3244
+ <output_instructions>
3245
+ Output a string with the `input_raw_prompt` properly tagged using XML as metadata and structural elements to enhance clarity and organization. The output may include, but is not limited to:
3246
+ 1. `<instructions>`: Guidelines or directives for the model's output.
3247
+ 2. `<context>`: Background information or relevant data for understanding the task.
3248
+ 3. `<examples>`: Specific instances that guide the model's response.
3249
+ 4. `<formatting>`: Special formatting instructions for the output.
3250
+ </output_instructions>
3251
+
3252
+ <steps>
3253
+ Follow these steps to tag the prompt:
3254
+ Step 1. Write out the analysis of the input_raw_prompt by identifying components like instructions, context, and examples.
3255
+ Step 2. Discuss what could be appropriate XML tags for this input_raw_prompt.
3256
+ Step 3. Insert the XML tags at the correct locations in the input_raw_prompt without introducing any new content. Only add tags to existing content. The XML tags should be enhancing the input_raw_prompt's format, structure and readability.
3257
+ </steps>
3258
+
3259
+ <general_points>
3260
+ - With triple backtick includes and curly bracket placeholders, there could be lots of text in them after preprocessing so XML tags will help to organize the content.
3261
+ - No need to include the initial and ending triple backticks for the XML code block.
3262
+ </general_points>
24
3263
  </example_tagged_prompt>
25
3264
  </example_2>
26
3265
  </examples>