# app/core/prompt_engine.py import openai from app.core.schema_definition import BIMProjectJSON import json class PromptEngine: def __init__(self, api_key: str): self.api_key = api_key openai.api_key = self.api_key async def generate_json_from_prompt(self, metadata: dict, user_text: str) -> BIMProjectJSON: """ این متد، اطلاعات فرم (metadata) و متن کاربر (user_text) را می‌گیرد و خروجی را دقیقاً مطابق با ساختار BIMProjectJSON برمی‌گرداند. """ # ۱. ساختن System Prompt بسیار دقیق برای مدل system_instruction = f""" You are a highly specialized BIM Data Extraction Engine. Your ONLY task is to convert architectural descriptions into a strict JSON format. ### STRICT RULES: 1. Use the provided metadata as the base for 'project_metadata'. 2. Map all architectural elements to these exact types: [Column, Beam, Wall-Structural, Wall-Non-Structural, Door, Window, Slab, Floor-Finish, Ceiling, Roof, Light-Fixture]. 3. All coordinates (x, y, z) and dimensions (length, width, height) must be in FLOAT (meters). 4. If a dimension is not mentioned, use a logical default or null, but NEVER guess incorrectly. 5. Output MUST be a single, valid JSON object following the schema. 6. Do not include any preamble, explanations, or markdown code blocks (like ```json). Just the raw JSON. ### OUTPUT SCHEMA EXAMPLE: {{ "project_metadata": {{{{ "name": "Example", "level": "Ground", "unit": "meter" }}}}, "elements": [ {{ "id": "COL_01", "element_type": "Column", "position": {{"x": 0.0, "y": 0.0, "z": 0.0}}, "dimensions": {{"length": 0.5, "width": 0.5, "height": 3.0}}, "material": "Concrete", "description": "Corner column" }} ] }} """ # ۲. ترکیب Metadata و User Text برای ایجاد Prompt نهایی user_content = f""" ### CONTEXT FROM FORM: {json.dumps(metadata, indent=2)} ### USER ARCHITECTURAL DESCRIPTION: "{user_text}" ### FINAL TASK: Generate the complete JSON object based on the context and description above. """ try: # ۳. فراخوانی مدل response = await openai.ChatCompletion.acreate( model="gpt-4o", # یا gpt-5.5 در صورت در دسترس بودن messages=[ {"role": "system", "content": system_instruction}, {"role": "user", "content": user_content} ], temperature=0.0, # دما را روی صفر می‌گذاریم تا دقت بالا و خلاقیت (و خطا) کم شود response_format={ "type": "json_object" } # اجبار مدل به تولید JSON ) # ۴. استخراج و اعتبارسنجی با Pydantic raw_json_str = response.choices[0].message.content parsed_data = json.loads(raw_json_str) # این خط بسیار مهم است: اگر AI خروجی اشتباه بدهد، Pydantic خطا می‌دهد و ما متوجه می‌شویم validated_json = BIMProjectJSON(**parsed_data) return validated_json except Exception as e: print(f"Error in Prompt Engine: {e}") raise e