ziadsameh32 commited on
Commit
65638b6
ยท
1 Parent(s): dc2d297

final-version

Browse files
OBJECTIVES_AGENT_README.md ADDED
@@ -0,0 +1,413 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ๐Ÿ“š Objectives Agent - Complete Rebuild
2
+
3
+ ## ๐ŸŽฏ Overview
4
+
5
+ ุชู… ุฅุนุงุฏุฉ ุจู†ุงุก Objectives Agent ุจุงู„ูƒุงู…ู„ ู…ู† ุงู„ุตูุฑ ู„ุชูˆู„ูŠุฏ ุฃู‡ุฏุงู ุชุนู„ูŠู…ูŠุฉ ูˆุงุถุญุฉ ูˆู‚ุงุจู„ุฉ ู„ู„ู‚ูŠุงุณ ู„ูƒู„ ู…ุญูˆุฑ (axis) ููŠ ุงู„ู…ู†ู‡ุฌ ุงู„ุชุฏุฑูŠุจูŠ.
6
+
7
+ ---
8
+
9
+ ## ๐Ÿ“ Files Modified/Created
10
+
11
+ ### 1. `schemas/objectives_schema.py` โœจ (REBUILT)
12
+ **ุงู„ุชุนุฏูŠู„ุงุช:**
13
+ - ุฅุนุงุฏุฉ ูƒุชุงุจุฉ Pydantic models ุจุงู„ูƒุงู…ู„
14
+ - ู†ู…ูˆุฐุฌ `ObjectiveItem`: ูŠู…ุซู„ ู‡ุฏู ุชุนู„ูŠู…ูŠ ูˆุงุญุฏ ู„ู…ุญูˆุฑ ูˆุงุญุฏ
15
+ - ู†ู…ูˆุฐุฌ `ObjectivesOutput`: ูŠุญุชูˆูŠ ุนู„ู‰ ู‚ุงุฆู…ุฉ ูƒุงู…ู„ุฉ ุจุงู„ุฃู‡ุฏุงู
16
+
17
+ **ุงู„ุญู‚ูˆู„ ุงู„ุฌุฏูŠุฏุฉ:**
18
+ ```python
19
+ class ObjectiveItem(BaseModel):
20
+ unit: str # ุนู†ูˆุงู† ุงู„ูˆุญุฏุฉ
21
+ unit_description: str # ูˆุตู ุงู„ูˆุญุฏุฉ (focus)
22
+ axis: str # ุนู†ูˆุงู† ุงู„ู…ุญูˆุฑ
23
+ module_description: str # ูˆุตู ุงู„ู…ุญูˆุฑ (purpose)
24
+ level: str # ู…ุณุชูˆู‰ Bloom
25
+ verbs: List[str] # 3 ุฃูุนุงู„ ู…ู‚ุชุฑุญุฉ
26
+ objective: str # ุงู„ู‡ุฏู ุงู„ุชุนู„ูŠู…ูŠ ุจุงู„ุนุฑุจูŠุฉ
27
+ ```
28
+
29
+ ---
30
+
31
+ ### 2. `agents/analysis_phase/objectives.py` โœจ (REBUILT)
32
+ **ุงู„ุชุนุฏูŠู„ุงุช:**
33
+ - ุฅุนุงุฏุฉ ูƒุชุงุจุฉ Agent ูˆTask ุจุงู„ูƒุงู…ู„
34
+ - ุชูˆุซูŠู‚ ุดุงู…ู„ ูˆู…ูุตู„
35
+ - Helper functions ู…ุญุณู‘ู†ุฉ
36
+ - Instructions ูˆุงุถุญุฉ ูˆู…ู†ุธู…ุฉ
37
+
38
+ **ุงู„ู…ูƒูˆู†ุงุช ุงู„ุฑุฆูŠุณูŠุฉ:**
39
+
40
+ #### ๐Ÿ”ง Helper Functions:
41
+ ```python
42
+ get_bloom_verb(level: str)
43
+ get_verbs_by_domain_and_level(domain: str, level_name: str)
44
+ format_domain_levels_info() โ†’ str
45
+ ```
46
+
47
+ #### ๐Ÿค– Agent:
48
+ - **Role:** Expert Learning Objectives Designer
49
+ - **Goal:** ุชูˆู„ูŠุฏ ู‡ุฏู ูˆุงุญุฏ ู„ูƒู„ axis
50
+ - **Backstory:** ุฎุจูŠุฑ ุชุตู…ูŠู… ุชุนู„ูŠู…ูŠ ู…ุชุฎุตุต
51
+
52
+ #### ๐Ÿ“‹ Task:
53
+ - **Description:** ุชุนู„ูŠู…ุงุช ู…ูุตู„ุฉ ุจู€ 80+ ุณุทุฑ
54
+ - **Expected Output:** JSON structure ูˆุงุถุญ
55
+ - **Output Schema:** ObjectivesOutput
56
+
57
+ #### ๐ŸŽฏ Main Function:
58
+ ```python
59
+ generate_objectives(
60
+ topic: str,
61
+ domain: str,
62
+ content_type: str,
63
+ audience: str,
64
+ material_type: list,
65
+ outlines: dict
66
+ ) โ†’ dict
67
+ ```
68
+
69
+ ---
70
+
71
+ ### 3. `test_objectives.py` โœจ (NEW)
72
+ **ุงู„ุบุฑุถ:**
73
+ - ุงุฎุชุจุงุฑ ุงู„ู€ agent ุจุงุณุชุฎุฏุงู… ุจูŠุงู†ุงุช ูุนู„ูŠุฉ
74
+ - ุนุฑุถ ุงู„ุฅุญุตุงุฆูŠุงุช ูˆุงู„ุชุญู„ูŠู„ุงุช
75
+ - ุญูุธ ุงู„ู†ุชุงุฆุฌ ููŠ `objectives_output.json`
76
+
77
+ **ุงู„ู…ูŠุฒุงุช:**
78
+ - โœ… ุนุฑุถ Input Summary
79
+ - โœ… Count Verification (objectives vs axes)
80
+ - โœ… Verb Diversity Analysis
81
+ - โœ… Domain Distribution Analysis
82
+ - โœ… Sample Objectives Display
83
+ - โœ… Error Handling & Traceback
84
+
85
+ ---
86
+
87
+ ## ๐Ÿ”„ Input Structure
88
+
89
+ ```json
90
+ {
91
+ "Metadata": [{
92
+ "topic": "...",
93
+ "domain": "...",
94
+ "content_type": "...",
95
+ "audience": "...",
96
+ "material_type": [...]
97
+ }],
98
+ "main_concept": "...",
99
+ "related_concepts": [...],
100
+ "units": [
101
+ {
102
+ "unit_number": 1,
103
+ "title": "ุนู†ูˆุงู† ุงู„ูˆุญุฏุฉ",
104
+ "focus": "ูˆุตู ุงู„ูˆุญุฏุฉ",
105
+ "axes": [
106
+ {
107
+ "axis_number": 1,
108
+ "title": "ุนู†ูˆุงู† ุงู„ู…ุญูˆุฑ",
109
+ "purpose": "ุงู„ุบุฑุถ ู…ู† ุงู„ู…ุญูˆุฑ"
110
+ }
111
+ ]
112
+ }
113
+ ]
114
+ }
115
+ ```
116
+
117
+ ---
118
+
119
+ ## ๐Ÿ“ค Output Structure
120
+
121
+ ```json
122
+ {
123
+ "objectives": [
124
+ {
125
+ "unit": "ุงู„ูุตู„ ุงู„ุฃูˆู„: ู…ูุงู‡ูŠู… ูˆู…ุจุงุฏุฆ ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ",
126
+ "unit_description": "ูŠู…ู†ุญ ุงู„ู…ุชุนู„ู…ูŠู† ูู‡ู…ุงู‹ ู…ุชุทูˆุฑุงู‹...",
127
+ "axis": "ุชุนุฑูŠู ุงู„ู…ุตุทู„ุญุงุช ุงู„ุฃุณุงุณูŠุฉ ู„ู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ",
128
+ "module_description": "ุชุนุฑูŠู ุงู„ู…ุตุทู„ุญุงุช ุงู„ุฃุณุงุณูŠุฉ...",
129
+ "level": "Cognitive - Remember",
130
+ "verbs": ["ูŠุฐูƒุฑ", "ูŠุนุฏุฏ", "ูŠุณู…ูŠ"],
131
+ "objective": "ุฃู† ูŠุฐูƒุฑ ุงู„ู…ุชุนู„ู… ุงู„ู…ุตุทู„ุญุงุช ุงู„ุฃุณุงุณูŠุฉ ู„ู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ ุจุฏู‚ุฉ."
132
+ }
133
+ ]
134
+ }
135
+ ```
136
+
137
+ ---
138
+
139
+ ## โœ… Key Rules Implemented
140
+
141
+ ### 1. One-to-One Mapping
142
+ - โœ… **ู‡ุฏู ูˆุงุญุฏ ูู‚ุท** ู„ูƒู„ ู…ุญูˆุฑ (axis)
143
+ - โœ… ุนุฏุฏ ุงู„ุฃู‡ุฏุงู = ุนุฏุฏ ุงู„ู…ุญุงูˆุฑ
144
+ - โœ… ู„ุง ูŠุชู… ุฅู†ุดุงุก ู…ุญุงูˆุฑ ุฌุฏูŠุฏุฉ
145
+ - โœ… ู„ุง ูŠุชู… ุชุฎุทูŠ ุฃูŠ ู…ุญูˆุฑ
146
+
147
+ ### 2. Verb Diversity
148
+ - โœ… ุงุณุชุฎุฏุงู… ุฃูุนุงู„ ู…ุชู†ูˆุนุฉ ู…ู† Bloom
149
+ - โœ… ุชุฌู†ุจ ุชูƒุฑุงุฑ ู†ูุณ ุงู„ูุนู„
150
+ - โœ… ู‡ุฏู: 70-80% ุฃูุนุงู„ ูุฑูŠุฏุฉ
151
+ - โœ… ุชุชุจุน ุงู„ุฃูุนุงู„ ุงู„ู…ุณุชุฎุฏู…ุฉ
152
+
153
+ ### 3. Domain Balance
154
+ - โœ… Cognitive (Knowledge): 50-60%
155
+ - โœ… Affective (Attitude): 20-30%
156
+ - โœ… Psychomotor (Skills): 20-30%
157
+
158
+ ### 4. Bloom's Progression
159
+ - โœ… ุชุฏุฑุฌ ู…ู†ุทู‚ูŠ ุฏุงุฎู„ ูƒู„ ูˆุญุฏุฉ:
160
+ - ุงู„ุจุฏุงูŠุฉ: Remember, Understand
161
+ - ุงู„ูˆุณุท: Apply, Analyze
162
+ - ุงู„ู†ู‡ุงูŠุฉ: Evaluate, Create
163
+
164
+ ### 5. Quality Standards
165
+ - โœ… ุฃู‡ุฏุงู ู‚ุงุจู„ุฉ ู„ู„ู‚ูŠุงุณ
166
+ - โœ… ุฃู‡ุฏุงู ูˆุงุถุญุฉ ูˆู…ุญุฏุฏุฉ
167
+ - โœ… ุจุฏูˆู† ุบู…ูˆุถ ุฃูˆ ุชุนู‚ูŠุฏ
168
+ - โœ… ู…ู†ุงุณุจุฉ ู„ู„ุฌู…ู‡ูˆุฑ ุงู„ู…ุณุชู‡ุฏู
169
+ - โœ… ุจุงู„ู„ุบุฉ ุงู„ุนุฑุจูŠุฉ ุงู„ูุตุญู‰
170
+
171
+ ---
172
+
173
+ ## ๐Ÿš€ Usage
174
+
175
+ ### ุงู„ุจุณูŠุท (Simple):
176
+ ```python
177
+ from agents.analysis_phase.objectives import generate_objectives
178
+
179
+ result = generate_objectives(
180
+ topic="Design Thinking",
181
+ domain="Management",
182
+ content_type="Training",
183
+ audience="Professionals",
184
+ material_type=["Conceptual", "Procedural"],
185
+ outlines=curriculum_structure
186
+ )
187
+
188
+ print(result['objectives'])
189
+ ```
190
+
191
+ ### ุงู„ุงุฎุชุจุงุฑ (Testing):
192
+ ```bash
193
+ cd Project
194
+ python test_objectives.py
195
+ ```
196
+
197
+ ---
198
+
199
+ ## ๐Ÿ“Š Expected Metrics
200
+
201
+ ุนู†ุฏ ุงู„ุชุดุบูŠู„ ุงู„ุตุญูŠุญุŒ ูŠุฌุจ ุฃู† ุชุญุตู„ ุนู„ู‰:
202
+
203
+ | Metric | Target | Status |
204
+ |--------|--------|--------|
205
+ | Objectives Count | = Axes Count | โœ… Match |
206
+ | Verb Diversity | 70-80% | โœ… Pass |
207
+ | Cognitive Domain | 50-60% | โœ… Balanced |
208
+ | Affective Domain | 20-30% | โœ… Balanced |
209
+ | Psychomotor Domain | 20-30% | โœ… Balanced |
210
+ | Measurability | 100% | โœ… All Clear |
211
+ | Arabic Language | 100% | โœ… Correct |
212
+
213
+ ---
214
+
215
+ ## ๐ŸŽฏ Learning Domains Reference
216
+
217
+ ### 1. ุงู„ู…ุฌุงู„ ุงู„ู…ุนุฑููŠ (Cognitive)
218
+ **Levels:**
219
+ - Remember (ูŠุฐูƒุฑุŒ ูŠุญุฏุฏุŒ ูŠุณู…ูŠ)
220
+ - Understand (ูŠูุณุฑุŒ ูŠุดุฑุญุŒ ูŠูˆุถุญ)
221
+ - Apply (ูŠุทุจู‚ุŒ ูŠุณุชุฎุฏู…ุŒ ูŠู†ูุฐ)
222
+ - Analyze (ูŠุญู„ู„ุŒ ูŠู‚ุงุฑู†ุŒ ูŠู…ูŠุฒ)
223
+ - Evaluate (ูŠู‚ูŠู…ุŒ ูŠู†ู‚ุฏุŒ ูŠุจุฑุฑ)
224
+ - Create (ูŠุจุชูƒุฑุŒ ูŠุตู…ู…ุŒ ูŠุทูˆุฑ)
225
+
226
+ ### 2. ุงู„ู…ุฌุงู„ ุงู„ูˆุฌุฏุงู†ูŠ (Affective)
227
+ **Levels:**
228
+ - Reception (ูŠู†ุชุจู‡ุŒ ูŠุณุชู‚ุจู„ุŒ ูŠู„ุงุญุธ)
229
+ - Response (ูŠุณุชุฌูŠุจุŒ ูŠุดุงุฑูƒุŒ ูŠุชุทูˆุน)
230
+ - Valuing (ูŠู‚ุฏุฑุŒ ูŠุญุชุฑู…ุŒ ูŠุคูŠุฏ)
231
+ - Organization (ูŠู†ุธู…ุŒ ูŠู„ุชุฒู…ุŒ ูŠูˆุงุฒู†)
232
+ - Characterization (ูŠู…ูŠุฒุŒ ูŠุชุจู†ู‰ุŒ ูŠู…ุงุฑุณ)
233
+
234
+ ### 3. ุงู„ู…ุฌุงู„ ุงู„ู…ู‡ุงุฑูŠ (Psychomotor)
235
+ **Levels:**
236
+ - Readiness (ูŠุณุชุนุฏุŒ ูŠุชู‡ูŠุฃ)
237
+ - Guided Response (ูŠู‚ู„ุฏุŒ ูŠุญุงูƒูŠุŒ ูŠุฌุฑุจ)
238
+ - Mechanism (ูŠู…ุงุฑุณุŒ ูŠุทุจู‚ุŒ ูŠู†ูุฐ)
239
+ - Complex Response (ูŠุชู‚ู†ุŒ ูŠุคุฏูŠ ุจุณู„ุงุณุฉ)
240
+ - Adaptation (ูŠุนุฏู„ุŒ ูŠูƒูŠูุŒ ูŠุญุณู†)
241
+ - Origination (ูŠุจุชูƒุฑุŒ ูŠุตู…ู…ุŒ ูŠุจุฏุน)
242
+
243
+ ---
244
+
245
+ ## ๐Ÿ“ Example Test Data
246
+
247
+ ุงู„ู…ู„ู `test_objectives.py` ูŠุญุชูˆูŠ ุนู„ู‰ ุจูŠุงู†ุงุช ุชุฌุฑูŠุจูŠุฉ ูƒุงู…ู„ุฉ:
248
+
249
+ **ุงู„ู…ูˆุถูˆุน:**
250
+ ```
251
+ ุชู‚ู†ูŠุงุช ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ ู„ุญู„ ุงู„ู…ุดูƒู„ุงุช ูˆุงุชุฎุงุฐ ุงู„ู‚ุฑุงุฑุงุช
252
+ ```
253
+
254
+ **ุงู„ูˆุญุฏุงุช (4 units):**
255
+ 1. ู…ูุงู‡ูŠู… ูˆู…ุจุงุฏุฆ ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ (5 axes)
256
+ 2. ุงู„ุนู…ู„ูŠุฉ ุงู„ู…ูŠุฏุงู†ูŠุฉ ู„ุชู‚ู†ูŠุงุช ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ (5 axes)
257
+ 3. ุชุทุจูŠู‚ุงุช ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ (5 axes)
258
+ 4. ุงู„ุชู†ููŠุฐ ูˆุงู„ุชู‚ูŠูŠู… (5 axes)
259
+
260
+ **ุฅุฌู…ุงู„ูŠ ุงู„ู…ุญุงูˆุฑ:** 20 axes
261
+ **ุงู„ุฃู‡ุฏุงู ุงู„ู…ุชูˆู‚ุนุฉ:** 20 objectives
262
+
263
+ ---
264
+
265
+ ## ๐Ÿ› Troubleshooting
266
+
267
+ ### ู…ุดูƒู„ุฉ: ุนุฏุฏ ุงู„ุฃู‡ุฏุงู โ‰  ุนุฏุฏ ุงู„ู…ุญุงูˆุฑ
268
+ **ุงู„ุญู„:**
269
+ - ุชุญู‚ู‚ ู…ู† ุจู†ูŠุฉ ุงู„ู€ `outlines` input
270
+ - ุชุฃูƒุฏ ู…ู† ูˆุฌูˆุฏ `axes` ููŠ ูƒู„ unit
271
+ - ุฑุงุฌุน ุงู„ู€ Task description
272
+
273
+ ### ู…ุดูƒู„ุฉ: ุชูƒุฑุงุฑ ุงู„ุฃูุนุงู„
274
+ **ุงู„ุญู„:**
275
+ - ุฑุงุฌุน Verb Diversity Instructions
276
+ - ุชุญู‚ู‚ ู…ู† `get_verbs_by_domain_and_level()`
277
+ - ุฒูŠุงุฏุฉ ุนุฏุฏ ุงู„ุฃูุนุงู„ ุงู„ู…ุชุงุญุฉ
278
+
279
+ ### ู…ุดูƒู„ุฉ: ุนุฏู… ุงู„ุชูˆุงุฒู† ุจูŠู† ุงู„ู…ุฌุงู„ุงุช
280
+ **ุงู„ุญู„:**
281
+ - ุฑุงุฌุน Domain Balance Rules
282
+ - ุชุฃูƒุฏ ู…ู† ุชูˆุฒูŠุน ุงู„ุฃู‡ุฏุงู ุนู„ู‰ ุงู„ู…ุฌุงู„ุงุช ุงู„ุซู„ุงุซุฉ
283
+ - ุงุถุจุท ุงู„ู†ุณุจ ุญุณุจ ุทุจูŠุนุฉ ุงู„ู…ุญุชูˆู‰
284
+
285
+ ---
286
+
287
+ ## ๐Ÿ”— Integration
288
+
289
+ ู„ู„ุชูƒุงู…ู„ ู…ุน ุงู„ู€ API:
290
+
291
+ ```python
292
+ # ููŠ routers/objective_route.py
293
+
294
+ from agents.analysis_phase.objectives import generate_objectives
295
+
296
+ @app.post("/objectives/generate")
297
+ async def generate_objectives_route(data: OutlineInput):
298
+ result = generate_objectives(
299
+ topic=data.topic,
300
+ domain=data.domain,
301
+ content_type=data.content_type,
302
+ audience=data.audience,
303
+ material_type=data.material_type,
304
+ outlines=data.outlines
305
+ )
306
+ return result
307
+ ```
308
+
309
+ ---
310
+
311
+ ## ๐Ÿ“š Documentation
312
+
313
+ ### ููŠ ุงู„ูƒูˆุฏ:
314
+ - โœ… Docstrings ุดุงู…ู„ุฉ ู„ูƒู„ function
315
+ - โœ… Type hints ูˆุงุถุญุฉ
316
+ - โœ… Comments ุชูˆุถูŠุญูŠุฉ
317
+ - โœ… Examples ููŠ ุงู„ู€ docstrings
318
+
319
+ ### Instructions ู„ู„ู€ AI:
320
+ - โœ… 80+ ุณุทุฑ ู…ู† ุงู„ุชุนู„ูŠู…ุงุช ุงู„ู…ูุตู„ุฉ
321
+ - โœ… ุฃู…ุซู„ุฉ ูˆุงุถุญุฉ
322
+ - โœ… ู‚ูˆุงุนุฏ ุตุงุฑู…ุฉ
323
+ - โœ… Checklists ู„ู„ุชุญู‚ู‚
324
+
325
+ ---
326
+
327
+ ## โœจ Features Highlights
328
+
329
+ ### 1. Comprehensive Instructions
330
+ - ุชุนู„ูŠู…ุงุช ู…ูุตู„ุฉ ุจู€ 80+ ุณุทุฑ
331
+ - ุฃู…ุซู„ุฉ ูˆุงุถุญุฉ
332
+ - ู‚ูˆุงุนุฏ ุตุงุฑู…ุฉ ู„ู„ุฌูˆุฏุฉ
333
+
334
+ ### 2. Helper Functions
335
+ - `get_bloom_verb()`: ุงุณุชุฎุฑุงุฌ ุงู„ุฃูุนุงู„ ู…ู† Bloom
336
+ - `get_verbs_by_domain_and_level()`: ุฃูุนุงู„ ุญุณุจ ุงู„ู…ุฌุงู„
337
+ - `format_domain_levels_info()`: ุชู†ุณูŠู‚ ู…ุนู„ูˆู…ุงุช ุงู„ู…ุฌุงู„ุงุช
338
+
339
+ ### 3. Validation & Quality
340
+ - ุนุฏ ุงู„ุฃู‡ุฏุงู vs ุงู„ู…ุญุงูˆุฑ
341
+ - ุชุญู„ูŠู„ ุชู†ูˆุน ุงู„ุฃูุนุงู„
342
+ - ุชูˆุฒูŠุน ุงู„ู…ุฌุงู„ุงุช
343
+ - ู‚ุงุจู„ูŠุฉ ุงู„ู‚ูŠุงุณ
344
+
345
+ ### 4. Error Handling
346
+ - Try-except blocks
347
+ - Traceback display
348
+ - Clear error messages
349
+
350
+ ### 5. Test Suite
351
+ - ุจูŠุงู†ุงุช ุชุฌุฑูŠุจูŠุฉ ูƒุงู…ู„ุฉ
352
+ - ุชุญู„ูŠู„ุงุช ูˆุฅุญุตุงุฆูŠุงุช
353
+ - ุญูุธ ุงู„ู†ุชุงุฆุฌ
354
+
355
+ ---
356
+
357
+ ## ๐ŸŽ“ Best Practices Implemented
358
+
359
+ 1. โœ… **Type Safety:** ุงุณุชุฎุฏุงู… Pydantic ู„ู„ุชุญู‚ู‚ ู…ู† ุงู„ุจูŠุงู†ุงุช
360
+ 2. โœ… **Documentation:** ุชูˆุซูŠู‚ ุดุงู…ู„ ู„ูƒู„ component
361
+ 3. โœ… **Modularity:** ูุตู„ ุงู„ู…ู‡ุงู… ุฅู„ู‰ functions ุตุบูŠุฑุฉ
362
+ 4. โœ… **Testing:** ู…ู„ู ุงุฎุชุจุงุฑ ู…ุณุชู‚ู„
363
+ 5. โœ… **Error Handling:** ู…ุนุงู„ุฌุฉ ุงู„ุฃุฎุทุงุก ุจุดูƒู„ ุตุญูŠุญ
364
+ 6. โœ… **Code Style:** PEP 8 compliant
365
+ 7. โœ… **Comments:** ุชุนู„ูŠู‚ุงุช ูˆุงุถุญุฉ ุจุงู„ุนุฑุจูŠุฉ ูˆุงู„ุฅู†ุฌู„ูŠุฒูŠุฉ
366
+ 8. โœ… **Examples:** ุฃู…ุซู„ุฉ ูˆุงู‚ุนูŠุฉ ููŠ ุงู„ูƒูˆุฏ
367
+
368
+ ---
369
+
370
+ ## ๐Ÿšฆ Status
371
+
372
+ | Component | Status | Notes |
373
+ |-----------|--------|-------|
374
+ | Schema | โœ… Complete | Rebuilt from scratch |
375
+ | Agent | โœ… Complete | Fully documented |
376
+ | Task | โœ… Complete | 80+ lines instructions |
377
+ | Helpers | โœ… Complete | 3 utility functions |
378
+ | Tests | โœ… Complete | Full test suite |
379
+ | Docs | โœ… Complete | This README |
380
+
381
+ ---
382
+
383
+ ## ๐Ÿ“ž Support
384
+
385
+ ู„ู„ุฃุณุฆู„ุฉ ุฃูˆ ุงู„ู…ุดุงูƒู„:
386
+ 1. ุฑุงุฌุน ู‡ุฐุง ุงู„ู€ README
387
+ 2. ุงูุญุต ู…ู„ู `test_objectives.py`
388
+ 3. ุฑุงุฌุน ุงู„ู€ docstrings ููŠ ุงู„ูƒูˆุฏ
389
+ 4. ุชุญู‚ู‚ ู…ู† ุงู„ู€ error messages
390
+
391
+ ---
392
+
393
+ ## ๐ŸŽ‰ Summary
394
+
395
+ โœ… **ุชู… ุฅุนุงุฏุฉ ุจู†ุงุก Objectives Agent ุจุงู„ูƒุงู…ู„**
396
+
397
+ **ุงู„ุชุญุณูŠู†ุงุช ุงู„ุฑุฆูŠุณูŠุฉ:**
398
+ - ๐Ÿ“Š Pydantic schema ู…ุญุณู‘ู†
399
+ - ๐Ÿค– Agent instructions ู…ูุตู„ุฉ (80+ ุณุทุฑ)
400
+ - ๐Ÿ”ง Helper functions ู…ุญุณู‘ู†ุฉ
401
+ - ๐Ÿงช Test suite ูƒุงู…ู„
402
+ - ๐Ÿ“š Documentation ุดุงู…ู„
403
+ - โœจ Quality standards ุนุงู„ูŠุฉ
404
+
405
+ **ุงู„ู†ุชูŠุฌุฉ:**
406
+ ู†ุธุงู… ู‚ูˆูŠ ูˆู…ุชูƒุงู…ู„ ู„ุชูˆู„ูŠุฏ ุฃู‡ุฏุงู ุชุนู„ูŠู…ูŠุฉ ุนุงู„ูŠุฉ ุงู„ุฌูˆุฏุฉุŒ ู‚ุงุจู„ุฉ ู„ู„ู‚ูŠุงุณุŒ ูˆู…ุชู†ูˆุนุฉ ู„ูƒู„ ู…ุญูˆุฑ ููŠ ุงู„ู…ู†ู‡ุฌ ุงู„ุชุฏุฑูŠุจูŠ.
407
+
408
+ ---
409
+
410
+ **๐ŸŽฏ Ready to use!**
411
+
412
+ Run: `python test_objectives.py`
413
+
agents/analysis_phase/objectives.py CHANGED
@@ -1,358 +1,648 @@
1
- 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:
9
- """Returns verbs from the given Bloom's taxonomy level."""
 
10
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  if level not in bloom_taxonomy_2:
12
- raise ValueError(f"Invalid Bloom level: {level}")
 
13
  verbs_key = [k for k in bloom_taxonomy_2[level].keys() if "_verbs_examples" in k][0]
14
  return bloom_taxonomy_2[level][verbs_key]
15
 
16
 
17
- def get_verbs_by_domain_and_level(domain, level_name):
18
  """
19
- ุงุณุชุฎุฑุงุฌ ุงู„ุฃูุนุงู„ ุงู„ู…ู†ุงุณุจุฉ ู…ู† ู‚ุงู…ูˆุณ ุงู„ุฃุจุนุงุฏ ุงู„ุชุนู„ูŠู…ูŠุฉ
20
-
21
  Args:
22
- domain: "Knowledge", "Ability", or "Skills"
23
  level_name: ุงุณู… ุงู„ู…ุณุชูˆู‰ ู…ุซู„ "Remember", "Response", "Practice"
24
-
25
  Returns:
26
- ู‚ุงุฆู…ุฉ ุจุงู„ุฃูุนุงู„ ุงู„ู…ุชุงุญุฉ
27
  """
28
  if domain not in objectives_dimensions:
29
  return []
30
-
31
  for level in objectives_dimensions[domain]["levels"]:
32
  if level_name.lower() in level["level_name"].lower():
33
  return level["verbs_examples"]
34
-
35
  return []
36
 
37
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  objectives_generator = Agent(
39
- role="Expert Learning Objectives Designer (Instructional Design Specialist)",
 
40
  goal=(
41
- "Design a comprehensive list of clear, measurable, and achievable learning objectives in Arabic "
42
- "for each axis in the training curriculum. Your objectives must be based on {topic} and the "
43
- "- one objective for one modeule not more not less."
44
- "provided axes and units and their describtions and focuses. "
45
- "You must carefully read and analyze every axis title, its purpose, and the unit description "
46
- "before writing any objective. "
47
- "Each objective must align with Bloomโ€™s Taxonomy and the three learning domains "
48
- "(cognitive, affective, psychomotor), accurately reflect the intended learning outcome, "
49
- "and meet all 12 professional instructional design standards. "
50
- "**Critical:** You must maximize verb diversity across all objectives โ€” avoid repeating the same "
51
- "verb whenever possible. "
52
- "You must carefully not generate new axes or units, make the objectives Only"
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  ),
 
54
  backstory=(
55
- "You are an expert instructional designer with deep experience in creating professional training programs. "
56
- "You analyze each unit and axis to determine the type of knowledge, skill, or attitude learners "
57
- "should achieve. "
58
- "Then, you write one short, measurable, learner-centered objective for each axis following Bloomโ€™s "
59
- "Taxonomy sequence (Remember โ†’ Understand โ†’ Apply โ†’ Analyze โ†’ Evaluate โ†’ Create). "
60
- "**You are exceptionally skilled at selecting diverse and non-repetitive verbs from Bloomโ€™s Taxonomy "
61
- "and the three learning domains.** "
62
- "You maintain a mental tracker of all verbs used and actively avoid repetition across the entire curriculum. "
63
- "You ensure maximum verb diversity, linguistic precision, and that every objective is "
64
- "clear, measurable, realistic, achievable, and free from ambiguity or linguistic complexity. "
65
- "Your objectives must reflect the parameters of {domain}, {content_type}, {audience}, and {material_type}, "
66
- "while covering the cognitive, psychomotor, and affective domains."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  ),
 
68
  llm=llm_g,
69
  verbose=True,
70
- max_iter=100,
 
71
  )
72
 
73
 
 
 
 
 
74
  objectives_task = Task(
75
  description=(
76
- "You have a complete and well-structured training curriculum provided in {outlines}. "
77
- "### Input Structure Clarification\n"
78
- "The input will contain a full structured outline in JSON format, where each **unit** includes several **axes**."
79
- "Each `axis` represents one **axis**, containing the following keys:"
80
- "- `axis_number`"
81
- "- `title`"
82
- "- `purpose`"
83
- ""
84
- "You must:"
85
- "- Generate **exactly one Arabic learning objective** per `axis`."
86
- "- Use only the content provided in `title` and `purpose`."
87
- "- Do **not invent**, expand, or infer any additional topics or meanings beyond what exists."
88
- "- Keep terminology and concepts consistent with the input text."
89
- "- Maintain the relationship between the unit and its axes."
90
- ""
91
- "---"
92
- ""
93
- "### Output Format"
94
- "The output must include all axes as separate entries, each with:"
95
- "- `unit` (unit title)"
96
- "- `unit_description` (the โ€œfocusโ€ field)"
97
- "- `axis` (axis title)"
98
- "- `module_description` (axis purpose)"
99
- "- `level` (Bloomโ€™s level)"
100
- "- `verbs` (three suggested verbs)"
101
- "- `objective` (one clear Arabic measurable learning objective)"
102
- ""
103
- "---"
104
- ""
105
- "### Example (Simplified)"
106
- "**Example Input:**"
107
- "```json"
108
- "{"
109
- ' "units": ['
110
- " {"
111
- ' "title": "ุงู„ูˆุญุฏุฉ ุงู„ุฃูˆู„ู‰: ู…ู‚ุฏู…ุฉ ููŠ ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ",'
112
- ' "focus": "ูŠุชุนุฑู ุงู„ู…ุชุนู„ู… ุนู„ู‰ ู…ูู‡ูˆู… ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ ูˆุฃู‡ู…ูŠุชู‡.",'
113
- ' "axes": ['
114
- " {"
115
- ' "title": "ุชุนุฑูŠู ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ",'
116
- ' "purpose": "ูŠูู‡ู… ุงู„ู…ุชุนู„ู… ู…ุนู†ู‰ ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ ูˆู…ูƒูˆู†ุงุชู‡."'
117
- " },"
118
- " {"
119
- ' "title": "ุฃู‡ู…ูŠุฉ ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ",'
120
- ' "purpose": "ูŠุดุฑุญ ุงู„ู…ุชุนู„ู… ูƒูŠู ูŠุณุงู‡ู… ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ ููŠ ุญู„ ุงู„ู…ุดูƒู„ุงุช."'
121
- " }"
122
- " ]"
123
- " }"
124
- " ]"
125
  "}\n"
126
- "**Example Output:**"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
  ' "objectives": [\n'
128
  " {\n"
129
- ' "unit": "ุงู„ูˆุญุฏุฉ ุงู„ุฃูˆู„ู‰: ู…ู‚ุฏู…ุฉ ููŠ ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ",\n'
130
- ' "unit_description": "ูŠุชุนุฑู ุงู„ู…ุชุนู„ู… ุนู„ู‰ ู…ูู‡ูˆู… ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ ูˆุฃู‡ู…ูŠุชู‡.",\n'
131
- ' "axis": "ุชุนุฑูŠู ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ",\n'
132
- ' "module_description": "ูŠูู‡ู… ุงู„ู…ุชุนู„ู… ู…ุนู†ู‰ ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ ูˆู…ูƒูˆู†ุงุชู‡.",\n'
133
- ' "level": "Cognitive - Understand",\n'
134
- ' "verbs": ["ูŠูู‡ู…", "ูŠุตู", "ูŠูˆุถุญ"],\n'
135
- ' "objective": "ุฃู† ูŠูุณู‘ุฑ ุงู„ู…ุชุนู„ู… ู…ูู‡ูˆู… ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ ูˆู…ูƒูˆู†ุงุชู‡ ุจุฏู‚ุฉ."\n'
136
  " },\n"
137
  " {\n"
138
- ' "unit": "ุงู„ูˆุญุฏุฉ ุงู„ุฃูˆู„ู‰: ู…ู‚ุฏู…ุฉ ููŠ ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ",\n'
139
- ' "unit_description": "ูŠุชุนุฑู ุงู„ู…ุชุนู„ู… ุนู„ู‰ ู…ูู‡ูˆู… ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ ูˆุฃู‡ู…ูŠุชู‡.",\n'
140
- ' "axis": "ุฃู‡ู…ูŠุฉ ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ",\n'
141
- ' "module_description": "ูŠุดุฑุญ ุงู„ู…ุชุนู„ู… ูƒูŠู ูŠุณุงู‡ู… ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ ููŠ ุญู„ ุงู„ู…ุดูƒู„ุงุช.",\n'
142
  ' "level": "Cognitive - Understand",\n'
143
- ' "verbs": ["ูŠุดุฑุญ", "ูŠุณุชู†ุชุฌ", "ูŠูุณุฑ"],\n'
144
- ' "objective": "ุฃู† ูŠุดุฑุญ ุงู„ู…ุชุนู„ู… ุฏูˆุฑ ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ ููŠ ุญู„ ุงู„ู…ุดูƒู„ุงุช."\n'
145
  " }\n"
 
146
  " ]\n"
147
- "}"
148
- "```\n"
149
- "You must make One Objective per module, not more, not less."
150
- "Very Important: You should carefully validate that the axes you used are the same in outlines that i gived to you above, and the total number of objectives is equal the axes."
151
- "The objectives should aligned with Bloomโ€™s Taxonomy and the three learning domains, and consistent with the purpose of each axis.\n"
152
- "### Step-by-Step Process\n"
153
- "1. Read the curriculum overview to understand the full learning journey.\n"
154
- "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"
155
- "3. **Create a mental or written record of verbs as you use them to avoid repetition.**\n"
156
- "4. For each unit:\n"
157
- " a. Analyze the unit description to understand the learning scope and intended outcomes.\n"
158
- " b. For each axis within that unit:\n"
159
- " - Carefully read the axis title and its purpose.\n"
160
- " - Identify the main learning outcome (Knowledge, Skill, or Attitude/Behavior).\n"
161
- " - **First, determine the appropriate domain: Cognitive (Knowledge), Affective (Attitude), or Psychomotor (Skills).**\n"
162
- " - Choose the most suitable Bloomโ€™s level or the appropriate level of that domain.\n"
163
- " - **From the available verbs at that level, select one that has not been used before (or only minimally used).**\n"
164
- " - Choose three relevant Bloomโ€™s verbs that suit the abilities of {audience}.\n"
165
- " - Write one measurable learning objective in Arabic that accurately reflects the axisโ€™s purpose.\n"
166
- " - **Track the chosen verb to prevent reusing it in later objectives.**\n\n"
167
- "### Requirements for the Three Learning Domains\n"
168
- "**Objectives must cover the three domains in a balanced way:**\n\n"
169
- f"**1. Cognitive Domain (Knowledge):**\n"
170
- f"{objectives_dimensions['Knowledge']['description']}\n"
171
- "**Levels:**\n"
172
- + "\n".join(
173
- [
174
- f" - {level['level_name']}: {level['description']}\n Verbs: {', '.join(level['verbs_examples'])}"
175
- for level in objectives_dimensions["Knowledge"]["levels"]
176
- ]
177
- )
178
- + "\n\n"
179
- f"**2. Affective Domain (Attitude/Ability):**\n"
180
- f"{objectives_dimensions['Ability']['description']}\n"
181
- "**Levels:**\n"
182
- + "\n".join(
183
- [
184
- f" - {level['level_name']}: {level['description']}\n Verbs: {', '.join(level['verbs_examples'])}"
185
- for level in objectives_dimensions["Ability"]["levels"]
186
- ]
187
- )
188
- + "\n\n"
189
- f"**3. Psychomotor Domain (Skills):**\n"
190
- f"{objectives_dimensions['Skills']['description']}\n"
191
- "**Levels:**\n"
192
- + "\n".join(
193
- [
194
- f" - {level['level_name']}: {level['description']}\n Verbs: {', '.join(level['verbs_examples'])}"
195
- for level in objectives_dimensions["Skills"]["levels"]
196
- ]
197
- )
198
- + "\n\n"
199
- "### Critical Requirement: Verb Diversity \n"
200
- "**This is a top-priority rule that must be followed precisely:**\n\n"
201
- "**Verb Non-Repetition Rules:**\n"
202
- "1. **Maximize verb diversity** โ€” each objective should ideally use a different verb than all previous ones.\n"
203
- "2. **Before selecting a verb, check:** Have I used this verb before? If yes, choose another.\n"
204
- "3. **Repeat a verb only when:**\n"
205
- " - All suitable alternative verbs in that Bloom level or domain are exhausted.\n"
206
- " - The axisโ€™s content explicitly requires that verb for accuracy.\n"
207
- " - You can justify why no other verb fits.\n"
208
- "4. **Prioritize diversity over perfect synonyms** โ€” itโ€™s better to use a slightly different but valid verb than to repeat.\n"
209
- "5. **Use the full range of verbs from Bloom and the three domains** โ€” avoid overusing common ones like 'define' or 'explain'.\n"
210
- "6. **Track verb usage:** after writing each objective, note the verb and consciously avoid it in the next.\n"
211
- "7. **If repetition is necessary:**\n"
212
- " - Space it out by at least 3โ€“5 objectives.\n"
213
- " - Add a justification note in your internal reasoning.\n"
214
- " - Try using it in a different context or content area.\n\n"
215
- "### The 12 Mandatory Design Standards โ€” Each Objective Must Meet All\n"
216
- "**Based on the detailed objectives reference document:**\n\n"
217
- "1. **Linked to the general goal:**\n"
218
- " - Every objective must connect to the courseโ€™s overall goal.\n"
219
- " - Example: If the general goal is 'Understand the concept of e-learning', "
220
- "the specific objective could be 'The trainee accurately defines e-learning.'\n\n"
221
- "2. **Measurable:**\n"
222
- " - Objectives must be assessable using measurable performance indicators or outcomes.\n"
223
- " - Correct: 'The trainee compares synchronous and asynchronous learning accurately.'\n"
224
- " - Incorrect: 'The trainee understands e-learning.' (Not measurable)\n\n"
225
- "3. **Achievable:**\n"
226
- " - Realistic, suitable for learner ability and course duration.\n"
227
- " - Correct: 'The trainee applies the steps to create a learning management account.'\n"
228
- " - Incorrect: 'The trainee develops a full e-learning system in one hour.' (Unrealistic)\n\n"
229
- "4. **Covers all three domains (Cognitive, Psychomotor, Affective):**\n"
230
- " - Cognitive: 'The trainee defines e-learning accurately.'\n"
231
- " - Psychomotor: 'The trainee practices using LMS assessment tools.'\n"
232
- " - Affective: 'The trainee demonstrates interest in participating in e-learning activities.'\n\n"
233
- "5. **Aligned with Bloomโ€™s hierarchy:**\n"
234
- " - Objectives must progress logically from lower to higher levels (Remember โ†’ Create).\n\n"
235
- "6. **Clarity and precision:** Objective must be completely clear and specific.\n\n"
236
- "7. **Free from ambiguity:** No vague or overly complex phrasing.\n\n"
237
- "8. **Vocabulary clarity:** All terms must be understandable to {audience}.\n\n"
238
- "9. **Single, focused goal:** Each objective expresses only one learning outcome.\n"
239
- " - Correct: 'The trainee identifies the components of a virtual classroom.'\n"
240
- " - Incorrect: 'The trainee identifies and applies virtual classroom components.'\n\n"
241
- "10. **Realistic and feasible:** Achievable within program time and resources.\n\n"
242
- "11. **Consistent with program outcomes:** Must align with the general and specific learning outcomes.\n\n"
243
- "12. **Content-linked:** Directly related to the unit or module content.\n\n"
244
- "### Objective Writing Rules\n"
245
- "- One objective per axis โ€” no more, no less.\n"
246
- "- Each must directly and precisely reflect the axisโ€™s purpose.\n"
247
- "- Follow Bloomโ€™s sequence within each unit (from lower to higher order thinking).\n"
248
- "- If a level doesnโ€™t logically fit, skip it but maintain general progression.\n"
249
- "- You may combine two levels (e.g., Understand + Apply) if justified by axis purpose.\n"
250
- "- Start each objective with '[verb in present]' and keep length between 6โ€“10 words.\n"
251
- "- Use verbs suitable for {audience} โ€” e.g., children cannot 'evaluate' or 'analyze' like professionals.\n"
252
- "- **Core rule: Avoid verb repetition โ€” use the widest possible range from all three domains.**\n"
253
- "- Ensure objectives are **measurable** and **achievable**.\n"
254
- "- Maintain linguistic clarity โ€” no vague or double meanings.\n"
255
- "- Each objective must express only one precise learning outcome.\n\n"
256
- "### Strategies for Verb Diversity\n"
257
- "**Use these strategies to ensure maximum variety:**\n\n"
258
- "- **Alternate synonyms:**\n"
259
- " - Instead of always 'define', use: name, list, mention, identify, classify, select.\n"
260
- "- **Use less common verbs:**\n"
261
- " - Distinguish, infer, demonstrate, interpret, justify, summarize, illustrate.\n"
262
- "- **Match verbs to content type:**\n"
263
- " - Use verbs that capture the learning result precisely.\n"
264
- "- **Consult the full domain verb lists** (above) with 5โ€“7 verbs per level.\n"
265
- "- **Distribute objectives across the three domains** โ€” avoid focusing only on the cognitive domain.\n\n"
266
- "### Examples of Correct and Incorrect Objectives\n\n"
267
- "**Correct Examples (Good verb diversity and domain balance):**\n"
268
- "1. (Cognitive - Remember): The trainee lists five types of e-learning platforms.\n"
269
- "2. (Cognitive - Understand): The trainee distinguishes between various digital assessment tools.\n"
270
- "3. (Cognitive - Apply): The trainee applies active learning strategies in the classroom.\n"
271
- "4. (Cognitive - Understand): The trainee infers the main benefits of blended learning.\n"
272
- "5. (Psychomotor - Practice): The trainee practices designing an interactive learning activity.\n"
273
- "6. (Affective - Respond): The trainee actively participates in collaborative learning discussions.\n"
274
- "7. (Cognitive - Analyze): The trainee compares different instructional design models.\n"
275
- "8. (Psychomotor - Adapt): The trainee adjusts learning activities to meet learner needs.\n\n"
276
- "**Incorrect Examples (Verb repetition โ€” avoid this):**\n"
277
- "1. The trainee defines the types of e-learning platforms.\n"
278
- "2. The trainee defines digital assessment tools.\n"
279
- "3. The trainee defines active learning strategies.\n"
280
- "4. The trainee defines blended learning benefits.\n"
281
- "5. The trainee defines steps of activity design.\n\n"
282
- "**Unclear or Unmeasurable Objectives:**\n"
283
- "- 'The trainee understands e-learning.' (Vague, not measurable)\n"
284
- "- 'The trainee learns how to use tools.' (Unclear โ€” which tools?)\n"
285
- "- 'The trainee becomes an expert in instructional design.' (Unrealistic, not measurable)\n\n"
286
- "**Improved Versions:**\n"
287
- "- 'The trainee accurately defines e-learning.'\n"
288
- "- 'The trainee effectively uses LMS tools.'\n"
289
- "- 'The trainee applies instructional design principles to create a learning unit.'\n\n"
290
- "### Critical Quality Checklist โ€” Verify Before Finalizing Each Objective:\n"
291
- "1. โœ“ Is it clear and accurately expresses the intended outcome?\n"
292
- "2. โœ“ Does it align with a Bloomโ€™s level or learning domain?\n"
293
- "3. โœ“ Is it free from ambiguity?\n"
294
- "4. โœ“ Is all vocabulary appropriate for {audience}?\n"
295
- "5. โœ“ Does it express only one learning outcome?\n"
296
- "6. โœ“ Is it measurable through observable performance?\n"
297
- "7. โœ“ Is it realistic and achievable?\n"
298
- "8. โœ“ Does it align with the overall outcomes?\n"
299
- "9. โœ“ Is it directly linked to the axis content?\n"
300
- "10. โœ“ Is it sequenced logically (simple โ†’ complex)?\n"
301
- "11. โœ“ Is it suitable for the learnersโ€™ level?\n"
302
- "12. โœ“ Do all objectives collectively cover knowledge, skills, and attitudes?\n"
303
- "**13. Verb Check: Have you reused this verb? If yes, can you replace it?**\n"
304
- "**14. Domain Check: Are the objectives balanced across all three domains?**\n\n"
305
- "### Self-Reflection Requirement\n"
306
- "After generating all objectives for a unit, pause and evaluate:\n"
307
- "- Do objectives progress logically through Bloomโ€™s levels?\n"
308
- "- **How many unique verbs did you use? Any repetition?**\n"
309
- "- **Can any repeated verbs be replaced with alternatives?**\n"
310
- "- Are verbs diverse and contextually appropriate?\n"
311
- "- **Do objectives cover all three domains evenly?**\n"
312
- "- Can an external evaluator assess each objective clearly?\n"
313
- "- Are all objectives realistic for {audience} and course duration?\n\n"
314
- "### Final Verification: Verb Diversity & Domain Balance\n"
315
- "**Before submitting your final output:**\n"
316
- "1. Count how many times each verb appears.\n"
317
- "2. If any verb appears more than 2โ€“3 times, review and replace it where possible.\n"
318
- "3. Aim for at least 70โ€“80% unique verbs across the entire curriculum.\n"
319
- "4. Keep a mental record of verb use for ongoing awareness.\n"
320
- "5. **Check balanced distribution:**\n"
321
- " - Cognitive (Knowledge): 50โ€“60% of objectives\n"
322
- " - Affective (Attitude): 20โ€“30% of objectives\n"
323
- " - Psychomotor (Skills): 20โ€“30% of objectives\n"
324
- "6. If imbalance occurs, revisit and adjust classifications.\n\n"
325
- "### Domain-Specific Guidelines\n\n"
326
- "**When writing Cognitive (Knowledge) objectives:**\n"
327
- "- Use for topics focused on information, understanding, applying, analyzing, evaluating, or creating.\n"
328
- "- Examples: 'The trainee defines...', 'The trainee compares...', 'The trainee designs...'.\n\n"
329
- "**When writing Affective (Attitude) objectives:**\n"
330
- "- Use for topics involving values, emotions, interests, or behaviors.\n"
331
- "- Examples: 'The trainee demonstrates interest in...', 'The trainee participates actively...', 'The trainee commits to...'.\n\n"
332
- "**When writing Psychomotor (Skills) objectives:**\n"
333
- "- Use for topics requiring physical, technical, or procedural performance.\n"
334
- "- Examples: 'The trainee practices...', 'The trainee performs...', 'The trainee innovates...'.\n\n"
335
- "### Final Important Notes\n"
336
- "- **Top Priority:** Verb diversity and balanced domain distribution.\n"
337
- "- **Quality over quantity:** One well-crafted, diverse objective is better than several repetitive ones.\n"
338
- "- **Flexibility with precision:** Be flexible in verb choice but never compromise on accuracy.\n"
339
- "- **Continuous review:** Revisit objectives regularly for diversity and balance.\n"
340
- "- **Context matters:** Always choose the verb that best reflects what the learner should achieve in that specific axis.\n"
341
  ),
342
- expected_output="""{
343
- "objectives": [
344
- {
345
- "unit": "Unit title",
346
- "unit_description": "Brief summary of the unit scope",
347
- "axis": "axis title",
348
- "module_description": "Brief summary of what this axis covers",
349
- "level": "Bloom's level assigned based on axis analysis",
350
- "verbs": ["verb1", "verb2", "verb3"],
351
- "objective": "One measurable Arabic objective derived from the axis purpose",
352
- }
353
- ],
354
- }""",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
355
  output_json=ObjectivesOutput,
356
  agent=objectives_generator,
357
- human_input=False,
358
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”
3
+ ๐Ÿ“š Objectives Generator Agent - Learning Objectives Designer
4
+ โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”
5
+
6
+ ุงู„ู‡ุฏู: ุชูˆู„ูŠุฏ ุฃู‡ุฏุงู ุชุนู„ูŠู…ูŠุฉ ูˆุงุถุญุฉ ูˆู‚ุงุจู„ุฉ ู„ู„ู‚ูŠุงุณ ู„ูƒู„ ู…ุญูˆุฑ (axis) ููŠ ุงู„ู…ู†ู‡ุฌ ุงู„ุชุฏุฑูŠุจูŠ.
7
+
8
+ ุงู„ู…ุฏุฎู„ุงุช:
9
+ ---------
10
+ 1. topic: ู…ูˆุถูˆุน ุงู„ุชุฏุฑูŠุจ ุงู„ุฑุฆูŠุณูŠ
11
+ 2. domain: ุงู„ู…ุฌุงู„ (Management, Technology, etc.)
12
+ 3. content_type: ู†ูˆุน ุงู„ู…ุญุชูˆู‰ (Educational, Training, etc.)
13
+ 4. audience: ุงู„ูุฆุฉ ุงู„ู…ุณุชู‡ุฏูุฉ (Professionals, Students, etc.)
14
+ 5. material_type: ู†ูˆุน ุงู„ู…ุงุฏุฉ (Conceptual, Procedural, etc.)
15
+ 6. outlines: ุงู„ุจู†ูŠุฉ ุงู„ูƒุงู…ู„ุฉ ู„ู„ู…ู†ู‡ุฌ ู…ู† outliner agent
16
+
17
+ ุงู„ุจู†ูŠุฉ ุงู„ู…ุชูˆู‚ุนุฉ ู„ู„ู€ outlines:
18
+ {
19
+ "units": [
20
+ {
21
+ "unit_number": 1,
22
+ "title": "ุนู†ูˆุงู† ุงู„ูˆุญุฏุฉ",
23
+ "focus": "ูˆุตู ุงู„ูˆุญุฏุฉ",
24
+ "axes": [
25
+ {
26
+ "axis_number": 1,
27
+ "title": "ุนู†ูˆุงู† ุงู„ู…ุญูˆุฑ",
28
+ "purpose": "ุงู„ุบุฑุถ ู…ู† ุงู„ู…ุญูˆุฑ"
29
+ },
30
+ ...
31
+ ]
32
+ },
33
+ ...
34
+ ]
35
+ }
36
+
37
+ ุงู„ู…ุฎุฑุฌุงุช:
38
+ --------
39
+ {
40
+ "objectives": [
41
+ {
42
+ "unit": "ุนู†ูˆุงู† ุงู„ูˆุญุฏุฉ",
43
+ "unit_description": "ูˆุตู ุงู„ูˆุญุฏุฉ",
44
+ "axis": "ุนู†ูˆุงู† ุงู„ู…ุญูˆุฑ",
45
+ "module_description": "ุงู„ุบุฑุถ ู…ู† ุงู„ู…ุญูˆุฑ",
46
+ "level": "Cognitive - Understand",
47
+ "verbs": ["ูุนู„1", "ูุนู„2", "ูุนู„3"],
48
+ "objective": "ุฃู† ูŠุญู‚ู‚ ุงู„ู…ุชุนู„ู…..."
49
+ },
50
+ ...
51
+ ]
52
+ }
53
+
54
+ ุงู„ู‚ูˆุงุนุฏ ุงู„ุฃุณุงุณูŠุฉ:
55
+ ----------------
56
+ โœ… ู‡ุฏู ูˆุงุญุฏ ูู‚ุท ู„ูƒู„ ู…ุญูˆุฑ (axis) - ู„ุง ุฃูƒุซุฑ ูˆู„ุง ุฃู‚ู„
57
+ โœ… ุงุณุชุฎุฏุงู… ุฃูุนุงู„ ู…ุชู†ูˆุนุฉ ู…ู† ุชุตู†ูŠู ุจู„ูˆู… ูˆุงู„ู…ุฌุงู„ุงุช ุงู„ุซู„ุงุซุฉ
58
+ โœ… ุนุฏู… ุชูƒุฑุงุฑ ู†ูุณ ุงู„ูุนู„ ู‚ุฏุฑ ุงู„ุฅู…ูƒุงู†
59
+ โœ… ุงู„ุชุฏุฑุฌ ุงู„ู…ู†ุทู‚ูŠ ููŠ ู…ุณุชูˆูŠุงุช ุจู„ูˆู… ุฏุงุฎู„ ูƒู„ ูˆุญุฏุฉ
60
+ โœ… ุงู„ุฃู‡ุฏุงู ู‚ุงุจู„ุฉ ู„ู„ู‚ูŠุงุณ ูˆุงู„ุชุญู‚ู‚
61
+ โœ… ุงู„ุฃู‡ุฏุงู ูˆุงุถุญุฉ ูˆู…ุญุฏุฏุฉ ุจุฏูˆู† ุบู…ูˆุถ
62
+ โœ… ู…ู†ุงุณุจุฉ ู„ู…ุณุชูˆู‰ ุงู„ุฌู…ู‡ูˆุฑ ุงู„ู…ุณุชู‡ุฏู
63
+
64
+ โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”
65
+ """
66
+
67
+ from crewai import Agent, Task, Crew, Process
68
  from modules import bloom_taxonomy_2, objectives_dimensions, llm_g
69
  from schemas import ObjectivesOutput
70
+ import json
71
 
72
 
73
+ # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
74
+ # ๐Ÿ”ง Helper Functions
75
+ # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
76
 
77
+ def get_bloom_verb(level: str) -> str:
78
+ """
79
+ ุงุณุชุฎุฑุงุฌ ุงู„ุฃูุนุงู„ ู…ู† ู…ุณุชูˆู‰ ู…ุญุฏุฏ ููŠ ุชุตู†ูŠู ุจู„ูˆู….
80
+
81
+ Args:
82
+ level: ุงุณู… ุงู„ู…ุณุชูˆู‰ (ู…ุซู„ "Remember", "Understand", "Apply")
83
+
84
+ Returns:
85
+ str: ุงู„ุฃูุนุงู„ ุงู„ู…ุชุงุญุฉ ู„ู‡ุฐุง ุงู„ู…ุณุชูˆู‰
86
+
87
+ Raises:
88
+ ValueError: ุฅุฐุง ูƒุงู† ุงู„ู…ุณุชูˆู‰ ุบูŠุฑ ู…ูˆุฌูˆุฏ
89
+ """
90
  if level not in bloom_taxonomy_2:
91
+ raise ValueError(f"โŒ Invalid Bloom level: {level}")
92
+
93
  verbs_key = [k for k in bloom_taxonomy_2[level].keys() if "_verbs_examples" in k][0]
94
  return bloom_taxonomy_2[level][verbs_key]
95
 
96
 
97
+ def get_verbs_by_domain_and_level(domain: str, level_name: str) -> list:
98
  """
99
+ ุงุณุชุฎุฑุงุฌ ุงู„ุฃูุนุงู„ ุงู„ู…ู†ุงุณุจุฉ ู…ู† ู‚ุงู…ูˆุณ ุงู„ุฃุจุนุงุฏ ุงู„ุชุนู„ูŠู…ูŠุฉ.
100
+
101
  Args:
102
+ domain: "Knowledge" (ุงู„ู…ุนุฑููŠ), "Ability" (ุงู„ูˆุฌุฏุงู†ูŠ), or "Skills" (ุงู„ู…ู‡ุงุฑูŠ)
103
  level_name: ุงุณู… ุงู„ู…ุณุชูˆู‰ ู…ุซู„ "Remember", "Response", "Practice"
104
+
105
  Returns:
106
+ list: ู‚ุงุฆู…ุฉ ุจุงู„ุฃูุนุงู„ ุงู„ู…ุชุงุญ๏ฟฝ๏ฟฝ ู„ู‡ุฐุง ุงู„ู…ุฌุงู„ ูˆุงู„ู…ุณุชูˆู‰
107
  """
108
  if domain not in objectives_dimensions:
109
  return []
110
+
111
  for level in objectives_dimensions[domain]["levels"]:
112
  if level_name.lower() in level["level_name"].lower():
113
  return level["verbs_examples"]
114
+
115
  return []
116
 
117
 
118
+ def format_domain_levels_info() -> str:
119
+ """
120
+ ุชู†ุณูŠู‚ ู…ุนู„ูˆู…ุงุช ุงู„ู…ุฌุงู„ุงุช ุงู„ุชุนู„ูŠู…ูŠุฉ ุงู„ุซู„ุงุซุฉ ูˆู…ุณุชูˆูŠุงุชู‡ุง ู„ุงุณุชุฎุฏุงู…ู‡ุง ููŠ ุงู„ู€ prompt.
121
+
122
+ Returns:
123
+ str: ู†ุต ู…ู†ุณู‚ ูŠุญุชูˆูŠ ุนู„ู‰ ุฌู…ูŠุน ุงู„ู…ุฌุงู„ุงุช ูˆู…ุณุชูˆูŠุงุชู‡ุง ูˆุงู„ุฃูุนุงู„
124
+ """
125
+ domains_info = []
126
+
127
+ # 1. ุงู„ู…ุฌุงู„ ุงู„ู…ุนุฑููŠ (Cognitive/Knowledge)
128
+ domains_info.append(f"**1. Cognitive Domain (Knowledge):**\n")
129
+ domains_info.append(f"{objectives_dimensions['Knowledge']['description']}\n")
130
+ domains_info.append("**Levels:**\n")
131
+ for level in objectives_dimensions["Knowledge"]["levels"]:
132
+ domains_info.append(
133
+ f" - {level['level_name']}: {level['description']}\n"
134
+ f" Verbs: {', '.join(level['verbs_examples'])}\n"
135
+ )
136
+
137
+ # 2. ุงู„ู…ุฌุงู„ ุงู„ูˆุฌุฏุงู†ูŠ (Affective/Ability)
138
+ domains_info.append(f"\n**2. Affective Domain (Attitude/Ability):**\n")
139
+ domains_info.append(f"{objectives_dimensions['Ability']['description']}\n")
140
+ domains_info.append("**Levels:**\n")
141
+ for level in objectives_dimensions["Ability"]["levels"]:
142
+ domains_info.append(
143
+ f" - {level['level_name']}: {level['description']}\n"
144
+ f" Verbs: {', '.join(level['verbs_examples'])}\n"
145
+ )
146
+
147
+ # 3. ุงู„ู…ุฌุงู„ ุงู„ู…ู‡ุงุฑูŠ (Psychomotor/Skills)
148
+ domains_info.append(f"\n**3. Psychomotor Domain (Skills):**\n")
149
+ domains_info.append(f"{objectives_dimensions['Skills']['description']}\n")
150
+ domains_info.append("**Levels:**\n")
151
+ for level in objectives_dimensions["Skills"]["levels"]:
152
+ domains_info.append(
153
+ f" - {level['level_name']}: {level['description']}\n"
154
+ f" Verbs: {', '.join(level['verbs_examples'])}\n"
155
+ )
156
+
157
+ return "".join(domains_info)
158
+
159
+
160
+ # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
161
+ # ๐Ÿค– Agent Definition
162
+ # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
163
+
164
  objectives_generator = Agent(
165
+ role="Expert Learning Objectives Designer (ู…ุตู…ู… ุงู„ุฃู‡ุฏุงู ุงู„ุชุนู„ูŠู…ูŠุฉ ุงู„ู…ุชุฎุตุต)",
166
+
167
  goal=(
168
+ "Design clear, measurable, and achievable learning objectives in Arabic "
169
+ "for EACH AXIS in the training curriculum.\n\n"
170
+
171
+ "๐ŸŽฏ **Critical Rules:**\n"
172
+ "1. Generate **EXACTLY ONE objective per axis** - no more, no less\n"
173
+ "2. Each objective must be based on:\n"
174
+ " - The axis title\n"
175
+ " - The axis purpose\n"
176
+ " - The unit description (focus)\n"
177
+ "3. **DO NOT** create new axes or units - work ONLY with provided axes\n"
178
+ "4. **DO NOT** invent, expand, or infer additional topics\n"
179
+ "5. Maximize verb diversity - avoid repeating verbs\n"
180
+ "6. Follow Bloom's Taxonomy progression within each unit\n"
181
+ "7. Balance objectives across three domains:\n"
182
+ " - Cognitive (Knowledge): 50-60%\n"
183
+ " - Affective (Attitude): 20-30%\n"
184
+ " - Psychomotor (Skills): 20-30%\n\n"
185
+
186
+ "๐Ÿ“Š **Input Data:**\n"
187
+ "- Topic: {topic}\n"
188
+ "- Domain: {domain}\n"
189
+ "- Content Type: {content_type}\n"
190
+ "- Audience: {audience}\n"
191
+ "- Material Type: {material_type}\n"
192
+ "- Outlines: {outlines}"
193
  ),
194
+
195
  backstory=(
196
+ "ุฃู†ุช ุฎุจูŠุฑ ุชุตู…ูŠู… ุชุนู„ูŠู…ูŠ (Instructional Designer) ู…ุชุฎุตุต ููŠ ูƒุชุงุจุฉ ุงู„ุฃู‡ุฏุงู ุงู„ุชุนู„ูŠู…ูŠุฉ.\n\n"
197
+
198
+ "๐ŸŽ“ **ุฎุจุฑุงุชูƒ:**\n"
199
+ "- ุฎุจุฑุฉ ุนู…ูŠู‚ุฉ ููŠ ุชุตู†ูŠู ุจู„ูˆู… (Bloom's Taxonomy)\n"
200
+ "- ุฅุชู‚ุงู† ุงู„ู…ุฌุงู„ุงุช ุงู„ุชุนู„ูŠู…ูŠุฉ ุงู„ุซู„ุงุซุฉ (ุงู„ู…ุนุฑููŠุŒ ุงู„ูˆุฌุฏุงู†ูŠุŒ ุงู„ู…ู‡ุงุฑูŠ)\n"
201
+ "- ู…ู‡ุงุฑุฉ ุนุงู„ูŠุฉ ููŠ ุงุฎุชูŠุงุฑ ุฃูุนุงู„ ู…ุชู†ูˆุนุฉ ูˆุบูŠุฑ ู…ุชูƒุฑุฑุฉ\n"
202
+ "- ู‚ุฏุฑุฉ ุนู„ู‰ ุชุญู„ูŠู„ ุงู„ู…ุญุงูˆุฑ ูˆุชุญุฏูŠุฏ ู†ูˆุน ุงู„ู‡ุฏู ุงู„ู…ู†ุงุณุจ (ู…ุนุฑูุฉุŒ ู…ู‡ุงุฑุฉุŒ ุงุชุฌุงู‡)\n"
203
+ "- ุงู„ุชุฒุงู… ุจุงู„ู…ุนุงูŠูŠุฑ ุงู„ู€ 12 ู„ู„ุชุตู…ูŠู… ุงู„ุชุนู„ูŠู…ูŠ ุงู„ุงุญุชุฑุงููŠ\n\n"
204
+
205
+ "๐Ÿ“ **ู…ู†ู‡ุฌูŠุชูƒ:**\n"
206
+ "1. ุชู‚ุฑุฃ ูˆุชุญู„ู„ ูƒู„ ู…ุญูˆุฑ (axis) ุจุนู†ุงูŠุฉ:\n"
207
+ " - ุนู†ูˆุงู† ุงู„ู…ุญูˆุฑ (title)\n"
208
+ " - ุบุฑุถ ุงู„ู…ุญูˆุฑ (purpose)\n"
209
+ " - ุณูŠุงู‚ ุงู„ูˆุญุฏุฉ (unit focus)\n"
210
+ "2. ุชุญุฏุฏ ู†ูˆุน ุงู„ุชุนู„ู… ุงู„ู…ุทู„ูˆุจ:\n"
211
+ " - ู…ุนุฑูุฉ (Knowledge) โ†’ Cognitive domain\n"
212
+ " - ู…ู‡ุงุฑุฉ (Skill) โ†’ Psychomotor domain\n"
213
+ " - ุงุชุฌุงู‡/ุณู„ูˆูƒ (Attitude) โ†’ Affective domain\n"
214
+ "3. ุชุฎุชุงุฑ ู…ุณุชูˆู‰ ุจู„ูˆู… ุงู„ู…ู†ุงุณุจ ุจู†ุงุกู‹ ุนู„ู‰:\n"
215
+ " - ุทุจูŠุนุฉ ุงู„ู…ุญูˆุฑ\n"
216
+ " - ุงู„ุชุฏุฑุฌ ุงู„ู…ู†ุทู‚ูŠ ุฏุงุฎู„ ุงู„ูˆุญุฏุฉ\n"
217
+ " - ู‚ุฏุฑุงุช ุงู„ุฌู…ู‡ูˆุฑ ุงู„ู…ุณุชู‡ุฏู\n"
218
+ "4. ุชุฎุชุงุฑ ูุนู„ุงู‹ **ู„ู… ูŠุณุชุฎุฏู… ู…ู† ู‚ุจู„** ู…ู† ุงู„ู…ุณุชูˆู‰ ุงู„ู…ุฎุชุงุฑ\n"
219
+ "5. ุชูƒุชุจ ู‡ุฏูุงู‹ ูˆุงุญุฏุงู‹ ูˆุงุถุญุงู‹ ู‚ุงุจู„ุงู‹ ู„ู„ู‚ูŠุงุณ ุจุงู„ุนุฑุจูŠุฉ\n"
220
+ "6. ุชุชุงุจุน ุงู„ุฃูุนุงู„ ุงู„ู…ุณุชุฎุฏู…ุฉ ู„ุชุฌู†ุจ ุงู„ุชูƒุฑุงุฑ\n\n"
221
+
222
+ "๐ŸŽฏ **ุฃู‡ุฏุงููƒ:**\n"
223
+ "- ุฏู‚ุฉ ู„ุบูˆูŠุฉ ุนุงู„ูŠุฉ - ุจุฏูˆู† ุบู…ูˆุถ ุฃูˆ ุชุนู‚ูŠุฏ\n"
224
+ "- ุชู†ูˆุน ุฃู‚ุตู‰ ููŠ ุงู„ุฃูุนุงู„ - ุชุฌู†ุจ ุงู„ุชูƒุฑุงุฑ\n"
225
+ "- ุชูˆุงุฒู† ุจูŠู† ุงู„ู…ุฌุงู„ุงุช ุงู„ุซู„ุงุซุฉ\n"
226
+ "- ู‚ุงุจู„ูŠุฉ ู„ู„ู‚ูŠุงุณ ูˆุงู„ุชุญู‚ู‚\n"
227
+ "- ู…ู„ุงุกู…ุฉ ู„ู…ุณุชูˆู‰ {audience}\n"
228
+ "- ุงุชุณุงู‚ ู…ุน {domain}, {content_type}, {material_type}"
229
  ),
230
+
231
  llm=llm_g,
232
  verbose=True,
233
+ max_iter=150, # ุฒูŠุงุฏุฉ ุนุฏุฏ ุงู„ุชูƒุฑุงุฑุงุช ู„ู„ุฏู‚ุฉ
234
+ allow_delegation=False
235
  )
236
 
237
 
238
+ # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
239
+ # ๐Ÿ“‹ Task Definition
240
+ # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
241
+
242
  objectives_task = Task(
243
  description=(
244
+ "# ๐Ÿ“š Generate Learning Objectives for Training Curriculum\n\n"
245
+
246
+ "## ๐Ÿ“ฅ Input Structure\n\n"
247
+ "You will receive a complete curriculum structure in `{outlines}` with the following format:\n\n"
248
+ "```json\n"
249
+ "{\n"
250
+ ' "units": [\n'
251
+ " {\n"
252
+ ' "unit_number": 1,\n'
253
+ ' "title": "ุนู†ูˆุงู† ุงู„ูˆุญุฏุฉ",\n'
254
+ ' "focus": "ูˆุตู ุงู„ูˆุญุฏุฉ ูˆุงู„ู‡ุฏู ุงู„ุนุงู… ู…ู†ู‡ุง",\n'
255
+ ' "axes": [\n'
256
+ " {\n"
257
+ ' "axis_number": 1,\n'
258
+ ' "title": "ุนู†ูˆุงู† ุงู„ู…ุญูˆุฑ",\n'
259
+ ' "purpose": "ุงู„ุบุฑุถ ู…ู† ุชุฏุฑูŠุณ ู‡ุฐุง ุงู„ู…ุญูˆุฑ"\n'
260
+ " },\n"
261
+ " ...\n"
262
+ " ]\n"
263
+ " },\n"
264
+ " ...\n"
265
+ " ]\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
266
  "}\n"
267
+ "```\n\n"
268
+
269
+ "## ๐ŸŽฏ Your Mission\n\n"
270
+ "Generate **EXACTLY ONE learning objective** for **EACH axis** in **EVERY unit**.\n\n"
271
+
272
+ "### โœ… Requirements:\n\n"
273
+ "1. **One-to-One Mapping:**\n"
274
+ " - If there are 20 axes total โ†’ generate 20 objectives\n"
275
+ " - Each axis gets exactly 1 objective\n"
276
+ " - No axis should be missed\n"
277
+ " - No extra objectives\n\n"
278
+
279
+ "2. **Content Fidelity:**\n"
280
+ " - Use ONLY the `title` and `purpose` from each axis\n"
281
+ " - Use the `focus` from the unit for context\n"
282
+ " - DO NOT invent new content\n"
283
+ " - DO NOT expand beyond what's given\n"
284
+ " - Keep terminology consistent with input\n\n"
285
+
286
+ "3. **Output Structure:**\n"
287
+ " Each objective must include:\n"
288
+ " ```json\n"
289
+ " {\n"
290
+ ' "unit": "ุนู†ูˆุงู† ุงู„ูˆุญุฏุฉ (from unit.title)",\n'
291
+ ' "unit_description": "ูˆุตู ุงู„ูˆุญุฏุฉ (from unit.focus)",\n'
292
+ ' "axis": "ุนู†ูˆุงู† ุงู„ู…ุญูˆุฑ (from axis.title)",\n'
293
+ ' "module_description": "ุงู„ุบุฑุถ ู…ู† ุงู„ู…ุญูˆุฑ (from axis.purpose)",\n'
294
+ ' "level": "Cognitive - Understand",\n'
295
+ ' "verbs": ["ูุนู„1", "ูุนู„2", "ูุนู„3"],\n'
296
+ ' "objective": "ุฃู† ูŠุญู„ู„ ุงู„ู…ุชุนู„ู…..."\n'
297
+ " }\n"
298
+ " ```\n\n"
299
+
300
+ "## ๐Ÿ“– Bloom's Taxonomy and Learning Domains\n\n"
301
+ f"{format_domain_levels_info()}\n\n"
302
+
303
+ "## ๐Ÿ”ฅ Critical Requirement: Verb Diversity\n\n"
304
+ "**This is your TOP PRIORITY - follow these rules precisely:**\n\n"
305
+
306
+ "### Verb Non-Repetition Rules:\n\n"
307
+ "1. **Maximize diversity** - each objective should use a DIFFERENT verb\n"
308
+ "2. **Before selecting:** Check if you've used this verb before\n"
309
+ "3. **Track usage:** Keep a mental record of all verbs used\n"
310
+ "4. **Only repeat when:**\n"
311
+ " - All alternatives in that level are exhausted\n"
312
+ " - The axis content explicitly requires it\n"
313
+ " - You can justify why no other verb fits\n"
314
+ "5. **If you must repeat:**\n"
315
+ " - Space it out by at least 3-5 objectives\n"
316
+ " - Use it in a different domain or context\n"
317
+ "6. **Aim for:** 70-80% unique verbs across all objectives\n\n"
318
+
319
+ "### Strategies for Diversity:\n\n"
320
+ "- **Instead of 'ูŠุนุฑู':** use ูŠุฐูƒุฑ, ูŠุญุฏุฏ, ูŠุณู…ูŠ, ูŠุนุฏุฏ, ูŠุณุชุฑุฌุน, ูŠุตู†ู\n"
321
+ "- **Instead of 'ูŠูู‡ู…':** use ูŠูุณุฑ, ูŠุณุชู†ุชุฌ, ูŠุตู, ูŠู…ูŠุฒ, ูŠุดุฑุญ, ูŠู„ุฎุต\n"
322
+ "- **Instead of 'ูŠุทุจู‚':** use ูŠุณุชุฎุฏู…, ูŠุฌุฑุจ, ูŠุจุฑู‡ู†, ูŠู†ูุฐ, ูŠุญู„, ูŠูˆุธู\n"
323
+ "- Use less common verbs: ูŠู…ูŠุฒ, ูŠุณุชุฎู„ุต, ูŠุจุฑุฑ, ูŠูˆุงุฒู†, ูŠุฑูƒุจ, ูŠุฏู…ุฌ\n"
324
+ "- Alternate between domains: Cognitive โ†’ Affective โ†’ Psychomotor\n\n"
325
+
326
+ "## ๐Ÿ“ The 12 Mandatory Design Standards\n\n"
327
+ "Each objective MUST meet ALL of these criteria:\n\n"
328
+
329
+ "1. **Linked to general goal:** Connects to course's overall objective\n"
330
+ "2. **Measurable:** Can be assessed through observable performance\n"
331
+ " - โœ… Good: 'ูŠุญู„ู„ ุงู„ู…ุชุนู„ู… ู…ูƒูˆู†ุงุช ุงู„ุนู…ู„ูŠุฉ ุจุฏู‚ุฉ'\n"
332
+ " - โŒ Bad: 'ูŠูู‡ู… ุงู„ู…ุชุนู„ู… ุงู„ุนู…ู„ูŠุฉ' (not measurable)\n"
333
+ "3. **Achievable:** Realistic for learner ability and course duration\n"
334
+ "4. **Domain coverage:** Balance across Cognitive, Affective, Psychomotor\n"
335
+ "5. **Bloom's alignment:** Progress logically (Remember โ†’ Create)\n"
336
+ "6. **Clear and precise:** Completely unambiguous\n"
337
+ "7. **No vagueness:** Avoid complex or unclear phrasing\n"
338
+ "8. **Appropriate vocabulary:** Suitable for {audience}\n"
339
+ "9. **Single focus:** One outcome per objective\n"
340
+ " - โœ… Good: 'ูŠุญุฏุฏ ุงู„ู…ุชุนู„ู… ู…ูƒูˆู†ุงุช ุงู„ู†ุธุงู…'\n"
341
+ " - โŒ Bad: 'ูŠุญุฏุฏ ูˆูŠุทุจู‚ ุงู„ู…ุชุนู„ู… ู…ูƒูˆู†ุงุช ุงู„ู†ุธุงู…' (two actions)\n"
342
+ "10. **Realistic and feasible:** Within program resources\n"
343
+ "11. **Consistent with outcomes:** Aligns with program goals\n"
344
+ "12. **Content-linked:** Directly relates to axis content\n\n"
345
+
346
+ "## โœ๏ธ Objective Writing Rules\n\n"
347
+ "- **Format:** Start with 'ุฃู†' or 'ูŠู€' + present verb\n"
348
+ "- **Length:** 6-10 words (concise and clear)\n"
349
+ "- **Language:** Modern Standard Arabic\n"
350
+ "- **Tone:** Professional and academic\n"
351
+ "- **Structure:** Subject + Verb + Object + Condition (if needed)\n"
352
+ "- **Examples:**\n"
353
+ " - 'ุฃู† ูŠุญู„ู„ ุงู„ู…ุชุนู„ู… ู…ุฑุงุญู„ ุงู„ุนู…ู„ูŠุฉ ุงู„ุชุตู…ูŠู…ูŠุฉ ุจุฏู‚ุฉ.'\n"
354
+ " - 'ูŠุทุจู‚ ุงู„ู…ุชุฏุฑุจ ุชู‚ู†ูŠุงุช ุงู„ุชุนุงุทู ููŠ ู…ุดุฑูˆุน ูˆุงู‚ุนูŠ.'\n"
355
+ " - 'ูŠู‚ุฏุฑ ุงู„ู…ุชุนู„ู… ุฃู‡ู…ูŠุฉ ุงู„ุชููƒูŠุฑ ุงู„ู…ุชุนุฏุฏ ุงู„ู…ู†ุธูˆุฑุงุช.'\n\n"
356
+
357
+ "## ๐Ÿ“‹ Step-by-Step Process\n\n"
358
+ "Follow this systematic approach:\n\n"
359
+
360
+ "### Phase 1: Preparation\n"
361
+ "1. Read the ENTIRE curriculum to understand the learning journey\n"
362
+ "2. Review ALL Bloom's verbs and domain levels\n"
363
+ "3. Create a mental tracker for verb usage\n"
364
+ "4. Count total number of axes to know expected output size\n\n"
365
+
366
+ "### Phase 2: For Each Unit\n"
367
+ "1. Read the unit title and focus carefully\n"
368
+ "2. Understand the unit's scope and intended outcomes\n"
369
+ "3. Note the unit's position in the overall curriculum\n\n"
370
+
371
+ "### Phase 3: For Each Axis in the Unit\n"
372
+ "1. **Analyze:**\n"
373
+ " - Read axis title\n"
374
+ " - Read axis purpose\n"
375
+ " - Understand what learners should achieve\n\n"
376
+
377
+ "2. **Classify:**\n"
378
+ " - Determine learning type: Knowledge? Skill? Attitude?\n"
379
+ " - Select appropriate domain:\n"
380
+ " * Cognitive โ†’ for information, understanding, analysis\n"
381
+ " * Affective โ†’ for values, attitudes, behaviors\n"
382
+ " * Psychomotor โ†’ for physical/technical skills\n\n"
383
+
384
+ "3. **Choose Bloom Level:**\n"
385
+ " - Consider axis complexity\n"
386
+ " - Maintain logical progression in unit:\n"
387
+ " * Early axes โ†’ Lower levels (Remember, Understand)\n"
388
+ " * Middle axes โ†’ Middle levels (Apply, Analyze)\n"
389
+ " * Later axes โ†’ Higher levels (Evaluate, Create)\n"
390
+ " - Match level to audience capability\n\n"
391
+
392
+ "4. **Select Verbs:**\n"
393
+ " - Check your tracker: Have I used this verb?\n"
394
+ " - Choose an UNUSED verb from the selected level\n"
395
+ " - Select 3 similar verbs for the 'verbs' field\n"
396
+ " - Mark this verb as 'used' in your tracker\n\n"
397
+
398
+ "5. **Write Objective:**\n"
399
+ " - Start with verb\n"
400
+ " - Add subject (ุงู„ู…ุชุนู„ู…/ุงู„ู…ุชุฏุฑุจ)\n"
401
+ " - State what they should do\n"
402
+ " - Add quality indicator if appropriate (ุจุฏู‚ุฉุŒ ุจูุนุงู„ูŠุฉุŒ ุจูˆุถูˆุญ)\n"
403
+ " - Ensure it's measurable and clear\n\n"
404
+
405
+ "6. **Quality Check:**\n"
406
+ " - โœ“ Is it clear?\n"
407
+ " - โœ“ Is it measurable?\n"
408
+ " - โœ“ Does it match the axis purpose?\n"
409
+ " - โœ“ Is the verb new/diverse?\n"
410
+ " - โœ“ Is it appropriate for {audience}?\n"
411
+ " - โœ“ Does it follow Bloom's progression?\n\n"
412
+
413
+ "### Phase 4: Final Verification\n\n"
414
+ "After generating all objectives:\n\n"
415
+ "1. **Count Check:**\n"
416
+ " - Total objectives = Total axes?\n"
417
+ " - Every axis has exactly 1 objective?\n\n"
418
+
419
+ "2. **Verb Diversity Check:**\n"
420
+ " - Count verb occurrences\n"
421
+ " - Any verb used > 3 times? Replace if possible\n"
422
+ " - Diversity rate > 70%?\n\n"
423
+
424
+ "3. **Domain Balance Check:**\n"
425
+ " - Cognitive: 50-60%?\n"
426
+ " - Affective: 20-30%?\n"
427
+ " - Psychomotor: 20-30%?\n"
428
+ " - Adjust if imbalanced\n\n"
429
+
430
+ "4. **Bloom Progression Check:**\n"
431
+ " - Within each unit, do objectives progress logically?\n"
432
+ " - Simple โ†’ Complex?\n"
433
+ " - Remember/Understand โ†’ Apply/Analyze โ†’ Evaluate/Create?\n\n"
434
+
435
+ "5. **Quality Check:**\n"
436
+ " - All objectives measurable?\n"
437
+ " - All objectives clear?\n"
438
+ " - All objectives achievable?\n"
439
+ " - All objectives match their axes?\n\n"
440
+
441
+ "## โš ๏ธ Common Mistakes to Avoid\n\n"
442
+ "โŒ **DON'T:**\n"
443
+ "- Create objectives for axes that don't exist\n"
444
+ "- Skip any axes\n"
445
+ "- Generate multiple objectives for one axis\n"
446
+ "- Invent new content not in the axis\n"
447
+ "- Use vague, unmeasurable verbs (ูŠุนุฑูุŒ ูŠูู‡ู…ุŒ ูŠุฏุฑูƒ)\n"
448
+ "- Repeat the same verb many times\n"
449
+ "- Write objectives with multiple actions\n"
450
+ "- Use overly complex or academic language\n"
451
+ "- Ignore the audience level\n"
452
+ "- Create objectives that can't be assessed\n\n"
453
+
454
+ "โœ… **DO:**\n"
455
+ "- Generate exactly 1 objective per axis\n"
456
+ "- Use precise, action-oriented verbs\n"
457
+ "- Maximize verb diversity\n"
458
+ "- Follow Bloom's progression\n"
459
+ "- Balance across three domains\n"
460
+ "- Write clear, measurable objectives\n"
461
+ "- Match axis purpose exactly\n"
462
+ "- Keep objectives concise (6-10 words)\n"
463
+ "- Use appropriate vocabulary for {audience}\n"
464
+ "- Ensure every objective can be tested/assessed\n\n"
465
+
466
+ "## ๐Ÿ“ค Expected Output Format\n\n"
467
+ "Your output MUST be a valid JSON matching this structure:\n\n"
468
+ "```json\n"
469
+ "{\n"
470
  ' "objectives": [\n'
471
  " {\n"
472
+ ' "unit": "ุงู„ูุตู„ ุงู„ุฃูˆู„: ู…ูุงู‡ูŠู… ูˆู…ุจุงุฏุฆ ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ",\n'
473
+ ' "unit_description": "ูŠู…ู†ุญ ุงู„ู…ุชุนู„ู…ูŠู† ูู‡ู…ุงู‹ ู…ุชุทูˆุฑุงู‹ ู„ู„ู…ูุงู‡ูŠู… ุงู„ุฃุณุงุณูŠุฉ...",\n'
474
+ ' "axis": "ุชุนุฑูŠู ุงู„ู…ุตุทู„ุญุงุช ุงู„ุฃุณุงุณูŠุฉ ู„ู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ",\n'
475
+ ' "module_description": "ุชุนุฑูŠู ุงู„ู…ุตุทู„ุญุงุช ุงู„ุฃุณุงุณูŠุฉ ูŠุณุงุนุฏ ุงู„ู…ุชุนู„ู…ูŠู†...",\n'
476
+ ' "level": "Cognitive - Remember",\n'
477
+ ' "verbs": ["ูŠุฐูƒุฑ", "ูŠุนุฏุฏ", "ูŠุณู…ูŠ"],\n'
478
+ ' "objective": "ุฃู† ูŠุฐูƒุฑ ุงู„ู…ุชุนู„ู… ุงู„ู…ุตุทู„ุญุงุช ุงู„ุฃุณุงุณูŠุฉ ู„ู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ ุจุฏู‚ุฉ."\n'
479
  " },\n"
480
  " {\n"
481
+ ' "unit": "ุงู„ูุตู„ ุงู„ุฃูˆู„: ู…ูุงู‡ูŠู… ูˆู…ุจุงุฏุฆ ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ",\n'
482
+ ' "unit_description": "ูŠู…ู†ุญ ุงู„ู…ุชุนู„ู…ูŠู† ูู‡ู…ุงู‹ ู…ุชุทูˆุฑุงู‹ ู„ู„ู…ูุงู‡ูŠู… ุงู„ุฃุณุงุณูŠุฉ...",\n'
483
+ ' "axis": "ุดุฑุญ ุชุงุฑูŠุฎ ุชุทูˆุฑ ู…ู†ู‡ุฌ ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ",\n'
484
+ ' "module_description": "ุชูˆุถูŠุญ ุชุงุฑูŠุฎ ุชุทูˆุฑ ู…ู†ู‡ุฌ ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ...",\n'
485
  ' "level": "Cognitive - Understand",\n'
486
+ ' "verbs": ["ูŠูุณุฑ", "ูŠุดุฑุญ", "ูŠูˆุถุญ"],\n'
487
+ ' "objective": "ุฃู† ูŠูุณุฑ ุงู„ู…ุชุนู„ู… ุชุงุฑูŠุฎ ุชุทูˆุฑ ู…ู†ู‡ุฌ ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ ุจูˆุถูˆุญ."\n'
488
  " }\n"
489
+ " // ... ุงู„ู…ุฒูŠุฏ ู…ู† ุงู„ุฃู‡ุฏุงู ู„ูƒู„ ู…ุญูˆุฑ\n"
490
  " ]\n"
491
+ "}\n"
492
+ "```\n\n"
493
+
494
+ "## ๐ŸŽฏ Success Criteria\n\n"
495
+ "Your output will be considered successful if:\n\n"
496
+ "โœ… Number of objectives = Number of axes in input\n"
497
+ "โœ… Every axis has exactly 1 corresponding objective\n"
498
+ "โœ… No axis is missed or duplicated\n"
499
+ "โœ… Verb diversity > 70%\n"
500
+ "โœ… Domain balance: Cognitive (50-60%), Affective (20-30%), Psychomotor (20-30%)\n"
501
+ "โœ… All objectives are measurable and clear\n"
502
+ "โœ… Objectives progress logically within each unit\n"
503
+ "โœ… All objectives appropriate for {audience}\n"
504
+ "โœ… Output is valid JSON matching ObjectivesOutput schema\n\n"
505
+
506
+ "---\n\n"
507
+ "## ๐Ÿš€ Now Begin!\n\n"
508
+ "Analyze the curriculum in `{outlines}` and generate learning objectives following ALL the rules above.\n\n"
509
+ "Remember:\n"
510
+ "- ๐ŸŽฏ One objective per axis\n"
511
+ "- ๐ŸŽจ Maximum verb diversity\n"
512
+ "- ๐Ÿ“Š Balance across domains\n"
513
+ "- ๐Ÿ“ Follow Bloom's progression\n"
514
+ "- โœ๏ธ Clear, measurable, achievable\n\n"
515
+ "Good luck! ๐ŸŒŸ"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
516
  ),
517
+
518
+ expected_output=(
519
+ "A valid JSON object matching the ObjectivesOutput schema:\n\n"
520
+ "{\n"
521
+ ' "objectives": [\n'
522
+ " {\n"
523
+ ' "unit": "Unit title from input",\n'
524
+ ' "unit_description": "Unit focus from input",\n'
525
+ ' "axis": "Axis title from input",\n'
526
+ ' "module_description": "Axis purpose from input",\n'
527
+ ' "level": "Domain - Level (e.g., Cognitive - Understand)",\n'
528
+ ' "verbs": ["verb1", "verb2", "verb3"],\n'
529
+ ' "objective": "ุฃู† + verb + ุงู„ู…ุชุนู„ู… + action + condition"\n'
530
+ " },\n"
531
+ " // ... one objective for each axis in all units\n"
532
+ " ]\n"
533
+ "}\n\n"
534
+ "Requirements:\n"
535
+ "- Total objectives = Total axes in input\n"
536
+ "- Each objective maps to exactly one axis\n"
537
+ "- All objectives in Arabic\n"
538
+ "- All objectives measurable and clear\n"
539
+ "- Diverse verbs (70-80% unique)\n"
540
+ "- Balanced domains (Cognitive 50-60%, Affective 20-30%, Psychomotor 20-30%)\n"
541
+ "- Logical Bloom's progression within each unit"
542
+ ),
543
+
544
  output_json=ObjectivesOutput,
545
  agent=objectives_generator,
546
+ human_input=False
547
  )
548
+
549
+
550
+ # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
551
+ # ๐ŸŽฏ Main Execution Function
552
+ # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
553
+
554
+ def generate_objectives(
555
+ topic: str,
556
+ domain: str,
557
+ content_type: str,
558
+ audience: str,
559
+ material_type: list,
560
+ outlines: dict
561
+ ) -> dict:
562
+ """
563
+ ุชูˆู„ูŠุฏ ุงู„ุฃู‡ุฏุงู ุงู„ุชุนู„ูŠู…ูŠุฉ ู„ู„ู…ู†ู‡ุฌ ุงู„ุชุฏุฑูŠุจูŠ.
564
+
565
+ Args:
566
+ topic: ู…ูˆุถูˆุน ุงู„ุชุฏุฑูŠุจ ุงู„ุฑุฆูŠุณูŠ
567
+ domain: ุงู„ู…ุฌุงู„ (Management, Technology, etc.)
568
+ content_type: ู†ูˆุน ุงู„ู…ุญุชูˆู‰ (Educational, Training, etc.)
569
+ audience: ุงู„ูุฆุฉ ุงู„ู…ุณุชู‡ุฏูุฉ
570
+ material_type: ุฃู†ูˆุงุน ุงู„ู…ูˆุงุฏ ุงู„ุชุฏุฑูŠุจูŠุฉ
571
+ outlines: ุงู„ุจู†ูŠุฉ ุงู„ูƒุงู…ู„ุฉ ู„ู„ู…ู†ู‡ุฌ ู…ู† outliner agent
572
+
573
+ Returns:
574
+ dict: ุงู„ุฃู‡ุฏุงู ุงู„ุชุนู„ูŠู…ูŠุฉ ุจุตูŠุบุฉ JSON
575
+
576
+ Example:
577
+ >>> result = generate_objectives(
578
+ ... topic="Design Thinking",
579
+ ... domain="Management",
580
+ ... content_type="Training",
581
+ ... audience="Professionals",
582
+ ... material_type=["Conceptual", "Procedural"],
583
+ ... outlines=curriculum_structure
584
+ ... )
585
+ >>> print(result['objectives'][0])
586
+ """
587
+
588
+ # Create crew with the agent and task
589
+ crew = Crew(
590
+ agents=[objectives_generator],
591
+ tasks=[objectives_task],
592
+ process=Process.sequential,
593
+ verbose=True
594
+ )
595
+
596
+ # Execute the crew with inputs
597
+ result = crew.kickoff(
598
+ inputs={
599
+ "topic": topic,
600
+ "domain": domain,
601
+ "content_type": content_type,
602
+ "audience": audience,
603
+ "material_type": material_type,
604
+ "outlines": json.dumps(outlines, ensure_ascii=False, indent=2)
605
+ }
606
+ )
607
+
608
+ return result
609
+
610
+
611
+ # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
612
+ # ๐Ÿ“ Usage Example
613
+ # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
614
+
615
+ if __name__ == "__main__":
616
+ # Example usage
617
+ sample_outlines = {
618
+ "units": [
619
+ {
620
+ "unit_number": 1,
621
+ "title": "ุงู„ูุตู„ ุงู„ุฃูˆู„: ุงู„ู…ูุงู‡ูŠู… ุงู„ุฃุณุงุณูŠุฉ",
622
+ "focus": "ูŠุชุน๏ฟฝ๏ฟฝู ุงู„ู…ุชุนู„ู… ุนู„ู‰ ุงู„ู…ูุงู‡ูŠู… ุงู„ุฃุณุงุณูŠุฉ ู„ู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ",
623
+ "axes": [
624
+ {
625
+ "axis_number": 1,
626
+ "title": "ุชุนุฑูŠู ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ",
627
+ "purpose": "ูŠูู‡ู… ุงู„ู…ุชุนู„ู… ู…ุนู†ู‰ ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ ูˆู…ูƒูˆู†ุงุชู‡"
628
+ },
629
+ {
630
+ "axis_number": 2,
631
+ "title": "ุฃู‡ู…ูŠุฉ ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ",
632
+ "purpose": "ูŠุฏุฑูƒ ุงู„ู…ุชุนู„ู… ุฃู‡ู…ูŠุฉ ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ ููŠ ุญู„ ุงู„ู…ุดูƒู„ุงุช"
633
+ }
634
+ ]
635
+ }
636
+ ]
637
+ }
638
+
639
+ result = generate_objectives(
640
+ topic="Design Thinking",
641
+ domain="Management",
642
+ content_type="Training",
643
+ audience="Professionals",
644
+ material_type=["Conceptual", "Procedural"],
645
+ outlines=sample_outlines
646
+ )
647
+
648
+ print(json.dumps(result, ensure_ascii=False, indent=2))
app.py CHANGED
@@ -1,39 +1,84 @@
1
  import os
2
- # Force HOME to /tmp so CrewAI doesn't try writing to /.local
 
 
 
 
 
 
3
  os.environ["HOME"] = "/tmp"
4
  os.environ["XDG_DATA_HOME"] = "/tmp/.local/share"
5
  os.environ["CREWAI_STORAGE_PATH"] = "/tmp/crewai_data"
6
  os.environ["CREWAI_HOME"] = "/tmp/crewai_home"
7
 
8
- # Create safe directories
9
  os.makedirs("/tmp/.local/share", exist_ok=True)
10
  os.makedirs("/tmp/crewai_data", exist_ok=True)
11
  os.makedirs("/tmp/crewai_home", exist_ok=True)
12
- from crewai import Crew, Process
13
- import json
14
- from fastapi import FastAPI
15
- from routers import objective_route, outliner_route, outcome_route,introduction_route
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
 
 
 
18
  app = FastAPI(title="AI Agent Project", version="1.0.0")
19
 
 
20
  app.include_router(outliner_route.router)
21
  app.include_router(objective_route.router)
22
  app.include_router(outcome_route.router)
23
  app.include_router(introduction_route.router)
24
 
25
 
26
- # Example root endpoint
 
 
27
  @app.get("/")
28
  def read_root():
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)
 
1
  import os
2
+ import shutil
3
+ from fastapi import FastAPI, HTTPException, Header
4
+ from routers import objective_route, outliner_route, outcome_route, introduction_route
5
+
6
+ # ---------------------------------
7
+ # ๐Ÿงน ุฅุนุฏุงุฏ ุงู„ุจูŠุฆุฉ ูˆู…ุณุงุฑุงุช ุงู„ูƒุงุด
8
+ # ---------------------------------
9
  os.environ["HOME"] = "/tmp"
10
  os.environ["XDG_DATA_HOME"] = "/tmp/.local/share"
11
  os.environ["CREWAI_STORAGE_PATH"] = "/tmp/crewai_data"
12
  os.environ["CREWAI_HOME"] = "/tmp/crewai_home"
13
 
14
+ # ุฅู†ุดุงุก ุงู„ู…ุณุงุฑุงุช ู„ูˆ ู…ุด ู…ูˆุฌูˆุฏุฉ
15
  os.makedirs("/tmp/.local/share", exist_ok=True)
16
  os.makedirs("/tmp/crewai_data", exist_ok=True)
17
  os.makedirs("/tmp/crewai_home", exist_ok=True)
 
 
 
 
18
 
19
+ # ---------------------------------
20
+ # ๐Ÿงฝ ุชู†ุธูŠู ุงู„ูƒุงุด ุนู†ุฏ ุจุฏุก ุงู„ุชุดุบูŠู„
21
+ # ---------------------------------
22
+ CACHE_PATHS = [
23
+ "/tmp/crewai_data",
24
+ "/tmp/crewai_home",
25
+ "/tmp/.local/share/crewai_data",
26
+ ]
27
+
28
+ for path in CACHE_PATHS:
29
+ if os.path.exists(path):
30
+ shutil.rmtree(path, ignore_errors=True)
31
+ print(f"๐Ÿงน Cleared cache folder: {path}")
32
 
33
+ # ---------------------------------
34
+ # ๐Ÿš€ ุฅุนุฏุงุฏ ุงู„ุชุทุจูŠู‚
35
+ # ---------------------------------
36
  app = FastAPI(title="AI Agent Project", version="1.0.0")
37
 
38
+ # Routers
39
  app.include_router(outliner_route.router)
40
  app.include_router(objective_route.router)
41
  app.include_router(outcome_route.router)
42
  app.include_router(introduction_route.router)
43
 
44
 
45
+ # ---------------------------------
46
+ # โœ… Root endpoint
47
+ # ---------------------------------
48
  @app.get("/")
49
  def read_root():
50
  return {"message": "Welcome to AI Agent Project API ๐Ÿš€"}
51
 
52
 
53
+ # ---------------------------------
54
+ # ๐Ÿงน Endpoint ู„ู…ุณุญ ุงู„ูƒุงุด ูŠุฏูˆูŠู‹ุง
55
+ # ---------------------------------
56
+ ADMIN_TOKEN = "ziad_secret_123" # ุบูŠู‘ุฑู‡ ู„ุฃูŠ ู‚ูŠู…ุฉ ุณุฑูŠุฉ
57
+
58
+
59
+ @app.post("/reset-cache")
60
+ def reset_cache(x_token: str = Header(...)):
61
+
62
+ paths = [
63
+ "/tmp/crewai_data",
64
+ "/tmp/crewai_home",
65
+ "/tmp/.local/share/crewai_data",
66
+ ]
67
+
68
+ for path in paths:
69
+ if os.path.exists(path):
70
+ shutil.rmtree(path, ignore_errors=True)
71
 
72
+ os.makedirs("/tmp/crewai_data", exist_ok=True)
73
+ os.makedirs("/tmp/crewai_home", exist_ok=True)
74
+ os.makedirs("/tmp/.local/share/crewai_data", exist_ok=True)
75
+
76
+ return {"message": "โœ… Cache cleared successfully."}
77
+
78
+
79
+ # ---------------------------------
80
+ # ๐Ÿ ุชุดุบูŠู„ ุงู„ุณูŠุฑูุฑ
81
+ # ---------------------------------
82
  # if __name__ == "__main__":
83
  # import uvicorn
 
84
  # uvicorn.run("main:app", host="127.0.0.1", port=8000, reload=True)
schemas/objectives_schema.py CHANGED
@@ -1,55 +1,80 @@
1
  from pydantic import BaseModel, Field
2
- from typing import List, Dict, Literal, Optional
3
  from typing import List
4
- from pydantic import BaseModel, Field
5
 
6
 
7
- class Objective(BaseModel):
8
- unit: str = Field(..., description="The title of the unit.")
9
- unit_description: str = Field(..., description="A brief summary of the unit scope.")
10
- subtopic: str = Field(..., description="The title of the subtopic (axis).")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  module_description: str = Field(
12
- ..., description="A brief summary of what this subtopic covers."
 
13
  )
14
  level: str = Field(
15
- ..., description="Bloom's level assigned based on subtopic analysis."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  )
17
  verbs: List[str] = Field(
18
- ..., description="A list of verbs used to define the learning objective."
 
 
 
19
  )
20
  objective: str = Field(
21
- ...,
22
- description="A measurable Arabic objective derived from the subtopic purpose.",
 
 
 
 
23
  )
24
 
25
 
26
  class ObjectivesOutput(BaseModel):
27
- objectives: List[Objective] = Field(
28
- ...,
29
- description="List of objectives including unit, subtopic, and measurable goals.",
30
- )
31
-
32
- 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
  )
 
1
  from pydantic import BaseModel, Field
 
2
  from typing import List
 
3
 
4
 
5
+ class ObjectiveItem(BaseModel):
6
+ """
7
+ ู†ู…ูˆุฐุฌ ูŠู…ุซู„ ู‡ุฏู ุชุนู„ูŠู…ูŠ ูˆุงุญุฏ (Learning Objective) ู„ู…ุญูˆุฑ (axis) ูˆุงุญุฏ.
8
+
9
+ ูŠุฌุจ ุฃู† ูŠูƒูˆู† ู‡ู†ุงูƒ ู‡ุฏู ูˆุงุญุฏ ูู‚ุท ู„ูƒู„ ู…ุญูˆุฑุŒ ู…ุน ุฑุจุทู‡ ุจุงู„ูˆุญุฏุฉ ุงู„ุชูŠ ูŠู†ุชู…ูŠ ุฅู„ูŠู‡ุง.
10
+ """
11
+ unit: str = Field(
12
+ ...,
13
+ description="ุนู†ูˆุงู† ุงู„ูˆุญุฏุฉ ุงู„ุชุนู„ูŠู…ูŠุฉ (Unit title) ุงู„ุชูŠ ูŠู†ุชู…ูŠ ุฅู„ูŠู‡ุง ู‡ุฐุง ุงู„ู…ุญูˆุฑ."
14
+ )
15
+ unit_description: str = Field(
16
+ ...,
17
+ description="ูˆุตู ุงู„ูˆุญุฏุฉ (Unit focus) - ุงู„ู‡ุฏู ุงู„ุนุงู… ู„ู„ูˆุญุฏุฉ."
18
+ )
19
+ axis: str = Field(
20
+ ...,
21
+ description="ุนู†ูˆุงู† ุงู„ู…ุญูˆุฑ (Axis title) - ุงู„ู…ูˆุถูˆุน ุงู„ูุฑุนูŠ ุฏุงุฎู„ ุงู„ูˆุญุฏุฉ."
22
+ )
23
  module_description: str = Field(
24
+ ...,
25
+ description="ูˆุตู ุงู„ู…ุญูˆุฑ (Axis purpose) - ุงู„ุบุฑุถ ุฃูˆ ุงู„ู‡ุฏู ู…ู† ุชุฏุฑูŠุณ ู‡ุฐุง ุงู„ู…ุญูˆุฑ."
26
  )
27
  level: str = Field(
28
+ ...,
29
+ description=(
30
+ "ู…ุณุชูˆู‰ Bloom's Taxonomy ุฃูˆ ุงู„ู…ุฌุงู„ ุงู„ุชุนู„ูŠู…ูŠ ุงู„ู…ู†ุงุณุจ.\n"
31
+ "ุฃู…ุซู„ุฉ:\n"
32
+ " - Cognitive - Remember\n"
33
+ " - Cognitive - Understand\n"
34
+ " - Cognitive - Apply\n"
35
+ " - Cognitive - Analyze\n"
36
+ " - Cognitive - Evaluate\n"
37
+ " - Cognitive - Create\n"
38
+ " - Affective - Reception\n"
39
+ " - Affective - Response\n"
40
+ " - Affective - Valuing\n"
41
+ " - Affective - Organization\n"
42
+ " - Affective - Characterization\n"
43
+ " - Psychomotor - Readiness\n"
44
+ " - Psychomotor - Guided Response\n"
45
+ " - Psychomotor - Mechanism\n"
46
+ " - Psychomotor - Complex Overt Response\n"
47
+ " - Psychomotor - Adaptation\n"
48
+ " - Psychomotor - Origination"
49
+ )
50
  )
51
  verbs: List[str] = Field(
52
+ ...,
53
+ min_items=3,
54
+ max_items=3,
55
+ description="ุซู„ุงุซุฉ ุฃูุนุงู„ ู…ู† ุชุตู†ูŠู ุจู„ูˆู… ุฃูˆ ุงู„ู…ุฌุงู„ุงุช ุงู„ุชุนู„ูŠู…ูŠุฉ ุชู†ุงุณุจ ู‡ุฐุง ุงู„ู‡ุฏู."
56
  )
57
  objective: str = Field(
58
+ ...,
59
+ description=(
60
+ "ุงู„ู‡ุฏู ุงู„ุชุนู„ูŠู…ูŠ ุงู„ู‚ุงุจู„ ู„ู„ู‚ูŠุงุณ ุจุงู„ู„ุบุฉ ุงู„ุนุฑุจูŠุฉ.\n"
61
+ "ูŠุฌุจ ุฃู† ูŠุจุฏุฃ ุจู€ 'ุฃู†' ุฃูˆ 'ูŠู€' ู…ุชุจูˆุนู‹ุง ุจูุนู„ ู…ุถุงุฑุน ูˆุงุถุญ.\n"
62
+ "ู…ุซุงู„: 'ุฃู† ูŠุญู„ู„ ุงู„ู…ุชุนู„ู… ู…ูƒูˆู†ุงุช ุงู„ุนู…ู„ูŠุฉ ุงู„ุชุตู…ูŠู…ูŠุฉ ุจุฏู‚ุฉ.'"
63
+ )
64
  )
65
 
66
 
67
  class ObjectivesOutput(BaseModel):
68
+ """
69
+ ุงู„ู†ู…ูˆุฐุฌ ุงู„ุดุงู…ู„ ุงู„ุฐูŠ ูŠุญุชูˆูŠ ุนู„ู‰ ู‚ุงุฆู…ุฉ ูƒุงู…ู„ุฉ ุจุงู„ุฃู‡ุฏุงู ุงู„ุชุนู„ูŠู…ูŠุฉ.
70
+
71
+ ูŠุฌุจ ุฃู† ูŠุญุชูˆูŠ ุนู„ู‰ ู‡ุฏู ูˆุงุญุฏ ู„ูƒู„ ู…ุญูˆุฑ (axis) ููŠ ุฌู…ูŠุน ุงู„ูˆุญุฏุงุช (units).
72
+ """
73
+ objectives: List[ObjectiveItem] = Field(
74
+ ...,
75
+ description=(
76
+ "ู‚ุงุฆู…ุฉ ูƒุงู…ู„ุฉ ุจุงู„ุฃู‡ุฏุงู ุงู„ุชุนู„ูŠู…ูŠุฉ.\n"
77
+ "ูƒู„ ุนู†ุตุฑ ูŠู…ุซู„ ู‡ุฏู ูˆุงุญุฏ ู„ู…ุญูˆุฑ ูˆุงุญุฏุŒ ู…ุฑุชุจุท ุจูˆุญุฏุชู‡.\n"
78
+ "ุนุฏุฏ ุงู„ุนู†ุงุตุฑ ูŠุฌุจ ุฃู† ูŠุณุงูˆูŠ ุนุฏุฏ ุงู„ู…ุญุงูˆุฑ ููŠ ุฌู…ูŠุน ุงู„ูˆุญุฏุงุช."
79
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
  )
test_objectives.py ADDED
@@ -0,0 +1,292 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”
3
+ ๐Ÿงช Test Script for Objectives Generator
4
+ โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”
5
+
6
+ ู‡ุฐุง ุงู„ู…ู„ู ู„ุงุฎุชุจุงุฑ ุชูˆู„ูŠุฏ ุงู„ุฃู‡ุฏุงู ุงู„ุชุนู„ูŠู…ูŠุฉ ุจุงุณุชุฎุฏุงู… ุงู„ุจูŠุงู†ุงุช ุงู„ูุนู„ูŠุฉ.
7
+ """
8
+
9
+ import json
10
+ import sys
11
+ import os
12
+
13
+ # Add project root to path
14
+ sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
15
+
16
+ from agents.analysis_phase.objectives import generate_objectives
17
+
18
+
19
+ # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
20
+ # ๐Ÿ“Š Test Data - ุงู„ุจูŠุงู†ุงุช ุงู„ูุนู„ูŠุฉ ู…ู† ุงู„ู…ุณุชุฎุฏู…
21
+ # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
22
+
23
+ METADATA = {
24
+ 'topic': '(Design thinking) ุชู‚ู†ูŠุงุช ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ ู„ุญู„ ุงู„ู…ุดูƒู„ุงุช ูˆุงุชุฎุงุฐ ุงู„ู‚ุฑุงุฑุงุช',
25
+ 'domain': 'Multidisciplinary',
26
+ 'content_type': 'Educational',
27
+ 'audience': 'Professionals and Students',
28
+ 'material_type': ['Conceptual', 'Procedural', 'Structural', 'Personal', 'Realistic']
29
+ }
30
+
31
+ OUTLINES = {
32
+ 'Metadata': [METADATA],
33
+ 'main_concept': 'ุชู‚ู†ูŠุงุช ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ ู„ุญู„ ุงู„ู…ุดูƒู„ุงุช ูˆุงุชุฎุงุฐ ุงู„ู‚ุฑุงุฑุงุช',
34
+ 'related_concepts': ['Management', 'Technology', 'Aerospace', 'Psychologists', 'Entrepreneurs', 'Educational', 'Awareness'],
35
+ 'units': [
36
+ {
37
+ 'unit_number': 1,
38
+ 'title': 'ุงู„ูุตู„ ุงู„ุฃูˆู„: ู…ูุงู‡ูŠู… ูˆู…ุจุงุฏุฆ ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ',
39
+ 'focus': 'ูŠู…ู†ุญ ุงู„ู…ุชุนู„ู…ูŠู† ูู‡ู…ุงู‹ ู…ุชุทูˆุฑุงู‹ ู„ู„ู…ูุงู‡ูŠู… ุงู„ุฃุณุงุณูŠุฉุŒ ุชุงุฑูŠุฎ ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠุŒ ูˆุงู„ู†ุธุฑุฉ ุงู„ู…ู†ู‡ุฌูŠุฉ ุงู„ุชูŠ ุชูุดูƒู‘ู„ ุฃุณุงุณุงู‹ ู„ู„ุชุนุงู…ู„ ู…ุน ุงู„ู…ุดูƒู„ุงุช ุงู„ู…ุนู‚ุฏุฉ.',
40
+ 'axes': [
41
+ {
42
+ 'axis_number': 1,
43
+ 'title': 'ุชุนุฑูŠู ุงู„ู…ุตุทู„ุญุงุช ุงู„ุฃุณุงุณูŠุฉ ู„ู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ',
44
+ 'purpose': 'ุชุนุฑูŠู ุงู„ู…ุตุทู„ุญุงุช ุงู„ุฃุณุงุณูŠุฉ ูŠุณุงุนุฏ ุงู„ู…ุชุนู„ู…ูŠู† ุนู„ู‰ ุจู†ุงุก ู‚ุงุนุฏุฉ ู…ุนุฑููŠุฉ ุซุงุจุชุฉ'
45
+ },
46
+ {
47
+ 'axis_number': 2,
48
+ 'title': 'ุดุฑุญ ุชุงุฑูŠุฎ ุชุทูˆุฑ ู…ู†ู‡ุฌ ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ',
49
+ 'purpose': 'ุชูˆุถูŠุญ ุชุงุฑูŠุฎ ุชุทูˆุฑ ู…ู†ู‡ุฌ ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ ูŠุนุฒุฒ ูู‡ู… ุงู„ุณูŠุงู‚ ูˆุงู„ุชุทุจูŠู‚'
50
+ },
51
+ {
52
+ 'axis_number': 3,
53
+ 'title': 'ุฃู…ุซู„ุฉ ุชุทุจูŠู‚ูŠุฉ ู„ู„ู…ุจุงุฏุฆ ุงู„ุชุตู…ูŠู…ูŠุฉ',
54
+ 'purpose': 'ุนุฑุถ ุฃู…ุซู„ุฉ ุนู…ู„ูŠุฉ ูŠุฑุจุท ุงู„ู…ุจุงุฏุฆ ุจุงู„ูˆุงู‚ุน ูˆุชุทุจูŠู‚ุงุชู‡ู…'
55
+ },
56
+ {
57
+ 'axis_number': 4,
58
+ 'title': 'ุชุญู„ูŠู„ ู…ูƒูˆู†ุงุช ุงู„ุนู…ู„ูŠุฉ ุงู„ุชุตู…ูŠู…ูŠุฉ ููŠ ู…ุดุฑูˆุน ุนู…ู„ูŠ',
59
+ 'purpose': 'ุชุญู„ูŠู„ ู…ูƒูˆู†ุงุช ุงู„ุนู…ู„ูŠุฉ ููŠ ู…ุดุฑูˆุน ุนู…ู„ูŠ ูŠุทูˆู‘ุฑ ู…ู‡ุงุฑุงุช ุงู„ุชููƒูŠุฑ ุงู„ู†ู‚ุฏูŠ'
60
+ },
61
+ {
62
+ 'axis_number': 5,
63
+ 'title': 'ุงุจุชูƒุงุฑ ู†ู…ูˆุฐุฌ ุชุตู…ูŠู…ูŠ ู„ุญู„ ู…ุดูƒู„ุฉ ู…ุญุฏุฏุฉ',
64
+ 'purpose': 'ุงุจุชูƒุงุฑ ู†ู…ูˆุฐุฌ ุชุตู…ูŠู…ูŠ ู„ุญู„ ู…ุดูƒู„ุฉ ู…ุญุฏุฏ ูŠุนุฒุฒ ุงู„ุงุจุชูƒุงุฑ ูˆุงู„ุฅุจุฏุงุน'
65
+ }
66
+ ]
67
+ },
68
+ {
69
+ 'unit_number': 2,
70
+ 'title': 'ุงู„ูุตู„ ุงู„ุซุงู†ูŠ: ุงู„ุนู…ู„ูŠุฉ ุงู„ู…ูŠุฏุงู†ูŠุฉ ู„ุชู‚ู†ูŠุงุช ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ',
71
+ 'focus': 'ูŠูุฏุฑู‘ุณ ุงู„ู…ุชุนู„ู…ูŠู† ุงู„ุฎุทูˆุงุช ุงู„ุนู…ู„ูŠุฉ (ุงู„ุชุนุงุทูŠุŒ ุงู„ุชุญุฏูŠุฏุŒ ุงู„ุฅุจุฏุงุนุŒ ุงู„ู†ู…ุฐุฌุฉุŒ ูˆุงู„ุงุฎุชุจุงุฑ) ู…ุน ุชุทุจูŠู‚ ุชู…ุงุฑูŠู† ุชุฌุฑูŠุจูŠุฉ ุชูุจู†ู‰ ู…ู‡ุงุฑุงุช ุชู†ููŠุฐูŠุฉ ู…ุจุงุดุฑุฉ.',
72
+ 'axes': [
73
+ {
74
+ 'axis_number': 1,
75
+ 'title': 'ุฏุฑุงุณุฉ ุฎุทูˆุงุช ุงู„ุนู…ู„ูŠุฉ ุงู„ู…ูŠุฏุงู†ูŠุฉ',
76
+ 'purpose': 'ุชุฐูƒุฑ ุฎุทูˆุงุช ุงู„ุนู…ู„ูŠุฉ ุงู„ู…ูŠุฏุงู†ูŠุฉ ุงู„ุฃุณุงุณูŠุฉ ูŠุนุฒุฒ ุงู„ุชุชุจุน ุงู„ุณู„ุณ ู„ู„ุนู…ู„ูŠุฉ'
77
+ },
78
+ {
79
+ 'axis_number': 2,
80
+ 'title': 'ุดุฑุญ ู…ูุตู„ ู„ู…ุฑุงุญู„ ุงู„ุชุนุงุทูŠ ูˆุงู„ุชุญุฏูŠุฏ',
81
+ 'purpose': 'ุดุฑุญ ู…ูุตู„ ู„ู…ุฑุงุญู„ ุงู„ุชุนุงุทูŠ ูˆุงู„ุชุญุฏูŠุฏ ูŠูˆุถุญ ูƒู„ ุฎุทูˆุฉ ู…ู† ุงู„ุนู…ู„ูŠุฉ'
82
+ },
83
+ {
84
+ 'axis_number': 3,
85
+ 'title': 'ุชู†ููŠุฐ ุชู…ุฑูŠู† ุชุนุงุทูŠ ู„ุญุงู„ุฉ ูˆุงู‚ุนูŠุฉ',
86
+ 'purpose': 'ุชู†ููŠุฐ ุชู…ุฑูŠู† ุชุนุงุทูŠ ู„ุญุงู„ุฉ ูˆุงู‚ุนูŠุฉ ูŠุฑุจุท ุงู„ู†ุธุฑูŠุฉ ุจุงู„ุชุทุจูŠู‚'
87
+ },
88
+ {
89
+ 'axis_number': 4,
90
+ 'title': 'ุชุญู„ูŠู„ ู†ุชุงุฆุฌ ุงู„ู…ุฑุญู„ุฉ ุงู„ุฅุจุฏุงุนูŠุฉ ู„ู„ู†ู…ุงุฐุฌ',
91
+ 'purpose': 'ุชุญู„ูŠู„ ู†ุชุงุฆุฌ ุงู„ู…ุฑุญู„ุฉ ุงู„ุฅุจุฏุงุนูŠุฉ ู„ู„ู†ู…ุงุฐุฌ ูŠูˆุถุญ ู†ู‚ุงุท ุงู„ู‚ูˆุฉ ูˆุงู„ุถุนู'
92
+ },
93
+ {
94
+ 'axis_number': 5,
95
+ 'title': 'ุงุจุชูƒุงุฑ ุญู„ ู†ู‡ุงุฆูŠ ุจุนุฏ ุงุฎุชุจุงุฑ ุงู„ู†ู…ูˆุฐุฌ',
96
+ 'purpose': 'ุงุจุชูƒุงุฑ ุญู„ ู†ู‡ุงุฆูŠ ุจุนุฏ ุงุฎุชุจุงุฑ ุงู„ู†ู…ูˆุฐุฌ ูŠุนุฒุฒ ุงู„ุชุนู„ู… ุงู„ุนู…ู„ูŠ'
97
+ }
98
+ ]
99
+ },
100
+ {
101
+ 'unit_number': 3,
102
+ 'title': 'ุงู„ูุตู„ ุงู„ุซุงู„ุซ: ุชุทุจูŠู‚ุงุช ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ ููŠ ุงู„ุฅุฏุงุฑุฉุŒ ุงู„ุชู‚ู†ูŠุฉุŒ ุงู„ูุถุงุกุŒ ุนู„ู… ุงู„ู†ูุณ ูˆุฑูŠุงุฏุฉ ุงู„ุฃุนู…ุงู„',
103
+ 'focus': 'ูŠูุธู‡ุฑ ูƒูŠู ูŠู…ูƒู† ุฏู…ุฌ ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ ููŠ ู…ุฌุงู„ุงุช ู…ุชุนุฏุฏุฉุŒ ู…ู‚ุฏู…ู‹ุง ุฏุฑุงุณุงุช ุญุงู„ุฉ ูˆุงู‚ุนูŠุฉ ุชูุซุจุช ูุงุนู„ูŠุชู‡ ููŠ ุชุญุณูŠู† ุงู„ุนู…ู„ูŠุงุช ูˆุงุชุฎุงุฐ ุงู„ู‚ุฑุงุฑุงุช ุงู„ูุนุงู„ุฉ.',
104
+ 'axes': [
105
+ {
106
+ 'axis_number': 1,
107
+ 'title': 'ุชุญุฏูŠุฏ ู…ุฌุงู„ุงุช ุชุทุจูŠู‚ ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ',
108
+ 'purpose': 'ุชุญุฏูŠุฏ ู…ุฌุงู„ุงุช ุชุทุจูŠู‚ ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ ูŠุญุฏุฏ ุงู„ูุถุงุกุงุช ุงู„ุชูŠ ูŠู…ูƒู† ุชูˆุธูŠูู‡ุง'
109
+ },
110
+ {
111
+ 'axis_number': 2,
112
+ 'title': 'ุดุฑุญ ุฏูˆุฑ ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ ููŠ ุงู„ุฅุฏุงุฑุฉ',
113
+ 'purpose': 'ุดุฑุญ ุฏูˆุฑ ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ ููŠ ุงู„ุฅุฏุงุฑุฉ ูŠูˆุถุญ ูƒูŠู ูŠุญุณู‘ู† ุงู„ุนู…ู„ูŠุงุช'
114
+ },
115
+ {
116
+ 'axis_number': 3,
117
+ 'title': 'ุชุทุจูŠู‚ ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ ุนู„ู‰ ู‚ุถูŠุฉ ุฅุฏุงุฑูŠุฉ',
118
+ 'purpose': 'ุชุทุจูŠู‚ ุงู„ุชููƒูŠุฑ ุงู„ุชุตู…ูŠู…ูŠ ุนู„ู‰ ู‚ุถูŠุฉ ุฅุฏุงุฑูŠุฉ ูŠุฎุชุจุฑ ูุนุงู„ูŠุฉ ุงู„ุชูƒุชูŠูƒุงุช'
119
+ },
120
+ {
121
+ 'axis_number': 4,
122
+ 'title': 'ุชุญู„ูŠู„ ูุงุนู„ูŠุฉ ุงู„ุชุทุจูŠู‚ุงุช ููŠ ู…ุฌุงู„ ุงู„ูุถุงุก',
123
+ 'purpose': 'ุชุญู„ูŠู„ ูุงุนู„ูŠุฉ ุงู„ุชุทุจูŠู‚ุงุช ููŠ ู…ุฌุงู„ ุงู„ูุถุงุก ูŠู‚ูŠู‘ู… ุฅู…ูƒุงู†ูŠุงุช ุงู„ุงุจุชูƒุงุฑ'
124
+ },
125
+ {
126
+ 'axis_number': 5,
127
+ 'title': 'ุงุจุชูƒุงุฑ ู…ุจุงุฏุฑุฉ ุชุตู…ูŠู…ูŠุฉ ู„ุฑุจุท ุนู„ู… ุงู„ู†ูุณ ูˆุฑูŠุงุฏุฉ ุงู„ุฃุนู…ุงู„',
128
+ 'purpose': 'ุงุจุชูƒุงุฑ ู…ุจุงุฏุฑุฉ ุชุตู…ูŠู…ูŠุฉ ู„ุฑุจุท ุนู„ู… ุงู„ู†ูุณ ูˆุฑูŠุงุฏุฉ ุงู„ุฃุนู…ุงู„ ูŠุฏู…ุฌ ุงู„ู…ู†ู‡ุฌูŠุฉ'
129
+ }
130
+ ]
131
+ },
132
+ {
133
+ 'unit_number': 4,
134
+ 'title': 'ุงู„ูุตู„ ุงู„ุฑุงุจุน: ุงู„ุชู†ููŠุฐ ูˆุงู„ุชู‚ูŠูŠู… โ€“ ุงู„ุชู†ู…ูŠุฉ ุงู„ุดุฎุตูŠุฉ ูˆุงู„ูˆุนูŠ ุงู„ู…ุฌุชู…ุนูŠ',
135
+ 'focus': 'ูŠุดุฌุน ุงู„ู…ุชุนู„ู…ูŠู† ุนู„ู‰ ุชู†ููŠุฐ ุญู„ูˆู„ ู…ูุตู…ู…ุฉ ุจูุนู‘ุงู„ูŠุฉุŒ ู‚ูŠุงุณ ุฃุซุฑู‡ุงุŒ ูˆุชุนุฒูŠุฒ ุงู„ูˆุนูŠ ุงู„ุฐุงุชูŠ ูˆุงู„ู…ุฌุชู…ุนูŠุŒ ู…ุน ุชูˆุฌูŠู‡ ู„ู…ู‡ุงุฑุงุช ุงู„ู‚ูŠุงุฏุฉ ูˆุงู„ุชููƒูŠุฑ ุงู„ู†ู‚ุฏูŠ.',
136
+ 'axes': [
137
+ {
138
+ 'axis_number': 1,
139
+ 'title': 'ู…ุฑุงุฌุนุฉ ู…ูุงู‡ูŠู… ุชู†ููŠุฐ ุงู„ุญู„ูˆู„ ุงู„ู…ุจุฏุนุฉ',
140
+ 'purpose': 'ุชุฐูƒูŠุฑ ุจู…ูุงู‡ูŠู… ุชู†ููŠุฐ ุงู„ุญู„ูˆู„ ุงู„ู…ุจุฏุนุฉ ูŠุญู‚ู‚ ูˆุถูˆุญ ุงู„ุฑุคูŠุฉ'
141
+ },
142
+ {
143
+ 'axis_number': 2,
144
+ 'title': 'ุดุฑุญ ุชู‚ู†ูŠุงุช ู‚ูŠุงุณ ุฃุซุฑ ุงู„ุญู„ูˆู„ ุงู„ุชุญู„ูŠู„ูŠุฉ',
145
+ 'purpose': 'ุดุฑุญ ุชู‚ู†ูŠุงุช ู‚ูŠุงุณ ุฃุซุฑ ุงู„ุญู„ูˆู„ ุงู„ุชุญู„ูŠู„ูŠุฉ ูŠู‚ุฏู‘ู… ุฅุทุงุฑ ู„ู„ุชู‚ูŠูŠู…'
146
+ },
147
+ {
148
+ 'axis_number': 3,
149
+ 'title': 'ุงุณุชุฎุฏุงู… ุฃุฏูˆุงุช ู‚ูŠุงุณ ุชู‚ูŠูŠู… ุญู„ ู…ุดุฑูˆุนูƒ',
150
+ 'purpose': 'ุงุณุชุฎุฏุงู… ุฃุฏูˆุงุช ู‚ูŠุงุณ ุชู‚ูŠูŠู… ุญู„ ู…ุดุฑูˆุนูƒ ูŠูŽู…ูƒู‘ู† ุงู„ู…ุชุนู„ู…ูŠู† ู…ู† ุงู„ุชุญู„ูŠู„'
151
+ },
152
+ {
153
+ 'axis_number': 4,
154
+ 'title': 'ุชุญู„ูŠู„ ู…ุคุดุฑุงุช ุงู„ุฃุฏุงุก ูˆุงู„ุชุฃุซูŠุฑ ุงู„ู…ุฌุชู…ุนูŠ',
155
+ 'purpose': 'ุชุญู„ูŠู„ ู…ุคุดุฑุงุช ุงู„ุฃุฏุงุก ูˆุงู„ุชุฃุซูŠุฑ ุงู„ู…ุฌุชู…ุนูŠ ูŠุญุฏุฏ ุงู„ูุงุนู„ูŠุฉ ูˆุงู„ุชุฃุซูŠุฑ'
156
+ },
157
+ {
158
+ 'axis_number': 5,
159
+ 'title': 'ุงุจุชูƒุงุฑ ุงุณุชุฑุงุชูŠุฌูŠุฉ ู‚ูŠุงุฏุฉ ู„ุชุนุฒูŠุฒ ุงู„ูˆุนูŠ ุงู„ุฐุงุชูŠ',
160
+ 'purpose': 'ุงุจุชูƒุงุฑ ุงุณุชุฑุงุชูŠุฌูŠุฉ ู‚ูŠุงุฏุฉ ู„ุชุนุฒูŠุฒ ุงู„ูˆุนูŠ ุงู„ุฐุงุชูŠ ูŠุซู…ุฑ ุฅู…ูƒุงู†ูŠุฉ ุงู„ู‚ูŠุงุฏุฉ'
161
+ }
162
+ ]
163
+ }
164
+ ]
165
+ }
166
+
167
+
168
+ # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
169
+ # ๐Ÿงช Test Function
170
+ # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
171
+
172
+ def test_objectives_generator():
173
+ """
174
+ ุงุฎุชุจุงุฑ ุชูˆู„ูŠุฏ ุงู„ุฃู‡ุฏุงู ุงู„ุชุนู„ูŠู…ูŠุฉ.
175
+ """
176
+
177
+ print("โ”" * 80)
178
+ print("๐Ÿš€ Starting Objectives Generation Test")
179
+ print("โ”" * 80)
180
+ print()
181
+
182
+ # Print input summary
183
+ print("๐Ÿ“Š Input Data:")
184
+ print(f" โ€ข Topic: {METADATA['topic']}")
185
+ print(f" โ€ข Domain: {METADATA['domain']}")
186
+ print(f" โ€ข Content Type: {METADATA['content_type']}")
187
+ print(f" โ€ข Audience: {METADATA['audience']}")
188
+ print(f" โ€ข Material Type: {', '.join(METADATA['material_type'])}")
189
+ print(f" โ€ข Units: {len(OUTLINES['units'])}")
190
+
191
+ # Count total axes
192
+ total_axes = sum(len(unit['axes']) for unit in OUTLINES['units'])
193
+ print(f" โ€ข Total Axes: {total_axes}")
194
+ print()
195
+
196
+ # Generate objectives
197
+ print("โณ Generating objectives...")
198
+ print("โ”" * 80)
199
+ print()
200
+
201
+ try:
202
+ result = generate_objectives(
203
+ topic=METADATA['topic'],
204
+ domain=METADATA['domain'],
205
+ content_type=METADATA['content_type'],
206
+ audience=METADATA['audience'],
207
+ material_type=METADATA['material_type'],
208
+ outlines=OUTLINES
209
+ )
210
+
211
+ print()
212
+ print("โ”" * 80)
213
+ print("โœ… Objectives Generated Successfully!")
214
+ print("โ”" * 80)
215
+ print()
216
+
217
+ # Print results summary
218
+ objectives = result.get('objectives', [])
219
+ print(f"๐Ÿ“ˆ Results Summary:")
220
+ print(f" โ€ข Total Objectives Generated: {len(objectives)}")
221
+ print(f" โ€ข Expected (Total Axes): {total_axes}")
222
+ print(f" โ€ข Match: {'โœ… YES' if len(objectives) == total_axes else 'โŒ NO'}")
223
+ print()
224
+
225
+ # Analyze verb diversity
226
+ verbs_used = [obj['objective'].split()[1] for obj in objectives if len(obj['objective'].split()) > 1]
227
+ unique_verbs = len(set(verbs_used))
228
+ diversity_rate = (unique_verbs / len(verbs_used)) * 100 if verbs_used else 0
229
+
230
+ print(f"๐Ÿ“Š Verb Diversity:")
231
+ print(f" โ€ข Total Verbs Used: {len(verbs_used)}")
232
+ print(f" โ€ข Unique Verbs: {unique_verbs}")
233
+ print(f" โ€ข Diversity Rate: {diversity_rate:.1f}%")
234
+ print(f" โ€ข Target: 70-80%")
235
+ print(f" โ€ข Status: {'โœ… PASS' if diversity_rate >= 70 else 'โš ๏ธ NEEDS IMPROVEMENT'}")
236
+ print()
237
+
238
+ # Analyze domain distribution
239
+ domain_counts = {
240
+ 'Cognitive': sum(1 for obj in objectives if 'Cognitive' in obj['level']),
241
+ 'Affective': sum(1 for obj in objectives if 'Affective' in obj['level']),
242
+ 'Psychomotor': sum(1 for obj in objectives if 'Psychomotor' in obj['level'])
243
+ }
244
+
245
+ total_objs = len(objectives)
246
+ print(f"๐Ÿ“Š Domain Distribution:")
247
+ for domain, count in domain_counts.items():
248
+ percentage = (count / total_objs) * 100 if total_objs > 0 else 0
249
+ print(f" โ€ข {domain}: {count} ({percentage:.1f}%)")
250
+ print()
251
+
252
+ # Print first few objectives as examples
253
+ print("๐Ÿ“ Sample Objectives (First 3):")
254
+ print("โ”" * 80)
255
+ for i, obj in enumerate(objectives[:3], 1):
256
+ print(f"\n{i}. Unit: {obj['unit']}")
257
+ print(f" Axis: {obj['axis']}")
258
+ print(f" Level: {obj['level']}")
259
+ print(f" Verbs: {', '.join(obj['verbs'])}")
260
+ print(f" Objective: {obj['objective']}")
261
+ print()
262
+ print("โ”" * 80)
263
+
264
+ # Save to file
265
+ output_file = 'objectives_output.json'
266
+ with open(output_file, 'w', encoding='utf-8') as f:
267
+ json.dump(result, f, ensure_ascii=False, indent=2)
268
+
269
+ print(f"๐Ÿ’พ Full output saved to: {output_file}")
270
+ print()
271
+
272
+ return result
273
+
274
+ except Exception as e:
275
+ print()
276
+ print("โ”" * 80)
277
+ print("โŒ Error During Generation")
278
+ print("โ”" * 80)
279
+ print(f"Error: {str(e)}")
280
+ print()
281
+ import traceback
282
+ traceback.print_exc()
283
+ return None
284
+
285
+
286
+ # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
287
+ # ๐ŸŽฏ Main Execution
288
+ # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
289
+
290
+ if __name__ == "__main__":
291
+ test_objectives_generator()
292
+