ContiAI / agents /books /auto_units_structure.py
ziadsameh32's picture
Add login page
325b94c
Raw
History Blame Contribute Delete
2.72 kB
from modules import model, llm_g
import json
import re
from langchain_core.messages import SystemMessage, HumanMessage
def book_units_langchain_agent(
topic: str,
units_number: int,
notes: str | None = None,
course_description: str | None = None,
course_audience: str | None = None,
):
# ---------- Step 1 : Generate Markdown Outline ----------
llm = llm_g()
notes_block = ""
if notes:
notes_block = f"""
Additional author notes (optional guidance):
{notes}
Use these notes to guide the course structure but do NOT copy them literally.
"""
description_block = ""
if course_description:
description_block = f"""
Book description (guidance):
{course_description}
Use it to understand the theme and depth of the course.
Do NOT copy it literally in the output.
"""
audience_block = ""
if course_audience:
audience_block = f"""
Target audience (guidance):
{course_audience}
Use it to adapt the level and focus of the units.
"""
result = llm.call(
f"""
Create a structured outline for a professional course about [{topic}].
The course should contain exactly {units_number} units.
For each unit include:
- Unit title
- Learning outcome
- Main topics
{description_block}
{audience_block}
{notes_block}
Return the outline in Markdown.
Focus on logical learning progression.
"""
)
# ---------- Step 2 : System Prompt for JSON extraction ----------
system_prompt = f"""
Extract structured course data from the Markdown text.
Return JSON with EXACTLY this structure:
{{
"course_name": "{topic}",
"course_description": "string",
"course_audience": "string",
"learning_outcomes": [
"string"
],
"units": [
{{
"unit_name": "string",
"outcome": "string",
"topics": [
"string"
]
}}
]
}}
Rules:
- If course_description is missing, generate one
- If course_audience is missing, generate one
- Generate 4-6 topics per unit
- Units must equal {units_number}
- unit_name should look like: "الفصل الأول: ..."
- topics must be short educational titles
- Output ONLY valid JSON
- No markdown
- No explanations
"""
# ---------- Step 3 : Call Model ----------
llm_model = model()
response = llm_model.invoke(
[
SystemMessage(content=system_prompt),
HumanMessage(content=result),
]
)
raw_output = response.content.strip()
# ---------- Step 4 : Clean JSON ----------
try:
structured_data = json.loads(raw_output)
except json.JSONDecodeError:
cleaned = re.sub(r"```json|```", "", raw_output).strip()
structured_data = json.loads(cleaned)
return structured_data