zidea21 commited on
Commit
8ef892f
·
1 Parent(s): c523692

final-version

Browse files
agents/analysis_phase/objectives.py CHANGED
@@ -127,8 +127,6 @@ objectives_task = Task(
127
  "}\n"
128
  "The output must be valid JSON, without markdown formatting or code blocks."
129
  ),
130
- output_model=LearningObjectivesOutput,
131
  agent=objectives_generator,
132
- # context=[outline_task],
133
- human_input=False,
134
  )
 
127
  "}\n"
128
  "The output must be valid JSON, without markdown formatting or code blocks."
129
  ),
130
+ output_json=LearningObjectivesOutput,
131
  agent=objectives_generator,
 
 
132
  )
agents/final_outliners/__init__.py ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ from .unit_generator import unit_generation_task, unit_generator_agent
2
+ from .axis_generator import axis_generator_agent, axis_generation_task
agents/final_outliners/axis_generator.py ADDED
@@ -0,0 +1,198 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from crewai import Agent, Task, Crew, Process, LLM
2
+ import os
3
+ import json
4
+ from modules import output_dir, llm
5
+ from schemas import FullCurriculumStructure
6
+
7
+ axis_generator_agent = Agent(
8
+
9
+ role="Arabic Educational Subtopic Generator (Subtopic Developer)",
10
+
11
+ goal=(
12
+ "Analyze the provided metadata ({topic}, {domain}, {audience}, {content_type}, {material_type}) "
13
+ "along with the CurriculumStructure (main concept, related concepts, and units). "
14
+ # "Receive the output of the unit generator (which includes units titles and focuses). "
15
+ "For each unit — based on its title and focus — generate 5 coherent and progressive Arabic subtopics (axes). "
16
+ "These subtopics should represent a logical and educational flow from foundational understanding "
17
+ "to advanced application and creativity. "
18
+
19
+ # "Each axis should represent a specific stage of learning progression — starting from basic knowledge acquisition "
20
+ # "and moving toward critical thinking and creative application. "
21
+ "Each axis should correspond to a cognitive stage: remembering, understanding, applying, analyzing, evaluating, and creating. "
22
+
23
+ "Ensure that the axes are written as Arabic educational subheadings that align with the unit’s focus, "
24
+ "support conceptual growth, and maintain thematic coherence across the curriculum."
25
+ "Ensure all axes are contextually relevant to the unit's focus and contribute to the learner's comprehensive understanding."
26
+
27
+ "Additionally, before finalizing each axis, verify that it can be supported by available educational content such as articles, research papers, open educational resources, or online books. "
28
+ "Ensure that each axis represents a concept or topic that has sufficient publicly available Arabic or English educational materials that could be used for further learning content generation."
29
+
30
+ ),
31
+
32
+ backstory=(
33
+ "You are a senior Arabic curriculum designer and learning progression specialist. "
34
+ "You possess deep expertise in Arabic pedagogy and cognitive development frameworks such as Bloom’s Taxonomy. "
35
+ "You skillfully expand each educational unit into coherent Arabic subtopics (axes) that reflect a logical learning progression — "
36
+ "starting from basic understanding and moving toward higher-order thinking and creative application. "
37
+ "Each axis builds upon the previous one to form a cohesive and culturally relevant learning journey. "
38
+ "Your designs prioritize conceptual clarity, educational depth, and alignment with Arabic academic standards."
39
+ "You also ensure that each generated subtopic (axis) is research-backed and can be supported by credible educational materials available online, enabling later integration with content retrieval systems."
40
+
41
+ ),
42
+
43
+ output_format = (
44
+ "Return valid JSON strictly following this structure:\n"
45
+ "{\n"
46
+ " 'main_concept': '...',\n"
47
+ " 'related_concepts': ['...', '...'],\n"
48
+ " 'units': [\n"
49
+ " {\n"
50
+ " 'unit_number': 1,\n"
51
+ " 'title': 'الوحدة الأولى: ...',\n"
52
+ " 'focus': '...',\n"
53
+ " 'axes': [\n"
54
+ " {'axis_number': 1, 'title': '...', 'purpose': '...'},\n"
55
+ " {'axis_number': 2, 'title': '...', 'purpose': '...'},\n"
56
+ " {'axis_number': 3, 'title': '...', 'purpose': '...'},\n"
57
+ " {'axis_number': 4, 'title': '...', 'purpose': '...'},\n"
58
+ " {'axis_number': 5, 'title': '...', 'purpose': '...'}\n"
59
+ " ]\n"
60
+ " }, ...\n"
61
+ " ]\n"
62
+ "}"
63
+ ),
64
+
65
+ examples = [
66
+ {
67
+ "input": {
68
+ "main_concept": "التفكير التصميمي",
69
+ "related_concepts": ["حل المشكلات", "اتخاذ القرار", "الإبداع", "تحسين العمليات"],
70
+ "units": [
71
+ {
72
+ "unit_number": 1,
73
+ "title": "الوحدة الأولى: مدخل إلى التفكير التصميمي",
74
+ "focus": "فهم المفهوم الجوهري وأبعاده الفكرية والنظرية"
75
+ },
76
+ {
77
+ "unit_number": 2,
78
+ "title": "الوحدة الثانية: الأدوات والمجالات العملية لتطبيق التفكير التصميمي",
79
+ "focus": "تطبيق أدوات التفكير التصميمي في بيئات واقعية ومجالات مختلفة"
80
+ },
81
+ {
82
+ "unit_number": 3,
83
+ "title": "الوحدة الثالثة: التفكير التصميمي وحل المشكلات",
84
+ "focus": "توظيف التفكير التصميمي كمنهج فعال في معالجة التحديات وإيجاد حلول مبت��رة"
85
+ },
86
+ {
87
+ "unit_number": 4,
88
+ "title": "الوحدة الرابعة: التفكير التصميمي مدخل لتطوير مهارات اتخاذ القرار",
89
+ "focus": "استخدام التفكير التصميمي كأداة لتحسين جودة القرارات وتطوير مهارات المفكر التصميمي"
90
+ }
91
+ ]
92
+ },
93
+ "output": {
94
+ "units": [
95
+ {
96
+ "unit_number": 1,
97
+ "title": "الوحدة الأولى: مدخل إلى التفكير التصميمي",
98
+ "focus": "فهم المفهوم الجوهري وأبعاده الفكرية والنظرية",
99
+ "axes": [
100
+ {"axis_number": 1, "title": "ما هو التفكير التصميمي؟", "purpose": "تعريف المفهوم وشرح جوهره الفلسفي والعملي"},
101
+ {"axis_number": 2, "title": "أهمية التفكير التصميمي", "purpose": "إبراز الدور الحيوي للتفكير التصميمي في الإبداع والابتكار"},
102
+ {"axis_number": 3, "title": "المبادئ الأساسية للتفكير التصميمي", "purpose": "توضيح الأسس التي يقوم عليها النهج التصميمي"},
103
+ {"axis_number": 4, "title": "المراحل الخمس للتفكير التصميمي", "purpose": "شرح خطوات العملية التصميمية من التعاطف إلى الاختبار"},
104
+ {"axis_number": 5, "title": "نماذج تطبيقية ناجحة للتفكير التصميمي", "purpose": "عرض أمثلة عملية من مؤسسات استخدمت التفكير التصميمي بفعالية"}
105
+ ]
106
+ },
107
+ {
108
+ "unit_number": 2,
109
+ "title": "الوحدة الثانية: الأدوات والمجالات العملية لتطبيق التفكير التصميمي",
110
+ "focus": "تطبيق أدوات التفكير التصميمي في بيئات واقعية ومجالات مختلفة",
111
+ "axes": [
112
+ {"axis_number": 1, "title": "استخدامات التفكير التصميمي", "purpose": "توضيح المجالات التي يمكن تطبيق التفكير التصميمي فيها"},
113
+ {"axis_number": 2, "title": "ستة مجالات عملية يظهر فيها أثر التفكير التصميمي", "purpose": "عرض تطبيقات التفكير التصميمي في مجالات متنوعة"},
114
+ {"axis_number": 3, "title": "أدوات التفكير التصميمي", "purpose": "تعريف المتعلم بأهم الأدوات والوسائل المستخدمة في العملية التصميمية"},
115
+ {"axis_number": 4, "title": "عوامل يجب مراعاتها عند تنفيذ عملية التفكير التصميمي", "purpose": "توضيح الاعتبارات التي تضمن نجاح التطبيق"},
116
+ {"axis_number": 5, "title": "التحديات الشائعة في التفكير التصميمي", "purpose": "تحليل العقبات التي تواجه الفرق عند تطبيق هذا النهج"}
117
+ ]
118
+ },
119
+ {
120
+ "unit_number": 3,
121
+ "title": "الوحدة الثالثة: التفكير التصميمي وحل المشكلات",
122
+ "focus": "توظيف التفكير التصميمي كمنهج فعال في معالجة التحديات وإيجاد حلول مبتكرة",
123
+ "axes": [
124
+ {"axis_number": 1, "title": "ماذا يعني حل المشكلة؟", "purpose": "توضيح المفهوم النظري والعملي لحل المشكلات"},
125
+ {"axis_number": 2, "title": "أربع خطوات لحل المشكلة", "purpose": "شرح المراحل الأساسية في عملية حل المشكلات"},
126
+ {"axis_number": 3, "title": "الفرق بين التفكير التحليلي والتصميمي في حل المشكلات", "purpose": "المقارنة بين نهجين مختلفين في معالجة القضايا"},
127
+ {"axis_number": 4, "title": "نهج التفكير التصميمي لحل المشكلات", "purpose": "شرح كيفية استخدام التفكير التصميمي لإيجاد حلول مبتكرة"},
128
+ {"axis_number": 5, "title": "نماذج تطبيقية ناجحة في حل المشكلات بالتفك��ر التصميمي", "purpose": "تقديم دراسات حالة توضح نجاح النهج التصميمي في معالجة قضايا واقعية"}
129
+ ]
130
+ },
131
+ {
132
+ "unit_number": 4,
133
+ "title": "الوحدة الرابعة: التفكير التصميمي مدخل لتطوير مهارات اتخاذ القرار",
134
+ "focus": "استخدام التفكير التصميمي كأداة لتحسين جودة القرارات وتطوير مهارات المفكر التصميمي",
135
+ "axes": [
136
+ {"axis_number": 1, "title": "ما هو اتخاذ القرار؟", "purpose": "تعريف عملية اتخاذ القرار وعناصرها الأساسية"},
137
+ {"axis_number": 2, "title": "خصائص المفكر التصميمي ودوره في تحسين القرارات", "purpose": "توضيح السمات الشخصية والعقلية للمفكر التصميمي"},
138
+ {"axis_number": 3, "title": "العلاقة بين التفكير التصميمي واتخاذ القرار", "purpose": "شرح كيفية مساهمة النهج التصميمي في اتخاذ قرارات فعالة"},
139
+ {"axis_number": 4, "title": "سبع خطوات لعملية اتخاذ القرار باستخدام التفكير التصميمي", "purpose": "عرض مراحل متكاملة لاتخاذ القرار بأسلوب تصميمي"},
140
+ {"axis_number": 5, "title": "كيف انعكس التفكير التصميمي في قرارات ناجحة؟", "purpose": "عرض أمثلة واقعية لنجاحات عملية في قرارات اتخذت عبر التفكير التصميمي"}
141
+ ]
142
+ }
143
+ ]
144
+ }
145
+ }
146
+ ],
147
+
148
+ llm=llm,
149
+ # llm=llm_5m,
150
+ allow_delegation=False,
151
+ verbose=True,
152
+ reasoning=True,
153
+ max_iter=100
154
+ )
155
+
156
+ # ============================================================
157
+ # 🧩 3. Axis Generation Task
158
+ # ============================================================
159
+
160
+ axis_generation_task = Task(
161
+
162
+ description=(
163
+ "## GOAL\n"
164
+ "Expand each educational unit from the Unit Generator output into 5 structured Arabic subtopics (axes). "
165
+
166
+ # "Each axis should develop the learner’s understanding progressively — starting with remembering, "
167
+ # "then understanding, applying, analyzing, and finally creating.\n"
168
+ "Each axis should represent a cognitive development stage — moving from foundational understanding to applied mastery.\n\n"
169
+
170
+ "## CONTEXT\n"
171
+ # "You are provided with a units_agent_conceptual JSON (containing the main concept, related concepts, and list of units). "
172
+ "You are provided with a CurriculumStructure JSON (containing the main concept, related concepts, and list of units). "
173
+ "Each unit includes a title and conceptual focus.\n\n"
174
+ "## STEPS\n"
175
+ "1. Read the CurriculumStructure carefully to understand the hierarchy and conceptual logic.\n"
176
+ "2. For each unit:\n"
177
+ " - Identify its conceptual focus.\n"
178
+ " - Generate 5 progressive subtopics (axes) that unfold logically.\n"
179
+ " - Each axis must include:\n"
180
+ " • 'axis_number': numerical order from 1 to 5.\n"
181
+ " • 'title': Arabic title that feels like a subheading in a textbook.\n"
182
+ " • 'purpose': one-sentence explanation of the educational goal behind that subtopic.\n\n"
183
+
184
+ "3. For each generated axis, verify conceptually that it can be expanded using available online educational content (articles, academic papers, or open textbooks).\n"
185
+ " - Prefer subtopics that are well-established in educational or academic literature.\n"
186
+ " - Avoid overly niche or abstract titles that would lack sufficient learning resources.\n\n"
187
+
188
+ "## NOTES\n"
189
+ # "- Make sure the subtopics flow naturally, covering introduction, comprehension, practice, and innovation.\n"
190
+ "- The 5 axes should reflect a natural flow following Bloom’s taxonomy: Remember → Understand → Apply → Analyze → Create.\n"
191
+ "- Ensure the titles sound academic, culturally appropriate, and pedagogically progressive.\n"
192
+ "- Return the result as a valid FullCurriculumStructure JSON containing all units with their axes."
193
+ ),
194
+
195
+ expected_output="A FullCurriculumStructure JSON object containing all units and their respective 5 axes each.",
196
+ agent=axis_generator_agent,
197
+ output_json=FullCurriculumStructure,
198
+ )
agents/final_outliners/unit_generator.py ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from crewai import Agent, Task, Crew, Process, LLM
2
+ import os
3
+ import json
4
+ from modules import llm
5
+ from schemas import CurriculumStructure
6
+
7
+
8
+ unit_generator_agent = Agent(
9
+ role="Arabic Educational Unit Generator (Conceptual Curriculum Designer)",
10
+ goal=(
11
+ "Analyze the provided metadata ({topic}, {domain}, {audience}, {content_type}, {material_type}). "
12
+ "Understand the main concept and its related sub-concepts within the topic title. "
13
+ # "Generate 4 educational units that fully cover all the key aspects of the topic, "
14
+ "Design 4 coherent Arabic educational units that collectively cover the full conceptual scope of the topic. "
15
+ # "differentiate between the main and related concepts, and build meaningful learning flow. "
16
+ "Ensure that each unit builds upon the previous one — moving from conceptual understanding "
17
+ "to deeper analysis, differentiation, and application."
18
+ "Additionally, verify that each generated unit represents a concept or learning area that can be supported "
19
+ "by available educational materials such as online articles, academic papers, open courses, or textbooks. "
20
+ "Each unit should correspond to a topic that has sufficient real-world educational content, "
21
+ "so it can later be expanded into detailed axes and linked with web-based learning resources."
22
+ ),
23
+ backstory=(
24
+ # "You are an expert Arabic curriculum designer who understands how to transform conceptual topics "
25
+ # "into coherent learning structures. You design units that reflect deep comprehension of the main topic "
26
+ # "and its related ideas, ensuring logical flow from foundational understanding to practical application. "
27
+ # "You write unit titles in Arabic that sound like chapters of a book, ready to be expanded later into subtopics."
28
+ "You are an expert Arabic curriculum designer specializing in conceptual and competency-based education. "
29
+ "You transform topics into structured learning journeys that reflect progressive understanding — "
30
+ "starting from foundational ideas and moving toward advanced, practical, or reflective application. "
31
+ "Your writing style for unit titles follows the elegance of Arabic academic chapters, "
32
+ "while maintaining clarity and purpose. Each unit’s focus must capture the essential learning outcomes "
33
+ "and intellectual goals of that section."
34
+ "You also ensure that each generated unit can be reinforced by real and accessible educational materials — "
35
+ "such as books, articles, or open educational resources — enabling future integration with automated content retrieval and enrichment systems."
36
+ ),
37
+ output_format=(
38
+ "Return **valid JSON** matching the following structure:\n"
39
+ "{\n"
40
+ " 'main_concept': '...',\n"
41
+ " 'related_concepts': ['...', '...'],\n"
42
+ " 'units': [\n"
43
+ " {'unit_number': 1, 'title': 'الوحدة الأولى: ...', 'focus': '...'},\n"
44
+ " {'unit_number': 2, 'title': 'الوحدة الثانية: ...', 'focus': '...'},\n"
45
+ " {'unit_number': 3, 'title': 'الوحدة الثالثة: ...', 'focus': '...'},\n"
46
+ " {'unit_number': 4, 'title': 'الوحدة الرابعة: ...', 'focus': '...'}\n"
47
+ " ]\n"
48
+ "}"
49
+ ),
50
+ examples=[
51
+ {
52
+ "input": {
53
+ "topic": "تقنيات التفكير التصميمي (Design Thinking) لحل المشكلات واتخاذ القرارات",
54
+ "domain": "الإدارة والتفكير الإبداعي",
55
+ "content_type": "تدريبي",
56
+ "audience": "القادة والمدربون والموظفون الإداريون",
57
+ "material_type": ["مفاهمية", "هيكلية", "إجرائية", "واقعية", "إبداعية"],
58
+ },
59
+ "output": {
60
+ "main_concept": "التفكير التصميمي",
61
+ "related_concepts": [
62
+ "حل المشكلات",
63
+ "اتخاذ القرار",
64
+ "الإبداع",
65
+ "تحسين العمليات",
66
+ ],
67
+ "units": [
68
+ {
69
+ "unit_number": 1,
70
+ "title": "الوحدة الأولى: مدخل إلى التفكير التصميمي وفلسفته",
71
+ "focus": "فهم الأسس الفكرية والنظرية للتفكير التصميمي وموقعه ضمن أنماط التفكير الإبداعي.",
72
+ },
73
+ {
74
+ "unit_number": 2,
75
+ "title": "الوحدة الثانية: مراحل وأدوات تطبيق التفكير التصميمي",
76
+ "focus": "تعلّم الخطوات العملية وأهم الأدوات المنهجية لتطبيق التفكير التصميمي في المواقف الواقعية.",
77
+ },
78
+ {
79
+ "unit_number": 3,
80
+ "title": "الوحدة الثالثة: التفكير التصميمي كأداة لحل المشكلات المعقدة",
81
+ "focus": "تحليل العلاقة بين التفكير التصميمي والتفكير التحليلي عند التعامل مع القضايا التنظيمية والمهنية.",
82
+ },
83
+ {
84
+ "unit_number": 4,
85
+ "title": "الوحدة الرابعة: التفكير التصميمي كمدخل لاتخاذ القرارات الإبداعية",
86
+ "focus": "تطبيق التفكير التصميمي في اتخاذ قرارات استراتيجية مبتكرة وتحسين العمليات المؤسسية.",
87
+ },
88
+ ],
89
+ },
90
+ }
91
+ ],
92
+ llm=llm,
93
+ # llm=llm_5m,
94
+ allow_delegation=False,
95
+ reasoning=True,
96
+ max_iter=100,
97
+ verbose=True,
98
+ )
99
+
100
+
101
+ # ============================================================
102
+ # 🧠 4. Task Definition
103
+ # ============================================================
104
+
105
+ unit_generation_task = Task(
106
+ description=(
107
+ "## GOAL\n"
108
+ "Generate **4 comprehensive and logically structured Arabic educational units** that summarize all key aspects of the topic: {topic}.\n\n"
109
+ "## STEPS\n"
110
+ "1. Extract the **main concept** and its **related sub-concepts** from the topic title.\n"
111
+ "2. Divide the topic into **4 major units** that together form a complete conceptual narrative.\n"
112
+ "3. Ensure the units are **progressive** — starting from foundational understanding and moving toward practical or reflective application.\n"
113
+ "4. Phrase each unit title like an **Arabic book chapter**, clear, formal, and pedagogically meaningful.\n"
114
+ "5. Write each unit’s focus as a **short, outcome-oriented summary** describing the main skills, ideas, or insights learners will gain.\n\n"
115
+ "6. Ensure that each proposed unit corresponds to a topic that can be supported by available educational content on the web, "
116
+ "including Arabic or English articles, research papers, or learning materials. "
117
+ "Prefer units that align with well-documented or widely discussed educational themes.\n\n"
118
+ "## NOTE\n"
119
+ "- Each unit should represent a major conceptual pillar essential for fully understanding the topic.\n"
120
+ "- Titles should be phrased like Arabic book chapters, preparing readers for deeper exploration through future subtopics.\n"
121
+ "- Avoid overlap or repetition between units; instead, show logical and conceptual progression.\n"
122
+ "- Maintain an academic yet clear tone — precise, structured, and free from unnecessary jargon.\n"
123
+ ),
124
+ expected_output="A `CurriculumStructure` JSON object containing: `main_concept`, `related_concepts`, and `units`.",
125
+ agent=unit_generator_agent,
126
+ output_json=CurriculumStructure,
127
+ )
app.py CHANGED
@@ -1,4 +1,8 @@
1
  import os
 
 
 
 
2
 
3
  # Force HOME to /tmp so CrewAI doesn't try writing to /.local
4
  os.environ["HOME"] = "/tmp"
@@ -11,47 +15,12 @@ os.makedirs("/tmp/.local/share", exist_ok=True)
11
  os.makedirs("/tmp/crewai_data", exist_ok=True)
12
  os.makedirs("/tmp/crewai_home", exist_ok=True)
13
 
14
- from crewai import Crew, Process
15
-
16
- import json
17
- from fastapi import FastAPI
18
- from agents.outliner_phase import (
19
- research_agent,
20
- research_task,
21
- structure_agent,
22
- structure_task,
23
- design_task,
24
- designer_agent,
25
- review_agent,
26
- review_task,
27
- )
28
- from agents.analysis_phase import (
29
- outline_agent,
30
- outline_task,
31
- objectives_generator,
32
- objectives_task,
33
- outcomes_generator,
34
- outcomes_task,
35
- )
36
- from modules import (
37
- llm,
38
- inputs,
39
- # outlines,
40
- # objectives,
41
- init_firebase,
42
- get_realtime_db,
43
- get_firestore_db,
44
- )
45
-
46
- from schemas import OutlineInput, DNAMetadata, LearningObjectivesOutput, CurriculumOutline
47
-
48
 
49
  app = FastAPI(title="AI Agent Project", version="1.0.0")
50
 
51
- # Firebase
52
- init_firebase()
53
- realtime_db = get_realtime_db()
54
- firestore_db = get_firestore_db()
55
 
56
 
57
  # Example root endpoint
@@ -60,130 +29,11 @@ def read_root():
60
  return {"message": "Welcome to AI Agent Project API 🚀"}
61
 
62
 
63
- # -----------------------------------------------
64
- # === Agent 1: Deep Semantic Topics Generator ===
65
- # === Agent 2: Expander to 20 Topics ===
66
- # === Agent 3: Module Organizer ===
67
- # === Agent 4: Final Reviewer (اختياري) ===
68
- # -----------------------------------------------
69
- @app.post("/run_outliner_agents")
70
- def run_outliner_agents(data: OutlineInput):
71
- outline_crew = Crew(
72
- agents=[research_agent, structure_agent, designer_agent, review_agent],
73
- tasks=[research_task, structure_task, design_task, review_task],
74
- process=Process.sequential,
75
- )
76
-
77
- inputs=data.dict()
78
- user_inputs = DNAMetadata(
79
- topic=inputs["topic"],
80
- domain=inputs["domain"],
81
- content_type=inputs["content_type"],
82
- audience=inputs["audience"],
83
- material_type=inputs["material_type"],
84
- ).dict()
85
-
86
- result = outline_crew.kickoff(inputs=user_inputs)
87
-
88
- print(result.json_dict)
89
- return {"message": "Deep Semantic Topics Generator works well 🚀","result":result}
90
-
91
-
92
- # ------------------------------------
93
- # === Agent 5:Objectives Generator ===
94
- # ------------------------------------
95
-
96
-
97
- @app.post("/objectives")
98
- def run_objectives(data: OutlineInput, outlines: CurriculumOutline):
99
- objectives_crew = Crew(
100
- agents=[objectives_generator],
101
- tasks=[objectives_task],
102
- process=Process.sequential,
103
- )
104
- inputs = data.dict()
105
- user_inputs = DNAMetadata(
106
- topic=inputs["topic"],
107
- domain=inputs["domain"],
108
- content_type=inputs["content_type"],
109
- audience=inputs["audience"],
110
- material_type=inputs["material_type"],
111
- ).dict()
112
- merged_inputs = {**user_inputs, "outlines": outlines.dict()}
113
-
114
- result = objectives_crew.kickoff(inputs=merged_inputs)
115
-
116
- print(result.json_dict)
117
-
118
- return {"message": "Objectives Generated Well 🚀","result":result}
119
-
120
-
121
- # ------------------------------------
122
- # === Agent 6:Outcomes Generator ===
123
- # ------------------------------------
124
-
125
-
126
- @app.post("/outcomes")
127
- def run_outcomes(
128
- data: OutlineInput, objectives: LearningObjectivesOutput):
129
- outcomes_crew = Crew(
130
- agents=[outcomes_generator],
131
- tasks=[outcomes_task],
132
- process=Process.sequential,
133
- )
134
-
135
- inputs = data.dict()
136
- user_inputs = DNAMetadata(
137
- topic=inputs["topic"],
138
- domain=inputs["domain"],
139
- content_type=inputs["content_type"],
140
- audience=inputs["audience"],
141
- material_type=inputs["material_type"],
142
- ).dict()
143
- merged_inputs = {**user_inputs, "objectives": objectives.dict()}
144
-
145
- result = outcomes_crew.kickoff(inputs=merged_inputs)
146
- print(result.json_dict)
147
-
148
- return {"message": "Outcomes Generated Well 🚀", "result": result}
149
-
150
-
151
- ###########################################################
152
-
153
- # ------------------------------------
154
- # === Agent 7:Outcomes Generator ===
155
- # ------------------------------------
156
-
157
-
158
- @app.get("/training")
159
- def run_training(data: OutlineInput, objectives: LearningObjectivesOutput):
160
- training_crew = Crew(
161
- agents=[outcomes_generator],
162
- tasks=[outcomes_task],
163
- process=Process.sequential,
164
- )
165
-
166
- inputs = data.dict()
167
- user_inputs = DNAMetadata(
168
- topic=inputs["topic"],
169
- domain=inputs["domain"],
170
- content_type=inputs["content_type"],
171
- audience=inputs["audience"],
172
- material_type=inputs["material_type"],
173
- ).dict()
174
-
175
- merged_inputs = {**user_inputs, "objectives": objectives.dict()}
176
- result = training_crew.kickoff(inputs=merged_inputs)
177
- print(result.json_dict)
178
-
179
- return {"message": "Outcomes Generated Well 🚀", "result": result}
180
-
181
-
182
  # ------------------------
183
  # ✅ نقطة تشغيل السيرفر
184
  # ------------------------
185
 
186
- if __name__ == "__main__":
187
- import uvicorn
188
 
189
- uvicorn.run("main:app", host="127.0.0.1", port=8000, reload=True)
 
1
  import os
2
+ from crewai import Crew, Process
3
+ import json
4
+ from fastapi import FastAPI
5
+ from routers import objective_route, outliner_route, outcome_route
6
 
7
  # Force HOME to /tmp so CrewAI doesn't try writing to /.local
8
  os.environ["HOME"] = "/tmp"
 
15
  os.makedirs("/tmp/crewai_data", exist_ok=True)
16
  os.makedirs("/tmp/crewai_home", exist_ok=True)
17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
19
  app = FastAPI(title="AI Agent Project", version="1.0.0")
20
 
21
+ app.include_router(outliner_route.router)
22
+ app.include_router(objective_route.router)
23
+ app.include_router(outcome_route.router)
 
24
 
25
 
26
  # Example root endpoint
 
29
  return {"message": "Welcome to AI Agent Project API 🚀"}
30
 
31
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  # ------------------------
33
  # ✅ نقطة تشغيل السيرفر
34
  # ------------------------
35
 
36
+ # if __name__ == "__main__":
37
+ # import uvicorn
38
 
39
+ # uvicorn.run("main:app", host="127.0.0.1", port=8000, reload=True)
modules/__init__.py CHANGED
@@ -15,5 +15,3 @@ from .directory import (
15
  scraper_dir,
16
  urls_dir
17
  )
18
-
19
- from .firebase_config import init_firebase, get_realtime_db, get_firestore_db
 
15
  scraper_dir,
16
  urls_dir
17
  )
 
 
modules/firebase_config.py DELETED
@@ -1,44 +0,0 @@
1
- import os
2
- import json
3
- import firebase_admin
4
- from firebase_admin import credentials, db, firestore
5
-
6
-
7
- def init_firebase():
8
- """
9
- Initializes Firebase with credentials and database URL.
10
- Works both locally (with firebase_credentials.json) and on Hugging Face Spaces (with FIREBASE_CREDENTIALS env variable).
11
- """
12
- try:
13
- if not firebase_admin._apps:
14
- # لو شغال على Hugging Face Space – اقرأ من المتغير السري
15
- firebase_json_str = os.getenv("FIREBASE_CREDENTIALS")
16
-
17
- if firebase_json_str:
18
- firebase_credentials = json.loads(firebase_json_str)
19
- cred = credentials.Certificate(firebase_credentials)
20
- else:
21
- # لو شغال محليًا – اقرأ من الملف
22
- cred = credentials.Certificate("modules/firebase_credentials.json")
23
-
24
- firebase_admin.initialize_app(
25
- cred,
26
- {"databaseURL": "https://contiai-cfbff-default-rtdb.firebaseio.com/"},
27
- )
28
- print("✅ Firebase initialized successfully.")
29
- except Exception as e:
30
- print(f"❌ Error initializing Firebase: {e}")
31
-
32
-
33
- def get_realtime_db():
34
- """
35
- Returns a reference to the Firebase Realtime Database.
36
- """
37
- return db.reference("/")
38
-
39
-
40
- def get_firestore_db():
41
- """
42
- Returns a reference to the Firestore client.
43
- """
44
- return firestore.client()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
modules/firebase_credentials.json DELETED
@@ -1,13 +0,0 @@
1
- {
2
- "type": "service_account",
3
- "project_id": "contiai-cfbff",
4
- "private_key_id": "586ff713c2ed3a1d61228378d01cc0bd6f4519ee",
5
- "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC1zGqYIBTS5qM+\nAge3H5FRNwbCVPDCVdDvm44GuIdaQ5SrTQuk/D9PV5L6W0FkMXVhrL/ihU6DxfFw\nx+q8pYGvesdqbbn3wCsgSz0C4aUeMroAKeNYUQgYo6mohAstSswYMk8szfP/NHey\n4RcBASbU4b5+yEFBhWEihBi41wLoXkgS04OVIfGKVJD+tcdE/iKxQtsbA3M/LfHX\nCmpm/2/20l/ONhysXOdXDjR3jKxNTTbVuSE1vL5nYhlPejEFr8ROheo0HpdmDxR7\n2Qiblc4x7sll3KvRfbWnObBsUQU3TL5c//oYdJyeSQWWMNPVA2chPkJbEa8IxkLS\nbCvjd4ylAgMBAAECggEAC3eTLawWxCrKFzCXl5eewFAUb0ORhobuzX5MjUrGA6dW\narh9+70kqfa5jZ/qvJm/o3z7AxwqrkMl2vN+CfVcL1szCUwi7WhD3OvOzS5TqCQs\nLIB35Guc2bkEPyqwOpe7zrbo3MgGeo17rPia5w3q8VIzHg1RmGlqWnv/xAD3IC/F\nV00RMKWr8n/6rVt1G/dnsHAQUYcxPxta6AlcqaKt4FPNVp3Jy4tEysYCNROckiQm\nkzWs19/e+c5DUZwTq4L3mHrOt1HA+0TNUqALn7MYXkq4+QZ7BsLzPuz7MgcO2PHg\njSXk7L9km+iSGE7MrQ67hpSvvxrb4wWsytpLyxEiLQKBgQDpO7xSvQ7XCwp3pByk\n91WE0+/LDbKdOyCke7EpJYCn2LxV0Mtg64uT9DbhvpB+G5MtTT+S7VNCCxYkD/wG\ng5SjoLkqG35GZRtfzM8s5oxmP9flUPSTpGxTPTFQ4v2+hGJbcHW0enzCHi4Affxe\nYOKXZ2uDy3S+2czKoInDLICJbwKBgQDHi2BVyJOH+eZocMXK7uN7gQRK2PEx+Tbh\nUSBPy/u77fmlnXUDSOhkUJJ449nOpDmXIP08vRDc7VSx0Nba5/OGIJPv+9zAnB77\nYS8ZV4FFR2V/vGhSA8Arw4ez+0hlmd0tZDU6K4qzd3+tol+5Gcx6blG6IJ/cm+vk\n1ZSpQkV5KwKBgAqhUV0IBuQgObLoRPHz3+705eoATtLBviQhCxsP/YQo6bSTlqFt\nOuhcah/x2o4U3alj6vDcZj4NWU39eIQnfR/UFHxp0mCM/SlpoUuvmliSslleTjdo\neBN3J4dDQUNsrzrxrjuylXsXewtEsrrueYVjDlBsdn64WJAnrv+5SIZ7AoGABhoI\n9BaSDFJj7UWlhrMPWbN0QiWoGnMYboNgjZAbPn/kZmAON+9+y7J7CB9PhbYX3Lsx\ngy302gyXzmgoacE1/R/55hi5g1pCyEUMf6XhWhD41ZMZTYi3057DA4nniNPPo5ew\n2PqD30EEMncInkxfqE6/SQW+XayW5gRx60sPfMkCgYANJV3w6Torl/6gGhcTdK81\nm7UNSQ5TOWGoyknGJlV2dnPXQH+l9doPdqGu/TZdtp7uhNJRxRyOZxq6iI+vvyPP\nt+ZWbB4x1qR2lsUI/3vCDtNpdsanoYFglIJpNSkSgs+dILy4CulUhsCPnT/y7QTp\nGDRfPtyjdtOQSZLlwljUEQ==\n-----END PRIVATE KEY-----\n",
6
- "client_email": "firebase-adminsdk-fbsvc@contiai-cfbff.iam.gserviceaccount.com",
7
- "client_id": "105916337677880596734",
8
- "auth_uri": "https://accounts.google.com/o/oauth2/auth",
9
- "token_uri": "https://oauth2.googleapis.com/token",
10
- "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
11
- "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-fbsvc%40contiai-cfbff.iam.gserviceaccount.com",
12
- "universe_domain": "googleapis.com"
13
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
requirements.txt CHANGED
@@ -8,4 +8,4 @@ langchain_openai
8
  litellm
9
  openai
10
  fastapi
11
- firebase-admin
 
8
  litellm
9
  openai
10
  fastapi
11
+ crewai[anthropic]
routers/objective_route.py ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from crewai import Crew, Process
3
+ import json
4
+ from fastapi import APIRouter, HTTPException, Depends
5
+ from agents.analysis_phase import (
6
+ objectives_generator,
7
+ objectives_task,
8
+ )
9
+ from modules import (
10
+ llm,
11
+ inputs,
12
+ )
13
+ from schemas import (
14
+ CurriculumStructure,
15
+ DNAMetadata,
16
+ OutlineInput,
17
+ )
18
+
19
+
20
+ router = APIRouter(prefix="/analysis", tags=["Objectives"])
21
+
22
+
23
+ # ------------------------------------
24
+ # === Agent 5:Objectives Generator ===
25
+ # ------------------------------------
26
+
27
+
28
+ @router.post("/objectives")
29
+ def run_objectives(data: OutlineInput, outlines: CurriculumStructure):
30
+ objectives_crew = Crew(
31
+ agents=[objectives_generator],
32
+ tasks=[objectives_task],
33
+ process=Process.sequential,
34
+ )
35
+ inputs = data.dict()
36
+ user_inputs = DNAMetadata(
37
+ topic=inputs["topic"],
38
+ domain=inputs["domain"],
39
+ content_type=inputs["content_type"],
40
+ audience=inputs["audience"],
41
+ material_type=inputs["material_type"],
42
+ ).dict()
43
+ merged_inputs = {**user_inputs, "outlines": outlines.dict()}
44
+
45
+ result = objectives_crew.kickoff(inputs=merged_inputs)
46
+
47
+ print(result.json_dict)
48
+
49
+ return {"message": "Objectives Generated Well 🚀", "result": result}
routers/outcome_route.py ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from crewai import Crew, Process
3
+ import json
4
+ from fastapi import APIRouter, HTTPException, Depends
5
+ from agents.analysis_phase import (
6
+ outcomes_generator,
7
+ outcomes_task,
8
+ )
9
+ from modules import (
10
+ llm,
11
+ inputs,
12
+ )
13
+ from schemas import (
14
+ LearningObjectivesOutput,
15
+ DNAMetadata,
16
+ OutlineInput,
17
+ )
18
+
19
+
20
+ router = APIRouter(prefix="/analysis", tags=["outcomes"])
21
+
22
+
23
+ # ------------------------------------
24
+ # === Agent 6:Outcomes Generator ===
25
+ # ------------------------------------
26
+
27
+
28
+ @router.post("/outcomes")
29
+ def run_outcomes(data: OutlineInput, objectives: LearningObjectivesOutput):
30
+ outcomes_crew = Crew(
31
+ agents=[outcomes_generator],
32
+ tasks=[outcomes_task],
33
+ process=Process.sequential,
34
+ )
35
+
36
+ inputs = data.dict()
37
+ user_inputs = DNAMetadata(
38
+ topic=inputs["topic"],
39
+ domain=inputs["domain"],
40
+ content_type=inputs["content_type"],
41
+ audience=inputs["audience"],
42
+ material_type=inputs["material_type"],
43
+ ).dict()
44
+ merged_inputs = {**user_inputs, "objectives": objectives.dict()}
45
+
46
+ result = outcomes_crew.kickoff(inputs=merged_inputs)
47
+ print(result.json_dict)
48
+
49
+ return {"message": "Outcomes Generated Well 🚀", "result": result}
routers/outliner_route.py ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from crewai import Crew, Process
3
+ import json
4
+ from fastapi import APIRouter, HTTPException, Depends
5
+ from agents.final_outliners import (
6
+ unit_generator_agent,
7
+ unit_generation_task,
8
+ axis_generator_agent,
9
+ axis_generation_task,
10
+ )
11
+ from modules import (
12
+ llm,
13
+ inputs,
14
+ )
15
+ from schemas import (
16
+ CurriculumStructure,
17
+ DNAMetadata,
18
+ OutlineInput,
19
+ )
20
+
21
+ router = APIRouter(prefix="/outliner", tags=["Authentication"])
22
+
23
+
24
+ # === Agent 1: Deep Semantic Topics Generator ===
25
+ # === Agent 2: Expander to 20 Topics ===
26
+ # === Agent 3: Module Organizer ===
27
+ # === Agent 4: Final Reviewer (اختياري) ===
28
+ # -----------------------------------------------
29
+ @router.post("/run_outliner_agents")
30
+ def run_outliner_agents(data: OutlineInput):
31
+ outline_crew = Crew(
32
+ agents=[
33
+ unit_generator_agent,
34
+ axis_generator_agent,
35
+ ],
36
+ tasks=[
37
+ unit_generation_task,
38
+ axis_generation_task,
39
+ ],
40
+ process=Process.sequential,
41
+ )
42
+
43
+ inputs = data.dict()
44
+ user_inputs = DNAMetadata(
45
+ topic=inputs["topic"],
46
+ domain=inputs["domain"],
47
+ content_type=inputs["content_type"],
48
+ audience=inputs["audience"],
49
+ material_type=inputs["material_type"],
50
+ ).dict()
51
+
52
+ result = outline_crew.kickoff(inputs=user_inputs)
53
+
54
+ print(result.json_dict)
55
+ return {"message": "Deep Semantic Topics Generator works well 🚀", "result": result}
routers/training_route.py ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from crewai import Crew, Process
3
+ import json
4
+ from fastapi import APIRouter, HTTPException, Depends
5
+ from agents.analysis_phase import (
6
+ training_agent,
7
+ training_task,
8
+ )
9
+ from modules import (
10
+ llm,
11
+ inputs,
12
+ )
13
+ from schemas import (
14
+ LearningObjectivesOutput,
15
+ DNAMetadata,
16
+ OutlineInput,
17
+ )
18
+
19
+
20
+ router = APIRouter(prefix="/analysis", tags=["training"])
21
+
22
+ # ------------------------------------
23
+ # === Agent 7:Training Generator ===
24
+ # ------------------------------------
25
+
26
+
27
+ @app.get("/training")
28
+ def run_training(data: OutlineInput, objectives: LearningObjectivesOutput):
29
+ training_crew = Crew(
30
+ agents=[training_agent],
31
+ tasks=[training_task],
32
+ process=Process.sequential,
33
+ )
34
+
35
+ inputs = data.dict()
36
+ user_inputs = DNAMetadata(
37
+ topic=inputs["topic"],
38
+ domain=inputs["domain"],
39
+ content_type=inputs["content_type"],
40
+ audience=inputs["audience"],
41
+ material_type=inputs["material_type"],
42
+ ).dict()
43
+
44
+ merged_inputs = {**user_inputs, "objectives": objectives.dict()}
45
+ result = training_crew.kickoff(inputs=merged_inputs)
46
+ print(result.json_dict)
47
+
48
+ return {"message": "Outcomes Generated Well 🚀", "result": result}
schemas/__init__.py CHANGED
@@ -4,7 +4,14 @@ from .extractor_schema import AllPartsOfContent, SinglePartOfContent, Section
4
  from .keywoard_schema import SuggestedSearchQueries
5
  from .objectives_schema import LearningObjectivesOutput
6
  from .outcomes_schema import BloomOutcomesOutput
7
- from .outliner_schema import CurriculumOutline, Unit, DeepSemanticTopicsOutput,ExpandedTopicsList
 
 
 
 
 
 
 
8
  from .source_schema import AllResults, SingleResult
9
  from .training_schema import TrainingProgramOutput
10
  from .inputs_schema import OutlineInput
 
4
  from .keywoard_schema import SuggestedSearchQueries
5
  from .objectives_schema import LearningObjectivesOutput
6
  from .outcomes_schema import BloomOutcomesOutput
7
+ from .outliner_schema import (
8
+ CurriculumOutline,
9
+ Unit,
10
+ DeepSemanticTopicsOutput,
11
+ ExpandedTopicsList,
12
+ CurriculumStructure,
13
+ FullCurriculumStructure,
14
+ )
15
  from .source_schema import AllResults, SingleResult
16
  from .training_schema import TrainingProgramOutput
17
  from .inputs_schema import OutlineInput
schemas/outliner_schema.py CHANGED
@@ -1,7 +1,225 @@
1
  from pydantic import BaseModel, Field
2
  from typing import List, Dict, Literal, Optional
 
3
 
 
4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  # ========= 2. Schema for Units =========
6
  class Unit(BaseModel):
7
  module_title: str = Field(
 
1
  from pydantic import BaseModel, Field
2
  from typing import List, Dict, Literal, Optional
3
+ from .dna_schema import DNAMetadata
4
 
5
+ ################==NEW==################
6
 
7
+ # Unit Generator Schema #
8
+ class Unit(BaseModel):
9
+ """
10
+ Represents a single instructional unit within a curriculum.
11
+
12
+ Each unit is a focused section of the overall curriculum,
13
+ designed to teach a specific set of concepts or skills.
14
+ """
15
+
16
+ unit_number: int = Field(
17
+ ...,
18
+ title="The sequential number of this unit within the overall curriculum (e.g., 1, 2, 3).",
19
+ )
20
+ title: str = Field(
21
+ ...,
22
+ title="Unit Title",
23
+ description="The Arabic title or name of the educational unit, clearly representing its theme or purpose.",
24
+ )
25
+
26
+ # focus: str = Field(..., title="Unit Focus", description="Brief note on what this unit emphasizes conceptually")
27
+ focus: str = Field(
28
+ ...,
29
+ title="Unit Focus",
30
+ description=(
31
+ "A concise overview highlighting the main concepts, skills, and learning outcomes "
32
+ "covered in this unit. It describes what learners should understand or achieve after completing it."
33
+ "It sets the intellectual direction for the included axes."
34
+ ),
35
+ )
36
+
37
+
38
+ class CurriculumStructure(BaseModel):
39
+ """
40
+ Represents the full structure of a curriculum for a specific topic or program.
41
+
42
+ This model combines both conceptual metadata (via DNAMetadata) and pedagogical structure (via Unit).
43
+ It provides all the necessary contextual and educational information the AI agent or system
44
+ needs to generate, evaluate, or organize learning content effectively.
45
+ """
46
+
47
+ # topic: str
48
+ # domain: str
49
+ # audience: str
50
+ # content_type: str
51
+ # material_type: List[str]
52
+
53
+ Metadata: List["DNAMetadata"] = Field(
54
+ ...,
55
+ title="List of DNA Metadata Objects",
56
+ description=(
57
+ "A list of DNAMetadata items, where each item represents a distinct topic or concept "
58
+ "along with its domain, audience, content type, and material nature.\n"
59
+ "This allows the agent to process multiple curriculum components or educational segments "
60
+ "within a single structured input."
61
+ ),
62
+ )
63
+
64
+ main_concept: str = Field(
65
+ ...,
66
+ title="Main Concept",
67
+ description=(
68
+ "The central or core idea around which the curriculum is built. "
69
+ "It defines the overarching theme that connects all units and topics together."
70
+ ),
71
+ )
72
+
73
+ related_concepts: List[str] = Field(
74
+ ...,
75
+ title="Related Concepts",
76
+ description=(
77
+ "A set of secondary or supporting ideas that complement or expand upon the main concept. "
78
+ "These help the agent establish conceptual links and subtopics within the curriculum."
79
+ ),
80
+ )
81
+
82
+ units: List[Unit] = Field(
83
+ ...,
84
+ title="Curriculum Units",
85
+ description=(
86
+ "A detailed list of instructional units included in this curriculum. "
87
+ "Each unit includes its number, title, and conceptual focus to define its role "
88
+ "within the overall learning journey."
89
+ ),
90
+ )
91
+
92
+
93
+ # Axis Generator Schema #
94
+ class Axis(BaseModel):
95
+ """
96
+ Represents a single 'axis' or subtopic within an educational unit.
97
+
98
+ Each axis embodies a progressive learning step that moves from
99
+ basic understanding toward higher-order thinking such as
100
+ application, analysis, or creative synthesis.
101
+ """
102
+
103
+ axis_number: int = Field(
104
+ ...,
105
+ title="Axis Number",
106
+ description="The sequential order of this axis within the unit (1 to 5).",
107
+ )
108
+
109
+ title: str = Field(
110
+ ...,
111
+ title="Axis Title",
112
+ description=(
113
+ "The Arabic title of the subtopic or 'axis' inside the unit. "
114
+ "Each axis defines a distinct conceptual or cognitive step "
115
+ "that contributes to the overall unit progression."
116
+ ),
117
+ )
118
+
119
+ purpose: str = Field(
120
+ ...,
121
+ title="Axis Purpose",
122
+ description=(
123
+ "A concise statement describing the educational intent of this axis — "
124
+ "what learners should achieve cognitively (e.g., understanding, applying, analyzing, creating)."
125
+ ),
126
+ )
127
+
128
+
129
+ ############################################################################################################
130
+ class UnitWithAxes(BaseModel):
131
+ """
132
+ Represents a curriculum unit that contains multiple learning axes.
133
+
134
+ Each unit defines a coherent topic focus and consists of five axes,
135
+ each representing a structured subtopic or cognitive level that guides
136
+ the learner progressively from comprehension to advanced application.
137
+ """
138
+
139
+ unit_number: int = Field(
140
+ ...,
141
+ title="The sequential number of this unit within the overall curriculum (e.g., 1, 2, 3).",
142
+ )
143
+
144
+ title: str = Field(
145
+ ...,
146
+ title="Unit Title",
147
+ description="The Arabic title or name of the educational unit, clearly representing its theme or purpose.",
148
+ )
149
+
150
+ # focus: str = Field(..., title="Unit Focus", description="Brief note on what this unit emphasizes conceptually")
151
+ focus: str = Field(
152
+ ...,
153
+ title="Unit Focus",
154
+ description=(
155
+ "A concise overview highlighting the main concepts, skills, and learning outcomes "
156
+ "covered in this unit. It describes what learners should understand or achieve after completing it."
157
+ "It sets the intellectual direction for the included axes."
158
+ ),
159
+ )
160
+
161
+ axes: List[Axis] = Field(
162
+ ...,
163
+ title="Unit Axes",
164
+ description=(
165
+ "A list of five(5) coherent Arabic subtopics (axes) that make up the unit. "
166
+ "Each axis represents a progressive cognitive step — from foundational understanding "
167
+ "to creative synthesis — ensuring a balanced learning journey."
168
+ ),
169
+ )
170
+
171
+
172
+ ############################################################################################################
173
+ class FullCurriculumStructure(BaseModel):
174
+ """
175
+ Represents the complete process of axis generation for an educational curriculum.
176
+
177
+ This model integrates educational metadata (via DNAMetadata), the conceptual hierarchy
178
+ (main and related concepts), and the pedagogical structure (units and axes).
179
+ It serves as the core structure for AI-driven generation, evaluation, and organization
180
+ of educational axes aligned with learner needs and content goals.
181
+ """
182
+
183
+ Metadata: List["DNAMetadata"] = Field(
184
+ ...,
185
+ title="List of DNA Metadata Objects",
186
+ description=(
187
+ "A list of DNAMetadata items, where each item represents a distinct topic or concept "
188
+ "along with its domain, audience, content type, and material nature.\n"
189
+ "This allows the agent to process multiple curriculum components or educational segments "
190
+ "within a single structured input."
191
+ ),
192
+ )
193
+
194
+ main_concept: str = Field(
195
+ ...,
196
+ title="Main Concept",
197
+ description=(
198
+ "The central or core idea around which the curriculum is built. "
199
+ "It defines the overarching theme that connects all units and topics together."
200
+ ),
201
+ )
202
+
203
+ related_concepts: List[str] = Field(
204
+ ...,
205
+ title="Related Concepts",
206
+ description=(
207
+ "A set of secondary or supporting ideas that complement or expand upon the main concept. "
208
+ "These help the agent establish conceptual links and subtopics within the curriculum."
209
+ ),
210
+ )
211
+
212
+ units: List[UnitWithAxes] = Field(
213
+ ...,
214
+ title="Units with Axes",
215
+ description=(
216
+ "A structured list of educational units. Each unit includes its title, "
217
+ "conceptual focus, and five (5) well-defined axes that progressively develop the learner’s understanding."
218
+ ),
219
+ )
220
+
221
+
222
+ ##############################--OLD--#####################################################
223
  # ========= 2. Schema for Units =========
224
  class Unit(BaseModel):
225
  module_title: str = Field(