cryogenic22 commited on
Commit
e6ee63c
·
verified ·
1 Parent(s): 60affc8

Update learning_platform.py

Browse files
Files changed (1) hide show
  1. learning_platform.py +129 -97
learning_platform.py CHANGED
@@ -1,10 +1,16 @@
1
- from dataclasses import dataclass, field
2
  from typing import List, Dict, Any, Optional
 
3
  from datetime import datetime
4
  import asyncio
5
  import json
6
  import streamlit as st
7
- from openai import AsyncOpenAI
 
 
 
 
 
 
8
 
9
  @dataclass
10
  class Section:
@@ -33,146 +39,172 @@ class LearningPath:
33
  difficulty_level: str
34
  is_generating: bool = True
35
 
36
- class LLMService:
37
  def __init__(self, api_key: str):
38
- self.client = AsyncOpenAI(api_key=api_key)
39
- self.model = "gpt-4o"
 
 
 
 
 
 
 
40
 
41
- async def generate(self, prompt: str, temperature: float = 1.0) -> str:
42
- try:
43
- st.write("🤖 Calling OpenAI API...")
44
- response = await self.client.chat.completions.create(
45
- model=self.model,
46
- messages=[{"role": "system", "content": prompt}],
47
- temperature=temperature
 
 
 
 
 
 
 
48
  )
49
- return response.choices[0].message.content
50
- except Exception as e:
51
- st.error(f"OpenAI API error: {str(e)}")
52
- raise
53
 
54
  class ContentGenerator:
55
- def __init__(self, llm_service: LLMService):
56
- self.llm_service = llm_service
57
-
58
- async def generate_section_content(self, topic: str, section_title: str) -> Section:
59
- section = Section(title=section_title)
60
- try:
61
- content_prompt = f"""Create educational content for '{section_title}' in '{topic}' following this format exactly:
62
- {{
63
- "content": "# {section_title}\\n\\n[Your markdown content here with examples, code snippets, and explanations]",
64
- "key_points": [
65
- "First key point",
66
- "Second key point",
67
- "Third key point"
68
- ]
69
- }}
70
 
71
- Content guidelines:
72
- - Use markdown formatting with headers (##)
73
- - Include 2-3 practical examples or code snippets
74
- - Provide best practices and common pitfalls depending on the topic. Focus on providing some aha moment or things to learn and tips. adjust based on the topic and context.
75
- - Include diagrams and pictures where possible
76
- - Add expert tips and industry insights"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
 
78
- content_response = await self.llm_service.generate(content_prompt)
79
- content_data = json.loads(content_response)
 
 
 
 
80
 
81
- quiz_prompt = f"""Create quiz questions for '{section_title}' in '{topic}' following this format exactly:
82
- [{{
83
- "question": "Write your question here",
84
- "options": ["Option A", "Option B", "Option C", "Option D"],
85
- "correct_answer": "Option A",
86
- "explanation": "Explanation here",
87
- "hint": "Optional hint here"
88
- }}]"""
 
 
 
 
 
 
 
 
 
 
89
 
90
- quiz_response = await self.llm_service.generate(quiz_prompt)
91
- quiz_data = json.loads(quiz_response)
 
92
 
93
- section.content = content_data["content"]
94
- section.key_points = content_data["key_points"]
95
- section.quiz_questions = quiz_data
96
- section.is_complete = True
97
-
98
- return section
99
- except json.JSONDecodeError as e:
100
- st.error(f"JSON parsing error: {str(e)}\nResponse: {content_response}")
101
- return section
102
  except Exception as e:
103
- st.error(f"Section creation error: {str(e)}")
104
- return section
105
 
106
  class LearningPlatform:
107
  def __init__(self, api_key: str):
108
- self.llm_service = LLMService(api_key)
109
- self.content_generator = ContentGenerator(self.llm_service)
110
 
111
  async def create_course(self, topic: str, difficulty: str) -> LearningPath:
112
  try:
113
- st.write("🔍 Generating course outline...")
114
- titles_prompt = f"List 3 module titles for {topic} course. Return as JSON array of strings."
115
- titles_task = asyncio.create_task(self.llm_service.generate(titles_prompt))
 
 
 
 
 
 
 
 
 
116
 
117
- try:
118
- titles_response = await asyncio.wait_for(titles_task, timeout=30)
119
- titles = json.loads(titles_response)
120
- except asyncio.TimeoutError:
121
- st.error("Timeout generating course outline")
122
- raise
123
 
124
- st.write("📚 Creating course structure...")
125
- modules = [LearningModule(title=title) for title in titles]
126
  path = LearningPath(
127
  topic=topic,
128
- description=f"Course on {topic}",
129
  modules=modules,
130
  created_at=datetime.now(),
131
  difficulty_level=difficulty
132
  )
133
 
134
- st.write("🎯 Generating first module...")
135
- try:
136
- await asyncio.wait_for(
137
- self.create_module(path.modules[0], topic),
138
- timeout=60
139
- )
140
- except asyncio.TimeoutError:
141
- st.error("Timeout generating first module")
142
- raise
143
-
144
- st.write("✨ Starting background generation...")
145
  asyncio.create_task(self.generate_remaining_modules(path, topic))
146
 
147
  return path
148
 
149
  except Exception as e:
150
- st.error(f"Course creation failed: {str(e)}")
151
  raise
152
 
153
- async def create_module(self, module: LearningModule, topic: str, timeout: int = 30):
154
  try:
155
- st.write(f"Generating sections for {module.title}...")
156
- sections_prompt = f"List 3 section titles for module '{module.title}' in {topic}. Return JSON array."
 
 
 
 
 
 
 
157
 
158
- section_titles = json.loads(await asyncio.wait_for(
159
- self.llm_service.generate(sections_prompt),
160
- timeout=timeout
161
- ))
162
 
163
  for title in section_titles:
164
- st.write(f"Creating section: {title}")
165
  section = await self.content_generator.generate_section_content(topic, title)
166
  module.sections.append(section)
167
 
168
  module.is_complete = True
169
  return module
170
  except Exception as e:
171
- st.error(f"Module generation failed: {str(e)}")
172
  raise
173
 
174
  async def generate_remaining_modules(self, path: LearningPath, topic: str):
175
- for i, module in enumerate(path.modules[1:], 1):
176
- st.write(f"Generating module {i+1} of {len(path.modules)}...")
177
  await self.create_module(module, topic)
178
  path.is_generating = False
 
 
1
  from typing import List, Dict, Any, Optional
2
+ from dataclasses import dataclass, field
3
  from datetime import datetime
4
  import asyncio
5
  import json
6
  import streamlit as st
7
+ from crewai import Agent, Task, Crew, Process
8
+ from langchain.prompts import PromptTemplate
9
+ from langchain.chains import SequentialChain, LLMChain
10
+ from langchain.chat_models import ChatOpenAI
11
+ from langchain.embeddings import OpenAIEmbeddings
12
+ from langchain.vectorstores import FAISS
13
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
14
 
15
  @dataclass
16
  class Section:
 
39
  difficulty_level: str
40
  is_generating: bool = True
41
 
42
+ class CourseAgents:
43
  def __init__(self, api_key: str):
44
+ self.llm = ChatOpenAI(openai_api_key=api_key)
45
+
46
+ self.curriculum_designer = Agent(
47
+ role="Curriculum Designer",
48
+ goal="Design comprehensive course structure",
49
+ backstory="Expert in educational design with focus on progressive learning",
50
+ tools=[self.llm],
51
+ verbose=True
52
+ )
53
 
54
+ self.content_creator = Agent(
55
+ role="Content Creator",
56
+ goal="Create engaging, practical content",
57
+ backstory="Technical expert and educator",
58
+ tools=[self.llm],
59
+ verbose=True
60
+ )
61
+
62
+ self.quiz_master = Agent(
63
+ role="Assessment Developer",
64
+ goal="Create effective learning assessments",
65
+ backstory="Expert in educational assessment",
66
+ tools=[self.llm],
67
+ verbose=True
68
  )
 
 
 
 
69
 
70
  class ContentGenerator:
71
+ def __init__(self, api_key: str):
72
+ self.agents = CourseAgents(api_key)
73
+ self.llm = ChatOpenAI(openai_api_key=api_key)
74
+ self.setup_chains()
75
+ self.setup_rag()
 
 
 
 
 
 
 
 
 
 
76
 
77
+ def setup_chains(self):
78
+ self.structure_chain = LLMChain(
79
+ llm=self.llm,
80
+ prompt=PromptTemplate(
81
+ template="Create detailed structure for {topic} at {difficulty} level.",
82
+ input_variables=["topic", "difficulty"]
83
+ )
84
+ )
85
+
86
+ self.content_chain = LLMChain(
87
+ llm=self.llm,
88
+ prompt=PromptTemplate(
89
+ template="Create content for {section_title} in {topic}.",
90
+ input_variables=["section_title", "topic"]
91
+ )
92
+ )
93
+
94
+ self.quiz_chain = LLMChain(
95
+ llm=self.llm,
96
+ prompt=PromptTemplate(
97
+ template="Create assessment for {section_title} in {topic}.",
98
+ input_variables=["section_title", "topic"]
99
+ )
100
+ )
101
 
102
+ def setup_rag(self):
103
+ self.embeddings = OpenAIEmbeddings()
104
+ self.vector_store = FAISS.from_texts(
105
+ ["Initial knowledge base"],
106
+ embedding=self.embeddings
107
+ )
108
 
109
+ async def generate_section_content(self, topic: str, section_title: str) -> Section:
110
+ try:
111
+ crew = Crew(
112
+ agents=[
113
+ self.agents.content_creator,
114
+ self.agents.quiz_master
115
+ ],
116
+ tasks=[
117
+ Task(
118
+ description=f"Create content for {section_title} in {topic}",
119
+ agent=self.agents.content_creator
120
+ ),
121
+ Task(
122
+ description=f"Create quiz for {section_title}",
123
+ agent=self.agents.quiz_master
124
+ )
125
+ ]
126
+ )
127
 
128
+ results = await crew.kickoff()
129
+ content_data = json.loads(results['content'])
130
+ quiz_data = json.loads(results['quiz'])
131
 
132
+ return Section(
133
+ title=section_title,
134
+ content=content_data["content"],
135
+ key_points=content_data["key_points"],
136
+ quiz_questions=quiz_data,
137
+ is_complete=True
138
+ )
 
 
139
  except Exception as e:
140
+ st.error(f"Section generation error: {str(e)}")
141
+ return Section(title=section_title)
142
 
143
  class LearningPlatform:
144
  def __init__(self, api_key: str):
145
+ self.content_generator = ContentGenerator(api_key)
146
+ self.agents = CourseAgents(api_key)
147
 
148
  async def create_course(self, topic: str, difficulty: str) -> LearningPath:
149
  try:
150
+ crew = Crew(
151
+ agents=[self.agents.curriculum_designer],
152
+ tasks=[
153
+ Task(
154
+ description=f"Design course structure for {topic} at {difficulty} level",
155
+ agent=self.agents.curriculum_designer
156
+ )
157
+ ]
158
+ )
159
+
160
+ structure = await crew.kickoff()
161
+ module_data = json.loads(structure['course_structure'])
162
 
163
+ modules = [LearningModule(title=title) for title in module_data]
 
 
 
 
 
164
 
 
 
165
  path = LearningPath(
166
  topic=topic,
167
+ description=module_data["description"],
168
  modules=modules,
169
  created_at=datetime.now(),
170
  difficulty_level=difficulty
171
  )
172
 
173
+ await self.create_module(path.modules[0], topic)
 
 
 
 
 
 
 
 
 
 
174
  asyncio.create_task(self.generate_remaining_modules(path, topic))
175
 
176
  return path
177
 
178
  except Exception as e:
179
+ st.error(f"Course creation error: {str(e)}")
180
  raise
181
 
182
+ async def create_module(self, module: LearningModule, topic: str):
183
  try:
184
+ crew = Crew(
185
+ agents=[self.agents.curriculum_designer],
186
+ tasks=[
187
+ Task(
188
+ description=f"Create sections for module {module.title}",
189
+ agent=self.agents.curriculum_designer
190
+ )
191
+ ]
192
+ )
193
 
194
+ sections_data = await crew.kickoff()
195
+ section_titles = json.loads(sections_data['sections'])
 
 
196
 
197
  for title in section_titles:
 
198
  section = await self.content_generator.generate_section_content(topic, title)
199
  module.sections.append(section)
200
 
201
  module.is_complete = True
202
  return module
203
  except Exception as e:
204
+ st.error(f"Module generation error: {str(e)}")
205
  raise
206
 
207
  async def generate_remaining_modules(self, path: LearningPath, topic: str):
208
+ for module in path.modules[1:]:
 
209
  await self.create_module(module, topic)
210
  path.is_generating = False