Owen Wang commited on
Commit
4b2c4ed
·
1 Parent(s): 034be72

get it working with ash prompt and chat

Browse files
Files changed (2) hide show
  1. app.py +32 -23
  2. requirements.txt +2 -1
app.py CHANGED
@@ -1,10 +1,10 @@
1
- from typing import List, Optional, TypedDict
2
  import streamlit as st
3
  import requests
4
  import openai
5
  import pinecone
6
  import json
7
  import re
 
8
 
9
  PINECONE_API_KEY = st.secrets["PINECONE_API_KEY"]
10
  # Set OpenAI API key from Streamlit Secrets
@@ -12,16 +12,11 @@ OPENAI_API_KEY = st.secrets["OPENAI_API_KEY"]
12
  # Set maximum token length
13
  MAX_TOKENS = 1024
14
  # Set OpenAI model
15
- MODEL = "text-davinci-003"
16
-
17
- class Metadata(TypedDict):
18
- title: str
19
- description: str
20
- slides: str
21
- outcome: str
22
 
23
  # Initialize OpenAI
24
  openai.api_key = OPENAI_API_KEY
 
25
 
26
  @st.cache_resource
27
  def load_pinecone_index():
@@ -29,7 +24,7 @@ def load_pinecone_index():
29
  index_name = "prequelworkshops"
30
  return pinecone.Index(index_name)
31
 
32
- def get_embeddings(texts: List[str]) -> List[List[float]]:
33
  """
34
  Embed texts using OpenAI's ada model.
35
 
@@ -52,7 +47,8 @@ def get_embeddings(texts: List[str]) -> List[List[float]]:
52
  return [result["embedding"] for result in data]
53
 
54
  # Pinecone fetch function
55
- def fetch_lesson(index, query: str):
 
56
  vector = get_embeddings([query])[0]
57
 
58
  return index.query(
@@ -66,18 +62,22 @@ def fetch_lesson(index, query: str):
66
  )
67
 
68
  # OpenAI prompt generation function
69
- def query_openai(prompt) -> str:
70
- response = openai.Completion.create(
71
- engine=MODEL,
72
- prompt=prompt,
 
 
73
  max_tokens=MAX_TOKENS,
74
  n=1,
75
  stop=None,
76
  temperature=0.7,
 
77
  )
78
- return response.choices[0].text.strip()
 
79
 
80
- def extract_arrays(s: str) -> Optional[List[str]]:
81
  # Find the starting and ending indices of the array
82
  start = s.find('[')
83
  end = s.find(']')
@@ -102,17 +102,23 @@ def extract_arrays(s: str) -> Optional[List[str]]:
102
  else:
103
  return None
104
 
105
- def generate_curriculum(skills: str) -> Optional[List[str]]:
106
  prompt = f"You are a world-class middle and high school educator who develops project-based entrepreneurship curriculum catered to student interests. Create a curriculum of up to 5 lessons for a course based on the student's target skills to learn. Output the curriculum as a javascript array of strings, where each string is a description of the lesson. The output should just be the array and nothing else. Student's target skills: {skills}"
107
  response = query_openai(prompt)
108
  return extract_arrays(response)
109
 
110
- def generate_application(metadata: Metadata, interests: str) -> str:
111
- prompt = f"You are a world-class middle and high school educator who develops project-based entrepreneurship curriculum catered to student interests. You've created a lesson called \"{metadata['title']}\". The description of the lesson is \"{metadata['description']}\". The expected learning outcome is \"{metadata['outcome']}\". First describe the course and its outcome in one sentence objectively. Next, explain to a parent why a student who is interested in \"{interests}\" should take this lesson in one concise sentence."
 
 
 
 
 
 
112
  response = query_openai(prompt)
113
  return response
114
 
115
- def format_metadata(metadata: Metadata, interests: str) -> List[str]:
116
  print(metadata)
117
  application = generate_application(metadata, interests)
118
  return f"Title: [{metadata['title']}]({metadata['slides']})\n\n{application}"
@@ -140,15 +146,18 @@ if submit_button:
140
  curriculum = generate_curriculum(skills)
141
 
142
  if curriculum is not None:
143
- status.text("Feeding the hamsters powering our servers... we're harvesting the seeds")
144
  index = load_pinecone_index()
145
  lessons = [fetch_lesson(index, lesson) for lesson in curriculum]
146
  lessons_metadata = filtered_metadatas(lessons)
147
 
148
- status.text("Building a bridge from your dreams to reality... just one more moment")
 
 
 
149
  lesson_text = "\n\n".join([format_metadata(metadata, interests) for metadata in lessons_metadata])
150
  status.empty()
151
  st.markdown(f"\n\n## Your personalized learning playlist\n\n{lesson_text}")
152
  else:
153
- status.text("Error generating curriculum. Please try again")
154
 
 
 
1
  import streamlit as st
2
  import requests
3
  import openai
4
  import pinecone
5
  import json
6
  import re
7
+ from tenacity import retry, stop_after_attempt, wait_exponential
8
 
9
  PINECONE_API_KEY = st.secrets["PINECONE_API_KEY"]
10
  # Set OpenAI API key from Streamlit Secrets
 
12
  # Set maximum token length
13
  MAX_TOKENS = 1024
14
  # Set OpenAI model
15
+ MODEL = "gpt-3.5-turbo"
 
 
 
 
 
 
16
 
17
  # Initialize OpenAI
18
  openai.api_key = OPENAI_API_KEY
19
+ conversation = []
20
 
21
  @st.cache_resource
22
  def load_pinecone_index():
 
24
  index_name = "prequelworkshops"
25
  return pinecone.Index(index_name)
26
 
27
+ def get_embeddings(texts):
28
  """
29
  Embed texts using OpenAI's ada model.
30
 
 
47
  return [result["embedding"] for result in data]
48
 
49
  # Pinecone fetch function
50
+ @retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=2, max=6))
51
+ def fetch_lesson(index, query):
52
  vector = get_embeddings([query])[0]
53
 
54
  return index.query(
 
62
  )
63
 
64
  # OpenAI prompt generation function
65
+ @retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=2, max=6))
66
+ def query_openai(prompt):
67
+ conversation.append({"role": "user", "content": prompt})
68
+ response = openai.ChatCompletion.create(
69
+ model=MODEL,
70
+ messages=conversation,
71
  max_tokens=MAX_TOKENS,
72
  n=1,
73
  stop=None,
74
  temperature=0.7,
75
+ frequency_penalty=2
76
  )
77
+ conversation.append(response.choices[0].message)
78
+ return response.choices[0].message.content.strip()
79
 
80
+ def extract_arrays(s):
81
  # Find the starting and ending indices of the array
82
  start = s.find('[')
83
  end = s.find(']')
 
102
  else:
103
  return None
104
 
105
+ def generate_curriculum(skills):
106
  prompt = f"You are a world-class middle and high school educator who develops project-based entrepreneurship curriculum catered to student interests. Create a curriculum of up to 5 lessons for a course based on the student's target skills to learn. Output the curriculum as a javascript array of strings, where each string is a description of the lesson. The output should just be the array and nothing else. Student's target skills: {skills}"
107
  response = query_openai(prompt)
108
  return extract_arrays(response)
109
 
110
+ def generate_ideas(metadatas, interests):
111
+ summary = ".".join([f"Lesson {i} - title: {metadata['title']}, description: {metadata['description']}, learning outcome: {metadata['outcome']}" for i, metadata in enumerate(metadatas)])
112
+ prompt = f"We've created a curriculum for the student: {summary}. The student has an interest in \"{interests}\". What are some ambitious projects the student could do from what they'd learn from the curriculum?"
113
+ response = query_openai(prompt)
114
+ print(response)
115
+
116
+ def generate_application(metadata, interests):
117
+ prompt = f"For the lesson titled \"{metadata['title']}\" about \"{metadata['description']}\", first describe the lesson and its outcome in one sentence objectively. Next, explore possible personal growth outcomes that combine their interest in \"{interests}\" with this lesson in one concise sentence. Implicitly draw poetic connections between the interests and the lesson. Help them to feel inspired to connect with the lesson. Try to communicate this without using the words \"{interests}\". Instead, tie in one of the previously described ambitious projects. Don't repeat an example of a project if you've used it for a previous lesson. Help them to see how the knowledge they gain in this lesson will allow them to thrive in their interests."
118
  response = query_openai(prompt)
119
  return response
120
 
121
+ def format_metadata(metadata, interests):
122
  print(metadata)
123
  application = generate_application(metadata, interests)
124
  return f"Title: [{metadata['title']}]({metadata['slides']})\n\n{application}"
 
146
  curriculum = generate_curriculum(skills)
147
 
148
  if curriculum is not None:
149
+ status.text("Feeding the hamsters powering our servers...")
150
  index = load_pinecone_index()
151
  lessons = [fetch_lesson(index, lesson) for lesson in curriculum]
152
  lessons_metadata = filtered_metadatas(lessons)
153
 
154
+ status.text("Harvesting the seeds of wisdom...")
155
+ generate_ideas(lessons_metadata, interests)
156
+
157
+ status.text("Building a bridge from your dreams to reality... just one more moment!")
158
  lesson_text = "\n\n".join([format_metadata(metadata, interests) for metadata in lessons_metadata])
159
  status.empty()
160
  st.markdown(f"\n\n## Your personalized learning playlist\n\n{lesson_text}")
161
  else:
162
+ status.text("The Wheel of Education spun out of control! Care to give it another whirl? Click 'Generate curriculum' again")
163
 
requirements.txt CHANGED
@@ -1,3 +1,4 @@
1
  streamlit
2
  openai
3
- pinecone-client
 
 
1
  streamlit
2
  openai
3
+ pinecone-client
4
+ tenacity