-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprocess_incoming.py
More file actions
179 lines (140 loc) · 5.39 KB
/
Copy pathprocess_incoming.py
File metadata and controls
179 lines (140 loc) · 5.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
import pandas as pd
import requests
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
import joblib
import threading
import time
import sys
from openai import OpenAI
import os
from dotenv import load_dotenv
load_dotenv(".env.local")
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
if not OPENAI_API_KEY:
raise RuntimeError("OPENAI_API_KEY not found")
client = OpenAI(api_key=OPENAI_API_KEY)
def show_loading():
"""Display animated loading message"""
loading_chars = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']
i = 0
while loading_active:
sys.stdout.write(f'\r{loading_chars[i % len(loading_chars)]} Thinking...')
sys.stdout.flush()
time.sleep(0.1)
i += 1
# Clear the loading message
sys.stdout.write('\r' + ' ' * 15 + '\r')
sys.stdout.flush()
def create_embedding(text_list):
r = requests.post("http://localhost:11434/api/embed", json={
"model": "bge-m3",
"input": text_list
})
embedding = r.json()["embeddings"]
return embedding
# def inference(prompt):
# r = requests.post("http://localhost:11434/api/generate", json={
# "model": "llama3.2:latest",
# "prompt": prompt,
# "stream": False,
# # "max_new_tokens": 512,
# # "temperature": 0.1,
# # "top_p": 0.75,
# # "stop": ["###"]
# })
# response = r.json()
# return response
def response_openai(prompt):
response_openai = client.responses.create(
model="gpt-5",
input=prompt
)
return response_openai.output_text
# Load the embeddings dataframe
df = joblib.load("embeddings_df.joblib")
# Get user input
incoming_query = input("Enter your query: ")
# Global flag to control loading animation
loading_active = True
# Start loading animation in a separate thread
loading_thread = threading.Thread(target=show_loading, daemon=True)
loading_thread.start()
try:
# Process the query
question_embedding = create_embedding([incoming_query])[0]
# Find similarities
similarities = cosine_similarity(np.vstack(df["embedding"].values), [question_embedding]).flatten()
# Get top results
top_result = 5
max_indx = similarities.argsort()[::-1][0:top_result]
new_df = df.loc[max_indx]
# Create the prompt
prompt = f"""
You are a course assistant helping students learn from the Sigma Web Development Course.
You'll receive subtitle chunks from the course videos. Each chunk contains:
- Video title
- Video number
- Chunk ID
- Start time in seconds
- End time in seconds
- Transcript text
Your job:
1. Response as a human should when asked about that query
2. After that sentence, **show the relevant information in a clean structured format**:
- Mention **Video Number + Title** at the top.
- List each relevant segment with timestamps converted from **seconds to minutes:seconds format** (for example:
- 111 seconds → 1:51
- 356 seconds → 5:56
- 654 seconds → 10:54).
- Give a short one-line description of what is explained in that segment.
3. dont response too short and dont response too big also, it should be perfect and good enough response like a human.
4. End with a **Tip** line summarizing where to start watching.
5. **Do NOT ask the student any questions at the end.** Only give the response.
6. Use bullet points or a time-coded guide (like the example below):
Example output style:
ID and Class attributes in HTML are taught in Video 9 called "Id & Classes in HTML".
Video 9: "Id & Classes in HTML"
• 0:48 - 0:50 → Definition of ID attribute
• 0:49 - 0:51 → Definition of class attribute
• 1:18 - 1:21 → Usage of ID and classes in CSS
Tip: Watch from around 0:49 onwards for a clear explanation of both attributes.
7. **No small talk** - be factual and focused.
8. If the question is unrelated to the course, reply with: "I can only answer questions related to this course."
9. If not enough info is available, reply: "I'm not sure about that."
Here are the subtitle chunks you can use:
{new_df[["title", "number", "id", "start", "end", "text"]].to_json(orient="records", lines=False)}
--------------------------------------------------------------------------------------------------------
Student's Question: "{incoming_query}"
"""
# Save prompt to file
with open("prompt.txt", "w", encoding="utf-8") as f:
f.write(prompt)
# Get response from the model
# response = inference(prompt)
# Stop loading animation
loading_active = False
loading_thread.join(timeout=0.1) # Wait briefly for thread to finish
# Extract and display the response
# response_text = response.get("response", "")
# print(response_text)
response_text = response_openai(prompt)
print(response_text)
# Save response to file
with open("response.txt", "w", encoding="utf-8") as f:
f.write(response_text)
except Exception as e:
# Stop loading animation in case of error
loading_active = False
loading_thread.join(timeout=0.1)
print(f"\nError occurred: {str(e)}")
# Commented out debug section
# for index, item in new_df.iterrows():
# print(index)
# print(f"Title: {item['title']}")
# print(f"Video Number: {item['number']}")
# print(f"Chunk ID: {item['id']}")
# print(f"Text: {item['text']}")
# print(f"start: {item['start']/60}")
# print(f"end: {item['end']/60}")
# print("\n---\n")