# app/core/content_service.py from concurrent.futures import ThreadPoolExecutor from crewai import Crew, Process from .content_crew_config import safe_run_cached from agents.content_phase import ( course_writer_agent, course_writer_task, ) # انت عندك دول جاهزين MAX_UNIT_WORKERS = 3 def process_unit(unit: dict, course_title: str) -> dict: output_unit = { "unit_name": unit["unit_name"], "unit_outcome": unit["outcome"], "topics": [], } # ====== CACHED CREW (يُستخدم في أي مكان) ====== agent = course_writer_agent() task = course_writer_task(agent) cached_crew = Crew( agents=[agent], tasks=[task], process=Process.sequential, memory=False, verbose=False, ) for topic in unit["topics"]: topic_entry = {"topic_title": topic["title"], "subtopics": []} # sequential subtopics for highest quality for sub in topic["subtopics"]: combined_scraped = "\n\n".join( r.get("scraped_content", "")[:1500] for r in sub.get("results", []) if "scraped_content" in r ) inputs = { "course_title": course_title, "unit_title": unit["unit_name"], "topic_title": topic["title"], "subtopic_title": sub["title"], "subtopic_description": sub["description"], "combined_scraped_texts": combined_scraped, } print(f"🟢 Writing: {sub['title']}") generated, used_sources = safe_run_cached(inputs, cached_crew=cached_crew) topic_entry["subtopics"].append( { "title": sub["title"], "description": sub["description"], "generated_content": generated, "sources": used_sources, } ) output_unit["topics"].append(topic_entry) return output_unit def generate_course_content(course_data: dict) -> dict: """ دي اللي هتناديها من الـ FastAPI course_data شكلها زي اللي كان في الفايل: { "course_name": ..., "course_audience": ..., "units": [...] } """ units = course_data["units"] final_results_ordered = [None] * len(units) futures = [] with ThreadPoolExecutor(max_workers=MAX_UNIT_WORKERS) as executor: for idx, unit in enumerate(units): future = executor.submit(process_unit, unit, course_data["course_name"]) futures.append((idx, future)) for idx, future in futures: final_results_ordered[idx] = future.result() output = { "course_name": course_data["course_name"], "course_audience": course_data["course_audience"], "results": final_results_ordered, } return output