Spaces:
Sleeping
Sleeping
| # 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 | |