pdd-cli 0.0.42__py3-none-any.whl → 0.0.90__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pdd/__init__.py +4 -4
- pdd/agentic_common.py +863 -0
- pdd/agentic_crash.py +534 -0
- pdd/agentic_fix.py +1179 -0
- pdd/agentic_langtest.py +162 -0
- pdd/agentic_update.py +370 -0
- pdd/agentic_verify.py +183 -0
- pdd/auto_deps_main.py +15 -5
- pdd/auto_include.py +63 -5
- pdd/bug_main.py +3 -2
- pdd/bug_to_unit_test.py +2 -0
- pdd/change_main.py +11 -4
- pdd/cli.py +22 -1181
- pdd/cmd_test_main.py +80 -19
- pdd/code_generator.py +58 -18
- pdd/code_generator_main.py +672 -25
- pdd/commands/__init__.py +42 -0
- pdd/commands/analysis.py +248 -0
- pdd/commands/fix.py +140 -0
- pdd/commands/generate.py +257 -0
- pdd/commands/maintenance.py +174 -0
- pdd/commands/misc.py +79 -0
- pdd/commands/modify.py +230 -0
- pdd/commands/report.py +144 -0
- pdd/commands/templates.py +215 -0
- pdd/commands/utility.py +110 -0
- pdd/config_resolution.py +58 -0
- pdd/conflicts_main.py +8 -3
- pdd/construct_paths.py +281 -81
- pdd/context_generator.py +10 -2
- pdd/context_generator_main.py +113 -11
- pdd/continue_generation.py +47 -7
- pdd/core/__init__.py +0 -0
- pdd/core/cli.py +503 -0
- pdd/core/dump.py +554 -0
- pdd/core/errors.py +63 -0
- pdd/core/utils.py +90 -0
- pdd/crash_main.py +44 -11
- pdd/data/language_format.csv +71 -62
- pdd/data/llm_model.csv +20 -18
- pdd/detect_change_main.py +5 -4
- pdd/fix_code_loop.py +331 -77
- pdd/fix_error_loop.py +209 -60
- pdd/fix_errors_from_unit_tests.py +4 -3
- pdd/fix_main.py +75 -18
- pdd/fix_verification_errors.py +12 -100
- pdd/fix_verification_errors_loop.py +319 -272
- pdd/fix_verification_main.py +57 -17
- pdd/generate_output_paths.py +93 -10
- pdd/generate_test.py +16 -5
- pdd/get_jwt_token.py +48 -9
- pdd/get_run_command.py +73 -0
- pdd/get_test_command.py +68 -0
- pdd/git_update.py +70 -19
- pdd/increase_tests.py +7 -0
- pdd/incremental_code_generator.py +2 -2
- pdd/insert_includes.py +11 -3
- pdd/llm_invoke.py +1278 -110
- pdd/load_prompt_template.py +36 -10
- pdd/pdd_completion.fish +25 -2
- pdd/pdd_completion.sh +30 -4
- pdd/pdd_completion.zsh +79 -4
- pdd/postprocess.py +10 -3
- pdd/preprocess.py +228 -15
- pdd/preprocess_main.py +8 -5
- pdd/prompts/agentic_crash_explore_LLM.prompt +49 -0
- pdd/prompts/agentic_fix_explore_LLM.prompt +45 -0
- pdd/prompts/agentic_fix_harvest_only_LLM.prompt +48 -0
- pdd/prompts/agentic_fix_primary_LLM.prompt +85 -0
- pdd/prompts/agentic_update_LLM.prompt +1071 -0
- pdd/prompts/agentic_verify_explore_LLM.prompt +45 -0
- pdd/prompts/auto_include_LLM.prompt +98 -101
- pdd/prompts/change_LLM.prompt +1 -3
- pdd/prompts/detect_change_LLM.prompt +562 -3
- pdd/prompts/example_generator_LLM.prompt +22 -1
- pdd/prompts/extract_code_LLM.prompt +5 -1
- pdd/prompts/extract_program_code_fix_LLM.prompt +14 -2
- pdd/prompts/extract_prompt_update_LLM.prompt +7 -8
- pdd/prompts/extract_promptline_LLM.prompt +17 -11
- pdd/prompts/find_verification_errors_LLM.prompt +6 -0
- pdd/prompts/fix_code_module_errors_LLM.prompt +16 -4
- pdd/prompts/fix_errors_from_unit_tests_LLM.prompt +6 -41
- pdd/prompts/fix_verification_errors_LLM.prompt +22 -0
- pdd/prompts/generate_test_LLM.prompt +21 -6
- pdd/prompts/increase_tests_LLM.prompt +1 -2
- pdd/prompts/insert_includes_LLM.prompt +1181 -6
- pdd/prompts/split_LLM.prompt +1 -62
- pdd/prompts/trace_LLM.prompt +25 -22
- pdd/prompts/unfinished_prompt_LLM.prompt +85 -1
- pdd/prompts/update_prompt_LLM.prompt +22 -1
- pdd/prompts/xml_convertor_LLM.prompt +3246 -7
- pdd/pytest_output.py +188 -21
- pdd/python_env_detector.py +151 -0
- pdd/render_mermaid.py +236 -0
- pdd/setup_tool.py +648 -0
- pdd/simple_math.py +2 -0
- pdd/split_main.py +3 -2
- pdd/summarize_directory.py +56 -7
- pdd/sync_determine_operation.py +918 -186
- pdd/sync_main.py +82 -32
- pdd/sync_orchestration.py +1456 -453
- pdd/sync_tui.py +848 -0
- pdd/template_registry.py +264 -0
- pdd/templates/architecture/architecture_json.prompt +242 -0
- pdd/templates/generic/generate_prompt.prompt +174 -0
- pdd/trace.py +168 -12
- pdd/trace_main.py +4 -3
- pdd/track_cost.py +151 -61
- pdd/unfinished_prompt.py +49 -3
- pdd/update_main.py +549 -67
- pdd/update_model_costs.py +2 -2
- pdd/update_prompt.py +19 -4
- {pdd_cli-0.0.42.dist-info → pdd_cli-0.0.90.dist-info}/METADATA +20 -7
- pdd_cli-0.0.90.dist-info/RECORD +153 -0
- {pdd_cli-0.0.42.dist-info → pdd_cli-0.0.90.dist-info}/licenses/LICENSE +1 -1
- pdd_cli-0.0.42.dist-info/RECORD +0 -115
- {pdd_cli-0.0.42.dist-info → pdd_cli-0.0.90.dist-info}/WHEEL +0 -0
- {pdd_cli-0.0.42.dist-info → pdd_cli-0.0.90.dist-info}/entry_points.txt +0 -0
- {pdd_cli-0.0.42.dist-info → pdd_cli-0.0.90.dist-info}/top_level.txt +0 -0
|
@@ -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
|
-
<
|
|
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
|
-
<
|
|
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
|
-
|
|
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
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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>
|