Hma47 commited on
Commit
1de8a7b
·
verified ·
1 Parent(s): 0a2f404

Upload 4 files

Browse files
Files changed (4) hide show
  1. License.txt +17 -0
  2. README.md +92 -0
  3. index.html +875 -0
  4. 📘 AI Learning Coach Guide.txt +76 -0
License.txt ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ Copyright 2025 Shift Mind AI Labs
6
+
7
+ Licensed under the Apache License, Version 2.0 (the "License");
8
+ you may not use this file except in compliance with the License.
9
+ You may obtain a copy of the License at
10
+
11
+ http://www.apache.org/licenses/LICENSE-2.0
12
+
13
+ Unless required by applicable law or agreed to in writing, software
14
+ distributed under the License is distributed on an "AS IS" BASIS,
15
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ See the License for the specific language governing permissions and
17
+ limitations under the License.
README.md ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: "🧠 AI Learning Coach"
3
+ emoji: "🗣️"
4
+ colorFrom: "green"
5
+ colorTo: "yellow"
6
+ sdk: "static"
7
+ sdk_version: "0.1.0"
8
+ app_file: "index.html"
9
+ pinned: false
10
+ ---
11
+
12
+ # 🧠 AI Learning Coach (AI-Interactive Metacognition Tracker)
13
+ **Developed by Shift Mind AI Labs**
14
+
15
+ The AI Learning Coach is an open-source, browser-based metacognitive reflection tool designed to help learners, teachers, and lifelong students develop self-awareness, self-regulation, and reflective learning habits. Powered by GPT-4o-mini and advanced UI/UX, it guides users through structured metacognitive cycles with AI-powered chat, feedback, and personalized growth plans.
16
+
17
+ ---
18
+
19
+ ## 🚀 Features
20
+
21
+ - **Structured Metacognition:** Step-by-step guidance through five phases: task planning, pre-learning reflection, during-learning check-in, post-learning evaluation, and personalized development plan.
22
+ - **Conversational AI Chat:** Interactive, adaptive AI chatbot acts as a personal coach—asks questions, offers tips, and provides feedback at every stage.
23
+ - **Progress Visualization:** Visual progress bar for each session; previous session summaries saved in your browser.
24
+ - **Privacy-First:** All data—including OpenAI API key—is processed client-side; nothing leaves your browser.
25
+ - **No Login Required:** Start reflecting in seconds—no registration or account setup.
26
+
27
+ ---
28
+
29
+ ## 🛠 How to Use
30
+
31
+ 1. **Access the tool** in your browser (no install needed).
32
+ 2. **Enter your OpenAI API key** to unlock AI-powered conversations. *(Your key is only stored in your browser, never transmitted elsewhere.)*
33
+ 3. **Follow the stages**:
34
+ - **Task Planning:** Clarify your learning goal with AI help.
35
+ - **Pre-Learning:** Reflect on your readiness, confidence, and strategies.
36
+ - **During Learning:** Pause, check your progress, and adapt with the coach's suggestions.
37
+ - **Post-Learning:** Debrief with AI-guided questions—analyze what worked and what can improve.
38
+ - **Development Plan:** Get a personalized growth plan for your next steps.
39
+ 4. **Type your responses and interact with the AI** at every stage.
40
+ 5. **Navigate between stages** as you need, and complete the session to save your reflection history.
41
+
42
+ ---
43
+
44
+ ## 👩‍🏫 For Teachers: How It Supports Educators
45
+
46
+ - **Promotes metacognitive awareness** and reflective learning practices in any subject or level.
47
+ - **Flexible for in-class, homework, or blended learning**—use as a warm-up, self-check, or end-of-unit reflection.
48
+ - **No data privacy worries:** Suitable for classroom, no login, no accounts, no cloud storage.
49
+ - **Ideal for formative assessment, SEL, and independent learning portfolios.**
50
+
51
+ ---
52
+
53
+ ## 👨‍🎓 For Students: Benefits & Learning Outcomes
54
+
55
+ - **Self-guided learning reflection:** Build lifelong skills in planning, monitoring, and evaluating learning.
56
+ - **Personalized coaching:** Get friendly, AI-powered tips and support based on your unique context.
57
+ - **Easy to use:** Designed for all ages; visually clear and mobile-friendly.
58
+ - **Own your growth:** Download or save reflections for future review and share with teachers or mentors.
59
+
60
+ ---
61
+
62
+ ## 🔐 Data Privacy Notice
63
+
64
+ - All data and API keys stay local to your browser.
65
+ - No data is sent to Shift Mind AI Labs, Hugging Face, or any third-party (other than OpenAI if you use the API).
66
+
67
+
68
+ ---
69
+
70
+ ## 📄 License
71
+
72
+ Licensed under the [Apache License 2.0](./LICENSE).
73
+
74
+ ---
75
+
76
+ ## 🧠 About Shift Mind AI Labs
77
+
78
+ Shift Mind AI Labs creates ethical, scalable, and open-source AI tools for global education and self-improvement.
79
+
80
+ 🌐 https://shiftmind.io
81
+ ✉️ info@shiftmind.io
82
+
83
+ ---
84
+
85
+ ## 🙌 Contributing
86
+
87
+ Pull requests, issues, and feedback are welcome!
88
+ For school pilots or integration requests: **info@shiftmind.io**
89
+
90
+ ---
91
+
92
+ *Empowering every learner to become their own coach—one reflection at a time.*
index.html ADDED
@@ -0,0 +1,875 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <title>AI-Interactive Metacognition Tracker</title>
6
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
7
+ <!-- Tailwind CSS -->
8
+ <script src="https://cdn.tailwindcss.com"></script>
9
+ <!-- React & ReactDOM -->
10
+ <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
11
+ <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
12
+ <!-- @babel/standalone -->
13
+ <script crossorigin src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
14
+ <!-- Framer Motion - using different CDN -->
15
+ <script crossorigin src="https://cdn.jsdelivr.net/npm/framer-motion@10.16.4/dist/framer-motion.umd.js"></script>
16
+ <!-- Recharts - using different CDN -->
17
+ <script crossorigin src="https://cdn.jsdelivr.net/npm/recharts@2.8.0/umd/Recharts.min.js"></script>
18
+ <style>
19
+ html, body {
20
+ background: linear-gradient(135deg, #f8fafc 0%, #e0f2fe 100%);
21
+ min-height: 100%;
22
+ margin: 0;
23
+ }
24
+ .glass {
25
+ background: rgba(255, 255, 255, 0.85);
26
+ backdrop-filter: blur(10px);
27
+ border-radius: 1.25rem;
28
+ box-shadow: 0 8px 32px rgba(59, 130, 246, 0.15);
29
+ border: 1px solid rgba(255, 255, 255, 0.2);
30
+ }
31
+ .ai-message {
32
+ background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
33
+ color: white;
34
+ border-radius: 1rem 1rem 0.25rem 1rem;
35
+ padding: 1rem;
36
+ margin: 0.5rem 0;
37
+ max-width: 85%;
38
+ animation: slideInLeft 0.3s ease-out;
39
+ line-height: 1.6;
40
+ }
41
+ .ai-message p {
42
+ margin: 0.5rem 0;
43
+ }
44
+ .ai-message ul, .ai-message ol {
45
+ margin: 0.5rem 0;
46
+ padding-left: 1.5rem;
47
+ }
48
+ .ai-message li {
49
+ margin: 0.25rem 0;
50
+ }
51
+ .ai-message h3, .ai-message h4 {
52
+ margin: 1rem 0 0.5rem 0;
53
+ font-weight: bold;
54
+ }
55
+ .ai-message strong {
56
+ font-weight: bold;
57
+ }
58
+ .user-message {
59
+ background: linear-gradient(135deg, #10b981 0%, #059669 100%);
60
+ color: white;
61
+ border-radius: 1rem 1rem 1rem 0.25rem;
62
+ padding: 1rem;
63
+ margin: 0.5rem 0;
64
+ max-width: 80%;
65
+ margin-left: auto;
66
+ animation: slideInRight 0.3s ease-out;
67
+ }
68
+ .typing-indicator {
69
+ background: #f3f4f6;
70
+ border-radius: 1rem;
71
+ padding: 1rem;
72
+ margin: 0.5rem 0;
73
+ max-width: 80%;
74
+ animation: pulse 1.5s infinite;
75
+ }
76
+ .chat-container {
77
+ max-height: 500px;
78
+ overflow-y: auto;
79
+ padding: 1rem;
80
+ border: 1px solid #e5e7eb;
81
+ border-radius: 0.75rem;
82
+ background: rgba(255, 255, 255, 0.5);
83
+ }
84
+ .progress-bar {
85
+ background: linear-gradient(90deg, #3b82f6 0%, #1d4ed8 100%);
86
+ height: 6px;
87
+ border-radius: 3px;
88
+ transition: width 0.5s ease;
89
+ }
90
+ @keyframes slideInLeft {
91
+ from { opacity: 0; transform: translateX(-20px); }
92
+ to { opacity: 1; transform: translateX(0); }
93
+ }
94
+ @keyframes slideInRight {
95
+ from { opacity: 0; transform: translateX(20px); }
96
+ to { opacity: 1; transform: translateX(0); }
97
+ }
98
+ @keyframes pulse {
99
+ 0%, 100% { opacity: 1; }
100
+ 50% { opacity: 0.5; }
101
+ }
102
+ .fade-in {
103
+ animation: fadeIn 0.5s ease-in;
104
+ }
105
+ @keyframes fadeIn {
106
+ from { opacity: 0; transform: translateY(20px); }
107
+ to { opacity: 1; transform: translateY(0); }
108
+ }
109
+ /* Accessibility improvements */
110
+ .sr-only {
111
+ position: absolute;
112
+ width: 1px;
113
+ height: 1px;
114
+ padding: 0;
115
+ margin: -1px;
116
+ overflow: hidden;
117
+ clip: rect(0, 0, 0, 0);
118
+ white-space: nowrap;
119
+ border: 0;
120
+ }
121
+ button:focus, input:focus, textarea:focus, select:focus {
122
+ outline: 2px solid #3b82f6;
123
+ outline-offset: 2px;
124
+ }
125
+ @media (max-width: 640px) {
126
+ .ai-message, .user-message {
127
+ max-width: 95%;
128
+ }
129
+ .chat-container {
130
+ max-height: 400px;
131
+ }
132
+ }
133
+ </style>
134
+ </head>
135
+ <body>
136
+ <div id="root"></div>
137
+ <script type="text/babel">
138
+ const { useState, useEffect, useCallback, useRef } = React;
139
+
140
+ // Fallback motion component if framer-motion fails to load
141
+ const motion = window['framer-motion'] ? window['framer-motion'].motion : {
142
+ div: ({ children, className, initial, animate, ...props }) =>
143
+ React.createElement('div', { className: `${className} fade-in`, ...props }, children)
144
+ };
145
+
146
+ // Fallback chart components if Recharts fails to load
147
+ const Recharts = window['Recharts'] || {};
148
+ const {
149
+ LineChart = () => React.createElement('div', { className: 'text-center text-gray-500 p-4' }, 'Charts unavailable - external library loading issue'),
150
+ Line = () => null,
151
+ XAxis = () => null,
152
+ YAxis = () => null,
153
+ CartesianGrid = () => null,
154
+ Tooltip = () => null,
155
+ ResponsiveContainer = ({ children }) => React.createElement('div', { style: { width: '100%', height: '160px' } }, children),
156
+ RadarChart = () => React.createElement('div', { className: 'text-center text-gray-500 p-4' }, 'Charts unavailable - external library loading issue'),
157
+ PolarGrid = () => null,
158
+ PolarAngleAxis = () => null,
159
+ PolarRadiusAxis = () => null,
160
+ Radar = () => null
161
+ } = Recharts;
162
+
163
+ const AI_PROMPTS = {
164
+ welcome: `You are an AI learning coach specializing in metacognition. Your role is to guide users through a reflective learning process.
165
+
166
+ FORMATTING REQUIREMENTS:
167
+ - Use proper paragraph breaks with double line breaks
168
+ - Use bullet points (•) for lists
169
+ - Use numbered lists (1., 2., 3.) for sequential steps
170
+ - Use **bold** for emphasis on key points
171
+ - Structure responses with clear sections
172
+ - Keep paragraphs concise (2-3 sentences max)
173
+
174
+ Be encouraging, supportive, and ask thoughtful questions. Start by welcoming the user and explaining that you'll guide them through a metacognitive reflection process to improve their learning.`,
175
+
176
+ taskPlanning: `Help the user articulate their learning task clearly.
177
+
178
+ FORMATTING REQUIREMENTS:
179
+ - Use proper paragraph breaks
180
+ - Use bullet points for suggestions
181
+ - Use **bold** for key concepts
182
+ - Structure your response with clear sections
183
+
184
+ Ask about:
185
+ • Their specific learning goals
186
+ • What they want to achieve
187
+ • Help them break down complex tasks
188
+
189
+ Suggest appropriate learning strategies based on the task type. Be encouraging and help them set realistic expectations.`,
190
+
191
+ preLearning: `Guide the user through pre-learning reflection.
192
+
193
+ FORMATTING REQUIREMENTS:
194
+ - Use clear paragraph structure
195
+ - Use bullet points for strategies
196
+ - Use **bold** for important concepts
197
+ - Include numbered steps when appropriate
198
+
199
+ Help them:
200
+ • Assess their current confidence level
201
+ • Identify potential challenges
202
+ • Prepare mentally for the learning task
203
+ • Suggest specific strategies and resources
204
+ • Explore their prior knowledge and experience`,
205
+
206
+ duringLearning: `Support the user during their learning process.
207
+
208
+ FORMATTING REQUIREMENTS:
209
+ - Use paragraph breaks for readability
210
+ - Use bullet points for suggestions
211
+ - Use **bold** for key advice
212
+ - Structure responses clearly
213
+
214
+ Ask about:
215
+ • Their current progress
216
+ • Any difficulties they're encountering
217
+ • Whether their chosen strategies are working
218
+
219
+ Provide adaptive guidance and suggest adjustments if needed. Be encouraging and help them stay motivated.`,
220
+
221
+ postLearning: `Help the user evaluate their learning experience.
222
+
223
+ FORMATTING REQUIREMENTS:
224
+ - Use clear paragraph structure
225
+ - Use bullet points for reflection prompts
226
+ - Use **bold** for key insights
227
+ - Organize thoughts into sections
228
+
229
+ Guide them to reflect on:
230
+ • What worked well and what didn't
231
+ • Whether they achieved their goals
232
+ • What they learned about their own learning process
233
+ • Patterns and insights about their metacognitive strategies`,
234
+
235
+ developmentPlan: `Based on the entire conversation history, provide a comprehensive personalized development plan.
236
+
237
+ FORMATTING REQUIREMENTS:
238
+ - Use clear headings with **bold**
239
+ - Use bullet points and numbered lists extensively
240
+ - Use paragraph breaks for readability
241
+ - Structure as a complete action plan
242
+
243
+ Create a detailed plan that includes:
244
+
245
+ **METACOGNITIVE STRENGTHS IDENTIFIED:**
246
+ • List specific strengths observed
247
+ • Evidence from their responses
248
+
249
+ **AREAS FOR IMPROVEMENT:**
250
+ • Specific skills to develop
251
+ • Patterns that need attention
252
+
253
+ **PERSONALIZED LEARNING STRATEGIES:**
254
+ • Tailored strategies based on their task type
255
+ • Specific techniques that match their learning style
256
+
257
+ **ACTION PLAN:**
258
+ 1. Immediate next steps (this week)
259
+ 2. Short-term goals (next month)
260
+ 3. Long-term development (next 3 months)
261
+
262
+ **RECOMMENDED ACTIVITIES:**
263
+ • Specific exercises and practices
264
+ • Resources and tools to use
265
+ • Frequency and timing suggestions
266
+
267
+ **PROGRESS TRACKING:**
268
+ • How to monitor improvement
269
+ • Key indicators to watch for
270
+ • When to reassess and adjust
271
+
272
+ Make this a comprehensive, actionable plan they can follow.`
273
+ };
274
+
275
+ function AIInteractiveMetacognitionTracker() {
276
+ // Core state
277
+ const [stage, setStage] = useState(0); // 0: Setup, 1: Task Planning, 2: Pre-Learning, 3: During Learning, 4: Post-Learning, 5: Development Plan
278
+ const [apiKey, setApiKey] = useState("");
279
+ const [apiKeyInput, setApiKeyInput] = useState("");
280
+ const [apiError, setApiError] = useState("");
281
+
282
+ // Conversation state
283
+ const [conversations, setConversations] = useState({});
284
+ const [currentInput, setCurrentInput] = useState("");
285
+ const [isAITyping, setIsAITyping] = useState(false);
286
+ const [aiLoading, setAILoading] = useState(false);
287
+
288
+ // User data
289
+ const [userProfile, setUserProfile] = useState({});
290
+ const [sessionData, setSessionData] = useState({});
291
+ const [reflectionHistory, setReflectionHistory] = useState([]);
292
+
293
+ // Refs
294
+ const chatEndRef = useRef(null);
295
+
296
+ // Load data from localStorage on mount
297
+ useEffect(() => {
298
+ try {
299
+ const savedApiKey = localStorage.getItem('ai-metacognition-api-key');
300
+ const savedProfile = localStorage.getItem('ai-metacognition-profile');
301
+ const savedHistory = localStorage.getItem('ai-metacognition-history');
302
+
303
+ if (savedApiKey) {
304
+ setApiKey(savedApiKey);
305
+ }
306
+ if (savedProfile) {
307
+ setUserProfile(JSON.parse(savedProfile));
308
+ }
309
+ if (savedHistory) {
310
+ setReflectionHistory(JSON.parse(savedHistory));
311
+ }
312
+ } catch (error) {
313
+ console.error('Error loading saved data:', error);
314
+ }
315
+ }, []);
316
+
317
+ // Save data to localStorage
318
+ useEffect(() => {
319
+ try {
320
+ if (apiKey) {
321
+ localStorage.setItem('ai-metacognition-api-key', apiKey);
322
+ }
323
+ } catch (error) {
324
+ console.error('Error saving API key:', error);
325
+ }
326
+ }, [apiKey]);
327
+
328
+ useEffect(() => {
329
+ try {
330
+ localStorage.setItem('ai-metacognition-profile', JSON.stringify(userProfile));
331
+ } catch (error) {
332
+ console.error('Error saving profile:', error);
333
+ }
334
+ }, [userProfile]);
335
+
336
+ useEffect(() => {
337
+ try {
338
+ localStorage.setItem('ai-metacognition-history', JSON.stringify(reflectionHistory));
339
+ } catch (error) {
340
+ console.error('Error saving history:', error);
341
+ }
342
+ }, [reflectionHistory]);
343
+
344
+ // Auto-scroll to bottom of chat
345
+ useEffect(() => {
346
+ chatEndRef.current?.scrollIntoView({ behavior: 'smooth' });
347
+ }, [conversations, isAITyping]);
348
+
349
+ // Initialize conversation when stage changes
350
+ useEffect(() => {
351
+ if (stage > 0 && apiKey && !conversations[stage]) {
352
+ initializeStageConversation(stage);
353
+ }
354
+ }, [stage, apiKey]);
355
+
356
+ const initializeStageConversation = async (stageNum) => {
357
+ const stageNames = ['', 'Task Planning', 'Pre-Learning Reflection', 'During Learning Support', 'Post-Learning Evaluation', 'Development Plan'];
358
+ const stageName = stageNames[stageNum];
359
+
360
+ setIsAITyping(true);
361
+
362
+ try {
363
+ const contextPrompt = getContextPrompt(stageNum);
364
+ const aiResponse = await callAI(contextPrompt, stageNum);
365
+
366
+ setConversations(prev => ({
367
+ ...prev,
368
+ [stageNum]: [
369
+ { type: 'ai', content: aiResponse, timestamp: new Date().toISOString() }
370
+ ]
371
+ }));
372
+ } catch (error) {
373
+ console.error('Error initializing conversation:', error);
374
+ setApiError(`Failed to initialize ${stageName}: ${error.message}`);
375
+ } finally {
376
+ setIsAITyping(false);
377
+ }
378
+ };
379
+
380
+ const getContextPrompt = (stageNum) => {
381
+ const basePrompt = AI_PROMPTS[Object.keys(AI_PROMPTS)[stageNum]];
382
+
383
+ // For the final stage, include comprehensive context from all previous stages
384
+ if (stageNum === 5) {
385
+ const allConversations = Object.keys(conversations)
386
+ .filter(key => parseInt(key) < 5)
387
+ .map(key => ({
388
+ stage: parseInt(key),
389
+ stageName: ['', 'Task Planning', 'Pre-Learning', 'During Learning', 'Post-Learning'][parseInt(key)],
390
+ conversation: conversations[key]
391
+ }));
392
+
393
+ const contextSummary = allConversations.map(stage => {
394
+ const userMessages = stage.conversation.filter(msg => msg.type === 'user').map(msg => msg.content);
395
+ const aiMessages = stage.conversation.filter(msg => msg.type === 'ai').map(msg => msg.content);
396
+
397
+ return `**${stage.stageName} (Stage ${stage.stage}):**
398
+ User Responses: ${userMessages.join(' | ')}
399
+ AI Guidance: ${aiMessages.slice(-1)[0] || 'No AI response'}`;
400
+ }).join('\n\n');
401
+
402
+ return `${basePrompt}
403
+
404
+ **COMPLETE SESSION CONTEXT:**
405
+ ${contextSummary}
406
+
407
+ **SESSION DATA:**
408
+ ${JSON.stringify(sessionData, null, 2)}
409
+
410
+ Based on this complete interaction history, create a comprehensive, personalized development plan.`;
411
+ }
412
+
413
+ const context = {
414
+ userProfile,
415
+ sessionData,
416
+ previousConversations: conversations,
417
+ stage: stageNum
418
+ };
419
+
420
+ return `${basePrompt}\n\nContext: ${JSON.stringify(context, null, 2)}\n\nProvide a welcoming message to start this stage.`;
421
+ };
422
+
423
+ const callAI = async (prompt, stageNum, userMessage = '') => {
424
+ if (!apiKey) {
425
+ throw new Error('API key not provided');
426
+ }
427
+
428
+ const messages = [
429
+ { role: 'system', content: prompt }
430
+ ];
431
+
432
+ // Add conversation history
433
+ const stageConversation = conversations[stageNum] || [];
434
+ stageConversation.forEach(msg => {
435
+ messages.push({
436
+ role: msg.type === 'ai' ? 'assistant' : 'user',
437
+ content: msg.content
438
+ });
439
+ });
440
+
441
+ if (userMessage) {
442
+ messages.push({ role: 'user', content: userMessage });
443
+ }
444
+
445
+ const response = await fetch('https://api.openai.com/v1/chat/completions', {
446
+ method: 'POST',
447
+ headers: {
448
+ 'Content-Type': 'application/json',
449
+ 'Authorization': `Bearer ${apiKey.trim()}`
450
+ },
451
+ body: JSON.stringify({
452
+ model: 'gpt-4o-mini',
453
+ messages,
454
+ max_tokens: stageNum === 5 ? 1000 : 600, // More tokens for final comprehensive plan
455
+ temperature: 0.7
456
+ })
457
+ });
458
+
459
+ if (!response.ok) {
460
+ const errorData = await response.json().catch(() => ({}));
461
+ throw new Error(`OpenAI API error: ${response.status} ${response.statusText}${errorData.error ? ` - ${errorData.error.message}` : ''}`);
462
+ }
463
+
464
+ const data = await response.json();
465
+
466
+ if (!data.choices || !data.choices[0] || !data.choices[0].message) {
467
+ throw new Error('Invalid response format from OpenAI API');
468
+ }
469
+
470
+ return data.choices[0].message.content;
471
+ };
472
+
473
+ const formatAIResponse = (content) => {
474
+ // Convert markdown-style formatting to HTML
475
+ let formatted = content
476
+ // Convert **bold** to <strong>
477
+ .replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
478
+ // Convert bullet points
479
+ .replace(/^• (.+)$/gm, '<li>$1</li>')
480
+ .replace(/^- (.+)$/gm, '<li>$1</li>')
481
+ // Convert numbered lists
482
+ .replace(/^(\d+)\. (.+)$/gm, '<li>$2</li>')
483
+ // Convert double line breaks to paragraphs
484
+ .split('\n\n')
485
+ .map(paragraph => {
486
+ if (paragraph.includes('<li>')) {
487
+ return `<ul>${paragraph}</ul>`;
488
+ }
489
+ return paragraph.trim() ? `<p>${paragraph.trim()}</p>` : '';
490
+ })
491
+ .join('');
492
+
493
+ return formatted;
494
+ };
495
+
496
+ const handleSendMessage = async () => {
497
+ if (!currentInput.trim() || isAITyping) return;
498
+
499
+ const userMessage = currentInput.trim();
500
+ setCurrentInput("");
501
+
502
+ // Add user message to conversation
503
+ setConversations(prev => ({
504
+ ...prev,
505
+ [stage]: [
506
+ ...(prev[stage] || []),
507
+ { type: 'user', content: userMessage, timestamp: new Date().toISOString() }
508
+ ]
509
+ }));
510
+
511
+ setIsAITyping(true);
512
+ setAILoading(true);
513
+
514
+ try {
515
+ const contextPrompt = getContextPrompt(stage);
516
+ const aiResponse = await callAI(contextPrompt, stage, userMessage);
517
+
518
+ // Add AI response to conversation
519
+ setConversations(prev => ({
520
+ ...prev,
521
+ [stage]: [
522
+ ...prev[stage],
523
+ { type: 'ai', content: aiResponse, timestamp: new Date().toISOString() }
524
+ ]
525
+ }));
526
+
527
+ // Update session data based on stage
528
+ updateSessionData(stage, userMessage, aiResponse);
529
+
530
+ } catch (error) {
531
+ console.error('Error getting AI response:', error);
532
+ setApiError(`AI Error: ${error.message}`);
533
+ } finally {
534
+ setIsAITyping(false);
535
+ setAILoading(false);
536
+ }
537
+ };
538
+
539
+ const updateSessionData = (stageNum, userMessage, aiResponse) => {
540
+ const timestamp = new Date().toISOString();
541
+
542
+ setSessionData(prev => ({
543
+ ...prev,
544
+ [`stage${stageNum}`]: {
545
+ ...prev[`stage${stageNum}`],
546
+ lastUpdate: timestamp,
547
+ userInput: userMessage,
548
+ aiGuidance: aiResponse,
549
+ keyInsights: extractKeyInsights(userMessage, stageNum)
550
+ }
551
+ }));
552
+ };
553
+
554
+ const extractKeyInsights = (userMessage, stageNum) => {
555
+ // Extract key insights based on stage
556
+ const insights = {};
557
+
558
+ switch(stageNum) {
559
+ case 1: // Task Planning
560
+ insights.learningTask = userMessage;
561
+ break;
562
+ case 2: // Pre-Learning
563
+ insights.initialConfidence = userMessage;
564
+ break;
565
+ case 3: // During Learning
566
+ insights.learningProgress = userMessage;
567
+ break;
568
+ case 4: // Post-Learning
569
+ insights.learningOutcome = userMessage;
570
+ break;
571
+ case 5: // Development Plan
572
+ insights.developmentCommitment = userMessage;
573
+ break;
574
+ }
575
+
576
+ return insights;
577
+ };
578
+
579
+ const handleKeyPress = (e) => {
580
+ if (e.key === 'Enter' && !e.shiftKey) {
581
+ e.preventDefault();
582
+ handleSendMessage();
583
+ }
584
+ };
585
+
586
+ const validateApiKey = async () => {
587
+ if (!apiKeyInput.trim()) {
588
+ setApiError("Please enter your OpenAI API key");
589
+ return;
590
+ }
591
+
592
+ setAILoading(true);
593
+ setApiError("");
594
+
595
+ try {
596
+ const response = await fetch('https://api.openai.com/v1/models', {
597
+ headers: {
598
+ 'Authorization': `Bearer ${apiKeyInput.trim()}`
599
+ }
600
+ });
601
+
602
+ if (!response.ok) {
603
+ throw new Error('Invalid API key');
604
+ }
605
+
606
+ setApiKey(apiKeyInput.trim());
607
+ setStage(1);
608
+ setApiKeyInput("");
609
+ } catch (error) {
610
+ setApiError("Invalid API key. Please check and try again.");
611
+ } finally {
612
+ setAILoading(false);
613
+ }
614
+ };
615
+
616
+ const nextStage = () => {
617
+ if (stage < 5) {
618
+ setStage(stage + 1);
619
+ }
620
+ };
621
+
622
+ const previousStage = () => {
623
+ if (stage > 1) {
624
+ setStage(stage - 1);
625
+ }
626
+ };
627
+
628
+ const completeSession = () => {
629
+ const sessionSummary = {
630
+ id: Date.now(),
631
+ timestamp: new Date().toISOString(),
632
+ conversations,
633
+ sessionData,
634
+ userProfile,
635
+ completedStages: 5
636
+ };
637
+
638
+ setReflectionHistory(prev => [...prev, sessionSummary]);
639
+
640
+ // Reset for new session
641
+ setStage(1);
642
+ setConversations({});
643
+ setSessionData({});
644
+ setCurrentInput("");
645
+ };
646
+
647
+ const getProgressPercentage = () => {
648
+ return (stage / 5) * 100;
649
+ };
650
+
651
+ const stageNames = [
652
+ 'Setup',
653
+ 'Task Planning',
654
+ 'Pre-Learning Reflection',
655
+ 'During Learning Support',
656
+ 'Post-Learning Evaluation',
657
+ 'Development Plan'
658
+ ];
659
+
660
+ // Stage 0: API Key Setup
661
+ if (stage === 0) {
662
+ return (
663
+ <div className="min-h-screen flex flex-col items-center justify-center py-8">
664
+ <motion.div className="max-w-md w-full px-4">
665
+ <div className="glass p-8 text-center">
666
+ <div className="mb-6">
667
+ <h1 className="text-3xl font-bold text-blue-900 mb-2">🤖 AI Learning Coach</h1>
668
+ <p className="text-gray-600">Your personal AI guide for metacognitive reflection</p>
669
+ </div>
670
+
671
+ <div className="mb-6">
672
+ <label htmlFor="api-key" className="block font-semibold mb-2 text-left">OpenAI API Key</label>
673
+ <input
674
+ id="api-key"
675
+ type="password"
676
+ className="w-full px-4 py-3 border rounded-lg text-center"
677
+ placeholder="sk-..."
678
+ value={apiKeyInput}
679
+ onChange={e => setApiKeyInput(e.target.value)}
680
+ onKeyPress={e => e.key === 'Enter' && validateApiKey()}
681
+ autoFocus
682
+ />
683
+ <p className="text-xs text-gray-500 mt-2">
684
+ Get your API key at <a href="https://platform.openai.com/api-keys" target="_blank" rel="noopener noreferrer" className="text-blue-600 underline">OpenAI</a>
685
+ </p>
686
+ </div>
687
+
688
+ {apiError && (
689
+ <div className="mb-4 text-red-600 text-sm">{apiError}</div>
690
+ )}
691
+
692
+ <button
693
+ onClick={validateApiKey}
694
+ disabled={aiLoading || !apiKeyInput.trim()}
695
+ className="w-full bg-blue-600 text-white py-3 rounded-lg font-semibold hover:bg-blue-700 transition disabled:opacity-50"
696
+ >
697
+ {aiLoading ? "Validating..." : "Start AI-Guided Learning"}
698
+ </button>
699
+
700
+ <div className="mt-6 text-xs text-gray-500">
701
+ <p>🔒 Your API key is stored locally and used only for this session</p>
702
+ <p>🎯 AI will guide you through 5 stages of metacognitive reflection</p>
703
+ <p>📝 Responses will be structured with clear formatting</p>
704
+ </div>
705
+ </div>
706
+ </motion.div>
707
+ </div>
708
+ );
709
+ }
710
+
711
+ // Main Application Interface
712
+ return (
713
+ <div className="min-h-screen flex flex-col py-4">
714
+ <div className="max-w-4xl w-full mx-auto px-4">
715
+ {/* Header */}
716
+ <div className="glass p-4 mb-4">
717
+ <div className="flex items-center justify-between mb-4">
718
+ <div>
719
+ <h1 className="text-2xl font-bold text-blue-900">🤖 AI Learning Coach</h1>
720
+ <p className="text-sm text-gray-600">Stage {stage}: {stageNames[stage]}</p>
721
+ </div>
722
+ <div className="text-right">
723
+ <div className="text-xs text-gray-500 mb-1">Progress</div>
724
+ <div className="w-32 bg-gray-200 rounded-full h-2">
725
+ <div
726
+ className="progress-bar rounded-full h-2"
727
+ style={{ width: `${getProgressPercentage()}%` }}
728
+ ></div>
729
+ </div>
730
+ </div>
731
+ </div>
732
+
733
+ {/* Stage Navigation */}
734
+ <div className="flex gap-2 text-xs flex-wrap">
735
+ {stageNames.slice(1).map((name, i) => (
736
+ <span
737
+ key={i}
738
+ className={`px-2 py-1 rounded-full ${
739
+ stage === i + 1
740
+ ? "bg-blue-600 text-white"
741
+ : stage > i + 1
742
+ ? "bg-green-100 text-green-800"
743
+ : "bg-gray-100 text-gray-600"
744
+ }`}
745
+ >
746
+ {i + 1}. {name}
747
+ </span>
748
+ ))}
749
+ </div>
750
+ </div>
751
+
752
+ {/* Chat Interface */}
753
+ <div className="glass p-4 mb-4">
754
+ <div className="chat-container">
755
+ {conversations[stage]?.map((message, index) => (
756
+ <div
757
+ key={index}
758
+ className={message.type === 'ai' ? 'ai-message' : 'user-message'}
759
+ >
760
+ <div className="flex items-start gap-2">
761
+ <span className="text-xs opacity-75 mt-1">
762
+ {message.type === 'ai' ? '🤖' : '👤'}
763
+ </span>
764
+ <div className="flex-1">
765
+ {message.type === 'ai' ? (
766
+ <div dangerouslySetInnerHTML={{ __html: formatAIResponse(message.content) }} />
767
+ ) : (
768
+ message.content
769
+ )}
770
+ </div>
771
+ </div>
772
+ </div>
773
+ ))}
774
+
775
+ {isAITyping && (
776
+ <div className="typing-indicator">
777
+ <div className="flex items-center gap-2">
778
+ <span className="text-xs">🤖</span>
779
+ <div>AI is thinking...</div>
780
+ <div className="flex gap-1">
781
+ <div className="w-2 h-2 bg-blue-500 rounded-full animate-bounce"></div>
782
+ <div className="w-2 h-2 bg-blue-500 rounded-full animate-bounce" style={{animationDelay: '0.1s'}}></div>
783
+ <div className="w-2 h-2 bg-blue-500 rounded-full animate-bounce" style={{animationDelay: '0.2s'}}></div>
784
+ </div>
785
+ </div>
786
+ </div>
787
+ )}
788
+
789
+ <div ref={chatEndRef} />
790
+ </div>
791
+
792
+ {/* Input Area */}
793
+ <div className="mt-4 flex gap-2">
794
+ <textarea
795
+ value={currentInput}
796
+ onChange={e => setCurrentInput(e.target.value)}
797
+ onKeyPress={handleKeyPress}
798
+ placeholder="Type your response here... (Press Enter to send, Shift+Enter for new line)"
799
+ className="flex-1 px-3 py-2 border rounded-lg resize-none"
800
+ rows={3}
801
+ disabled={isAITyping}
802
+ />
803
+ <button
804
+ onClick={handleSendMessage}
805
+ disabled={!currentInput.trim() || isAITyping}
806
+ className="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition disabled:opacity-50"
807
+ >
808
+ Send
809
+ </button>
810
+ </div>
811
+
812
+ {apiError && (
813
+ <div className="mt-2 text-red-600 text-sm">{apiError}</div>
814
+ )}
815
+ </div>
816
+
817
+ {/* Navigation */}
818
+ <div className="glass p-4">
819
+ <div className="flex justify-between items-center">
820
+ <button
821
+ onClick={previousStage}
822
+ disabled={stage <= 1}
823
+ className="px-4 py-2 bg-gray-300 text-gray-700 rounded-lg hover:bg-gray-400 transition disabled:opacity-50"
824
+ >
825
+ ← Previous Stage
826
+ </button>
827
+
828
+ <div className="text-center">
829
+ <p className="text-sm text-gray-600">
830
+ {conversations[stage]?.length || 0} messages in this stage
831
+ </p>
832
+ {stage === 5 && (
833
+ <p className="text-xs text-blue-600 font-semibold">
834
+ 📋 Comprehensive Development Plan
835
+ </p>
836
+ )}
837
+ </div>
838
+
839
+ {stage < 5 ? (
840
+ <button
841
+ onClick={nextStage}
842
+ className="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition"
843
+ >
844
+ Next Stage →
845
+ </button>
846
+ ) : (
847
+ <button
848
+ onClick={completeSession}
849
+ className="px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 transition"
850
+ >
851
+ Complete Session ✓
852
+ </button>
853
+ )}
854
+ </div>
855
+ </div>
856
+
857
+ {/* Session History */}
858
+ {reflectionHistory.length > 0 && (
859
+ <div className="glass p-4 mt-4">
860
+ <h3 className="font-bold text-blue-900 mb-2">Previous Sessions</h3>
861
+ <div className="text-sm text-gray-600">
862
+ {reflectionHistory.length} completed reflection session{reflectionHistory.length !== 1 ? 's' : ''}
863
+ </div>
864
+ </div>
865
+ )}
866
+ </div>
867
+ </div>
868
+ );
869
+ }
870
+
871
+ ReactDOM.createRoot(document.getElementById("root")).render(<AIInteractiveMetacognitionTracker />);
872
+ </script>
873
+ </body>
874
+ </html>
875
+
📘 AI Learning Coach Guide.txt ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 📘 AI Learning Coach — Structured Guide
2
+ 1. Introduction
3
+ The AI Learning Coach guides learners through metacognitive reflection—helping them plan, monitor, and evaluate their learning with support from an interactive AI coach. It is fully privacy-first, open-source, and ideal for self-driven growth or classroom integration.
4
+
5
+ 2. Step-by-Step: How to Use
6
+ A. Starting a Session
7
+ Open the app in your browser (no login required).
8
+
9
+ Enter your OpenAI API key (instructions provided in the tool).
10
+
11
+ Click "Start AI-Guided Learning."
12
+
13
+ B. Working Through the Five Stages
14
+ Stage 1: Task Planning
15
+
16
+ The AI helps you clarify your learning goal and break it into actionable steps.
17
+
18
+ Stage 2: Pre-Learning Reflection
19
+
20
+ Reflect on your confidence, prior knowledge, and strategies before you begin.
21
+
22
+ Stage 3: During Learning Support
23
+
24
+ Check in as you learn. Discuss progress, difficulties, and adjust strategies with the AI’s suggestions.
25
+
26
+ Stage 4: Post-Learning Evaluation
27
+
28
+ Debrief after the learning task. Analyze what worked, what didn’t, and why.
29
+
30
+ Stage 5: Development Plan
31
+
32
+ Receive a comprehensive, personalized action plan from the AI—covering strengths, growth areas, and specific next steps.
33
+
34
+ C. Navigation & Saving
35
+ Type your response in the chat area at each stage; click “Send” to get AI feedback.
36
+
37
+ Move forward or back between stages as needed.
38
+
39
+ At the end, your session is saved in your browser’s history for future review.
40
+
41
+ 3. How It Supports Educators
42
+ Enhances metacognitive skills: Encourages students to think about their thinking, plan learning, monitor progress, and reflect after tasks.
43
+
44
+ Flexible classroom tool: Can be used as a warm-up, self-check, homework, or at the end of a lesson/unit.
45
+
46
+ Safe for all learners: No logins, accounts, or data risks; great for privacy-focused classrooms.
47
+
48
+ Builds SEL and self-regulation: Supports social-emotional learning, student agency, and ownership of progress.
49
+
50
+ Evidence for assessment: Use saved reflections as artifacts for formative or portfolio assessment.
51
+
52
+ 4. How It Supports Students
53
+ Personal growth: Build real-world skills in self-regulation and reflective learning.
54
+
55
+ Guided by AI: Instant, encouraging feedback at every phase of learning.
56
+
57
+ Actionable plans: Receive a tailored action plan to keep improving.
58
+
59
+ Ownership: Reflections and plans are saved for review, portfolio use, or sharing.
60
+
61
+ 5. Best Practices
62
+ For Teachers:
63
+
64
+ Assign as an exit ticket, homework reflection, or part of student learning portfolios.
65
+
66
+ Review student reflections together for coaching and discussion.
67
+
68
+ Use the tool’s privacy-first design to assure parents and administrators.
69
+
70
+ For Students:
71
+
72
+ Use for any subject, project, or personal learning goal.
73
+
74
+ Try multiple sessions—compare your reflections over time.
75
+
76
+ Share your development plans with mentors or teachers for more support.