pdd-cli 0.0.44__py3-none-any.whl → 0.0.45__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.
@@ -15,9 +15,7 @@
15
15
  </inputs_outputs_definitions>
16
16
 
17
17
  <change_prompt_examples>
18
- <include>
19
- ../prompts/xml/change_example_partial_processed.prompt
20
- </include>
18
+ [File not found: ../prompts/xml/change_example_partial_processed.prompt]
21
19
  </change_prompt_examples>
22
20
 
23
21
  <context>
@@ -16,16 +16,473 @@
16
16
  <example>
17
17
  <input_example>
18
18
  <prompt_list_example>
19
- <include>context/detect_change/2/prompt_list.json</include>
19
+ [{"PROMPT_NAME": "change_python.prompt", "PROMPT_DESCRIPTION": "% You are an expert Python Software Engineer. Your goal is to write a Python function, \"change\", that will modify an input_prompt into a modified_prompt per the change_prompt. All output to the console will be pretty printed using the Python Rich library. Ensure that the module imports are done using relative imports.\n\n% Here are the inputs and outputs of the function:\n Inputs:\n - 'input_prompt' - A string that contains the prompt that will be modified by the change_prompt.\n - 'input_code' - A string that contains the code that was generated from the input_prompt.\n - 'change_prompt' - A string that contains the instructions of how to modify the input_prompt.\n - 'strength': A float value representing the strength parameter for the LLM model, used to influence the model's behavior.\n - 'temperature': A float value representing the temperature parameter for the LLM model, used to control the randomness of the model's output.\n Outputs:\n - 'modified_prompt' - A string that contains the modified prompt that was changed based on the change_prompt.\n - 'total_cost': A float value representing the total cost of running the function.\n - 'model_name': A string representing the name of the selected LLM model.\n\n% Here is an example how to preprocess the prompt from a file: ```<./context/preprocess_example.py>```\n\n% Example usage of the Langchain LCEL program: ```<./context/langchain_lcel_example.py>```\n\n% Example of selecting a Langchain LLM and counting tokens using llm_selector: ```<./context/llm_selector_example.py>```\n\n% Steps to be followed by the function:\n 1. Load the '$PDD_PATH/prompts/xml/change_LLM.prompt' and '$PDD_PATH/prompts/extract_prompt_change_LLM.prompt' files.\n 2. Preprocess the change_LLM prompt using the preprocess function from the preprocess module and set double_curly_brackets to false.\n 3. Create a Langchain LCEL template from the processed change_LLM prompt to return a string output. \n 4. Use the llm_selector function for the LLM model and token counting.\n 5. Run the input_prompt through the model using Langchain LCEL:\n - a. Pass the following string parameters to the prompt during invocation: \n * 'input_prompt'\n * 'input_code'\n * 'change_prompt' (preprocess this with double_curly_brackets set to false)\n - b. Calculate the input and output token count using token_counter from llm_selector and pretty print the output of 4a, including the token count and estimated cost. The cost from llm_selector is in dollars per million tokens.\n 6. Create a Langchain LCEL template with strength .9 from the extract_prompt_change_LLM prompt that outputs JSON:\n - a. Pass the following string parameters to the prompt during invocation: 'llm_output' (this string is from Step 4).\n - b. Calculate input and output token count using token_counter from llm_selector and pretty print the running message with the token count and cost.\n - c. Use 'get' function to extract 'modified_prompt' key values using from the dictionary output.\n 7. Pretty print the extracted modified_prompt using Rich Markdown function. Include token counts and costs.\n 8. Return the 'modified_prompt' string, the total_cost of both invokes and model_name use for the change_LLM prompt.\n\n% Ensure the function handles edge cases, such as missing inputs or model errors, and provide clear error messages."}, {"PROMPT_NAME": "preprocess_python.prompt", "PROMPT_DESCRIPTION": "% You are an expert Python engineer. Your goal is to write a Python function, 'preprocess_prompt', that will preprocess the prompt from a prompt string for a LLM. This will use regular expressions to preprocess specific XML-like tags, if any, in the prompt. All output to the console will be pretty print using the Python rich library.\n\n% Here are the inputs and outputs of the function:\n Input: \n 'prompt' - A string that is the prompt to preprocess\n 'recursive' - A boolean that is True if the program needs to recursively process the includes in the prompt and False if it does not need to recursively process the prompt. Default is True.\n 'double_curly_brackets' - A boolean that is True if the curly brackets need to be doubled and False if they do not need to be doubled. Default is True.\n 'exclude_keys' - An optional list of strings that are excluded from the curly bracket doubling.\n Output: returns a string that is the preprocessed prompt, with any leading or trailing whitespace removed.\n\n% Here are the XML-like tags to preprocess, other tags will remain unmodified:\n 'include' - This tag will include the content of the file indicated in the include tag. The 'include tag' will be directly replaced with the content of the file in the prompt, without wrapping it in a new tag.\n 'pdd' - This tag indicates a comment and anything in this XML will be deleted from the string including the 'pdd' tags themselves.\n 'shell' - This tag indicates that there are shell commands to run. Capture all output of the shell commands and include it in the prompt but remove the shell tags.\n\n% Includes can be nested, that is there can be includes inside of the files of the includes and 'preprocess' should be called recursively on these include files if recursive is True. There are two ways of having includes in the prompt:\n 1. Will check to see if the file has any angle brackets in triple backticks. If so, it will read the included file indicated in the angle brackets and replace the angle brackets with the content of the included file. This will be done recursively until there are no more angle brackets in triple backticks. The program will then remove the angle brackets but leave the contents in the triple backticks.\n 2. The XML 'include' mentioned above.\n\n% If double_curly_brackets is True, the program will check to see if the file has any single curly brackets and if it does and the string in the curly brackets are not in the exclude_keys list, it will check to see if the curly brackets are already doubled before doubling the curly brackets.\n\n% The program should resolve file paths using the PDD_PATH environment variable. Implement a function 'get_file_path' that takes a file name and returns the full path using this environment variable.\n\n% Keep the user informed of the progress of the program by pretty printing messages."}, {"PROMPT_NAME": "unfinished_prompt_python.prompt", "PROMPT_DESCRIPTION": "% You are an expert Python engineer. Your goal is to write a python function called 'unfinished_prompt' that will determine if a given prompt is complete or needs to continue.\n\n% Here are the inputs and outputs of the function:\n Inputs:\n 'prompt_text' - A string containing the prompt text to analyze.\n 'strength' - A float that is the strength of the LLM model to use for the analysis. Default is 0.5.\n 'temperature' - A float that is the temperature of the LLM model to use for the analysis. Default is 0.\n Outputs:\n 'reasoning' - A string containing the structured reasoning for the completeness assessment.\n 'is_finished' - A boolean indicating whether the prompt is complete (True) or incomplete (False).\n 'total_cost' - A float that is the total cost of the analysis function. This is an optional output.\n 'model_name' - A string that is the name of the LLM model used for the analysis. This is an optional output.\n\n% Here is an example of a Langchain LCEL program: ```<./context/langchain_lcel_example.py>```\n\n% Here is an example how to select the Langchain llm and count tokens: ```<./context/llm_selector_example.py>```\n\n% Note: Use relative import for 'llm_selector' to ensure compatibility within the package structure (i.e. 'from .llm_selector') instead of 'from pdd.llm_selector'.\n\n% This function will do the following:\n Step 1. Use $PDD_PATH environment variable to get the path to the project. Load the '$PDD_PATH/prompts/unfinished_prompt_LLM.prompt' file.\n Step 2. Create a Langchain LCEL template from unfinished_prompt_LLM prompt so that it returns a JSON output.\n Step 3. Use the llm_selector function for the LLM model.\n Step 4. Run the prompt text through the model using Langchain LCEL.\n 4a. Pass the following string parameters to the prompt during invoke:\n - 'PROMPT_TEXT'\n 4b. Pretty print a message letting the user know it is running and how many tokens (using token_counter function from llm_selector) are in the prompt and the cost. The cost from llm_selector is in dollars per million tokens.\n 4c. The dictionary output of the LCEL will have the keys 'reasoning' and 'is_finished'. Be sure to access these keys using the get method with default error messages.\n 4d. Pretty print the reasoning and completion status using the rich library. Also, print the number of tokens in the result, the output token cost and the total_cost.\n Step 5. Return the 'reasoning' string and 'is_finished' boolean from the JSON output using 'get', and the 'total_cost' float, and 'model_name' string.\n\n% Ensure that the function handles potential errors gracefully, such as missing input parameters or issues with the LLM model responses.\n\n"}, {"PROMPT_NAME": "xml_tagger_python.prompt", "PROMPT_DESCRIPTION": "% You are an expert Python engineer. Your goal is to write a Python function, \"xml_tagger\", that will enhance a given LLM prompt by adding XML tags to improve its structure and readability.\n\n% The function should be part of a Python package, using relative imports (single dot) for internal modules (e.g. 'from .module_name import module_name'). All output to the console will be pretty printed using the Python Rich library. Ensure the function handles edge cases, such as missing inputs or model errors, and provide clear error messages.
20
+ % The ./pdd/__init__.py file will have the EXTRACTION_STRENGTH, DEFAULT_STRENGTH, DEFAULT_TIME and other global constants. Example: ```from . import DEFAULT_STRENGTH```\n\n% Here are the inputs and outputs of the function:\n Input: \n 'raw_prompt' - A string containing the prompt that needs XML tagging to improve its organization and clarity.\n 'strength' - A float value representing the strength parameter for the LLM model.\n 'temperature' - A float value representing the temperature parameter for the LLM model.\n Output: \n 'xml_tagged' - A string containing the prompt with properly added XML tags.\n 'total_cost' - A float representing the total cost of running the LCELs.\n 'model_name' - A string representing the name of the selected LLM model.\n\n% Here is an example of a LangChain Expression Language (LCEL) program: <lcel_example>import os
21
+ from langchain_core.prompts import PromptTemplate
22
+ from langchain_community.cache import SQLiteCache
23
+ from langchain_community.llms.mlx_pipeline import MLXPipeline
24
+ from langchain.globals import set_llm_cache
25
+ from langchain_core.output_parsers import JsonOutputParser, PydanticOutputParser # Parsers are only avaiable in langchain_core.output_parsers not langchain.output_parsers
26
+ from langchain_core.output_parsers import StrOutputParser
27
+ from langchain_core.prompts import ChatPromptTemplate
28
+ from langchain_core.runnables import RunnablePassthrough, ConfigurableField
29
+
30
+ from langchain_openai import AzureChatOpenAI
31
+ from langchain_fireworks import Fireworks
32
+ from langchain_anthropic import ChatAnthropic
33
+ from langchain_openai import ChatOpenAI # Chatbot and conversational tasks
34
+ from langchain_openai import OpenAI # General language tasks
35
+ from langchain_google_genai import ChatGoogleGenerativeAI
36
+ from langchain_google_vertexai import ChatVertexAI
37
+ from langchain_groq import ChatGroq
38
+ from langchain_together import Together
39
+
40
+ from langchain.callbacks.base import BaseCallbackHandler
41
+ from langchain.schema import LLMResult
42
+
43
+ import json
44
+
45
+ from langchain_community.chat_models.mlx import ChatMLX
46
+ from langchain_core.messages import HumanMessage
47
+
48
+ from langchain_ollama.llms import OllamaLLM
49
+ from langchain_aws import ChatBedrockConverse
50
+
51
+ # Define a base output parser (e.g., PydanticOutputParser)
52
+ from pydantic import BaseModel, Field
53
+
54
+
55
+
56
+ class CompletionStatusHandler(BaseCallbackHandler):
57
+ def __init__(self):
58
+ self.is_complete = False
59
+ self.finish_reason = None
60
+ self.input_tokens = None
61
+ self.output_tokens = None
62
+
63
+ def on_llm_end(self, response: LLMResult, **kwargs) -> None:
64
+ self.is_complete = True
65
+ if response.generations and response.generations[0]:
66
+ generation = response.generations[0][0]
67
+ self.finish_reason = generation.generation_info.get('finish_reason').lower()
68
+
69
+ # Extract token usage
70
+ if hasattr(generation.message, 'usage_metadata'):
71
+ usage_metadata = generation.message.usage_metadata
72
+ self.input_tokens = usage_metadata.get('input_tokens')
73
+ self.output_tokens = usage_metadata.get('output_tokens')
74
+ # print("response:",response)
75
+ print("Extracted information:")
76
+ print(f"Finish reason: {self.finish_reason}")
77
+ print(f"Input tokens: {self.input_tokens}")
78
+ print(f"Output tokens: {self.output_tokens}")
79
+
80
+ # Set up the LLM with the custom handler
81
+ handler = CompletionStatusHandler()
82
+ # Always setup cache to save money and increase speeds
83
+ set_llm_cache(SQLiteCache(database_path=".langchain.db"))
84
+
85
+
86
+ # Create the LCEL template. Make note of the variable {topic} which will be filled in later.
87
+ prompt_template = PromptTemplate.from_template("Tell me a joke about {topic}")
88
+
89
+ llm = ChatGoogleGenerativeAI(model="gemini-2.5-pro-exp-03-25", temperature=0, callbacks=[handler])
90
+ # Combine with a model and parser to output a string
91
+ chain = prompt_template |llm| StrOutputParser()
92
+
93
+ # Run the template. Notice that the input is a dictionary with a single key "topic" which feeds it into the above prompt template. This is needed because the prompt template has a variable {topic} which needs to be filled in when invoked.
94
+ result = chain.invoke({"topic": "cats"})
95
+ print("********Google:", result)
96
+
97
+
98
+ llm = ChatVertexAI(model="gemini-2.5-pro-exp-03-25", temperature=0, callbacks=[handler])
99
+ # Combine with a model and parser to output a string
100
+ chain = prompt_template |llm| StrOutputParser()
101
+
102
+ # Run the template. Notice that the input is a dictionary with a single key "topic" which feeds it into the above prompt template. This is needed because the prompt template has a variable {topic} which needs to be filled in when invoked.
103
+ result = chain.invoke({"topic": "cats"})
104
+ print("********GoogleVertex:", result)
105
+
106
+
107
+ # Define your desired data structure.
108
+ class Joke(BaseModel):
109
+ setup: str = Field(description="question to set up a joke")
110
+ punchline: str = Field(description="answer to resolve the joke")
111
+
112
+
113
+ # Set up a parser
114
+ parser = JsonOutputParser(pydantic_object=Joke)
115
+
116
+ # Create a prompt template
117
+ prompt = PromptTemplate(
118
+ template="Answer the user query.\n{format_instructions}\n{query}\n",
119
+ input_variables=["query"],
120
+ partial_variables={"format_instructions": parser.get_format_instructions()},
121
+ )
122
+
123
+ llm_no_struct = ChatOpenAI(model="gpt-4o-mini", temperature=0,
124
+ callbacks=[handler])
125
+ llm = llm_no_struct.with_structured_output(Joke) # with structured output forces the output to be a specific object, in this case Joke. Only OpenAI models have structured output
126
+ # Chain the components.
127
+ # The class `LLMChain` was deprecated in LangChain 0.1.17 and will be removed in 1.0. Use RunnableSequence, e.g., `prompt | llm` instead.
128
+ chain = prompt | llm
129
+
130
+ # Invoke the chain with a query.
131
+ # IMPORTANT: chain.run is now obsolete. Use chain.invoke instead.
132
+ result = chain.invoke({"query": "Tell me a joke about openai."})
133
+ print("4o mini JSON: ",result)
134
+ print(result.setup) # How to access the structured output
135
+
136
+ llm = ChatOpenAI(model="o1", temperature=1,
137
+ callbacks=[handler],model_kwargs = {"max_completion_tokens" : 1000})
138
+ # Chain the components.
139
+ # The class `LLMChain` was deprecated in LangChain 0.1.17 and will be removed in 1.0. Use RunnableSequence, e.g., `prompt | llm` instead.
140
+ chain = prompt | llm | parser
141
+
142
+ # Invoke the chain with a query.
143
+ # IMPORTANT: chain.run is now obsolete. Use chain.invoke instead.
144
+ result = chain.invoke({"query": "Tell me a joke about openai."})
145
+ print("o1 JSON: ",result)
146
+
147
+ # Get DEEPSEEK_API_KEY environmental variable
148
+
149
+ deepseek_api_key = os.getenv('DEEPSEEK_API_KEY')
150
+
151
+ # Ensure the API key is retrieved successfully
152
+ if deepseek_api_key is None:
153
+ raise ValueError("DEEPSEEK_API_KEY environment variable is not set")
154
+
155
+ llm = ChatOpenAI(
156
+ model='deepseek-chat',
157
+ openai_api_key=deepseek_api_key,
158
+ openai_api_base='https://api.deepseek.com',
159
+ temperature=0, callbacks=[handler]
160
+ )
161
+
162
+ # Chain the components
163
+ chain = prompt | llm | parser
164
+
165
+ # Invoke the chain with a query
166
+ result = chain.invoke({"query": "Write joke about deepseek."})
167
+ print("deepseek",result)
168
+
169
+
170
+ # Set up a parser
171
+ parser = PydanticOutputParser(pydantic_object=Joke)
172
+ # Chain the components
173
+ chain = prompt | llm | parser
174
+
175
+ # Invoke the chain with a query
176
+ result = chain.invoke({"query": "Write joke about deepseek and pydantic."})
177
+ print("deepseek pydantic",result)
178
+
179
+ # Set up the Azure ChatOpenAI LLM instance
180
+ llm_no_struct = AzureChatOpenAI(
181
+ model="o4-mini",
182
+ temperature=1,
183
+ callbacks=[handler]
184
+ )
185
+ llm = llm_no_struct.with_structured_output(Joke) # with structured output forces the output to be a specific JSON format
186
+ # Chain the components: prompt | llm | parser
187
+ chain = prompt | llm # returns a Joke object
188
+
189
+ # Invoke the chain with a query
190
+ result = chain.invoke({"query": "What is Azure?"}) # Pass a dictionary if `invoke` expects it
191
+ print("Azure Result:", result)
192
+
193
+ # Set up a parser
194
+ parser = JsonOutputParser(pydantic_object=Joke)
195
+
196
+ llm = Fireworks(
197
+ model="accounts/fireworks/models/llama4-maverick-instruct-basic",
198
+ temperature=0, callbacks=[handler])
199
+ # Chain the components
200
+ chain = prompt | llm | parser
201
+
202
+ # Invoke the chain with a query
203
+ # no money in account
204
+ # result = chain.invoke({"query": "Tell me a joke about the president"})
205
+ # print("fireworks",result)
206
+
207
+
208
+
209
+
210
+
211
+ prompt = ChatPromptTemplate.from_template(
212
+ "Tell me a short joke about {topic}"
213
+ )
214
+ chat_openai = ChatOpenAI(model="gpt-3.5-turbo", callbacks=[handler])
215
+ openai = OpenAI(model="gpt-3.5-turbo-instruct", callbacks=[handler])
216
+ anthropic = ChatAnthropic(model="claude-2", callbacks=[handler])
217
+ model = (
218
+ chat_openai
219
+ .with_fallbacks([anthropic])
220
+ .configurable_alternatives(
221
+ ConfigurableField(id="model"),
222
+ default_key="chat_openai",
223
+ openai=openai,
224
+ anthropic=anthropic,
225
+ )
226
+ )
227
+
228
+ chain = (
229
+ {"topic": RunnablePassthrough()}
230
+ | prompt
231
+ | model
232
+ | StrOutputParser()
233
+ )
234
+ result = chain.invoke({"topic": "Tell me a joke about the president"})
235
+ print("config alt:",result)
236
+
237
+
238
+
239
+ llm = ChatAnthropic(
240
+ model="claude-3-7-sonnet-latest",
241
+ max_tokens=5000, # Total tokens for the response
242
+ thinking={"type": "enabled", "budget_tokens": 2000}, # Tokens for internal reasoning
243
+ )
244
+
245
+ response = llm.invoke("What is the cube root of 50.653?")
246
+ print(json.dumps(response.content, indent=2))
247
+
248
+
249
+ llm = ChatGroq(temperature=0, model_name="qwen-qwq-32b", callbacks=[handler])
250
+ system = "You are a helpful assistant."
251
+ human = "{text}"
252
+ prompt = ChatPromptTemplate.from_messages([("system", system), ("human", human)])
253
+
254
+ chain = prompt | llm | StrOutputParser()
255
+ print(chain.invoke({"text": "Explain the importance of low latency LLMs."}))
256
+
257
+
258
+ llm = Together(
259
+ model="meta-llama/Llama-3-70b-chat-hf",
260
+ max_tokens=500, callbacks=[handler]
261
+ )
262
+ chain = prompt | llm | StrOutputParser()
263
+ print(chain.invoke({"text": "Explain the importance of together.ai."}))
264
+
265
+
266
+ # Define a prompt template with placeholders for variables
267
+ prompt_template = PromptTemplate.from_template("Tell me a {adjective} joke about {content}.")
268
+
269
+ # Format the prompt with the variables
270
+ formatted_prompt = prompt_template.format(adjective="funny", content="data scientists")
271
+
272
+ # Print the formatted prompt
273
+ print(formatted_prompt)
274
+
275
+
276
+ # Set up the LLM with the custom handler
277
+ handler = CompletionStatusHandler()
278
+
279
+
280
+ llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0.9, callbacks=[handler])
281
+
282
+ prompt = PromptTemplate.from_template("What is a good name for a company that makes {product}?")
283
+
284
+ chain = prompt | llm
285
+
286
+ # Invoke the chain
287
+ response = chain.invoke({"product":"colorful socks"})
288
+
289
+ # Check completion status
290
+ print(f"Is complete: {handler.is_complete}")
291
+ print(f"Finish reason: {handler.finish_reason}")
292
+ print(f"Response: {response}")
293
+ print(f"Input tokens: {handler.input_tokens}")
294
+ print(f"Output tokens: {handler.output_tokens}")
295
+
296
+
297
+
298
+ template = """Question: {question}"""
299
+
300
+ prompt = ChatPromptTemplate.from_template(template)
301
+
302
+ model = OllamaLLM(model="qwen2.5-coder:32b")
303
+
304
+ chain = prompt | model
305
+
306
+ output = chain.invoke({"question": "Write a python function that calculates Pi"})
307
+ print(output)
308
+
309
+
310
+
311
+ llm = MLXPipeline.from_model_id(
312
+ "mlx-community/quantized-gemma-2b-it",
313
+ pipeline_kwargs={"max_tokens": 10, "temp": 0.1},
314
+ )
315
+
316
+
317
+ chat_model = ChatMLX(llm=llm)
318
+ messages = [HumanMessage(content="What happens when an unstoppable force meets an immovable object?")]
319
+ response = chat_model.invoke(messages)
320
+ print(response.content)
321
+
322
+
323
+
324
+ llm = ChatBedrockConverse(
325
+ model_id="anthropic.claude-3-5-sonnet-20240620-v1:0",
326
+ # Additional parameters like temperature, max_tokens can be set here
327
+ )
328
+
329
+ messages = [HumanMessage(content="What happens when an unstoppable force meets an immovable sonnet?")]
330
+ response = llm.invoke(messages)
331
+ print(response.content)</lcel_example>\n\n% Here are examples of how to use internal modules:\n<internal_example_modules>\n % Example of selecting a Langchain LLM and counting tokens using llm_selector: <llm_selector_example>from pdd.llm_selector import llm_selector
332
+
333
+ def main() -> None:
334
+ """
335
+ Main function to demonstrate the usage of the llm_selector function.
336
+ """
337
+ # Define the strength and temperature parameters
338
+ strength: float = 0.5 # Example strength value for the LLM model
339
+ temperature: float = 1.0 # Example temperature value for the LLM model
340
+
341
+ try:
342
+ while strength <= 1.1:
343
+ # Call the llm_selector function with the specified strength and temperature
344
+ llm, token_counter, input_cost, output_cost, model_name = llm_selector(strength, temperature)
345
+ print(f"Strength: {strength}")
346
+
347
+ # Print the details of the selected LLM model
348
+ print(f"Selected LLM Model: {model_name}")
349
+ print(f"Input Cost per Million Tokens: {input_cost}")
350
+ print(f"Output Cost per Million Tokens: {output_cost}")
351
+
352
+ # Example usage of the token counter function
353
+ sample_text: str = "This is a sample text to count tokens."
354
+ token_count: int = token_counter(sample_text)
355
+ print(f"Token Count for Sample Text: {token_count}")
356
+ print(f"model_name: {model_name}")
357
+ strength += 0.05
358
+ except FileNotFoundError as e:
359
+ print(f"Error: {e}")
360
+ except ValueError as e:
361
+ print(f"Error: {e}")
362
+
363
+ if __name__ == "__main__":
364
+ main()</llm_selector_example>\n</internal_example_modules>\n\n% This program will use Langchain to do the following:\n Step 1. Use $PDD_PATH environment variable to get the path to the project. Load the '$PDD_PATH/prompts/xml_convertor_LLM.prompt' and '$PDD_PATH/prompts/extract_xml_LLM.prompt' files.\n Step 2. Create a Langchain LCEL template from xml_convertor prompt so that it returns a string output.\n Step 3. Use the llm_selector function for the LLM model and token counting.\n Step 4. Run the code through the model using Langchain LCEL. \n 4a. Pass the following string parameters to the prompt during invoke:\n - 'raw_prompt'\n 4b. Pretty print a message letting the user know it is running and how many tokens (using token_counter from llm_selector) are in the prompt and the cost. The cost from llm_selector is in dollars per million tokens. \n 4c. The string output of the LCEL will be 'xml_generated_analysis' that contains the tagged prompt.\n Step 5. The code result of the model will contain a mix of text and XML separated by triple backticks. Create a Langchain LCEL template but with a llm_selector with strength .8 from the extract_xml prompt that has a JSON output.\n 5a. Pass the following string parameters to the prompt during invoke:\n - 'xml_generated_analysis'\n 5b. Pretty print a message letting the user know it is running and how many tokens (using token_counter from llm_selector) are in the prompt and the cost. The cost from llm_selector is in dollars per million tokens.\n 5c. The JSON output of the LCEL will have the key 'xml_tagged' that contains the extracted tagged prompt.\n Step 6. Pretty print the extracted tagged prompt using the rich Markdown function. Also, print the number of tokens in the result and the cost.\n Step 7. Calculate the total cost by summing the costs from both LCEL runs.\n Step 8. Return the 'xml_tagged' string using 'get', the 'total_cost' and 'model_name'."}]
20
365
  </prompt_list_example>
21
366
 
22
367
  <change_description_example>
23
- <include>context/detect_change/2/change.prompt</include>
368
+ % Use context/python_preamble.prompt to make prompts more compact. Some prompts might already have this.
369
+
370
+ % Here is what is inside context/python_preamble.prompt:<preamble>% The function should be part of a Python package, using relative imports (single dot) for internal modules (e.g. 'from .module_name import module_name'). All output to the console will be pretty printed using the Python Rich library. Ensure the function handles edge cases, such as missing inputs or model errors, and provide clear error messages.
371
+ % The ./pdd/__init__.py file will have the EXTRACTION_STRENGTH, DEFAULT_STRENGTH, DEFAULT_TIME and other global constants. Example: ```from . import DEFAULT_STRENGTH```</preamble>
372
+
373
+ % Here is an example of this being done: <example>% You are an expert Python engineer. Your goal is to write a python function, "code_generator", that will compile a prompt into a code file.
374
+
375
+ [File not found: ../context/python_preamble.prompt]
376
+
377
+ % Here are the inputs and outputs of the function:
378
+ Inputs:
379
+ 'prompt' - A string containing the raw prompt to be processed.
380
+ 'language' - A string that is the language type (e.g. python, bash) of file that will be outputed by the LLM.
381
+ 'strength' - A float between 0 and 1 that is the strength of the LLM model to use.
382
+ 'temperature' - A float that is the temperature of the LLM model to use. Default is 0.
383
+ 'time' - A float between 0 and 1 that controls the thinking effort for the LLM model, passed to llm_invoke. Default is DEFAULT_TIME.
384
+ 'verbose' - A boolean that indicates whether to print out the details of the function. Default is False.
385
+ 'preprocess_prompt' - A boolean that indicates whether to preprocess the prompt. Default is True.
386
+ Outputs:
387
+ 'runnable_code' - A string that is runnable code
388
+ 'total_cost' - A float that is the total cost of the model run
389
+ 'model_name' - A string that is the name of the selected LLM model
390
+
391
+ % Here is how to use the internal modules:
392
+ <internal_modules>
393
+ For running prompts with llm_invoke:
394
+ <llm_invoke_example>
395
+ [File not found: ../context/llm_invoke_example.py]
396
+ </llm_invoke_example>
397
+
398
+ For preprocessing prompts:
399
+ <preprocess_example>
400
+ [File not found: ../context/preprocess_example.py]
401
+ </preprocess_example>
402
+
403
+ For handling unfinished prompts:
404
+ <unfinished_prompt_example>
405
+ [File not found: ../context/unfinished_prompt_example.py]
406
+ </unfinished_prompt_example>
407
+
408
+ For continuing generation:
409
+ <continue_generation_example>
410
+ [File not found: ../context/continue_generation_example.py]
411
+ </continue_generation_example>
412
+
413
+ For postprocessing results:
414
+ <postprocess_example>
415
+ [File not found: ../context/postprocess_example.py]
416
+ </postprocess_example>
417
+ </internal_modules>
418
+
419
+ % This program will do the following:
420
+ Step 1. Conditionally preprocess the raw prompt using the preprocess function from the preprocess module based on the value of 'preprocess_prompt'. If 'preprocess_prompt' is True, preprocess the prompt; otherwise, use the raw prompt directly.
421
+
422
+ Step 2. Run the prompt (either preprocessed or raw) through llm_invoke with an empty dictionary ('{}') and the provided strength, temperature, and time.
423
+
424
+ Step 3. Detect if the generation is incomplete using the unfinished_prompt function (strength .5) by passing in the last 600 characters of the output of Step 3.
425
+ - a. If incomplete, call the continue_generation function to complete the generation.
426
+ - b. Else, if complete, postprocess the model output result using the postprocess function from the postprocess module with the EXTRACTION_STRENGTH constant. Be sure to pass in all parameters like verbose to postprocess.
427
+ Step 4. Return the runnable_code, total_cost and model_name.</example>
24
428
  </change_description_example>
25
429
  </input_example>
26
430
 
27
431
  <output_example>
28
- <include>context/detect_change/2/detect_change_output.txt</include>
432
+ 1. **Impact of the Change and Potential Issues:**
433
+
434
+ The change description suggests using the contents of `context/python_preamble.prompt` to make prompts more compact. This preamble includes instructions for using relative imports, pretty printing with the Python Rich library, and handling edge cases. The main impact is to ensure consistency across prompts by centralizing common instructions, which can reduce redundancy and improve maintainability. Potential issues include ensuring that the preamble does not conflict with existing instructions in the prompts and that it is inserted in a way that maintains the logical flow of the prompt.
435
+
436
+ 2. **Possible Implementation Plans:**
437
+
438
+ - **Plan A: Direct Inclusion of Preamble**
439
+ - **Pros:** Simplifies prompts by removing redundant instructions and directly including the preamble.
440
+ - **Cons:** May require significant restructuring of prompts to ensure logical flow and avoid redundancy.
441
+
442
+ - **Plan B: Conditional Inclusion Based on Existing Content**
443
+ - **Pros:** Only includes the preamble if similar instructions are not already present, minimizing disruption.
444
+ - **Cons:** Requires careful analysis of each prompt to determine if the preamble is needed, which can be time-consuming.
445
+
446
+ - **Plan C: Hybrid Approach**
447
+ - **Pros:** Combines the benefits of both plans by including the preamble where it adds value and retaining existing instructions where they are more specific or detailed.
448
+ - **Cons:** Complexity in deciding which parts of the preamble to include or exclude for each prompt.
449
+
450
+ 3. **Analysis and Selection of the Best Plan:**
451
+
452
+ Plan C is the best approach as it allows for flexibility and ensures that the preamble is only included where it enhances the prompt. This minimizes redundancy and maintains the integrity of prompts that already have specific instructions. It also allows for a more tailored approach, ensuring that the preamble complements rather than conflicts with existing content.
453
+
454
+ 4. **Prompt Analysis Based on Selected Plan:**
455
+
456
+ - **change_python.prompt:** This prompt already contains detailed instructions similar to those in the preamble. However, it can benefit from the preamble for consistency in handling edge cases and pretty printing.
457
+ - **preprocess_python.prompt:** This prompt can include the preamble to ensure consistent handling of edge cases and pretty printing.
458
+ - **unfinished_prompt_python.prompt:** This prompt can include the preamble to ensure consistent handling of edge cases and pretty printing.
459
+ - **xml_tagger_python.prompt:** This prompt already includes the preamble, so no changes are needed.
460
+
461
+ 5. **Prompts That Need to Be Changed:**
462
+
463
+ - **change_python.prompt**
464
+ - **Instructions:**
465
+ - Insert the contents of the file `./context/python_preamble.prompt` immediately after the role and goal statement using 'include' XML tags.
466
+ - Remove any redundant instructions that are covered by the preamble, such as those related to pretty printing and handling edge cases.
467
+ - Ensure that the logical flow of the prompt is maintained and that any unique instructions specific to this prompt are retained.
468
+ - Here is what is inside context/python_preamble.prompt:<preamble>% The function should be part of a Python package, using relative imports (single dot) for internal modules (e.g. 'from .module_name import module_name'). All output to the console will be pretty printed using the Python Rich library. Ensure the function handles edge cases, such as missing inputs or model errors, and provide clear error messages.
469
+ % The ./pdd/__init__.py file will have the EXTRACTION_STRENGTH, DEFAULT_STRENGTH, DEFAULT_TIME and other global constants. Example: ```from . import DEFAULT_STRENGTH```</preamble>
470
+
471
+ - **preprocess_python.prompt**
472
+ - **Instructions:**
473
+ - Insert the contents of the file `./context/python_preamble.prompt` immediately after the role and goal statement using 'include' XML tags.
474
+ - Remove any redundant instructions that are covered by the preamble, such as those related to pretty printing and handling edge cases.
475
+ - Ensure that the logical flow of the prompt is maintained and that any unique instructions specific to this prompt are retained.
476
+ - Here is what is inside context/python_preamble.prompt:<preamble>% The function should be part of a Python package, using relative imports (single dot) for internal modules (e.g. 'from .module_name import module_name'). All output to the console will be pretty printed using the Python Rich library. Ensure the function handles edge cases, such as missing inputs or model errors, and provide clear error messages.
477
+ % The ./pdd/__init__.py file will have the EXTRACTION_STRENGTH, DEFAULT_STRENGTH, DEFAULT_TIME and other global constants. Example: ```from . import DEFAULT_STRENGTH```</preamble>
478
+
479
+ - **unfinished_prompt_python.prompt**
480
+ - **Instructions:**
481
+ - Insert the contents of the file `./context/python_preamble.prompt` immediately after the role and goal statement using 'include' XML tags.
482
+ - Remove any redundant instructions that are covered by the preamble, such as those related to pretty printing and handling edge cases.
483
+ - Ensure that the logical flow of the prompt is maintained and that any unique instructions specific to this prompt are retained.
484
+ - Here is what is inside context/python_preamble.prompt:<preamble>% The function should be part of a Python package, using relative imports (single dot) for internal modules (e.g. 'from .module_name import module_name'). All output to the console will be pretty printed using the Python Rich library. Ensure the function handles edge cases, such as missing inputs or model errors, and provide clear error messages.
485
+ % The ./pdd/__init__.py file will have the EXTRACTION_STRENGTH, DEFAULT_STRENGTH, DEFAULT_TIME and other global constants. Example: ```from . import DEFAULT_STRENGTH```</preamble>
29
486
  </output_example>
30
487
  </example>
31
488
 
@@ -9,50 +9,7 @@
9
9
  % This prompt is run iteratively. Here are the current errors and past potential fix attempts, if any, from the unit test and verification program run(s): <errors>{errors}</errors>
10
10
 
11
11
  % If the verfication program fails to run, the code_under_test and unit_test are unchanged from the previous iteration.
12
- <pdd>
13
- <examples>
14
- <example_1>
15
- % Here is an example_unit_test for the example_code_under_test: <example_unit_test><include>context/fix_errors_from_unit_tests/1/test_conflicts_in_prompts.py</include></example_unit_test>
16
-
17
- % Here is an example_code_under_test that fully passes the example_unit_test: <example_code_under_test><include>context/fix_errors_from_unit_tests/1/conflicts_in_prompts.py</include></example_code_under_test>
18
12
 
19
- % Here is the prompt that generated the example_code_under_test: <example_prompt><include>context/fix_errors_from_unit_tests/1/conflicts_in_prompts_python.prompt</include></example_prompt>
20
- </example_1>
21
-
22
- <example_2>
23
- % Here is an example_unit_test for the example_code_under_test: <example_unit_test><include>context/fix_errors_from_unit_tests/2/test_code_generator.py</include></example_unit_test>
24
-
25
- % Here is an example_code_under_test that fully passes the example_unit_test: <example_code_under_test><include>context/fix_errors_from_unit_tests/2/code_generator.py</include></example_code_under_test>
26
-
27
- % Here is the prompt that generated the example_code_under_test: <example_prompt><include>context/fix_errors_from_unit_tests/2/code_generator_python.prompt</include></example_prompt>
28
- </example_2>
29
-
30
- <example_3>
31
- % Here is an example_unit_test for the example_code_under_test: <example_unit_test><include>context/fix_errors_from_unit_tests/3/test_context_generator.py</include></example_unit_test>
32
-
33
- % Here is an example_code_under_test that fully passes the example_unit_test: <example_code_under_test><include>context/fix_errors_from_unit_tests/3/context_generator.py</include></example_code_under_test>
34
-
35
- % Here is the prompt that generated the example_code_under_test: <example_prompt><include>context/fix_errors_from_unit_tests/3/context_generator_python.prompt</include></example_prompt>
36
- </example_3>
37
-
38
-
39
- <example_4>
40
- % Here is an example_unit_test for the example_code_under_test: <example_unit_test><include>context/fix_errors_from_unit_tests/4/test_detect_change.py</include></example_unit_test>
41
-
42
- % Here is an example_code_under_test that fully passes the example_unit_test: <example_code_under_test><include>context/fix_errors_from_unit_tests/4/detect_change.py</include></example_code_under_test>
43
-
44
- % Here is the prompt that generated the example_code_under_test: <example_prompt><include>context/fix_errors_from_unit_tests/4/detect_change_python.prompt</include></example_prompt>
45
- </example_4>
46
-
47
- <example_5>
48
- % Here is an example_unit_test for the example_code_under_test: <example_unit_test><include>context/fix_errors_from_unit_tests/4/test_detect_change_1_0_1.py</include></example_unit_test>
49
-
50
- % Here is an example_code_under_test that didn't fully pass the example_unit_test: <example_code_under_test><include>context/fix_errors_from_unit_tests/4/detect_change_1_0_1.py</include></example_code_under_test>
51
-
52
- % Here is an example error/fix log showing how the issues were resolved: <example_error_fix_log><include>context/fix_errors_from_unit_tests/4/error.log</include></example_error_fix_log>
53
- </example_5>
54
- </examples>
55
- </pdd>
56
13
 
57
14
  <instructions>
58
15
  % Follow these steps to solve these errors:
@@ -13,4 +13,7 @@ Here is the coverage report: ```{coverage_report}```
13
13
  - The unit test should be in {language}. If Python, use pytest.
14
14
  - Use individual test functions for each case to make it easier to identify which specific cases pass or fail.
15
15
  - Use the description of the functionality in the prompt to generate tests with useful tests with good code coverage.
16
- <include>./context/test.prompt</include>
16
+ - Know that the generated test will be in a different directory (`tests`) than the module (in directory `pdd`) it is calling and will need an absolute reference. The module file name will be same as the function name.
17
+ - Created files should be in the `output` directory.
18
+ - Data files (language_format.csv and llm_model.csv) already exist in the PDD_PATH/`data` directory. Do not write over them. It already contains data for popular languages and LLM models and can be used for tests.
19
+ - The PDD_PATH environment variable is already set.