File size: 8,292 Bytes
eaf56bf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
# 🧠 HALE API Integration Guide (Next.js, Flutter, React, Mobile)

Welcome! This guide outlines how to integrate the HALE (Adaptive Learning Engine) backend into any frontend application. The HALE backend is a production-grade FastAPI app with a Reinforcement Learning engine that dynamically customizes study plans.

---

## 🌐 Server Details
- **Production API URL**: `https://raunak211006-hale-api.hf.space`
- **Swagger Documentation**: `https://raunak211006-hale-api.hf.space/docs`
- **Response Format**: JSON only.
- **Authentication**: JWT Bearer token in headers: `Authorization: Bearer <token>`

---

## 🔄 The Complete Lifecycle Flow
To build a seamless interface, your frontend should follow this logical flow:

```mermaid
graph TD
    A[1. Auth: Login/Register] -->|JWT Token| B[2. Setup: Create Goals & Timetable]
    B --> C[3. Daily Plan: Fetch Today's Tasks]
    C -->|If tasks pending| D[4. Work: Complete Tasks & Update State]
    D -->|Award XP + RL Reward| C
    C -->|If all tasks done| E[5. Day Close: Done for Today]
    E -->|Unlock Next Day Preview| F[6. Next Day Preview]
```

---

## 🛠️ Step-by-Step Implementation

### 1. Authentication (Login & JWT Store)
Save the `access_token` and `refresh_token` in `localStorage`, `secure_store`, or cookies.

#### Request Example (Javascript/Typescript):
```typescript
const API_URL = "https://raunak211006-hale-api.hf.space";

// 1. Register User
async function registerUser(userId: string, password: string, email?: string) {
  const res = await fetch(`${API_URL}/api/auth/register`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ user_id: userId, password, email })
  });
  return res.json();
}

// 2. Login User
async function loginUser(userId: string, password: string) {
  const res = await fetch(`${API_URL}/api/auth/login`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ user_id: userId, password })
  });
  const data = await res.json(); // returns { access_token, refresh_token }
  
  if (data.access_token) {
    localStorage.setItem("access_token", data.access_token);
    localStorage.setItem("refresh_token", data.refresh_token);
  }
  return data;
}
```

---

### 2. Authenticated Fetch Helper
Use this helper to automatically inject the Bearer token into all headers:

```typescript
async function fetchWithAuth(endpoint: string, options: RequestInit = {}) {
  const token = localStorage.getItem("access_token");
  const headers = {
    "Content-Type": "application/json",
    ...(token ? { "Authorization": `Bearer ${token}` } : {}),
    ...options.headers,
  };

  const response = await fetch(`${API_URL}${endpoint}`, { ...options, headers });
  
  if (response.status === 401) {
     // Handle expired token: refresh token logic goes here
     console.error("Session expired. Redirect to login.");
  }
  
  return response.json();
}
```

---

### 3. Create a Learning Goal
Curriculum plans are generated by Gemini AI instantly based on the prompt.

```typescript
async function createGoal(goalText: string, days = 30, priority = 1) {
  return fetchWithAuth("/api/goals/", {
    method: "POST",
    body: JSON.stringify({
      goal: goalText,             // e.g. "Master React and Typescript"
      duration_days: days,
      priority: priority          // Higher priority (1) gets more study allocation
    })
  });
}
```

---

### 4. Fetch the Daily Plan
This returns today's tasks and the Reinforcement Learning behavior engine's state parameters.

```typescript
async function getDailyPlan() {
  return fetchWithAuth("/api/plan");
}
```

#### JSON Response Schema:
```json
{
  "date": "2026-05-21",
  "tasks": [
    "Core: Learn JSX Syntax (~40 min)"
  ],
  "tasks_detail": [
    {
      "type": "core",
      "title": "Learn JSX Syntax",
      "est_min": 40,
      "deliverable": "Build static portfolio header",
      "goal_id": 1,
      "goal_label": "React.js Mastery",
      "date": "2026-05-21"
    }
  ],
  "behavior": {
    "action_label": "Normal",
    "intensity": 0.65,
    "mood": 0.8,
    "fatigue": 0.1,
    "cold_start": false,
    "plateau_detected": false
  },
  "coach_message": "Awesome energy today! Let's conquer this first React building block.",
  "streak": 5,
  "total_minutes": 40,
  "goals_count": 1,
  "next_day_preview": null
}
```

---

### 5. Mark a Task Complete (Triggers RL reward)
When completing a task, the RL engine modifies user parameters (`alpha`/`beta` parameters) based on task duration and subjective satisfaction.

```typescript
async function completeTask(date: string, goalId: number, durationMin: number, satisfaction: number) {
  return fetchWithAuth("/api/complete-task", {
    method: "POST",
    body: JSON.stringify({
      date: date,                    // YYYY-MM-DD from tasks_detail
      goal_id: goalId,               // goal_id from tasks_detail
      actual_duration_min: durationMin,
      satisfaction: satisfaction,    // Float between 0.0 (hated it) to 1.0 (loved it)
      notes: "Completed all code challenges!"
    })
  });
}
```
*Note: If `all_completed` is returned as `true` in the response, you can immediately notify the user and transition them to the next day's preview.*

---

### 6. Done For Today (Close Day Manually)
Forces manual closure of the day. All remaining tasks are completed, streak counts are updated, and the **Next Day's Preview** is generated.

```typescript
async function closeDay() {
  return fetchWithAuth("/api/day/complete", { method: "POST" });
}
```

#### Day Close Response Sample:
```json
{
  "closed": 1,
  "message": "Day closed. 1 task(s) marked as done.",
  "date": "2026-05-21",
  "streak": 6,
  "xp_gained": 15,
  "total_xp": 450,
  "level": 3,
  "leveled_up": false,
  "next_day_preview": {
    "action_label": "Deep Work",
    "intensity": 0.85,
    "preview": true
  }
}
```

---

### 7. Get Tomorrow's Preview Explicitly
Fetch a preview of tomorrow's focus and adaptive intensity without actually progressing the current state.

```typescript
async function getNextDayPreview() {
  return fetchWithAuth("/api/plan/next");
}
```

---

## ⚡ Real-Time Adaptive Feedback State

You should allow the user to input their behavioral metrics periodically (e.g., mood, fatigue, sleep quality). This recalibrates the Reinforcement Learning engine instantly:

```typescript
async function updateBehaviorState(mood: number, fatigue: number, stress: number, sleepQuality: number) {
  return fetchWithAuth("/api/update-state", {
    method: "POST",
    body: JSON.stringify({
      mood: mood,                 // 0.0 to 1.0
      fatigue: fatigue,           // 0.0 to 1.0
      stress: stress,             // 0.0 to 1.0
      sleep_quality: sleepQuality // 0.0 to 1.0
    })
  });
}
```
*Call this when a user changes their status slider. The next call to `/api/plan` will return adapted durations based on these metrics.*

---

## 📊 Summary Table of API Endpoints

| Resource | HTTP Method | Endpoint | Description |
|---|---|---|---|
| **Auth** | `POST` | `/api/auth/register` | Register new user |
| **Auth** | `POST` | `/api/auth/login` | Login and get tokens |
| **Goals** | `POST` | `/api/goals/` | Create a goal with AI syllabus |
| **Goals** | `GET` | `/api/goals/` | List user goals |
| **Daily Plan** | `GET` | `/api/plan` | Fetch current adaptive daily tasks |
| **Tasks** | `POST` | `/api/complete-task` | Mark task completed (awards XP/RL) |
| **Tasks** | `POST` | `/api/skip-task` | Skip a task |
| **Lifecycle** | `POST` | `/api/day/complete` | Complete day & generate next preview |
| **Lifecycle** | `GET` | `/api/plan/next` | Preview tomorrow's focus |
| **Lifecycle** | `GET` | `/api/day/status` | Today's completion details |
| **Analytics** | `GET` | `/api/stats` | Gamification stats (level, XP, streaks) |
| **Behavior** | `POST` | `/api/update-state` | Update mood/fatigue to adapt engine |

---

## 🛡️ Production Security Checklist
1. Always keep the Hugging Face `SECRET_KEY` secret.
2. In production, always set the connection string `DATABASE_URL` to the Neon PostgreSQL cluster.
3. CORS configuration allows `*` by default for testing. You can restrict it in Space Settings to only allow your domain (e.g. `https://my-lifeos-app.vercel.app`).