@more-ink/irt-edge 2.1.0 → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +66 -8
- package/package.json +5 -8
package/README.md
CHANGED
|
@@ -89,7 +89,7 @@ interface RecordAnswerRequest {
|
|
|
89
89
|
skillId: string // Skill identifier
|
|
90
90
|
itemId: string // Item identifier
|
|
91
91
|
score: number // Response score [0,1] (0=wrong, 1=correct)
|
|
92
|
-
timestamp
|
|
92
|
+
timestamp: number // When response occurred (ms)
|
|
93
93
|
updateOptions?: Partial<UpdateOptions> // Override learning rates
|
|
94
94
|
selectionOptions?: Partial<NextItemOptions> // Override selection behavior
|
|
95
95
|
}
|
|
@@ -184,6 +184,33 @@ Get the next recommended item without recording a response.
|
|
|
184
184
|
async selectNextItem(params: SelectNextItemRequest): Promise<SelectNextItemResponse>
|
|
185
185
|
```
|
|
186
186
|
|
|
187
|
+
#### resetUser() / resetItem()
|
|
188
|
+
|
|
189
|
+
Reset all Redis-backed skill state for a user or item.
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
async resetUser(userId: string): Promise<ResetUserResponse>
|
|
193
|
+
async resetItem(itemId: string): Promise<ResetItemResponse>
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
#### bulkUpdateUser() / bulkUpdateItem()
|
|
197
|
+
|
|
198
|
+
Bulk cold-start/backfill helpers that update **only** user skills or **only** item parameters.
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
async bulkUpdateUser(
|
|
202
|
+
userId: string,
|
|
203
|
+
events: BulkUpdateEvent[],
|
|
204
|
+
updateOptions?: Partial<UpdateOptions>
|
|
205
|
+
): Promise<BulkUpdateResponse>
|
|
206
|
+
|
|
207
|
+
async bulkUpdateItem(
|
|
208
|
+
itemId: string,
|
|
209
|
+
events: BulkUpdateEvent[],
|
|
210
|
+
updateOptions?: Partial<UpdateOptions>
|
|
211
|
+
): Promise<BulkUpdateResponse>
|
|
212
|
+
```
|
|
213
|
+
|
|
187
214
|
#### getUserState() / getUserStates()
|
|
188
215
|
|
|
189
216
|
Get current user ability estimates.
|
|
@@ -263,7 +290,7 @@ The backend server is **not published** to npm. It runs as a service on Aliyun F
|
|
|
263
290
|
|
|
264
291
|
### Features
|
|
265
292
|
|
|
266
|
-
- RESTful IRT API backed by **
|
|
293
|
+
- RESTful IRT API backed by **Redis (online state)** and **Postgres via Prisma** (durable via `/api/irt/sync`)
|
|
267
294
|
- Aliyun FC lifecycle hooks (`/initialize`, `/pre-stop`)
|
|
268
295
|
- Graceful shutdown and health checks
|
|
269
296
|
|
|
@@ -274,8 +301,9 @@ The backend server is **not published** to npm. It runs as a service on Aliyun F
|
|
|
274
301
|
npm install
|
|
275
302
|
|
|
276
303
|
# Create .env file with:
|
|
277
|
-
#
|
|
278
|
-
#
|
|
304
|
+
# REDIS_URL=redis://... (or rediss://...)
|
|
305
|
+
# REDIS_DB=2
|
|
306
|
+
# DATABASE_URL=postgres://user:pass@host:port/db
|
|
279
307
|
|
|
280
308
|
# Run dev server
|
|
281
309
|
npm run --workspace @more-ink/irt-edge dev
|
|
@@ -301,8 +329,8 @@ FEISHU_APP_ID="YOUR_FEISHU_APP_ID"
|
|
|
301
329
|
FEISHU_APP_SECRET="YOUR_FEISHU_APP_SECRET"
|
|
302
330
|
FEISHU_CHAT_ID="YOUR_FEISHU_CHAT_ID"
|
|
303
331
|
|
|
304
|
-
#
|
|
305
|
-
REDIS_URL=""
|
|
332
|
+
# Redis (primary online store)
|
|
333
|
+
REDIS_URL="redis://localhost:6379"
|
|
306
334
|
REDIS_DB=2
|
|
307
335
|
|
|
308
336
|
# Debug mode for Function Compute
|
|
@@ -319,20 +347,47 @@ See `src/index.ts` for default IRT engine parameters (learning rates, selection
|
|
|
319
347
|
**IRT Operations:**
|
|
320
348
|
- `POST /api/irt/answer` - Record response and get next item
|
|
321
349
|
- `POST /api/irt/answer-multi` - Record multiple skill responses for one item
|
|
350
|
+
- `POST /api/irt/sync` - Persist dirty Redis state to Postgres (cron-triggered)
|
|
322
351
|
- `POST /api/irt/next-item` - Get next item without recording response
|
|
352
|
+
- `POST /api/irt/users/:userId/reset` - Reset user skills in Redis
|
|
353
|
+
- `POST /api/irt/items/:itemId/reset` - Reset item skills in Redis
|
|
354
|
+
- `POST /api/irt/bulk-update-user/:userId` - Bulk update user skills (user-only)
|
|
355
|
+
- `POST /api/irt/bulk-update-item/:itemId` - Bulk update item parameters (item-only)
|
|
323
356
|
- `DELETE /api/irt/users/:userId` - Delete a user and all skill states
|
|
324
357
|
- `DELETE /api/irt/items/:itemId` - Delete an item and its per-skill calibrations
|
|
325
358
|
- `GET /api/irt/health` - Health check
|
|
326
359
|
|
|
327
360
|
**Aliyun FC Lifecycle:**
|
|
328
|
-
- `POST /initialize` - Instance startup (verifies Prisma DB and Redis
|
|
329
|
-
- `GET /pre-stop` - Instance shutdown (closes Prisma DB and Redis
|
|
361
|
+
- `POST /initialize` - Instance startup (verifies Prisma DB and Redis connection)
|
|
362
|
+
- `GET /pre-stop` - Instance shutdown (closes Prisma DB and Redis)
|
|
330
363
|
|
|
331
364
|
**System:**
|
|
332
365
|
- `GET /` - Service info
|
|
333
366
|
|
|
334
367
|
---
|
|
335
368
|
|
|
369
|
+
## Cold-start Guidance
|
|
370
|
+
|
|
371
|
+
When you have **no prior data** (no user θ, no item a/b), the recommended order for scale is:
|
|
372
|
+
|
|
373
|
+
1) **Item cold-start** using a default θ (e.g., θ=0).
|
|
374
|
+
2) **User cold-start** using the calibrated item a/b.
|
|
375
|
+
3) **Optional**: run item cold-start again to refine a/b.
|
|
376
|
+
|
|
377
|
+
Why this order: item sets are typically small and fixed, while user sets are large and segmented. A quick first-pass item calibration (with θ=0) reduces downstream work before user backfill.
|
|
378
|
+
|
|
379
|
+
Reset and cold-start operations clear **Redis** only. Postgres is treated as a backup store and may retain stale rows until fresh updates overwrite them.
|
|
380
|
+
|
|
381
|
+
### Bulk Update Constraints
|
|
382
|
+
|
|
383
|
+
- Maximum **10k events** per request (over limit returns 400).
|
|
384
|
+
- `timestamp` is **required** and events are processed in ascending time order.
|
|
385
|
+
- `score` must be in `[0, 1]` (invalid events are skipped with errors).
|
|
386
|
+
- Errors are reported per event; valid events still proceed.
|
|
387
|
+
- Only a **single global** `updateOptions` is supported per bulk request.
|
|
388
|
+
|
|
389
|
+
---
|
|
390
|
+
|
|
336
391
|
## Backend Deployment (Aliyun FC)
|
|
337
392
|
|
|
338
393
|
Deploy the backend server to Aliyun FC:
|
|
@@ -447,6 +502,9 @@ node -e "const { IrtClient } = require('@more-ink/irt-edge'); console.log('OK')"
|
|
|
447
502
|
## Architecture
|
|
448
503
|
|
|
449
504
|
```
|
|
505
|
+
|
|
506
|
+
---
|
|
507
|
+
|
|
450
508
|
irt-edge/
|
|
451
509
|
├── src/
|
|
452
510
|
│ ├── sdk/ # ✅ SDK source (published)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@more-ink/irt-edge",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.2",
|
|
4
4
|
"description": "IRT Edge API client SDK for JavaScript/TypeScript frontends.",
|
|
5
5
|
"main": "sdk/index.js",
|
|
6
6
|
"types": "sdk/index.d.ts",
|
|
@@ -32,12 +32,9 @@
|
|
|
32
32
|
"layer:clean": "rm -rf .layer",
|
|
33
33
|
"layer:deps": "bash scripts/layer-deps.sh"
|
|
34
34
|
},
|
|
35
|
-
"peerDependencies": {
|
|
36
|
-
"@more-ink/irt-core": "^1.2.0"
|
|
37
|
-
},
|
|
38
35
|
"dependencies": {
|
|
39
36
|
"@hono/node-server": "^1.19.6",
|
|
40
|
-
"@more-ink/irt-core": "^1.2.
|
|
37
|
+
"@more-ink/irt-core": "^1.2.2",
|
|
41
38
|
"@prisma/adapter-pg": "^7.1.0",
|
|
42
39
|
"@prisma/client": "^7.1.0",
|
|
43
40
|
"dayjs": "^1.11.19",
|
|
@@ -48,9 +45,9 @@
|
|
|
48
45
|
"undici": "^7.0.1"
|
|
49
46
|
},
|
|
50
47
|
"devDependencies": {
|
|
51
|
-
"prisma": "^7.1.0",
|
|
52
48
|
"@larksuiteoapi/node-sdk": "^1.55.0",
|
|
53
49
|
"@upstash/redis": "^1.35.7",
|
|
54
|
-
"fc-deploy": "^1.2.9"
|
|
50
|
+
"fc-deploy": "^1.2.9",
|
|
51
|
+
"prisma": "^7.1.0"
|
|
55
52
|
}
|
|
56
|
-
}
|
|
53
|
+
}
|