@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.
Files changed (2) hide show
  1. package/README.md +66 -8
  2. 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?: number // When response occurred (ms)
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 **PostgreSQL via Prisma** (Redis route kept only for diagnostics)
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
- # UPSTASH_REDIS_REST_URL=https://...
278
- # UPSTASH_REDIS_REST_TOKEN=...
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
- # Optional legacy Redis diagnostics route
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 diag route if configured)
329
- - `GET /pre-stop` - Instance shutdown (closes Prisma DB and Redis if used)
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.0",
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.0",
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
+ }