File size: 11,230 Bytes
780c251
59fdb92
 
 
e1a0e9e
8136580
780c251
 
e1a0e9e
 
 
 
cf11e01
 
 
 
 
0d3b455
2d7117e
5647284
 
 
e1a0e9e
5647284
49c0f36
cf11e01
8b2877d
 
cf11e01
 
 
 
8b2877d
 
e1a0e9e
8b2877d
2d7117e
cf11e01
 
 
e1a0e9e
cf11e01
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
780c251
 
2d7117e
 
780c251
cf11e01
 
 
 
 
 
 
 
 
 
2d7117e
e1a0e9e
 
5647284
 
e1a0e9e
5647284
 
 
 
 
8b2877d
e1a0e9e
8b2877d
 
cf11e01
8b2877d
 
2d7117e
5647284
780c251
5647284
e1a0e9e
5647284
 
 
 
 
 
 
 
 
e1a0e9e
5647284
 
 
 
 
780c251
 
 
 
 
5647284
 
 
 
e1a0e9e
5647284
 
 
 
 
 
 
 
 
e1a0e9e
5647284
 
 
 
 
780c251
5647284
 
 
 
e1a0e9e
5647284
 
e1a0e9e
5647284
 
 
780c251
 
2d7117e
 
 
 
 
780c251
 
 
2d7117e
 
 
5647284
 
e1a0e9e
5647284
e1a0e9e
5647284
 
 
 
2d7117e
780c251
e1a0e9e
2d7117e
780c251
 
 
 
 
 
 
2d7117e
 
780c251
 
 
2d7117e
780c251
5647284
780c251
2d7117e
 
 
 
 
 
 
 
 
 
780c251
2d7117e
5647284
 
e1a0e9e
5647284
e1a0e9e
5647284
 
 
 
2d7117e
 
 
 
 
780c251
 
 
 
 
2d7117e
5647284
 
e1a0e9e
5647284
e1a0e9e
5647284
 
 
 
2d7117e
e1a0e9e
780c251
2d7117e
 
 
 
780c251
2d7117e
 
e1a0e9e
780c251
2d7117e
 
780c251
2d7117e
 
4e32565
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
from flask import Flask, request, jsonify
from transformers import pipeline
from simple_salesforce import Salesforce
import datetime
import logging

app = Flask(__name__)

# Set up logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# Hardcode Salesforce credentials
SF_USERNAME = "app@coach.com"
SF_PASSWORD = "Geetha@1"
SF_SECURITY_TOKEN = "or9hAAcLK7L6cClJjOGwYjbZq"
SF_DOMAIN = "login"

# Initialize Hugging Face model
try:
    generator = pipeline("text-generation", model="distilgpt2")
except Exception as e:
    logger.error(f"Error initializing Hugging Face model: {str(e)}")
    generator = None

# Initialize Salesforce connection with hardcoded credentials
try:
    sf = Salesforce(
        username=SF_USERNAME,
        password=SF_PASSWORD,
        security_token=SF_SECURITY_TOKEN,
        domain=SF_DOMAIN
    )
except Exception as e:
    logger.error(f"Error connecting to Salesforce: {str(e)}")
    sf = None

# Add a default route for the root URL
@app.route('/')
def home():
    logger.info("Received request to root URL")
    return jsonify({
        "status": "running",
        "message": "This is the AI Coach App backend API. Use the /generate-ai-data endpoint to generate AI coaching data and reports.",
        "endpoint": "https://huggingface.co/spaces/varshakolanu/Supervisor/generate-ai-data",
        "method": "POST",
        "example_payload": {
            "supervisor_id": "003xxxxxxxxxxxx",
            "project_id": "a0Bxxxxxxxxxxxx",
            "supervisor_data": {
                "Role__c": "Supervisor",
                "Location__c": "New York"
            },
            "project_data": {
                "Name": "Highway Expansion",
                "Start_Date__c": "2025-05-15",
                "End_Date__c": "2025-12-31",
                "Milestones__c": "Bridge completion by June 1, 2025",
                "Project_Schedule__c": "Daily inspections"
            }
        }
    })

@app.route('/generate-ai-data', methods=['POST'])
def generate_ai_data():
    """
    Generate AI coaching data and reports based on supervisor and project data.
    This endpoint is called by Salesforce when a new project is created or during daily refresh.
    
    Inputs from Salesforce:
    - supervisor_id: ID of the supervisor from Supervisor_Profile__c
    - project_id: ID of the project from Project_Details__c
    - supervisor_data: Contains Role__c, Location__c from Supervisor_Profile__c
    - project_data: Contains Name, Start_Date__c, End_Date__c, Milestones__c, Project_Schedule__c from Project_Details__c
    
    Outputs stored in Salesforce:
    - AI_Coaching_Data__c: Daily_Checklist__c, Suggested_Tips__c, Risk_Alerts__c, Upcoming_Milestones__c, Performance_Trends__c, Generated_Date__c
    - Report_Download__c: Report_Type__c, Report_Data__c, Download_Link__c, Generated_Date__c
    """
    logger.info("Received request to /generate-ai-data endpoint")

    # Check if dependencies are initialized
    if generator is None:
        logger.error("Hugging Face model failed to initialize")
        return jsonify({
            "status": "error",
            "message": "Hugging Face model failed to initialize."
        }), 500

    if sf is None:
        logger.error("Salesforce connection failed")
        return jsonify({
            "status": "error",
            "message": "Salesforce connection failed. Check credentials in app.py."
        }), 500

    try:
        # Extract and validate inputs from the POST request
        data = request.get_json()
        if not data:
            logger.error("No data provided in the request")
            return jsonify({
                "status": "error",
                "message": "No data provided in the request."
            }), 400

        # Required fields
        required_fields = ['supervisor_id', 'project_id', 'supervisor_data', 'project_data']
        for field in required_fields:
            if field not in data or not data[field]:
                logger.error(f"Missing or empty required field: {field}")
                return jsonify({
                    "status": "error",
                    "message": f"Missing or empty required field: {field}"
                }), 400

        supervisor_id = data['supervisor_id']
        project_id = data['project_id']
        supervisor_data = data['supervisor_data']
        project_data = data['project_data']

        # Validate supervisor_data
        required_supervisor_fields = ['Role__c', 'Location__c']
        for field in required_supervisor_fields:
            if field not in supervisor_data or not supervisor_data[field]:
                logger.error(f"Missing or empty field in supervisor_data: {field}")
                return jsonify({
                    "status": "error",
                    "message": f"Missing or empty field in supervisor_data: {field}"
                }), 400

        # Validate project_data
        required_project_fields = ['Name', 'Start_Date__c', 'End_Date__c', 'Milestones__c', 'Project_Schedule__c']
        for field in required_project_fields:
            if field not in project_data or not project_data[field]:
                logger.error(f"Missing or empty field in project_data: {field}")
                return jsonify({
                    "status": "error",
                    "message": f"Missing or empty field in project_data: {field}"
                }), 400

        # Fetch existing checklists to determine progress
        try:
            checklists = sf.query(
                f"SELECT Task_Name__c, Status__c FROM Daily_Checklist__c WHERE Project_ID__c = '{project_id}' AND Date__c = TODAY"
            )['records']
            logger.info(f"Fetched {len(checklists)} checklists for project {project_id}")
        except Exception as e:
            checklists = []
            logger.warning(f"Error querying Daily_Checklist__c: {str(e)}")

        completed_tasks = [c['Task_Name__c'] for c in checklists if c.get('Status__c') == 'Completed']
        pending_tasks = [c['Task_Name__c'] for c in checklists if c.get('Status__c') == 'Pending']
        completion_rate = len(completed_tasks) / (len(completed_tasks) + len(pending_tasks)) * 100 if (len(completed_tasks) + len(pending_tasks)) > 0 else 0

        # Construct prompt for AI generation
        prompt = (
            f"Generate daily checklist, tips, risk alerts, upcoming milestones, and performance trends for a "
            f"{supervisor_data['Role__c']} at {supervisor_data['Location__c']} working on project "
            f"{project_data['Name']} with milestones {project_data['Milestones__c']} and schedule "
            f"{project_data['Project_Schedule__c']}. "
            f"Current completion rate: {completion_rate:.1f}%. Completed tasks: {', '.join(completed_tasks) if completed_tasks else 'None'}. "
            f"Pending tasks: {', '.join(pending_tasks) if pending_tasks else 'None'}."
        )

        # Generate AI output
        try:
            ai_response = generator(prompt, max_length=500, num_return_sequences=1)[0]['generated_text']
            logger.info("Successfully generated AI response")
        except Exception as e:
            logger.error(f"Error generating AI response: {str(e)}")
            return jsonify({
                "status": "error",
                "message": f"Error generating AI response: {str(e)}"
            }), 500

        # Parse AI response (more dynamic parsing based on project progress)
        today = "2025-05-22"  # Hardcoded to current date (May 22, 2025)
        daily_checklist = (
            f"1. Review pending tasks from yesterday (General, Pending)\n"
            f"2. Conduct daily safety inspection for {project_data['Name']} (Safety, Pending)\n"
            f"3. Schedule progress meeting (General, Pending)"
        ) if not pending_tasks else (
            f"1. Complete pending task: {pending_tasks[0]} (General, Pending)\n"
            f"2. Conduct daily safety inspection for {project_data['Name']} (Safety, Pending)\n"
            f"3. Schedule progress meeting (General, Pending)"
        )
        suggested_tips = (
            f"1. Focus on completing pending tasks to improve completion rate.\n"
            f"2. Monitor weather conditions in {supervisor_data['Location__c']}.\n"
            f"3. Prepare for upcoming milestone."
        )
        risk_alerts = f"Risk of delay: Weather risks in {supervisor_data['Location__c']} on {today}."
        upcoming_milestones = project_data['Milestones__c'].split(';')[0] if project_data['Milestones__c'] else "No milestones available"
        performance_trends = f"Task completion rate: {completion_rate:.1f}% (updated {today})."

        # Save AI data to AI_Coaching_Data__c
        ai_data = {
            'Supervisor_ID__c': supervisor_id,
            'Project_ID__c': project_id,
            'Daily_Checklist__c': daily_checklist,
            'Suggested_Tips__c': suggested_tips,
            'Risk_Alerts__c': risk_alerts,
            'Upcoming_Milestones__c': upcoming_milestones,
            'Performance_Trends__c': performance_trends,
            'Generated_Date__c': today
        }
        try:
            sf.AI_Coaching_Data__c.create(ai_data)
            logger.info(f"Successfully saved AI data to AI_Coaching_Data__c for project {project_id}")
        except Exception as e:
            logger.error(f"Error saving to AI_Coaching_Data__c: {str(e)}")
            return jsonify({
                "status": "error",
                "message": f"Error saving to AI_Coaching_Data__c: {str(e)}"
            }), 500

        # Generate a report for Report_Download__c
        report_data = {
            'Supervisor_ID__c': supervisor_id,
            'Project_ID__c': project_id,
            'Report_Type__c': 'Daily Progress',
            'Report_Data__c': f"Daily Progress Report ({today}): Completion rate: {completion_rate:.1f}%. "
                             f"Pending tasks: {len(pending_tasks)}. Completed tasks: {len(completed_tasks)}.",
            'Download_Link__c': 'https://your-salesforce-site.com/reports/RPT-' + project_id + '.pdf',  # Update with actual Salesforce Site URL
            'Generated_Date__c': today
        }
        try:
            sf.Report_Download__c.create(report_data)
            logger.info(f"Successfully saved report to Report_Download__c for project {project_id}")
        except Exception as e:
            logger.error(f"Error saving to Report_Download__c: {str(e)}")
            return jsonify({
                "status": "error",
                "message": f"Error saving to Report_Download__c: {str(e)}"
            }), 500

        logger.info("Successfully processed request to /generate-ai-data")
        return jsonify({
            "status": "success",
            "message": "AI data and report generated successfully",
            "ai_data": ai_data,
            "report_data": report_data
        })

    except Exception as e:
        logger.error(f"Error generating AI data: {str(e)}")
        return jsonify({
            "status": "error",
            "message": f"Error generating AI data: {str(e)}"
        }), 500

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=7860, debug=True)