ICAS03 commited on
Commit
eb04412
·
1 Parent(s): 3cbf3b3

- Fix code_modifier

Browse files
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 step_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,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
- with gr.Column(scale=1):
54
- editor_key = next((k for k in prompt_config.ui.keys() if k.endswith('_prompt_editor')), None)
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
- with gr.Column(scale=1):
76
- text_key = next((k for k in prompt_config.ui.keys() if k.endswith('_text')), None)
77
- markdown_key = next((k for k in prompt_config.ui.keys() if k.endswith('_markdown')), None)
78
-
79
- if text_key and markdown_key:
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
- with gr.Group():
90
- components[text_key] = create_ui_component(
91
- prompt_config.ui[text_key]
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
- else:
109
- for key, config in prompt_config.ui.items():
110
- if not key.endswith('_prompt_editor'):
111
- components[key] = create_ui_component(config)
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 IGNORE them
112
  - Examples of internal values:
113
- * quotation_cost: Generated as output, used as input in other steps
114
- * project_detail: Used as input without UI mapping
115
- * gathered_project_input: Internal state passed between steps
116
- * reviewed_project_input: Internal state passed between steps
 
 
 
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 (e.g., 'generated_prd') MUST map to TWO components:
122
  - base_name_text: For textbox display
123
  - base_name_markdown: For markdown display
124
  - Special Case - Mandays Pattern:
125
- * Mandays outputs (e.g., 'generated_plan_test_mandays') MUST map to ONE component:
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 (e.g., "generate_dev_components" --> "generate_development_components")
135
- - Component names (e.g., "generated_Tech_SOW_text" --> "generated_technical_sow_text")
136
  - Input/Output references
137
 
138
  WHERE TO CHECK:
139
- - step_handlers.py: Function names, component references
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. step_handlers.py:
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
- "step_handlers": {{
183
- "steps": [
184
  {{
185
- "step": "step_number",
 
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
- "step_handlers.py": [
206
  {{
207
- "step": "step_number",
208
- "type": "component|input|output",
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
- "step_handlers": {"steps": []},
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
- Generate a JSON response with this EXACT structure as shown as an example below:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
248
  {{
249
  "Project.py": {{
250
- "updates": []
251
- }},
252
- "step_handlers.py": {{
253
  "updates": [
254
  {{
255
- "type": "output", # Must be one of: component, input, output
256
- "location": "step_handlers.py - Step 3 Output Mapping",
257
- "explanation": "Mismatch in prompt name; 'generate_Tech_SOW' should be 'generate_Technical_SOW'",
258
- "old_code": "output_name = 'generate_Tech_SOW'",
259
- "new_code": "output_name = 'generate_Technical_SOW'"
260
- }},
 
 
 
 
 
 
 
 
 
 
261
  {{
262
- "type": "component",
263
- "location": "step_handlers.py - Step 3 Component Names",
264
- "explanation": "Component names should reflect the correct prompt name",
265
- "old_code": "generated_Tech_SOW_text, generated_Tech_SOW_markdown",
266
- "new_code": "generated_Technical_SOW_text, generated_Technical_SOW_markdown"
 
 
 
 
 
 
 
 
 
 
 
 
 
267
  }}
268
  ]
269
  }}
270
  }}
271
 
272
  Requirements:
273
- 1. Each update MUST include 'type' field with one of: component, input, output
274
- 2. Maintain exact function signatures
275
- 3. Preserve existing code structure
276
- 4. Only generate the specific changes needed
277
- 5. Include clear comments explaining changes
278
- 6. Each file must have an 'updates' array, even if empty
 
 
 
 
 
 
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
- if "Project.py" not in parsed_result:
290
- parsed_result["Project.py"] = {"updates": []}
291
- if "step_handlers.py" not in parsed_result:
292
- parsed_result["step_handlers.py"] = {"updates": []}
293
 
294
- # Ensure updates array exists and has required fields
295
- for file_updates in parsed_result.values():
296
- if "updates" not in file_updates:
297
- file_updates["updates"] = []
298
- for update in file_updates["updates"]:
 
299
  if "type" not in update:
300
- update["type"] = "component" # Default type if missing
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
- "step_handlers.py": {"updates": []}
310
  }
311
 
312
- def apply_project_updates(updates: List[Dict]) -> bool:
313
- """Apply updates to Project.py"""
314
  try:
315
- with open('Project.py', 'r') as f:
316
- content = f.read()
317
 
318
- for update in updates:
319
- if update['type'] == 'method':
320
- # Add new methods before the last class method
321
- class_end = content.rfind('\n\n')
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
- return True
 
339
 
340
- except Exception as e:
341
- print(f"Error applying Project.py updates: {str(e)}")
342
- return False
343
-
344
- def apply_handler_updates(updates: List[Dict]) -> bool:
345
- """Apply updates to step_handlers.py"""
346
- try:
347
- with open('step_handlers.py', 'r') as f:
348
- content = f.read()
349
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
350
  for update in updates:
351
- if not update.get('type') or not update.get('old_code') or not update.get('new_code'):
352
- print(f"Skipping invalid update: {update}")
 
 
 
353
  continue
354
 
355
- if update['type'] == 'component':
356
- # Update component references
357
- content = content.replace(update['old_code'], update['new_code'])
358
- elif update['type'] == 'input':
359
- # Update input parameters
360
- pattern = rf"inputs=\[([^\]]*)\]"
361
- replacement = f"inputs=[{update['new_code']}]"
362
- content = re.sub(pattern, replacement, content)
363
- elif update['type'] == 'output':
364
- # Update output parameters
365
- old_code = update['old_code'].strip()
366
- new_code = update['new_code'].strip()
367
- content = content.replace(old_code, new_code)
368
-
369
- with open('step_handlers.py', 'w') as f:
370
- f.write(content)
 
 
 
 
 
 
 
371
 
372
  return True
373
 
374
  except Exception as e:
375
- print(f"Error applying handler updates: {str(e)}")
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('step_handlers.py', 'r') as f:
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. Step Handlers:", len(analysis_result['step_handlers']['steps']))
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
- print(f"- {update['type']}: {update['reason']}")
 
 
 
454
 
455
  if analysis_result.get('validation_issues'):
456
  print("\nValidation Issues:")
457
  for issue in analysis_result['validation_issues']:
458
- print(f"- {issue['type']} ({issue['severity']}): {issue['description']}")
 
 
 
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['location']}")
476
- print(f" Explanation: {update['explanation']}")
477
  print(" Old code:")
478
- print(f"```\n{update['old_code']}\n```")
479
  print(" New code:")
480
- print(f"```\n{update['new_code']}\n```")
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 &= apply_project_updates(code_updates['Project.py']['updates'])
492
- if 'step_handlers.py' in code_updates:
493
- success &= apply_handler_updates(code_updates['step_handlers.py']['updates'])
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 step_handlers.py must match EXACTLY
99
  - Check for:
100
- * Function names in step_handlers.py
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. step_handlers.py (NEEDS VALIDATION):
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('step_handlers.py', 'r') as f:
242
  current_handlers = f.read()
243
- print("step_handlers.py content loaded")
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('step_handlers.py', 'r') as f:
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('step_handlers.py', 'w') as f:
328
  f.write(updated_content)
329
 
330
- print(f"Successfully updated Step {step} handler in step_handlers.py")
331
 
332
  # Verify the write
333
- with open('step_handlers.py', 'r') as f:
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 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
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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=False,
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=False,
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=False,
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 from plan_test components table",
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 from dev components table",
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=False,
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=False,
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
  }