ziadsameh32 commited on
Commit
17d0f30
·
1 Parent(s): 3dfedb7

final-version

Browse files
agents/analysis_phase/objectives.py CHANGED
@@ -2,7 +2,7 @@ from crewai import Agent, Task, Crew, Process, LLM
2
  import os
3
  import json
4
  from modules import bloom_taxonomy_2, objectives_dimensions, llm_g
5
- from schemas import ObjectivesOutput
6
 
7
 
8
  def get_bloom_verb(level: str) -> str:
@@ -65,86 +65,15 @@ objectives_generator = Agent(
65
  ),
66
  llm=llm_g,
67
  verbose=True,
68
- max_iter=100
69
  )
70
 
71
 
72
  objectives_task = Task(
73
  description=(
74
  "You have a complete and well-structured training curriculum provided in {outlines}. "
75
- "### Input Structure Clarification\n"
76
- "The input will contain a full structured outline in JSON format, where each **unit** includes several **axes**."
77
- "Each `axis` represents one **subtopic**, containing the following keys:"
78
- "- `axis_number`"
79
- "- `title`"
80
- "- `purpose`"
81
- ""
82
- "You must:"
83
- "- Generate **exactly one Arabic learning objective** per `axis`."
84
- "- Use only the content provided in `title` and `purpose`."
85
- "- Do **not invent**, expand, or infer any additional topics or meanings beyond what exists."
86
- "- Keep terminology and concepts consistent with the input text."
87
- "- Maintain the relationship between the unit and its axes."
88
- ""
89
- "---"
90
- ""
91
- "### Output Format"
92
- "The output must include all axes as separate entries, each with:"
93
- "- `unit` (unit title)"
94
- "- `unit_description` (the “focus” field)"
95
- "- `subtopic` (axis title)"
96
- "- `module_description` (axis purpose)"
97
- "- `level` (Bloom’s level)"
98
- "- `verbs` (three suggested verbs)"
99
- "- `objective` (one clear Arabic measurable learning objective)"
100
- ""
101
- "---"
102
- ""
103
- "### Example (Simplified)"
104
- "**Example Input:**"
105
- "```json"
106
- "{"
107
- ' "units": ['
108
- " {"
109
- ' "title": "الوحدة الأولى: مقدمة في التفكير التصميمي",'
110
- ' "focus": "يتعرف المتعلم على مفهوم التفكير التصميمي وأهميته.",'
111
- ' "axes": ['
112
- " {"
113
- ' "title": "تعريف التفكير التصميمي",'
114
- ' "purpose": "يفهم المتعلم معنى التفكير التصميمي ومكوناته."'
115
- " },"
116
- " {"
117
- ' "title": "أهمية التفكير التصميمي",'
118
- ' "purpose": "يشرح المتعلم كيف يساهم التفكير التصميمي في حل المشكلات."'
119
- " }"
120
- " ]"
121
- " }"
122
- " ]"
123
- "}\n"
124
- "**Example Output:**"
125
- ' "objectives": [\n'
126
- " {\n"
127
- ' "unit": "الوحدة الأولى: مقدمة في التفكير التصميمي",\n'
128
- ' "unit_description": "يتعرف المتعلم على مفهوم التفكير التصميمي وأهميته.",\n'
129
- ' "subtopic": "تعريف التفكير التصميمي",\n'
130
- ' "module_description": "يفهم المتعلم معنى التفكير التصميمي ومكوناته.",\n'
131
- ' "level": "Cognitive - Understand",\n'
132
- ' "verbs": ["يفهم", "يصف", "يوضح"],\n'
133
- ' "objective": "أن يفسّر المتعلم مفهوم التفكير التصميمي ومكوناته بدقة."\n'
134
- " },\n"
135
- " {\n"
136
- ' "unit": "الوحدة الأولى: مقدمة في التفكير التصميمي",\n'
137
- ' "unit_description": "يتعرف المتعلم على مفهوم التفكير التصميمي وأهميته.",\n'
138
- ' "subtopic": "أهمية التفكير التصميمي",\n'
139
- ' "module_description": "يشرح المتعلم كيف يساهم التفكير التصميمي في حل المشكلات.",\n'
140
- ' "level": "Cognitive - Understand",\n'
141
- ' "verbs": ["يشرح", "يستنتج", "يفسر"],\n'
142
- ' "objective": "أن يشرح المتعلم دور التفكير التصميمي في حل المشكلات."\n'
143
- " }\n"
144
- " ]\n"
145
- "}"
146
- "```\n"
147
- "The objectives should aligned with Bloom’s Taxonomy and the three learning domains, and consistent with the purpose of each subtopic.\n"
148
  "### Step-by-Step Process\n"
149
  "1. Read the curriculum overview to understand the full learning journey.\n"
150
  "2. **Before you begin, review the complete list of Bloom’s action verbs and the three domains for each level to plan maximum diversity.**\n"
@@ -334,22 +263,24 @@ objectives_task = Task(
334
  "- **Flexibility with precision:** Be flexible in verb choice but never compromise on accuracy.\n"
335
  "- **Continuous review:** Revisit objectives regularly for diversity and balance.\n"
336
  "- **Context matters:** Always choose the verb that best reflects what the learner should achieve in that specific subtopic.\n"
337
- "Very Important:"
 
338
  ),
339
- expected_output="""{
340
- "objectives": [
341
- {
342
- "unit": "Unit title",
343
- "unit_description": "Brief summary of the unit scope",
344
- "subtopic": "subtopic title",
345
- "module_description": "Brief summary of what this subtopic covers",
346
- "level": "Bloom's level assigned based on subtopic analysis",
347
- "verbs": ["verb1", "verb2", "verb3"],
348
- "objective": "One measurable Arabic objective derived from the subtopic purpose",
349
- }
350
- ],
 
351
  }""",
352
- output_json=ObjectivesOutput,
353
  agent=objectives_generator,
354
  human_input=False,
355
  )
 
2
  import os
3
  import json
4
  from modules import bloom_taxonomy_2, objectives_dimensions, llm_g
5
+ from schemas import LearningObjectivesOutput
6
 
7
 
8
  def get_bloom_verb(level: str) -> str:
 
65
  ),
66
  llm=llm_g,
67
  verbose=True,
68
+ max_iter=100,
69
  )
70
 
71
 
72
  objectives_task = Task(
73
  description=(
74
  "You have a complete and well-structured training curriculum provided in {outlines}. "
75
+ "Your task is to create one detailed, measurable learning objective in Arabic for each subtopic, "
76
+ "aligned with Bloom’s Taxonomy and the three learning domains, and consistent with the purpose of each subtopic.\n\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  "### Step-by-Step Process\n"
78
  "1. Read the curriculum overview to understand the full learning journey.\n"
79
  "2. **Before you begin, review the complete list of Bloom’s action verbs and the three domains for each level to plan maximum diversity.**\n"
 
263
  "- **Flexibility with precision:** Be flexible in verb choice but never compromise on accuracy.\n"
264
  "- **Continuous review:** Revisit objectives regularly for diversity and balance.\n"
265
  "- **Context matters:** Always choose the verb that best reflects what the learner should achieve in that specific subtopic.\n"
266
+ "### OUTPUT\n"
267
+ "Return the LearningObjectivesOutput structure in valid JSON format.\n\n"
268
  ),
269
+ expected_output="""JSON object with this structure:
270
+ {
271
+ "objectives": [
272
+ {
273
+ "unit": "Unit title",
274
+ "unit_description": "Brief summary of the unit scope",
275
+ "subtopic": "subtopic title",
276
+ "module_description": "Brief summary of what this subtopic covers",
277
+ "level": "Bloom's level assigned based on subtopic analysis",
278
+ "verbs": ["verb1", "verb2", "verb3"],
279
+ "objective": "One measurable Arabic objective"
280
+ }
281
+ ]
282
  }""",
283
+ output_json=LearningObjectivesOutput,
284
  agent=objectives_generator,
285
  human_input=False,
286
  )
agents/analysis_phase/outcomes.py CHANGED
@@ -288,14 +288,15 @@ outcomes_task = Task(
288
  "ensure the output in form of Json",
289
  ]
290
  ),
291
- expected_output="""{
292
- "outcomes": [
293
- {
294
- "unit": "Unit title",
295
- "unit_description": "Brief summary of the unit scope",
296
- "unit_outcome": "One measurable Arabic objective derived from the unit description and its subtopics and their purposes",
297
- }
298
- ],
 
299
  }""",
300
  agent=outcomes_generator,
301
  output_json=OutcomesOutput,
 
288
  "ensure the output in form of Json",
289
  ]
290
  ),
291
+ expected_output="""JSON object with this structure:
292
+ {
293
+ "objectives": [
294
+ {
295
+ "unit": "Unit title",
296
+ "unit_description": "Brief summary of the unit scope",
297
+ "unit_outcome": "One measurable Arabic objective derived from the unit description and its subtopics and their purposes",
298
+ }
299
+ ],
300
  }""",
301
  agent=outcomes_generator,
302
  output_json=OutcomesOutput,
agents/final_outliners/validator.py CHANGED
@@ -2,7 +2,7 @@ from crewai import Agent, Task, Crew, Process, LLM
2
  import os
3
  import json
4
  from modules import llm_5m
5
- from schemas import FullCurriculumStructure
6
 
7
  validator_agent = Agent(
8
  role="Arabic Educational Validator (Curriculum Quality & Integrity Specialist)",
@@ -225,7 +225,7 @@ validation_task = Task(
225
  "- Ensure titles are concise (4–8 words), contextually clear, and free from unnecessary punctuation.\n"
226
  "- Do not lose any important concept; prefer rephrasing over deletion.\n"
227
  ),
228
- expected_output="A JSON object showing validated units and axes with detailed statuses and refinements.",
229
  agent=validator_agent,
230
- output_json=FullCurriculumStructure
231
  )
 
2
  import os
3
  import json
4
  from modules import llm_5m
5
+ from schemas import ValidatedCurriculumOutput
6
 
7
  validator_agent = Agent(
8
  role="Arabic Educational Validator (Curriculum Quality & Integrity Specialist)",
 
225
  "- Ensure titles are concise (4–8 words), contextually clear, and free from unnecessary punctuation.\n"
226
  "- Do not lose any important concept; prefer rephrasing over deletion.\n"
227
  ),
228
+ expected_output="A JSON object showing validated units and axes.",
229
  agent=validator_agent,
230
+ output_json=ValidatedCurriculumOutput,
231
  )
routers/introduction_route.py CHANGED
@@ -11,7 +11,7 @@ from modules import (
11
  inputs,
12
  )
13
  from schemas import (
14
- FullCurriculumStructure,
15
  OutcomesOutput,
16
  DNAMetadata,
17
  OutlineInput,
@@ -26,7 +26,9 @@ router = APIRouter(prefix="/analysis", tags=["Introduction"])
26
 
27
 
28
  @router.post("/introduction")
29
- def run_training(data: OutlineInput, outlines: FullCurriculumStructure, outcomes:OutcomesOutput):
 
 
30
  training_crew = Crew(
31
  agents=[intro_agent],
32
  tasks=[intro_task],
 
11
  inputs,
12
  )
13
  from schemas import (
14
+ ValidatedCurriculumOutput,
15
  OutcomesOutput,
16
  DNAMetadata,
17
  OutlineInput,
 
26
 
27
 
28
  @router.post("/introduction")
29
+ def run_training(
30
+ data: OutlineInput, outlines: ValidatedCurriculumOutput, outcomes: OutcomesOutput
31
+ ):
32
  training_crew = Crew(
33
  agents=[intro_agent],
34
  tasks=[intro_task],
routers/objective_route.py CHANGED
@@ -11,13 +11,12 @@ from modules import (
11
  inputs,
12
  )
13
  from schemas import (
14
- CurriculumStructure,
15
  DNAMetadata,
16
  OutlineInput,
17
  )
18
 
19
 
20
-
21
  router = APIRouter(prefix="/analysis", tags=["Objectives"])
22
 
23
 
@@ -27,7 +26,7 @@ router = APIRouter(prefix="/analysis", tags=["Objectives"])
27
 
28
 
29
  @router.post("/objectives")
30
- def run_objectives(data: OutlineInput, outlines: CurriculumStructure):
31
  objectives_crew = Crew(
32
  agents=[objectives_generator],
33
  tasks=[objectives_task],
 
11
  inputs,
12
  )
13
  from schemas import (
14
+ ValidatedCurriculumOutput,
15
  DNAMetadata,
16
  OutlineInput,
17
  )
18
 
19
 
 
20
  router = APIRouter(prefix="/analysis", tags=["Objectives"])
21
 
22
 
 
26
 
27
 
28
  @router.post("/objectives")
29
+ def run_objectives(data: OutlineInput, outlines: ValidatedCurriculumOutput):
30
  objectives_crew = Crew(
31
  agents=[objectives_generator],
32
  tasks=[objectives_task],
routers/outcome_route.py CHANGED
@@ -27,7 +27,7 @@ router = APIRouter(prefix="/analysis", tags=["outcomes"])
27
 
28
 
29
  @router.post("/outcomes")
30
- def run_outcomes(data: OutlineInput, objectives: ObjectivesOutput):
31
  outcomes_crew = Crew(
32
  agents=[outcomes_generator],
33
  tasks=[outcomes_task],
 
27
 
28
 
29
  @router.post("/outcomes")
30
+ def run_outcomes(data: OutlineInput, objectives: LearningObjectivesOutput):
31
  outcomes_crew = Crew(
32
  agents=[outcomes_generator],
33
  tasks=[outcomes_task],
schemas/__init__.py CHANGED
@@ -11,6 +11,7 @@ from .outliner_schema import (
11
  ExpandedTopicsList,
12
  CurriculumStructure,
13
  FullCurriculumStructure,
 
14
  )
15
  from .source_schema import AllResults, SingleResult
16
  from .introduction_schema import IntroductionOutput
 
11
  ExpandedTopicsList,
12
  CurriculumStructure,
13
  FullCurriculumStructure,
14
+ ValidatedCurriculumOutput,
15
  )
16
  from .source_schema import AllResults, SingleResult
17
  from .introduction_schema import IntroductionOutput
schemas/objectives_schema.py CHANGED
@@ -33,23 +33,33 @@ from pydantic import BaseModel, Field
33
  from typing import List, Dict, Literal, Optional
34
 
35
 
36
- # نموذج يمثل كل هدف تعلم فردي (Learning Objective)
37
  class LearningObjective(BaseModel):
38
- unit: str = Field(..., description="اسم الوحدة التعليمية (Unit name).")
39
- module: str = Field(..., description="اسم الموديول داخل الوحدة.")
 
 
 
 
 
 
 
 
40
  level: str = Field(
41
- ...,
42
- description="مستوى Bloom’s Taxonomy (مثلاً: Remember, Understand, Apply, Analyze, Evaluate, Create).",
 
 
 
 
43
  )
44
- verbs: List[str] = Field(..., description="قائمة بالأفعال المستخدمة من تصنيف بلوم.")
45
  objective: str = Field(
46
- ...,
47
- description="الناتج التعليمي القابل للقياس، مكتوب بصيغة 'أن + فعل مضارع + الأداء المطلوب'.",
48
  )
49
 
50
 
51
- # النموذج العام اللي يحتوي على القائمة الكاملة للأهداف
52
  class LearningObjectivesOutput(BaseModel):
 
 
53
  objectives: List[LearningObjective] = Field(
54
- ..., description="قائمة كاملة بالأهداف التعليمية المتولدة من التحليل."
55
  )
 
33
  from typing import List, Dict, Literal, Optional
34
 
35
 
 
36
  class LearningObjective(BaseModel):
37
+ """Schema for a single learning objective"""
38
+
39
+ unit: str = Field(description="The title of the unit this objective belongs to")
40
+ unit_description: str = Field(
41
+ description="Brief summary of the unit scope and learning journey"
42
+ )
43
+ subtopic: str = Field(description="The title of the specific subtopic")
44
+ module_description: str = Field(
45
+ description="Brief summary of what this subtopic covers"
46
+ )
47
  level: str = Field(
48
+ description="Bloom's Taxonomy level or learning domain level assigned based on subtopic analysis"
49
+ )
50
+ verbs: List[str] = Field(
51
+ description="List of three relevant Bloom's verbs suitable for the audience",
52
+ min_items=3,
53
+ max_items=3,
54
  )
 
55
  objective: str = Field(
56
+ description="One measurable learning objective in Arabic derived from the subtopic purpose"
 
57
  )
58
 
59
 
 
60
  class LearningObjectivesOutput(BaseModel):
61
+ """Schema for the complete learning objectives output"""
62
+
63
  objectives: List[LearningObjective] = Field(
64
+ description="Complete list of learning objectives for all subtopics in the curriculum"
65
  )
schemas/outliner_schema.py CHANGED
@@ -129,6 +129,55 @@ class Axis(BaseModel):
129
  )
130
 
131
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  ############################################################################################################
133
  class UnitWithAxes(BaseModel):
134
  """
 
129
  )
130
 
131
 
132
+ ######################Validator############################
133
+ class ValidatedAxis(BaseModel):
134
+ """Schema for a validated subtopic (axis)"""
135
+
136
+ axis_number: int = Field(
137
+ description="Sequential number of the axis within the unit", ge=1
138
+ )
139
+
140
+ validated_title: str = Field(
141
+ description="The improved/validated axis title in Arabic (4-8 words, clear, focused)"
142
+ )
143
+
144
+ validated_purpose: str = Field(
145
+ description="The improved/validated axis purpose explaining its educational intent"
146
+ )
147
+ status: Literal["kept", "rephrased", "added", "removed"] = Field(
148
+ description="Validation status: 'kept' (unchanged), 'rephrased' (edited), 'added' (new), 'removed' (deleted/merged)"
149
+ )
150
+
151
+
152
+ class ValidatedUnit(BaseModel):
153
+ """Schema for a validated educational unit"""
154
+
155
+ unit_number: int = Field(
156
+ description="Sequential number of the unit in the curriculum", ge=1
157
+ )
158
+ title: str = Field(description="The title of the unit in Arabic")
159
+ focus: str = Field(
160
+ description="Description of the unit's main educational focus and objectives"
161
+ )
162
+ validated_axes: List[ValidatedAxis] = Field(
163
+ description="List of validated subtopics (axes) for this unit", min_items=1
164
+ )
165
+
166
+
167
+ class ValidatedCurriculumOutput(BaseModel):
168
+ """Schema for the complete validated curriculum output"""
169
+
170
+ main_concept: str = Field(
171
+ description="The main concept or topic of the entire curriculum"
172
+ )
173
+ related_concepts: List[str] = Field(
174
+ description="List of related concepts covered in the curriculum"
175
+ )
176
+ validated_units: List[ValidatedUnit] = Field(
177
+ description="List of all validated educational units with their axes"
178
+ )
179
+
180
+
181
  ############################################################################################################
182
  class UnitWithAxes(BaseModel):
183
  """