Spaces:
Runtime error
Runtime error
ICAS03 commited on
Commit ·
eb04412
1
Parent(s): 3cbf3b3
- Fix code_modifier
Browse files- app.py +41 -57
- code_modifier.py +399 -118
- code_updater.py +9 -9
- step_handlers.py → event_handlers.py +77 -77
- page_prompts_config.py +8 -9
app.py
CHANGED
|
@@ -10,7 +10,7 @@ from typing import Dict, Any, Tuple
|
|
| 10 |
from Project import update_system_prompts
|
| 11 |
import pandas as pd
|
| 12 |
from io import StringIO
|
| 13 |
-
from
|
| 14 |
|
| 15 |
def create_ui_component(config: UIConfig, prompt: str = None) -> Any:
|
| 16 |
if config.component_type == UIComponentType.TEXTBOX:
|
|
@@ -49,66 +49,50 @@ def create_ui_component(config: UIConfig, prompt: str = None) -> Any:
|
|
| 49 |
def create_section_components(prompt_config: PromptConfig) -> Dict[str, Any]:
|
| 50 |
components = {}
|
| 51 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
with gr.Row():
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
if editor_key:
|
| 56 |
-
lines = prompt_config.prompt.split('\n')
|
| 57 |
-
if lines:
|
| 58 |
-
min_indent = min((len(line) - len(line.lstrip())
|
| 59 |
-
for line in lines if line.strip()),
|
| 60 |
-
default=0)
|
| 61 |
-
formatted_lines = [
|
| 62 |
-
line[min_indent:] if line.strip() else ''
|
| 63 |
-
for line in lines
|
| 64 |
-
]
|
| 65 |
-
formatted_prompt = '\n'.join(formatted_lines)
|
| 66 |
-
formatted_prompt = f'"""\n{formatted_prompt}\n"""'
|
| 67 |
-
else:
|
| 68 |
-
formatted_prompt = '""""""'
|
| 69 |
-
|
| 70 |
-
components[editor_key] = create_ui_component(
|
| 71 |
-
prompt_config.ui[editor_key],
|
| 72 |
-
formatted_prompt
|
| 73 |
-
)
|
| 74 |
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
display_mode_key = f"display_mode_{text_key.replace('_text', '')}"
|
| 81 |
-
components[display_mode_key] = create_ui_component(
|
| 82 |
-
UIConfig(
|
| 83 |
-
component_type=UIComponentType.RADIO,
|
| 84 |
-
label="Select Mode",
|
| 85 |
-
elem_classes=["radio-group-horizontal"]
|
| 86 |
-
)
|
| 87 |
)
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
)
|
| 93 |
-
components[markdown_key] = create_ui_component(
|
| 94 |
-
prompt_config.ui[markdown_key]
|
| 95 |
-
)
|
| 96 |
-
|
| 97 |
-
components[display_mode_key].change(
|
| 98 |
-
fn=update_display_mode,
|
| 99 |
-
inputs=[
|
| 100 |
-
components[display_mode_key],
|
| 101 |
-
components[text_key]
|
| 102 |
-
],
|
| 103 |
-
outputs=[
|
| 104 |
-
components[text_key],
|
| 105 |
-
components[markdown_key]
|
| 106 |
-
]
|
| 107 |
)
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
|
| 113 |
return components
|
| 114 |
|
|
|
|
| 10 |
from Project import update_system_prompts
|
| 11 |
import pandas as pd
|
| 12 |
from io import StringIO
|
| 13 |
+
from event_handlers import setup_all_handlers
|
| 14 |
|
| 15 |
def create_ui_component(config: UIConfig, prompt: str = None) -> Any:
|
| 16 |
if config.component_type == UIComponentType.TEXTBOX:
|
|
|
|
| 49 |
def create_section_components(prompt_config: PromptConfig) -> Dict[str, Any]:
|
| 50 |
components = {}
|
| 51 |
|
| 52 |
+
editor_key = next((k for k in prompt_config.ui.keys() if k.endswith('_prompt_editor')), None)
|
| 53 |
+
if editor_key:
|
| 54 |
+
# Format the prompt
|
| 55 |
+
lines = prompt_config.prompt.split('\n')
|
| 56 |
+
if lines:
|
| 57 |
+
min_indent = min((len(line) - len(line.lstrip())
|
| 58 |
+
for line in lines if line.strip()),
|
| 59 |
+
default=0)
|
| 60 |
+
formatted_lines = [
|
| 61 |
+
line[min_indent:] if line.strip() else ''
|
| 62 |
+
for line in lines
|
| 63 |
+
]
|
| 64 |
+
formatted_prompt = '\n'.join(formatted_lines)
|
| 65 |
+
formatted_prompt = f'"""\n{formatted_prompt}\n"""'
|
| 66 |
+
else:
|
| 67 |
+
formatted_prompt = '""""""'
|
| 68 |
+
|
| 69 |
+
# Create prompt editor in dropdown
|
| 70 |
+
with gr.Accordion(prompt_config.ui[editor_key].label, open=False):
|
| 71 |
+
components[editor_key] = create_ui_component(
|
| 72 |
+
prompt_config.ui[editor_key],
|
| 73 |
+
formatted_prompt
|
| 74 |
+
)
|
| 75 |
+
|
| 76 |
+
# Create output components in two columns
|
| 77 |
with gr.Row():
|
| 78 |
+
text_key = next((k for k in prompt_config.ui.keys() if k.endswith('_text')), None)
|
| 79 |
+
markdown_key = next((k for k in prompt_config.ui.keys() if k.endswith('_markdown')), None)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 80 |
|
| 81 |
+
if text_key and markdown_key:
|
| 82 |
+
# Left column for textbox
|
| 83 |
+
with gr.Column(scale=1):
|
| 84 |
+
components[text_key] = create_ui_component(
|
| 85 |
+
prompt_config.ui[text_key]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 86 |
)
|
| 87 |
+
# Right column for markdown
|
| 88 |
+
with gr.Column(scale=1):
|
| 89 |
+
components[markdown_key] = create_ui_component(
|
| 90 |
+
prompt_config.ui[markdown_key]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 91 |
)
|
| 92 |
+
else:
|
| 93 |
+
for key, config in prompt_config.ui.items():
|
| 94 |
+
if not key.endswith('_prompt_editor'):
|
| 95 |
+
components[key] = create_ui_component(config)
|
| 96 |
|
| 97 |
return components
|
| 98 |
|
code_modifier.py
CHANGED
|
@@ -101,28 +101,32 @@ def analyze_config_structure(config_content: str, project_content: str, current_
|
|
| 101 |
3. DO NOT suggest changes based on previous versions
|
| 102 |
4. ONLY compare against the current files provided
|
| 103 |
5. IGNORE any remembered patterns or previous suggestions
|
|
|
|
|
|
|
| 104 |
|
| 105 |
Your task is to analyze and focus on the configuration structure and validate the relationships between components.
|
| 106 |
-
|
| 107 |
|
| 108 |
1. OUTPUT AND INPUT VALIDATION RULES:
|
| 109 |
- Not all outputs/inputs require UI component mappings
|
| 110 |
- Special outputs like 'quotation_cost' can be internal values used as inputs and outputs in other steps
|
| 111 |
-
- Internal values can be passed between steps without UI components , so just
|
| 112 |
- Examples of internal values:
|
| 113 |
-
* quotation_cost
|
| 114 |
-
* project_detail
|
| 115 |
-
* gathered_project_input
|
| 116 |
-
* reviewed_project_input
|
|
|
|
|
|
|
|
|
|
| 117 |
|
| 118 |
2. OUTPUT TO UI COMPONENT MAPPING RULES:
|
| 119 |
- Most outputs in config map to specific UI components
|
| 120 |
- Standard Output Pattern:
|
| 121 |
-
* Base output name
|
| 122 |
- base_name_text: For textbox display
|
| 123 |
- base_name_markdown: For markdown display
|
| 124 |
- Special Case - Mandays Pattern:
|
| 125 |
-
* Mandays outputs
|
| 126 |
- base_name_dataframe: For dataframe display
|
| 127 |
|
| 128 |
3. INPUT TO UI COMPONENT MAPPING RULES:
|
|
@@ -131,12 +135,12 @@ def analyze_config_structure(config_content: str, project_content: str, current_
|
|
| 131 |
|
| 132 |
4. NAMING CONVENTION (Source of Truth: Config File)
|
| 133 |
MUST CHECK:
|
| 134 |
-
- Prompt names
|
| 135 |
-
- Component names
|
| 136 |
- Input/Output references
|
| 137 |
|
| 138 |
WHERE TO CHECK:
|
| 139 |
-
-
|
| 140 |
- Project.py: Method names, mappings
|
| 141 |
- all_components dictionary: Component keys
|
| 142 |
|
|
@@ -146,6 +150,33 @@ def analyze_config_structure(config_content: str, project_content: str, current_
|
|
| 146 |
* Outputs to both _text and _markdown (or _dataframe for mandays)
|
| 147 |
- all_components dictionary keys must exactly match config naming
|
| 148 |
- Function parameters should align with Project.py signatures
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 149 |
|
| 150 |
Context Files:
|
| 151 |
1. Current Config:
|
|
@@ -154,9 +185,31 @@ def analyze_config_structure(config_content: str, project_content: str, current_
|
|
| 154 |
2. Project.py:
|
| 155 |
{project_content}
|
| 156 |
|
| 157 |
-
3.
|
| 158 |
{current_handlers}
|
| 159 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 160 |
Return a JSON analysis with this EXACT structure as shown as an example below:
|
| 161 |
{{
|
| 162 |
"component_mappings": {{
|
|
@@ -177,12 +230,25 @@ def analyze_config_structure(config_content: str, project_content: str, current_
|
|
| 177 |
"is_valid": false,
|
| 178 |
"issues": ["detailed_issue_description"]
|
| 179 |
}}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 180 |
]
|
| 181 |
}},
|
| 182 |
-
|
| 183 |
-
"
|
| 184 |
{{
|
| 185 |
-
"
|
|
|
|
| 186 |
"input_mappings": {{
|
| 187 |
"is_valid": false,
|
| 188 |
"issues": ["detailed_issue_description"]
|
|
@@ -190,6 +256,88 @@ def analyze_config_structure(config_content: str, project_content: str, current_
|
|
| 190 |
"output_mappings": {{
|
| 191 |
"is_valid": false,
|
| 192 |
"issues": ["detailed_issue_description"]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 193 |
}}
|
| 194 |
}}
|
| 195 |
]
|
|
@@ -202,10 +350,10 @@ def analyze_config_structure(config_content: str, project_content: str, current_
|
|
| 202 |
"reason": "detailed_explanation"
|
| 203 |
}}
|
| 204 |
],
|
| 205 |
-
"
|
| 206 |
{{
|
| 207 |
-
"
|
| 208 |
-
"type": "
|
| 209 |
"current": "current_code",
|
| 210 |
"required": "required_code",
|
| 211 |
"reason": "detailed_explanation"
|
|
@@ -231,7 +379,7 @@ def analyze_config_structure(config_content: str, project_content: str, current_
|
|
| 231 |
print("Raw response:", result)
|
| 232 |
return {
|
| 233 |
"component_mappings": {"outputs": [], "inputs": []},
|
| 234 |
-
"
|
| 235 |
"required_updates": {}
|
| 236 |
}
|
| 237 |
|
|
@@ -244,38 +392,86 @@ def generate_code_updates(analysis_result: Dict) -> Dict:
|
|
| 244 |
Analysis Result:
|
| 245 |
{json.dumps(analysis_result, indent=2)}
|
| 246 |
|
| 247 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 248 |
{{
|
| 249 |
"Project.py": {{
|
| 250 |
-
"updates": []
|
| 251 |
-
}},
|
| 252 |
-
"step_handlers.py": {{
|
| 253 |
"updates": [
|
| 254 |
{{
|
| 255 |
-
"type": "
|
| 256 |
-
"location": "
|
| 257 |
-
"explanation": "
|
| 258 |
-
"old_code": "
|
| 259 |
-
"new_code": "
|
| 260 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 261 |
{{
|
| 262 |
-
"type": "
|
| 263 |
-
"location": "
|
| 264 |
-
"explanation": "
|
| 265 |
-
"old_code": "
|
| 266 |
-
"new_code": "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 267 |
}}
|
| 268 |
]
|
| 269 |
}}
|
| 270 |
}}
|
| 271 |
|
| 272 |
Requirements:
|
| 273 |
-
1.
|
| 274 |
-
2.
|
| 275 |
-
3.
|
| 276 |
-
4.
|
| 277 |
-
|
| 278 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 279 |
|
| 280 |
IMPORTANT: Return ONLY the JSON object, without any markdown formatting or explanation.
|
| 281 |
"""
|
|
@@ -285,19 +481,41 @@ def generate_code_updates(analysis_result: Dict) -> Dict:
|
|
| 285 |
cleaned_result = clean_ai_response(result)
|
| 286 |
parsed_result = json.loads(cleaned_result)
|
| 287 |
|
| 288 |
-
# Ensure correct structure
|
| 289 |
-
|
| 290 |
-
|
| 291 |
-
|
| 292 |
-
parsed_result["step_handlers.py"] = {"updates": []}
|
| 293 |
|
| 294 |
-
|
| 295 |
-
|
| 296 |
-
|
| 297 |
-
|
| 298 |
-
|
|
|
|
| 299 |
if "type" not in update:
|
| 300 |
-
update["type"] = "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 301 |
|
| 302 |
return parsed_result
|
| 303 |
|
|
@@ -306,75 +524,132 @@ def generate_code_updates(analysis_result: Dict) -> Dict:
|
|
| 306 |
print("Raw response:", result)
|
| 307 |
return {
|
| 308 |
"Project.py": {"updates": []},
|
| 309 |
-
"
|
| 310 |
}
|
| 311 |
|
| 312 |
-
def
|
| 313 |
-
"""
|
| 314 |
try:
|
| 315 |
-
with open(
|
| 316 |
-
|
| 317 |
|
| 318 |
-
|
| 319 |
-
|
| 320 |
-
|
| 321 |
-
|
| 322 |
-
if class_end == -1:
|
| 323 |
-
return False
|
| 324 |
-
content = content[:class_end] + '\n' + update['new_code'] + content[class_end:]
|
| 325 |
-
|
| 326 |
-
elif update['type'] == 'mapping':
|
| 327 |
-
# Update INPUT_MAPPINGS
|
| 328 |
-
input_mappings_start = content.find('INPUT_MAPPINGS = {')
|
| 329 |
-
if input_mappings_start != -1:
|
| 330 |
-
input_mappings_end = content.find('}', input_mappings_start)
|
| 331 |
-
if input_mappings_end != -1:
|
| 332 |
-
# Replace old mapping with new one
|
| 333 |
-
content = content[:input_mappings_start] + update['new_code'] + content[input_mappings_end + 1:]
|
| 334 |
-
|
| 335 |
-
with open('Project.py', 'w') as f:
|
| 336 |
-
f.write(content)
|
| 337 |
|
| 338 |
-
|
|
|
|
| 339 |
|
| 340 |
-
|
| 341 |
-
|
| 342 |
-
|
| 343 |
-
|
| 344 |
-
|
| 345 |
-
|
| 346 |
-
|
| 347 |
-
|
| 348 |
-
|
| 349 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 350 |
for update in updates:
|
| 351 |
-
|
| 352 |
-
|
|
|
|
|
|
|
|
|
|
| 353 |
continue
|
| 354 |
|
| 355 |
-
|
| 356 |
-
|
| 357 |
-
|
| 358 |
-
|
| 359 |
-
|
| 360 |
-
|
| 361 |
-
|
| 362 |
-
|
| 363 |
-
|
| 364 |
-
|
| 365 |
-
|
| 366 |
-
|
| 367 |
-
|
| 368 |
-
|
| 369 |
-
|
| 370 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 371 |
|
| 372 |
return True
|
| 373 |
|
| 374 |
except Exception as e:
|
| 375 |
-
print(f"Error applying
|
| 376 |
return False
|
| 377 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 378 |
def extract_config_without_prompts() -> str:
|
| 379 |
"""Extract config file content without prompts"""
|
| 380 |
try:
|
|
@@ -428,7 +703,7 @@ def main():
|
|
| 428 |
|
| 429 |
with open('Project.py', 'r') as f:
|
| 430 |
project_content = f.read()
|
| 431 |
-
with open('
|
| 432 |
current_handlers = f.read()
|
| 433 |
|
| 434 |
# First AI: Analyze current structure
|
|
@@ -443,19 +718,25 @@ def main():
|
|
| 443 |
print("\nConfiguration Analysis:")
|
| 444 |
print("1. Output Mappings:", len(analysis_result['component_mappings']['outputs']))
|
| 445 |
print("2. Input Mappings:", len(analysis_result['component_mappings']['inputs']))
|
| 446 |
-
print("3.
|
| 447 |
|
| 448 |
if analysis_result.get('required_updates'):
|
| 449 |
print("\nRequired Updates:")
|
| 450 |
for file, updates in analysis_result['required_updates'].items():
|
| 451 |
print(f"\n{file}:")
|
| 452 |
for update in updates:
|
| 453 |
-
|
|
|
|
|
|
|
|
|
|
| 454 |
|
| 455 |
if analysis_result.get('validation_issues'):
|
| 456 |
print("\nValidation Issues:")
|
| 457 |
for issue in analysis_result['validation_issues']:
|
| 458 |
-
|
|
|
|
|
|
|
|
|
|
| 459 |
|
| 460 |
# Get user confirmation
|
| 461 |
confirm = input("\nProceed with generating code updates? (y/n): ")
|
|
@@ -472,12 +753,12 @@ def main():
|
|
| 472 |
for file, updates in code_updates.items():
|
| 473 |
print(f"\n{file}:")
|
| 474 |
for update in updates['updates']:
|
| 475 |
-
print(f"- Location: {update
|
| 476 |
-
print(f" Explanation: {update
|
| 477 |
print(" Old code:")
|
| 478 |
-
print(f"```\n{update
|
| 479 |
print(" New code:")
|
| 480 |
-
print(f"```\n{update
|
| 481 |
|
| 482 |
# Final confirmation
|
| 483 |
confirm = input("\nApply these code updates? (y/n): ")
|
|
@@ -488,9 +769,9 @@ def main():
|
|
| 488 |
# Apply updates
|
| 489 |
success = True
|
| 490 |
if 'Project.py' in code_updates:
|
| 491 |
-
success &=
|
| 492 |
-
if '
|
| 493 |
-
success &=
|
| 494 |
|
| 495 |
if success:
|
| 496 |
print("Successfully updated all files")
|
|
@@ -503,4 +784,4 @@ def main():
|
|
| 503 |
print("Traceback:", traceback.format_exc())
|
| 504 |
|
| 505 |
if __name__ == "__main__":
|
| 506 |
-
main()
|
|
|
|
| 101 |
3. DO NOT suggest changes based on previous versions
|
| 102 |
4. ONLY compare against the current files provided
|
| 103 |
5. IGNORE any remembered patterns or previous suggestions
|
| 104 |
+
6. The config file (page_prompts_config.py) is the source of truth for naming conventions
|
| 105 |
+
7. Component names MUST match their corresponding config names EXACTLY
|
| 106 |
|
| 107 |
Your task is to analyze and focus on the configuration structure and validate the relationships between components.
|
|
|
|
| 108 |
|
| 109 |
1. OUTPUT AND INPUT VALIDATION RULES:
|
| 110 |
- Not all outputs/inputs require UI component mappings
|
| 111 |
- Special outputs like 'quotation_cost' can be internal values used as inputs and outputs in other steps
|
| 112 |
+
- Internal values can be passed between steps without UI components , so just DO NOT suggest any changes for them.
|
| 113 |
- Examples of internal values:
|
| 114 |
+
* quotation_cost
|
| 115 |
+
* project_detail
|
| 116 |
+
* gathered_project_input
|
| 117 |
+
* reviewed_project_input
|
| 118 |
+
* client_follow_up_questions
|
| 119 |
+
* follow_up_questions
|
| 120 |
+
* client_followup_question_sample_answers
|
| 121 |
|
| 122 |
2. OUTPUT TO UI COMPONENT MAPPING RULES:
|
| 123 |
- Most outputs in config map to specific UI components
|
| 124 |
- Standard Output Pattern:
|
| 125 |
+
* Base output name MUST map to TWO components:
|
| 126 |
- base_name_text: For textbox display
|
| 127 |
- base_name_markdown: For markdown display
|
| 128 |
- Special Case - Mandays Pattern:
|
| 129 |
+
* Mandays outputs MUST map to ONE component:
|
| 130 |
- base_name_dataframe: For dataframe display
|
| 131 |
|
| 132 |
3. INPUT TO UI COMPONENT MAPPING RULES:
|
|
|
|
| 135 |
|
| 136 |
4. NAMING CONVENTION (Source of Truth: Config File)
|
| 137 |
MUST CHECK:
|
| 138 |
+
- Prompt names
|
| 139 |
+
- Component names
|
| 140 |
- Input/Output references
|
| 141 |
|
| 142 |
WHERE TO CHECK:
|
| 143 |
+
- event_handlers.py: Function names, component references
|
| 144 |
- Project.py: Method names, mappings
|
| 145 |
- all_components dictionary: Component keys
|
| 146 |
|
|
|
|
| 150 |
* Outputs to both _text and _markdown (or _dataframe for mandays)
|
| 151 |
- all_components dictionary keys must exactly match config naming
|
| 152 |
- Function parameters should align with Project.py signatures
|
| 153 |
+
|
| 154 |
+
6. PROMPTCONFIG CHANGES:
|
| 155 |
+
A. REMOVED PROMPTCONFIGS:
|
| 156 |
+
- When a PromptConfig is removed from config:
|
| 157 |
+
* ALL references to that prompt must be removed from Project.py
|
| 158 |
+
* ALL UI components associated with that prompt must be removed from event_handlers.py
|
| 159 |
+
* ALL method signatures and return values must be updated accordingly
|
| 160 |
+
* ALL dependent code that referenced the removed components must be updated
|
| 161 |
+
- Check for:
|
| 162 |
+
* Orphaned UI components
|
| 163 |
+
* Unused function parameters
|
| 164 |
+
* Outdated return values
|
| 165 |
+
* Broken event handler mappings
|
| 166 |
+
|
| 167 |
+
B. NEW PROMPTCONFIGS:
|
| 168 |
+
- When a new PromptConfig is added to config:
|
| 169 |
+
* Add corresponding execute_prompt() call in Project.py
|
| 170 |
+
* Add UI component references in event_handlers.py
|
| 171 |
+
* Add new step button handler if step is specified
|
| 172 |
+
* Add necessary input/output mappings
|
| 173 |
+
- Check for:
|
| 174 |
+
* Required method signatures
|
| 175 |
+
* Input/output component creation
|
| 176 |
+
* Event handler connections
|
| 177 |
+
* Step button integration
|
| 178 |
+
* State management updates
|
| 179 |
+
|
| 180 |
|
| 181 |
Context Files:
|
| 182 |
1. Current Config:
|
|
|
|
| 185 |
2. Project.py:
|
| 186 |
{project_content}
|
| 187 |
|
| 188 |
+
3. event_handlers.py:
|
| 189 |
{current_handlers}
|
| 190 |
+
|
| 191 |
+
CRITICAL ANALYSIS RULES:
|
| 192 |
+
1. RENAMED PROMPTS:
|
| 193 |
+
- First check if a component missing from config exists with a similar name
|
| 194 |
+
- Compare component names using similarity matching (e.g., generate_Tech_SOW vs generate_Technical_SOW)
|
| 195 |
+
- If a similar name exists in config, treat it as a rename operation
|
| 196 |
+
- Add it to the 'renamed_prompts' section with old and new names
|
| 197 |
+
- Do NOT mark it as a removed prompt
|
| 198 |
+
|
| 199 |
+
2. REMOVED PROMPTS:
|
| 200 |
+
- Only mark a prompt as removed if NO similar name exists in config
|
| 201 |
+
- If unsure, prefer rename over removal
|
| 202 |
+
- For confirmed removals:
|
| 203 |
+
* List ALL code locations that need cleanup
|
| 204 |
+
* Include exact file paths and line numbers if possible
|
| 205 |
+
* Specify what code needs to be removed
|
| 206 |
+
|
| 207 |
+
3. NAMING UPDATES:
|
| 208 |
+
- When a component name changes in config:
|
| 209 |
+
* Update ALL references to match exactly
|
| 210 |
+
* Maintain consistent casing and formatting
|
| 211 |
+
* Update both component names and method references
|
| 212 |
+
|
| 213 |
Return a JSON analysis with this EXACT structure as shown as an example below:
|
| 214 |
{{
|
| 215 |
"component_mappings": {{
|
|
|
|
| 230 |
"is_valid": false,
|
| 231 |
"issues": ["detailed_issue_description"]
|
| 232 |
}}
|
| 233 |
+
],
|
| 234 |
+
"buttons": [
|
| 235 |
+
{{
|
| 236 |
+
"button_id": "button_name",
|
| 237 |
+
"type": "step|action|recalculate|upload",
|
| 238 |
+
"handler": "handler_function_name",
|
| 239 |
+
"inputs": ["input1", "input2"],
|
| 240 |
+
"outputs": ["output1", "output2"],
|
| 241 |
+
"state_updates": ["state1", "state2"],
|
| 242 |
+
"is_valid": false,
|
| 243 |
+
"issues": ["detailed_issue_description"]
|
| 244 |
+
}}
|
| 245 |
]
|
| 246 |
}},
|
| 247 |
+
"event_handlers": {{
|
| 248 |
+
"handlers": [
|
| 249 |
{{
|
| 250 |
+
"button_id": "button_name",
|
| 251 |
+
"type": "step|recalculate|upload",
|
| 252 |
"input_mappings": {{
|
| 253 |
"is_valid": false,
|
| 254 |
"issues": ["detailed_issue_description"]
|
|
|
|
| 256 |
"output_mappings": {{
|
| 257 |
"is_valid": false,
|
| 258 |
"issues": ["detailed_issue_description"]
|
| 259 |
+
}},
|
| 260 |
+
"state_mappings": {{
|
| 261 |
+
"is_valid": false,
|
| 262 |
+
"issues": ["detailed_issue_description"]
|
| 263 |
+
}}
|
| 264 |
+
}}
|
| 265 |
+
]
|
| 266 |
+
}},
|
| 267 |
+
"prompt_changes": {{
|
| 268 |
+
"removed_prompts": [
|
| 269 |
+
{{
|
| 270 |
+
"prompt_name": "name_of_removed_prompt",
|
| 271 |
+
"affected_components": ["component1", "component2"],
|
| 272 |
+
"affected_handlers": ["handler1", "handler2"],
|
| 273 |
+
"cleanup_required": {{
|
| 274 |
+
"Project.py": [
|
| 275 |
+
{{
|
| 276 |
+
"type": "method_removal|signature_update",
|
| 277 |
+
"location": "exact_location",
|
| 278 |
+
"code_to_remove": "code_snippet",
|
| 279 |
+
"reason": "detailed_explanation"
|
| 280 |
+
}}
|
| 281 |
+
],
|
| 282 |
+
"event_handlers.py": [
|
| 283 |
+
{{
|
| 284 |
+
"type": "component_removal|handler_update",
|
| 285 |
+
"location": "exact_location",
|
| 286 |
+
"code_to_remove": "code_snippet",
|
| 287 |
+
"reason": "detailed_explanation"
|
| 288 |
+
}}
|
| 289 |
+
]
|
| 290 |
+
}}
|
| 291 |
+
}}
|
| 292 |
+
],
|
| 293 |
+
"renamed_prompts": [
|
| 294 |
+
{{
|
| 295 |
+
"old_name": "old_prompt_name",
|
| 296 |
+
"new_name": "new_prompt_name",
|
| 297 |
+
"affected_files": {{
|
| 298 |
+
"Project.py": [
|
| 299 |
+
{{
|
| 300 |
+
"type": "method_rename",
|
| 301 |
+
"location": "method references",
|
| 302 |
+
"old_code": "old_code_snippet",
|
| 303 |
+
"new_code": "new_code_snippet",
|
| 304 |
+
"reason": "Prompt name updated in config"
|
| 305 |
+
}}
|
| 306 |
+
],
|
| 307 |
+
"event_handlers.py": [
|
| 308 |
+
{{
|
| 309 |
+
"type": "component_rename",
|
| 310 |
+
"location": "component references",
|
| 311 |
+
"old_code": "old_code_snippet",
|
| 312 |
+
"new_code": "new_code_snippet",
|
| 313 |
+
"reason": "Prompt name updated in config"
|
| 314 |
+
}}
|
| 315 |
+
]
|
| 316 |
+
}}
|
| 317 |
+
}}
|
| 318 |
+
]
|
| 319 |
+
"new_prompts": [
|
| 320 |
+
{{
|
| 321 |
+
"prompt_name": "name_of_new_prompt",
|
| 322 |
+
"required_components": ["component1", "component2"],
|
| 323 |
+
"required_handlers": ["handler1", "handler2"],
|
| 324 |
+
"additions_required": {{
|
| 325 |
+
"Project.py": [
|
| 326 |
+
{{
|
| 327 |
+
"type": "method_addition|signature_update",
|
| 328 |
+
"location": "exact_location",
|
| 329 |
+
"code_to_add": "code_snippet",
|
| 330 |
+
"reason": "detailed_explanation"
|
| 331 |
+
}}
|
| 332 |
+
],
|
| 333 |
+
"event_handlers.py": [
|
| 334 |
+
{{
|
| 335 |
+
"type": "component_addition|handler_creation",
|
| 336 |
+
"location": "exact_location",
|
| 337 |
+
"code_to_add": "code_snippet",
|
| 338 |
+
"reason": "detailed_explanation"
|
| 339 |
+
}}
|
| 340 |
+
]
|
| 341 |
}}
|
| 342 |
}}
|
| 343 |
]
|
|
|
|
| 350 |
"reason": "detailed_explanation"
|
| 351 |
}}
|
| 352 |
],
|
| 353 |
+
"event_handlers.py": [
|
| 354 |
{{
|
| 355 |
+
"button_id": "button_name",
|
| 356 |
+
"type": "step|recalculate|upload",
|
| 357 |
"current": "current_code",
|
| 358 |
"required": "required_code",
|
| 359 |
"reason": "detailed_explanation"
|
|
|
|
| 379 |
print("Raw response:", result)
|
| 380 |
return {
|
| 381 |
"component_mappings": {"outputs": [], "inputs": []},
|
| 382 |
+
"event_handlers": {"steps": []},
|
| 383 |
"required_updates": {}
|
| 384 |
}
|
| 385 |
|
|
|
|
| 392 |
Analysis Result:
|
| 393 |
{json.dumps(analysis_result, indent=2)}
|
| 394 |
|
| 395 |
+
CRITICAL RULES:
|
| 396 |
+
1. REMOVED PROMPTS:
|
| 397 |
+
When a prompt is removed from config:
|
| 398 |
+
- REMOVE all related component references
|
| 399 |
+
- REMOVE all related handler code
|
| 400 |
+
- DO NOT suggest adding new components
|
| 401 |
+
- DO NOT suggest new mappings
|
| 402 |
+
|
| 403 |
+
2. NEW PROMPTS:
|
| 404 |
+
When a new prompt is added to config:
|
| 405 |
+
- ADD corresponding execute_prompt() method in Project.py
|
| 406 |
+
- ADD UI component references in event_handlers.py
|
| 407 |
+
- ADD new step button handler if step is specified
|
| 408 |
+
- ADD necessary input/output mappings
|
| 409 |
+
- FOLLOW exact naming from config
|
| 410 |
+
- ENSURE all required components are created
|
| 411 |
+
|
| 412 |
+
3. Processing Order:
|
| 413 |
+
a) Process removals FIRST (prompt_changes.removed_prompts)
|
| 414 |
+
b) Then process additions (prompt_changes.new_prompts)
|
| 415 |
+
c) Finally process other updates
|
| 416 |
+
|
| 417 |
+
Generate a JSON response with this EXACT structure:
|
| 418 |
{{
|
| 419 |
"Project.py": {{
|
|
|
|
|
|
|
|
|
|
| 420 |
"updates": [
|
| 421 |
{{
|
| 422 |
+
"type": "removal|addition|update", # Must specify type
|
| 423 |
+
"location": "exact_location",
|
| 424 |
+
"explanation": "Removing/Adding/Updating for prompt 'prompt_name'",
|
| 425 |
+
"old_code": "existing code to remove or update",
|
| 426 |
+
"new_code": "new code to add or update with",
|
| 427 |
+
"template": {{ # Only for additions
|
| 428 |
+
"method_signature": "def method_name(self, ...)",
|
| 429 |
+
"docstring": "\"\"\"Method documentation\"\"\"",
|
| 430 |
+
"implementation": "method implementation",
|
| 431 |
+
"return_statement": "return statement"
|
| 432 |
+
}}
|
| 433 |
+
}}
|
| 434 |
+
]
|
| 435 |
+
}},
|
| 436 |
+
"event_handlers.py": {{
|
| 437 |
+
"updates": [
|
| 438 |
{{
|
| 439 |
+
"type": "removal|addition|update",
|
| 440 |
+
"location": "event_handlers.py - Component References",
|
| 441 |
+
"explanation": "Adding/Removing components for prompt 'prompt_name'",
|
| 442 |
+
"old_code": "code to remove or update",
|
| 443 |
+
"new_code": "new code or empty string for removals",
|
| 444 |
+
"components": [ # Only for additions
|
| 445 |
+
{{
|
| 446 |
+
"name": "component_name",
|
| 447 |
+
"type": "text|markdown|dataframe",
|
| 448 |
+
"initial_value": "initial value"
|
| 449 |
+
}}
|
| 450 |
+
],
|
| 451 |
+
"handler": {{ # Only for additions requiring handlers
|
| 452 |
+
"name": "handler_name",
|
| 453 |
+
"inputs": ["input1", "input2"],
|
| 454 |
+
"outputs": ["output1", "output2"],
|
| 455 |
+
"implementation": "handler implementation"
|
| 456 |
+
}}
|
| 457 |
}}
|
| 458 |
]
|
| 459 |
}}
|
| 460 |
}}
|
| 461 |
|
| 462 |
Requirements:
|
| 463 |
+
1. Process changes in correct order (removals -> additions -> updates)
|
| 464 |
+
2. Each update MUST specify correct type (removal|addition|update)
|
| 465 |
+
3. For removals, new_code should be empty string
|
| 466 |
+
4. For additions:
|
| 467 |
+
- Include complete method templates
|
| 468 |
+
- Include all required components
|
| 469 |
+
- Include handler implementations if needed
|
| 470 |
+
- Follow exact naming from config
|
| 471 |
+
5. Maintain exact function signatures
|
| 472 |
+
6. Preserve existing code structure
|
| 473 |
+
7. Include clear comments explaining changes
|
| 474 |
+
8. Each file must have an 'updates' array, even if empty
|
| 475 |
|
| 476 |
IMPORTANT: Return ONLY the JSON object, without any markdown formatting or explanation.
|
| 477 |
"""
|
|
|
|
| 481 |
cleaned_result = clean_ai_response(result)
|
| 482 |
parsed_result = json.loads(cleaned_result)
|
| 483 |
|
| 484 |
+
# Ensure correct structure and validate updates
|
| 485 |
+
for file_name in ["Project.py", "event_handlers.py"]:
|
| 486 |
+
if file_name not in parsed_result:
|
| 487 |
+
parsed_result[file_name] = {"updates": []}
|
|
|
|
| 488 |
|
| 489 |
+
# Ensure updates array exists
|
| 490 |
+
if "updates" not in parsed_result[file_name]:
|
| 491 |
+
parsed_result[file_name]["updates"] = []
|
| 492 |
+
|
| 493 |
+
# Validate each update
|
| 494 |
+
for update in parsed_result[file_name]["updates"]:
|
| 495 |
if "type" not in update:
|
| 496 |
+
update["type"] = "update" # Default type if missing
|
| 497 |
+
if update["type"] == "removal" and update.get("new_code"):
|
| 498 |
+
update["new_code"] = "" # Ensure removals have empty new_code
|
| 499 |
+
if update["type"] == "addition":
|
| 500 |
+
# Ensure template exists for Project.py additions
|
| 501 |
+
if file_name == "Project.py" and "template" not in update:
|
| 502 |
+
update["template"] = {
|
| 503 |
+
"method_signature": "",
|
| 504 |
+
"docstring": "",
|
| 505 |
+
"implementation": "",
|
| 506 |
+
"return_statement": ""
|
| 507 |
+
}
|
| 508 |
+
# Ensure components and handler exist for event_handlers.py additions
|
| 509 |
+
if file_name == "event_handlers.py":
|
| 510 |
+
if "components" not in update:
|
| 511 |
+
update["components"] = []
|
| 512 |
+
if "handler" not in update:
|
| 513 |
+
update["handler"] = {
|
| 514 |
+
"name": "",
|
| 515 |
+
"inputs": [],
|
| 516 |
+
"outputs": [],
|
| 517 |
+
"implementation": ""
|
| 518 |
+
}
|
| 519 |
|
| 520 |
return parsed_result
|
| 521 |
|
|
|
|
| 524 |
print("Raw response:", result)
|
| 525 |
return {
|
| 526 |
"Project.py": {"updates": []},
|
| 527 |
+
"event_handlers.py": {"updates": []}
|
| 528 |
}
|
| 529 |
|
| 530 |
+
def apply_updates_with_ai(file_path: str, updates: List[Dict]) -> bool:
|
| 531 |
+
"""Third AI: Intelligently applies code updates while preserving structure"""
|
| 532 |
try:
|
| 533 |
+
with open(file_path, 'r') as f:
|
| 534 |
+
current_code = f.read()
|
| 535 |
|
| 536 |
+
# Store original empty lines and their positions
|
| 537 |
+
original_lines = current_code.splitlines(keepends=True)
|
| 538 |
+
empty_line_indices = [i for i, line in enumerate(original_lines) if not line.strip()]
|
| 539 |
+
trailing_spaces = [len(line) - len(line.rstrip()) for line in original_lines]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 540 |
|
| 541 |
+
update_prompt = f"""
|
| 542 |
+
You are an expert code updater. Your task is to apply updates to the code while perfectly preserving its structure and formatting.
|
| 543 |
|
| 544 |
+
CRITICAL RULES:
|
| 545 |
+
1. DO NOT modify any line breaks or indentation
|
| 546 |
+
2. DO NOT add or remove any lines
|
| 547 |
+
3. DO NOT change any code structure or formatting
|
| 548 |
+
4. ONLY replace the exact old_code with new_code
|
| 549 |
+
5. Return the COMPLETE file with ALL original formatting preserved
|
| 550 |
+
6. Keep ALL whitespace, commas, and brackets exactly as they are
|
| 551 |
+
7. Return ONLY the code, no explanations or markdown
|
| 552 |
+
8. Preserve ALL empty lines in their exact positions
|
| 553 |
+
9. Keep ALL trailing spaces at the end of each line
|
| 554 |
+
|
| 555 |
+
Current Code:
|
| 556 |
+
{current_code}
|
| 557 |
+
|
| 558 |
+
Required Updates:
|
| 559 |
+
{json.dumps(updates, indent=2)}
|
| 560 |
+
|
| 561 |
+
IMPORTANT:
|
| 562 |
+
- Empty lines are at these positions: {empty_line_indices}
|
| 563 |
+
- Each line must maintain its exact trailing spaces
|
| 564 |
+
- Return the complete file with perfect structure preservation
|
| 565 |
+
"""
|
| 566 |
+
|
| 567 |
+
# Get AI-generated update
|
| 568 |
+
result = call_o1_mini(update_prompt)
|
| 569 |
+
updated_code = clean_code_response(result)
|
| 570 |
+
|
| 571 |
+
# Split into lines while preserving endings
|
| 572 |
+
updated_lines = updated_code.splitlines(keepends=True)
|
| 573 |
+
|
| 574 |
+
# Handle line structure preservation
|
| 575 |
+
updated_code = preserve_line_structure(original_lines, updated_lines, empty_line_indices, trailing_spaces)
|
| 576 |
+
|
| 577 |
+
# Verify updates were applied using flexible pattern matching
|
| 578 |
for update in updates:
|
| 579 |
+
old_code = update.get('old_code', '').strip()
|
| 580 |
+
new_code = update.get('new_code', '').strip()
|
| 581 |
+
|
| 582 |
+
# Skip empty updates
|
| 583 |
+
if not old_code and not new_code:
|
| 584 |
continue
|
| 585 |
|
| 586 |
+
# For renames, extract the core identifiers
|
| 587 |
+
if update.get('type') == 'rename':
|
| 588 |
+
old_identifier = extract_identifier(old_code)
|
| 589 |
+
new_identifier = extract_identifier(new_code)
|
| 590 |
+
|
| 591 |
+
if old_identifier in updated_code:
|
| 592 |
+
print(f"Error: Old identifier '{old_identifier}' still present")
|
| 593 |
+
return False
|
| 594 |
+
if new_identifier not in updated_code:
|
| 595 |
+
print(f"Error: New identifier '{new_identifier}' not found")
|
| 596 |
+
return False
|
| 597 |
+
else:
|
| 598 |
+
# For other updates, check if the change was applied
|
| 599 |
+
if old_code and old_code in updated_code:
|
| 600 |
+
print(f"Error: Old code still present")
|
| 601 |
+
return False
|
| 602 |
+
if new_code and new_code not in updated_code:
|
| 603 |
+
print(f"Error: New code not found")
|
| 604 |
+
return False
|
| 605 |
+
|
| 606 |
+
# Write the updated code
|
| 607 |
+
with open(file_path, 'w') as f:
|
| 608 |
+
f.write(updated_code)
|
| 609 |
|
| 610 |
return True
|
| 611 |
|
| 612 |
except Exception as e:
|
| 613 |
+
print(f"Error applying AI updates: {str(e)}")
|
| 614 |
return False
|
| 615 |
|
| 616 |
+
def clean_code_response(result: str) -> str:
|
| 617 |
+
"""Clean up the AI response code"""
|
| 618 |
+
if '```python' in result:
|
| 619 |
+
result = result.split('```python', 1)[1]
|
| 620 |
+
if '```' in result:
|
| 621 |
+
result = result.split('```', 1)[0]
|
| 622 |
+
return result.strip()
|
| 623 |
+
|
| 624 |
+
def preserve_line_structure(original_lines: List[str], updated_lines: List[str],
|
| 625 |
+
empty_indices: List[int], trailing_spaces: List[int]) -> str:
|
| 626 |
+
"""Preserve the original code structure"""
|
| 627 |
+
if len(original_lines) != len(updated_lines):
|
| 628 |
+
fixed_lines = []
|
| 629 |
+
for i in range(len(original_lines)):
|
| 630 |
+
if i in empty_indices:
|
| 631 |
+
fixed_lines.append('\n')
|
| 632 |
+
else:
|
| 633 |
+
line = updated_lines[i].rstrip() if i < len(updated_lines) else ''
|
| 634 |
+
line = line + ' ' * trailing_spaces[i]
|
| 635 |
+
fixed_lines.append(line + '\n')
|
| 636 |
+
return ''.join(fixed_lines)
|
| 637 |
+
return ''.join(updated_lines)
|
| 638 |
+
|
| 639 |
+
def extract_identifier(code: str) -> str:
|
| 640 |
+
"""Extract the core identifier from a code snippet"""
|
| 641 |
+
# Remove common code patterns
|
| 642 |
+
code = code.replace('self.', '')
|
| 643 |
+
code = code.replace('execute_prompt(', '')
|
| 644 |
+
code = code.replace('generated_', '')
|
| 645 |
+
code = code.replace('all_components[', '')
|
| 646 |
+
code = code.replace(']', '')
|
| 647 |
+
code = code.replace('"', '')
|
| 648 |
+
code = code.replace("'", '')
|
| 649 |
+
|
| 650 |
+
# Return the cleaned identifier
|
| 651 |
+
return code.strip()
|
| 652 |
+
|
| 653 |
def extract_config_without_prompts() -> str:
|
| 654 |
"""Extract config file content without prompts"""
|
| 655 |
try:
|
|
|
|
| 703 |
|
| 704 |
with open('Project.py', 'r') as f:
|
| 705 |
project_content = f.read()
|
| 706 |
+
with open('event_handlers.py', 'r') as f:
|
| 707 |
current_handlers = f.read()
|
| 708 |
|
| 709 |
# First AI: Analyze current structure
|
|
|
|
| 718 |
print("\nConfiguration Analysis:")
|
| 719 |
print("1. Output Mappings:", len(analysis_result['component_mappings']['outputs']))
|
| 720 |
print("2. Input Mappings:", len(analysis_result['component_mappings']['inputs']))
|
| 721 |
+
print("3. Event Handlers:", len(analysis_result['event_handlers']['handlers']))
|
| 722 |
|
| 723 |
if analysis_result.get('required_updates'):
|
| 724 |
print("\nRequired Updates:")
|
| 725 |
for file, updates in analysis_result['required_updates'].items():
|
| 726 |
print(f"\n{file}:")
|
| 727 |
for update in updates:
|
| 728 |
+
# Safely access update information with fallbacks
|
| 729 |
+
update_type = update.get('type', 'Unknown')
|
| 730 |
+
explanation = update.get('reason', update.get('explanation', 'No explanation provided'))
|
| 731 |
+
print(f"- {update_type}: {explanation}")
|
| 732 |
|
| 733 |
if analysis_result.get('validation_issues'):
|
| 734 |
print("\nValidation Issues:")
|
| 735 |
for issue in analysis_result['validation_issues']:
|
| 736 |
+
severity = issue.get('severity', 'unknown')
|
| 737 |
+
description = issue.get('description', 'No description provided')
|
| 738 |
+
issue_type = issue.get('type', 'Unknown')
|
| 739 |
+
print(f"- {issue_type} ({severity}): {description}")
|
| 740 |
|
| 741 |
# Get user confirmation
|
| 742 |
confirm = input("\nProceed with generating code updates? (y/n): ")
|
|
|
|
| 753 |
for file, updates in code_updates.items():
|
| 754 |
print(f"\n{file}:")
|
| 755 |
for update in updates['updates']:
|
| 756 |
+
print(f"- Location: {update.get('location', 'Unknown location')}")
|
| 757 |
+
print(f" Explanation: {update.get('explanation', 'No explanation provided')}")
|
| 758 |
print(" Old code:")
|
| 759 |
+
print(f"```\n{update.get('old_code', 'No old code provided')}\n```")
|
| 760 |
print(" New code:")
|
| 761 |
+
print(f"```\n{update.get('new_code', 'No new code provided')}\n```")
|
| 762 |
|
| 763 |
# Final confirmation
|
| 764 |
confirm = input("\nApply these code updates? (y/n): ")
|
|
|
|
| 769 |
# Apply updates
|
| 770 |
success = True
|
| 771 |
if 'Project.py' in code_updates:
|
| 772 |
+
success &= apply_updates_with_ai('Project.py' ,code_updates['Project.py']['updates'])
|
| 773 |
+
if 'event_handlers.py' in code_updates:
|
| 774 |
+
success &= apply_updates_with_ai('event_handlers.py' , code_updates['event_handlers.py']['updates'])
|
| 775 |
|
| 776 |
if success:
|
| 777 |
print("Successfully updated all files")
|
|
|
|
| 784 |
print("Traceback:", traceback.format_exc())
|
| 785 |
|
| 786 |
if __name__ == "__main__":
|
| 787 |
+
main()
|
code_updater.py
CHANGED
|
@@ -95,9 +95,9 @@ You are an expert software engineer performing a comprehensive analysis. You mus
|
|
| 95 |
|
| 96 |
4. Prompt Name Validation :
|
| 97 |
- Prompt names in config are the source of truth
|
| 98 |
-
- Any references to these names in Project.py and
|
| 99 |
- Check for:
|
| 100 |
-
* Function names in
|
| 101 |
* Component references in all_components dictionary
|
| 102 |
* Input/output mappings in step handlers
|
| 103 |
* Method names in Project.py
|
|
@@ -120,7 +120,7 @@ Context Files:
|
|
| 120 |
2. Project.py (SOURCE OF TRUTH FOR FUNCTION PARAMETERS):
|
| 121 |
{project_content}
|
| 122 |
|
| 123 |
-
3.
|
| 124 |
{current_handlers}
|
| 125 |
|
| 126 |
Analysis Requirements:
|
|
@@ -238,9 +238,9 @@ def analyze_prompts_and_generate_handlers() -> Dict[int, str]:
|
|
| 238 |
project_content = f.read()
|
| 239 |
print("Project.py content loaded")
|
| 240 |
|
| 241 |
-
with open('
|
| 242 |
current_handlers = f.read()
|
| 243 |
-
print("
|
| 244 |
|
| 245 |
# Do one analysis for all files
|
| 246 |
print("\nAnalyzing all files...")
|
|
@@ -309,7 +309,7 @@ def main():
|
|
| 309 |
if update.lower() == 'y':
|
| 310 |
try:
|
| 311 |
# Read current content
|
| 312 |
-
with open('
|
| 313 |
content = f.read()
|
| 314 |
|
| 315 |
# Find and replace the specific step handler
|
|
@@ -324,13 +324,13 @@ def main():
|
|
| 324 |
updated_content = content[:match.start()] + code.strip() + content[match.end():]
|
| 325 |
|
| 326 |
# Write back to file
|
| 327 |
-
with open('
|
| 328 |
f.write(updated_content)
|
| 329 |
|
| 330 |
-
print(f"Successfully updated Step {step} handler in
|
| 331 |
|
| 332 |
# Verify the write
|
| 333 |
-
with open('
|
| 334 |
new_content = f.read()
|
| 335 |
if code.strip() in new_content:
|
| 336 |
print("Verified: Update successful")
|
|
|
|
| 95 |
|
| 96 |
4. Prompt Name Validation :
|
| 97 |
- Prompt names in config are the source of truth
|
| 98 |
+
- Any references to these names in Project.py and event_handlers.py must match EXACTLY
|
| 99 |
- Check for:
|
| 100 |
+
* Function names in event_handlers.py
|
| 101 |
* Component references in all_components dictionary
|
| 102 |
* Input/output mappings in step handlers
|
| 103 |
* Method names in Project.py
|
|
|
|
| 120 |
2. Project.py (SOURCE OF TRUTH FOR FUNCTION PARAMETERS):
|
| 121 |
{project_content}
|
| 122 |
|
| 123 |
+
3. event_handlers.py (NEEDS VALIDATION):
|
| 124 |
{current_handlers}
|
| 125 |
|
| 126 |
Analysis Requirements:
|
|
|
|
| 238 |
project_content = f.read()
|
| 239 |
print("Project.py content loaded")
|
| 240 |
|
| 241 |
+
with open('event_handlers.py', 'r') as f:
|
| 242 |
current_handlers = f.read()
|
| 243 |
+
print("event_handlers.py content loaded")
|
| 244 |
|
| 245 |
# Do one analysis for all files
|
| 246 |
print("\nAnalyzing all files...")
|
|
|
|
| 309 |
if update.lower() == 'y':
|
| 310 |
try:
|
| 311 |
# Read current content
|
| 312 |
+
with open('event_handlers.py', 'r') as f:
|
| 313 |
content = f.read()
|
| 314 |
|
| 315 |
# Find and replace the specific step handler
|
|
|
|
| 324 |
updated_content = content[:match.start()] + code.strip() + content[match.end():]
|
| 325 |
|
| 326 |
# Write back to file
|
| 327 |
+
with open('event_handlers.py', 'w') as f:
|
| 328 |
f.write(updated_content)
|
| 329 |
|
| 330 |
+
print(f"Successfully updated Step {step} handler in event_handlers.py")
|
| 331 |
|
| 332 |
# Verify the write
|
| 333 |
+
with open('event_handlers.py', 'r') as f:
|
| 334 |
new_content = f.read()
|
| 335 |
if code.strip() in new_content:
|
| 336 |
print("Verified: Update successful")
|
step_handlers.py → event_handlers.py
RENAMED
|
@@ -1,81 +1,81 @@
|
|
| 1 |
-
from Project import *
|
| 2 |
-
from google_drive import *
|
| 3 |
|
| 4 |
-
def setup_all_handlers(step_buttons, all_components, page_progress_update, quotation_cost , page_recalc_btn , page_upload_btn , drive_folder_name):
|
| 5 |
-
"""Set up all step handlers with the provided UI components"""
|
| 6 |
-
step_buttons['Step 1 : Scope & Components'].click(
|
| 7 |
-
fn=state.quotation_project.generate_prd_and_components,
|
| 8 |
-
inputs=[],
|
| 9 |
-
outputs=[
|
| 10 |
-
all_components['generate_prd']['generated_prd_text'],
|
| 11 |
-
all_components['generate_prd']['generated_prd_markdown'],
|
| 12 |
-
all_components['generate_plan_test_components']['generated_plan_test_components_text'],
|
| 13 |
-
all_components['generate_plan_test_components']['generated_plan_test_components_markdown'],
|
| 14 |
-
all_components['generate_dev_components']['generated_dev_components_text'],
|
| 15 |
-
all_components['generate_dev_components']['generated_dev_components_markdown'],
|
| 16 |
-
page_progress_update
|
| 17 |
-
],
|
| 18 |
-
)
|
| 19 |
-
|
| 20 |
-
step_buttons['Step 2 : Planning & Testing Mandays'].click(
|
| 21 |
-
fn=state.quotation_project.generate_mandays_and_quotation,
|
| 22 |
-
inputs=[
|
| 23 |
-
all_components['generate_plan_test_components']['generated_plan_test_components_text'],
|
| 24 |
-
all_components['generate_dev_components']['generated_dev_components_text']
|
| 25 |
-
],
|
| 26 |
-
outputs=[
|
| 27 |
-
all_components['generate_plan_test_mandays']['generated_plan_test_mandays_dataframe'],
|
| 28 |
-
all_components['generate_dev_mandays']['generated_dev_mandays_dataframe'],
|
| 29 |
-
page_progress_update,
|
| 30 |
-
quotation_cost
|
| 31 |
-
],
|
| 32 |
-
)
|
| 33 |
|
| 34 |
-
step_buttons['Step
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
all_components['generate_dev_components']['generated_dev_components_text'],
|
| 40 |
-
quotation_cost
|
| 41 |
-
],
|
| 42 |
-
outputs=[
|
| 43 |
-
all_components['generate_BD_SOW']['generated_BD_SOW_text'],
|
| 44 |
-
all_components['generate_BD_SOW']['generated_BD_SOW_markdown'],
|
| 45 |
-
all_components['generate_Tech_SOW']['generated_Tech_SOW_text'],
|
| 46 |
-
all_components['generate_Tech_SOW']['generated_Tech_SOW_markdown'],
|
| 47 |
-
page_progress_update
|
| 48 |
-
],
|
| 49 |
-
)
|
| 50 |
-
|
| 51 |
-
page_recalc_btn.click(
|
| 52 |
-
fn=state.quotation_project.recalculate_cost,
|
| 53 |
-
inputs=[
|
| 54 |
-
all_components['generate_plan_test_mandays']['generated_plan_test_mandays_dataframe'],
|
| 55 |
-
all_components['generate_dev_mandays']['generated_dev_mandays_dataframe'],
|
| 56 |
],
|
| 57 |
-
outputs=[
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
page_upload_btn.click(
|
| 64 |
-
fn=upload_to_gdrive,
|
| 65 |
-
inputs=[
|
| 66 |
-
drive_folder_name,
|
| 67 |
-
all_components['generate_prd']['generated_prd_markdown'],
|
| 68 |
-
all_components['generate_plan_test_components']['generated_plan_test_components_markdown'],
|
| 69 |
-
all_components['generate_dev_components']['generated_dev_components_markdown'],
|
| 70 |
-
all_components['generate_plan_test_mandays']['generated_plan_test_mandays_dataframe'],
|
| 71 |
-
all_components['generate_dev_mandays']['generated_dev_mandays_dataframe'],
|
| 72 |
-
quotation_cost,
|
| 73 |
-
all_components['generate_BD_SOW']['generated_BD_SOW_markdown'],
|
| 74 |
-
all_components['generate_Tech_SOW']['generated_Tech_SOW_markdown'],
|
| 75 |
],
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from Project import *
|
| 2 |
+
from google_drive import *
|
| 3 |
|
| 4 |
+
def setup_all_handlers(step_buttons, all_components, page_progress_update, quotation_cost , page_recalc_btn , page_upload_btn , drive_folder_name):
|
| 5 |
+
"""Set up all step handlers with the provided UI components"""
|
| 6 |
+
step_buttons['Step 1 : Scope & Components'].click(
|
| 7 |
+
fn=state.quotation_project.generate_prd_and_components,
|
| 8 |
+
inputs=[],
|
| 9 |
+
outputs=[
|
| 10 |
+
all_components['generate_prd']['generated_prd_text'],
|
| 11 |
+
all_components['generate_prd']['generated_prd_markdown'],
|
| 12 |
+
all_components['generate_plan_test_components']['generated_plan_test_components_text'],
|
| 13 |
+
all_components['generate_plan_test_components']['generated_plan_test_components_markdown'],
|
| 14 |
+
all_components['generate_dev_components']['generated_dev_components_text'],
|
| 15 |
+
all_components['generate_dev_components']['generated_dev_components_markdown'],
|
| 16 |
+
page_progress_update
|
| 17 |
+
],
|
| 18 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
|
| 20 |
+
step_buttons['Step 2 : Planning & Testing Mandays'].click(
|
| 21 |
+
fn=state.quotation_project.generate_mandays_and_quotation,
|
| 22 |
+
inputs=[
|
| 23 |
+
all_components['generate_plan_test_components']['generated_plan_test_components_text'],
|
| 24 |
+
all_components['generate_dev_components']['generated_dev_components_text']
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 25 |
],
|
| 26 |
+
outputs=[
|
| 27 |
+
all_components['generate_plan_test_mandays']['generated_plan_test_mandays_dataframe'],
|
| 28 |
+
all_components['generate_dev_mandays']['generated_dev_mandays_dataframe'],
|
| 29 |
+
page_progress_update,
|
| 30 |
+
quotation_cost
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
],
|
| 32 |
+
)
|
| 33 |
+
|
| 34 |
+
step_buttons['Step 3 : SOW Doc'].click(
|
| 35 |
+
fn=state.quotation_project.generate_sow,
|
| 36 |
+
inputs=[
|
| 37 |
+
all_components['generate_prd']['generated_prd_text'],
|
| 38 |
+
all_components['generate_plan_test_components']['generated_plan_test_components_text'],
|
| 39 |
+
all_components['generate_dev_components']['generated_dev_components_text'],
|
| 40 |
+
quotation_cost
|
| 41 |
+
],
|
| 42 |
+
outputs=[
|
| 43 |
+
all_components['generate_BD_SOW']['generated_BD_SOW_text'],
|
| 44 |
+
all_components['generate_BD_SOW']['generated_BD_SOW_markdown'],
|
| 45 |
+
all_components['generate_Tech_SOW']['generated_Tech_SOW_text'],
|
| 46 |
+
all_components['generate_Tech_SOW']['generated_Tech_SOW_markdown'],
|
| 47 |
+
page_progress_update
|
| 48 |
+
],
|
| 49 |
+
)
|
| 50 |
+
|
| 51 |
+
page_recalc_btn.click(
|
| 52 |
+
fn=state.quotation_project.recalculate_cost,
|
| 53 |
+
inputs=[
|
| 54 |
+
all_components['generate_plan_test_mandays']['generated_plan_test_mandays_dataframe'],
|
| 55 |
+
all_components['generate_dev_mandays']['generated_dev_mandays_dataframe'],
|
| 56 |
+
],
|
| 57 |
+
outputs=[
|
| 58 |
+
quotation_cost,
|
| 59 |
+
page_progress_update
|
| 60 |
+
]
|
| 61 |
+
)
|
| 62 |
+
|
| 63 |
+
page_upload_btn.click(
|
| 64 |
+
fn=upload_to_gdrive,
|
| 65 |
+
inputs=[
|
| 66 |
+
drive_folder_name,
|
| 67 |
+
all_components['generate_prd']['generated_prd_markdown'],
|
| 68 |
+
all_components['generate_plan_test_components']['generated_plan_test_components_markdown'],
|
| 69 |
+
all_components['generate_dev_components']['generated_dev_components_markdown'],
|
| 70 |
+
all_components['generate_plan_test_mandays']['generated_plan_test_mandays_dataframe'],
|
| 71 |
+
all_components['generate_dev_mandays']['generated_dev_mandays_dataframe'],
|
| 72 |
+
quotation_cost,
|
| 73 |
+
all_components['generate_BD_SOW']['generated_BD_SOW_markdown'],
|
| 74 |
+
all_components['generate_Tech_SOW']['generated_Tech_SOW_markdown'],
|
| 75 |
+
],
|
| 76 |
+
outputs=[
|
| 77 |
+
page_progress_update
|
| 78 |
+
]
|
| 79 |
+
)
|
| 80 |
+
|
| 81 |
+
|
page_prompts_config.py
CHANGED
|
@@ -134,7 +134,6 @@ PROMPTS = {
|
|
| 134 |
Rewrite this for clarity while keeping all specific details, metrics, and constraints.
|
| 135 |
Do not include context or assumptions beyond the input provided.
|
| 136 |
Structure the document to ensure clarity and logical flow.
|
| 137 |
-
Respond only in English.
|
| 138 |
""",
|
| 139 |
inputs=["project_detail"],
|
| 140 |
outputs=["generated_prd"],
|
|
@@ -157,7 +156,7 @@ PROMPTS = {
|
|
| 157 |
"generated_prd_markdown": UIConfig(
|
| 158 |
component_type=UIComponentType.MARKDOWN,
|
| 159 |
label="Requirements(PRD) Output",
|
| 160 |
-
visible=
|
| 161 |
show_copy_button=True
|
| 162 |
)
|
| 163 |
}
|
|
@@ -288,7 +287,7 @@ PROMPTS = {
|
|
| 288 |
"generated_plan_test_components_markdown": UIConfig(
|
| 289 |
component_type=UIComponentType.MARKDOWN,
|
| 290 |
label="Plan & Test Components Output",
|
| 291 |
-
visible=
|
| 292 |
show_copy_button=True
|
| 293 |
)
|
| 294 |
}
|
|
@@ -340,7 +339,7 @@ PROMPTS = {
|
|
| 340 |
step="Step 1 : Scope & Components",
|
| 341 |
ui={
|
| 342 |
"dev_component_prompt_editor": UIConfig(
|
| 343 |
-
component_type=UIComponentType.TEXTBOX,
|
| 344 |
label="Development System Prompt",
|
| 345 |
lines=20,
|
| 346 |
interactive=True
|
|
@@ -354,7 +353,7 @@ PROMPTS = {
|
|
| 354 |
"generated_dev_components_markdown": UIConfig(
|
| 355 |
component_type=UIComponentType.MARKDOWN,
|
| 356 |
label="Developemnt Components Output",
|
| 357 |
-
visible=
|
| 358 |
show_copy_button=True
|
| 359 |
)
|
| 360 |
}
|
|
@@ -392,7 +391,7 @@ PROMPTS = {
|
|
| 392 |
inputs=["generated_plan_test_components"],
|
| 393 |
outputs=["generated_plan_test_mandays"],
|
| 394 |
model=ModelType.O1_MINI,
|
| 395 |
-
description="Generate planning and testing mandays
|
| 396 |
step="Step 2 : Planning & Testing Mandays",
|
| 397 |
ui={
|
| 398 |
"plan_test_mandays_prompt_editor": UIConfig(
|
|
@@ -451,7 +450,7 @@ PROMPTS = {
|
|
| 451 |
inputs=["generated_dev_components"],
|
| 452 |
outputs=["generated_dev_mandays"],
|
| 453 |
model=ModelType.O1_MINI,
|
| 454 |
-
description="Generate development mandays
|
| 455 |
step="Step 2 : Planning & Testing Mandays",
|
| 456 |
ui={
|
| 457 |
"dev_mandays_prompt_editor": UIConfig(
|
|
@@ -664,7 +663,7 @@ PROMPTS = {
|
|
| 664 |
"generated_BD_SOW_markdown": UIConfig(
|
| 665 |
component_type=UIComponentType.MARKDOWN,
|
| 666 |
label="BD SOW Doc",
|
| 667 |
-
visible=
|
| 668 |
show_copy_button=True
|
| 669 |
)
|
| 670 |
}
|
|
@@ -739,7 +738,7 @@ PROMPTS = {
|
|
| 739 |
"generated_Tech_SOW_markdown": UIConfig(
|
| 740 |
component_type=UIComponentType.MARKDOWN,
|
| 741 |
label="Technical SOW Doc",
|
| 742 |
-
visible=
|
| 743 |
show_copy_button=True
|
| 744 |
)
|
| 745 |
}
|
|
|
|
| 134 |
Rewrite this for clarity while keeping all specific details, metrics, and constraints.
|
| 135 |
Do not include context or assumptions beyond the input provided.
|
| 136 |
Structure the document to ensure clarity and logical flow.
|
|
|
|
| 137 |
""",
|
| 138 |
inputs=["project_detail"],
|
| 139 |
outputs=["generated_prd"],
|
|
|
|
| 156 |
"generated_prd_markdown": UIConfig(
|
| 157 |
component_type=UIComponentType.MARKDOWN,
|
| 158 |
label="Requirements(PRD) Output",
|
| 159 |
+
visible=True,
|
| 160 |
show_copy_button=True
|
| 161 |
)
|
| 162 |
}
|
|
|
|
| 287 |
"generated_plan_test_components_markdown": UIConfig(
|
| 288 |
component_type=UIComponentType.MARKDOWN,
|
| 289 |
label="Plan & Test Components Output",
|
| 290 |
+
visible=True,
|
| 291 |
show_copy_button=True
|
| 292 |
)
|
| 293 |
}
|
|
|
|
| 339 |
step="Step 1 : Scope & Components",
|
| 340 |
ui={
|
| 341 |
"dev_component_prompt_editor": UIConfig(
|
| 342 |
+
component_type=UIComponentType.TEXTBOX,
|
| 343 |
label="Development System Prompt",
|
| 344 |
lines=20,
|
| 345 |
interactive=True
|
|
|
|
| 353 |
"generated_dev_components_markdown": UIConfig(
|
| 354 |
component_type=UIComponentType.MARKDOWN,
|
| 355 |
label="Developemnt Components Output",
|
| 356 |
+
visible=True,
|
| 357 |
show_copy_button=True
|
| 358 |
)
|
| 359 |
}
|
|
|
|
| 391 |
inputs=["generated_plan_test_components"],
|
| 392 |
outputs=["generated_plan_test_mandays"],
|
| 393 |
model=ModelType.O1_MINI,
|
| 394 |
+
description="Generate planning and testing mandays",
|
| 395 |
step="Step 2 : Planning & Testing Mandays",
|
| 396 |
ui={
|
| 397 |
"plan_test_mandays_prompt_editor": UIConfig(
|
|
|
|
| 450 |
inputs=["generated_dev_components"],
|
| 451 |
outputs=["generated_dev_mandays"],
|
| 452 |
model=ModelType.O1_MINI,
|
| 453 |
+
description="Generate development mandays",
|
| 454 |
step="Step 2 : Planning & Testing Mandays",
|
| 455 |
ui={
|
| 456 |
"dev_mandays_prompt_editor": UIConfig(
|
|
|
|
| 663 |
"generated_BD_SOW_markdown": UIConfig(
|
| 664 |
component_type=UIComponentType.MARKDOWN,
|
| 665 |
label="BD SOW Doc",
|
| 666 |
+
visible=True,
|
| 667 |
show_copy_button=True
|
| 668 |
)
|
| 669 |
}
|
|
|
|
| 738 |
"generated_Tech_SOW_markdown": UIConfig(
|
| 739 |
component_type=UIComponentType.MARKDOWN,
|
| 740 |
label="Technical SOW Doc",
|
| 741 |
+
visible=True,
|
| 742 |
show_copy_button=True
|
| 743 |
)
|
| 744 |
}
|