from fastapi import HTTPException import os from ..utils.hashing import HashGenerator from user_journey_service.crew import UserJourney from user_journey_service.processors.duration_estimator import MicrolearningDurationEstimator from user_journey_service.processors.user_journey_synthesizer import Synthesizer from user_journey_service.processors.topic_validator import MicrolearningTopicValidator duration_estimator = MicrolearningDurationEstimator() synthesizer = Synthesizer() topic_validator = MicrolearningTopicValidator() import re class MicrolearningService: def __init__(self,input_data): self.crew_instance = UserJourney() self.input_data = input_data self.input_hash = HashGenerator.generate_input_hash(input_data) self.research_file = f"research/{self.input_hash}.md" self.output_file = f"output/{self.input_hash}.md" self.output_file_1 = f"output1/{self.input_hash}.md" self.output_file_2 = f"output2/{self.input_hash}.md" self.json_output_path = f'parsed_course_content/{self.input_hash}.json' # def run_journey(self): # try: # if self._is_first_iteration(): # exists,_ = self._fetch_existing_result(self.output_file) # if exists: # return {"status": "success", "message": "Fetched existing result."} # else: # print("Need all the Agents..") # self._execute_first_iteration() # available_time = self._estimate_duration() # content1,content2 = self._load_content_based_feedback() # self._execute_restructure_crew(available_time,content1,content2) # self._combine_user_journeys() # return {"status": "success", "message": "Crew execution completed."} def run_journey(self): try: if self._is_first_iteration(): exists,result = self._fetch_existing_result(self.output_file) if exists: return {"status": "success", "message": "Fetched existing result.","output":result} else: if self._validate_the_topic(): print("Need all the Agents..") else: print("Invalid topic...") return {"status": "failed", "message": "Invalid topic."} self._execute_first_iteration() available_time = self._estimate_duration() content1,content2 = self._load_content_based_feedback() self._execute_restructure_crew(available_time,content1,content2) self._combine_user_journeys() exists,result = self._fetch_existing_result(self.output_file) return {"status": "success", "message": "Crew execution completed.","output":result} except Exception as e: raise HTTPException(status_code=500, detail=f"Error running crew: {e}") def _validate_the_topic(self): validate = topic_validator.validate_topic(self.input_data) print(f"The validator output is : {validate}") normalized = validate.strip().lower() if normalized.startswith("valid topic"): print("This is a valid topic.") return True else: print("This is an invalid topic.") return False def parse_questions(self,md_text): pattern = r"### Q\d+:\s*\n?(.*?)(?=\n### Q\d+:|\Z)" return re.findall(pattern, md_text, re.DOTALL) def _is_first_iteration(self): print(f"Inside feedback test : {self.input_data.feedback}") if self.input_data.feedback =="First iteration": return True return False def _fetch_existing_result(self,file_path): if os.path.exists(file_path): with open(file_path, 'r') as file: result = file.read() # print(f"The output is : {result}") return True, result return False, "" def _execute_first_iteration(self): exists,_ = self._fetch_existing_result(self.research_file) if exists: print("researcher already exists..") else: inputs = self.input_data.dict() crew = self.crew_instance.researcher_crew(research_file=self.research_file) crew.kickoff(inputs=inputs) def _estimate_duration(self): available_time = duration_estimator.estimate_duration(self.input_data) if isinstance(available_time, str): available_time = available_time.strip("[]") available_time = str(available_time) + " minutes" print(f"The available time estimated is : {available_time}") return available_time def _load_content_based_feedback(self): if self._is_first_iteration(): _,content = self._fetch_existing_result(self.research_file) return content,content else: _,content1 = self._fetch_existing_result(self.output_file_1) _,content2 = self._fetch_existing_result(self.output_file_2) return content1,content2 def _execute_restructure_crew(self,available_time,content1,content2): inputs = self.input_data.dict() inputs["content"] = content1 inputs["available_time"] = available_time crew = self.crew_instance.restructure_crew1(output_file_1=self.output_file_1,available_time=available_time,feedback=self.input_data.feedback) crew.kickoff(inputs=inputs) inputs["content"] = content2 crew = self.crew_instance.restructure_crew2(output_file_2=self.output_file_2, available_time=available_time,feedback=self.input_data.feedback) crew.kickoff(inputs=inputs) def _combine_user_journeys(self): _,user_journey1 = self._fetch_existing_result(self.output_file_1) _,user_journey2 = self._fetch_existing_result(self.output_file_2) combined_data = synthesizer.review_and_combine(designation=self.input_data.Job_Title,skills=self.input_data.Skills,experience=self.input_data.Experience,content1=user_journey1,content2=user_journey2) os.makedirs(os.path.dirname(self.output_file), exist_ok=True) with open(self.output_file, 'w', encoding='utf-8') as out_file: out_file.write(combined_data)