luckytri 1.0.8 → 1.1.0

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 (100) hide show
  1. package/README.en.md +1 -1
  2. package/README.md +1 -1
  3. package/docs/en/CHANGELOG.md +44 -24
  4. package/docs/en/architecture.md +4 -0
  5. package/docs/en/cognition.md +34 -0
  6. package/docs/en/guide.md +8 -6
  7. package/docs/zh/CHANGELOG.md +44 -24
  8. package/docs/zh/architecture.md +4 -0
  9. package/docs/zh/cognition.md +34 -0
  10. package/docs/zh/guide.md +8 -6
  11. package/package.json +112 -112
  12. package/public/app/assets/ChatsPage-DH4ZPRXB.js +3 -0
  13. package/public/app/assets/{Empty-C7yzOBzy.js → Empty-DRsHeX-L.js} +1 -1
  14. package/public/app/assets/Field-BfIUcaNa.js +1 -0
  15. package/public/app/assets/HeartPage-BxgSUJJ_.js +1 -0
  16. package/public/app/assets/LifePage-CAKr8h_q.js +1 -0
  17. package/public/app/assets/MemoryPage-CFq8L_TC.js +1 -0
  18. package/public/app/assets/NaturePage-BU1iDno3.js +3 -0
  19. package/public/app/assets/PeoplePage-C6i_nAfr.js +1 -0
  20. package/public/app/assets/PluginsPage-DRV8lzk3.js +2 -0
  21. package/public/app/assets/SystemPage-21AlQBiC.js +1 -0
  22. package/public/app/assets/SystemPage-CMcuUdLm.css +1 -0
  23. package/public/app/assets/TimePage-DUzjLnZV.js +3 -0
  24. package/public/app/assets/index-WAvrlAcO.js +4 -0
  25. package/public/app/assets/{knowledge-BJOIyuJo.js → knowledge-V_blbx9R.js} +1 -1
  26. package/public/app/assets/media-C7j5HqxK.js +1 -0
  27. package/public/app/assets/{mind-DtTVrW6Z.js → mind-BBAstMqH.js} +1 -1
  28. package/public/app/index.html +3 -3
  29. package/public/guide.en.html +13 -5
  30. package/public/guide.html +12 -5
  31. package/public/tutorial.en.md +3 -1
  32. package/public/tutorial.md +3 -1
  33. package/server/core/backoff.js +123 -0
  34. package/server/core/context-builder.js +307 -288
  35. package/server/core/contribution-check.js +50 -0
  36. package/server/core/conversation-cues.js +377 -385
  37. package/server/core/conversation-grounding.js +547 -304
  38. package/server/core/dialogue-context.js +247 -244
  39. package/server/core/dialogue-contract.js +33 -9
  40. package/server/core/embedding.js +246 -0
  41. package/server/core/expression-strategy.js +90 -0
  42. package/server/core/initiative-context.js +88 -68
  43. package/server/core/model-json.js +223 -190
  44. package/server/core/model-manager.js +256 -56
  45. package/server/core/model-presets.js +1045 -900
  46. package/server/core/orchestrator.js +41 -3
  47. package/server/core/persona-manager.js +364 -359
  48. package/server/core/reader-check.js +166 -62
  49. package/server/core/reply-delivery.js +688 -537
  50. package/server/core/repository.js +36 -0
  51. package/server/core/response-generator.js +101 -92
  52. package/server/core/response-validator.js +18 -3
  53. package/server/core/retired-prompts.js +53 -51
  54. package/server/core/time-expressions.js +143 -0
  55. package/server/core/turn-processor.js +175 -5
  56. package/server/core/turn.js +299 -44
  57. package/server/core/understanding.js +85 -0
  58. package/server/core/working-memory.js +149 -0
  59. package/server/i18n/decisions.js +225 -209
  60. package/server/i18n/errors.js +14 -0
  61. package/server/i18n/models.js +120 -111
  62. package/server/knowledge/api.js +362 -342
  63. package/server/knowledge/embedding-profile.js +158 -114
  64. package/server/knowledge/manager.js +6 -1
  65. package/server/mind/api.js +68 -0
  66. package/server/mind/continuity.js +634 -562
  67. package/server/mind/day-planner.js +52 -3
  68. package/server/mind/episodes.js +242 -0
  69. package/server/mind/expression-grounding.js +24 -21
  70. package/server/mind/index.js +13 -2
  71. package/server/mind/initiative.js +356 -338
  72. package/server/mind/life/index.js +6 -0
  73. package/server/mind/meetings.js +1112 -1069
  74. package/server/mind/memory.js +1091 -888
  75. package/server/mind/recall/index.js +776 -0
  76. package/server/mind/recall/schema.js +132 -0
  77. package/server/mind/recall/sources.js +220 -0
  78. package/server/mind/recall/store.js +368 -0
  79. package/server/mind/salience.js +202 -201
  80. package/server/mind/schema.js +568 -567
  81. package/server/mind/self.js +537 -496
  82. package/server/mind/time/activity-recall.js +65 -0
  83. package/server/mind/time/index.js +6 -2
  84. package/server/mind/time/tasks.js +36 -10
  85. package/server/mind/time/works.js +528 -527
  86. package/server/mind/view.js +63 -17
  87. package/server/storage/archive.js +1 -1
  88. package/public/app/assets/ChatsPage-CshdtTzV.js +0 -3
  89. package/public/app/assets/Field-BjFv4Rfn.js +0 -1
  90. package/public/app/assets/HeartPage-eqo6ru16.js +0 -1
  91. package/public/app/assets/LifePage-CN8GE5NK.js +0 -1
  92. package/public/app/assets/MemoryPage-CCpMN4Wg.js +0 -1
  93. package/public/app/assets/NaturePage-C0JqdBTR.js +0 -3
  94. package/public/app/assets/PeoplePage-BXGBbO4u.js +0 -1
  95. package/public/app/assets/PluginsPage-Dksp5AV5.js +0 -2
  96. package/public/app/assets/SystemPage-BenIyTvk.css +0 -1
  97. package/public/app/assets/SystemPage-Cd7aa8eE.js +0 -1
  98. package/public/app/assets/TimePage-Bs_zImb4.js +0 -3
  99. package/public/app/assets/index-CyRtYxP3.js +0 -4
  100. package/public/app/assets/media-Bwtx8blz.js +0 -1
@@ -0,0 +1,65 @@
1
+ const OWN_REFERENCE =
2
+ /你.{0,16}(?:不是说|明明说|说过|提过|答应过)|你跟.{0,16}(?:说|提过|答应过)|(?:上次|之前|刚才|昨天).{0,18}(?:你|我).{0,10}(?:说|提|答应)/;
3
+
4
+ // A same-person follow-up may point to what she just said without repeating
5
+ // a work's title. Use only replies actually addressed to this speaker as extra
6
+ // search terms; the private reply itself never enters the memory result.
7
+ export function activityRecallCue(
8
+ batch = [],
9
+ messages = [],
10
+ { excludedSpeakers = new Set() } = {},
11
+ ) {
12
+ const current = batch.filter(
13
+ (message) =>
14
+ message.role === "user" &&
15
+ !excludedSpeakers.has(String(message.speaker ?? message.userId ?? "")) &&
16
+ OWN_REFERENCE.test(message.text || ""),
17
+ );
18
+ if (!current.length) return batch;
19
+
20
+ const speakers = new Set(
21
+ current
22
+ .map((message) => String(message.speaker ?? message.userId ?? ""))
23
+ .filter(Boolean),
24
+ );
25
+ if (!speakers.size) return batch;
26
+ const byId = new Map(
27
+ messages.map((message) => [Number(message.seq ?? message.id), message]),
28
+ );
29
+ const cutoff = Math.min(
30
+ ...batch
31
+ .map((message) => Number(message.id ?? message.seq))
32
+ .filter(Number.isFinite),
33
+ );
34
+ const now = Math.max(
35
+ ...batch.map((message) => Number(message.time)).filter(Number.isFinite),
36
+ );
37
+ const replies = messages.filter((message) => {
38
+ if (message.role !== "assistant" || message.referenceOnly) return false;
39
+ if (Number.isFinite(message.id ?? message.seq) && Number.isFinite(cutoff)) {
40
+ const id = Number(message.id ?? message.seq);
41
+ if (
42
+ id >= cutoff &&
43
+ (!Number.isFinite(message.time) || message.time > now)
44
+ )
45
+ return false;
46
+ }
47
+ const targets = [
48
+ ...(Array.isArray(message.replyTargets) ? message.replyTargets : []),
49
+ ...(Array.isArray(message.replyTargetIds)
50
+ ? message.replyTargetIds.map((id) => byId.get(Number(id)))
51
+ : []),
52
+ ];
53
+ return targets.some((target) =>
54
+ speakers.has(String(target?.speaker ?? target?.userId ?? "")),
55
+ );
56
+ });
57
+ return [
58
+ ...batch,
59
+ ...replies.slice(-2).map((message) => ({
60
+ role: "assistant",
61
+ activityEvidence: true,
62
+ text: message.text || "",
63
+ })),
64
+ ];
65
+ }
@@ -422,7 +422,7 @@ export class TimeSystem {
422
422
  }),
423
423
  };
424
424
  }
425
- view({ session, now = this.now(), cue = [] } = {}) {
425
+ view({ session, now = this.now(), cue = [], activityCue = cue } = {}) {
426
426
  const primary = this.primary(),
427
427
  task = primary?.created <= now ? primary : null;
428
428
  let current =
@@ -548,7 +548,11 @@ export class TimeSystem {
548
548
  plannedFor: this.planView(row),
549
549
  })),
550
550
  works: this.works.fragments({ session, now, cue }),
551
- activityRecall: this.works.activityEvidence({ session, now, cue }),
551
+ activityRecall: this.works.activityEvidence({
552
+ session,
553
+ now,
554
+ cue: activityCue,
555
+ }),
552
556
  ...(() => {
553
557
  const actions = this.db
554
558
  .prepare(
@@ -212,16 +212,14 @@ export class Tasks {
212
212
  now,
213
213
  );
214
214
  if (type === "read" && awaitsTextInput(title)) {
215
- this.db
216
- .prepare("UPDATE mind_time_tasks SET checkpoint=? WHERE id=?")
217
- .run(
218
- JSON.stringify({
219
- awaitedText: true,
220
- expectedTextTitle: intent.topic,
221
- awaitedAfter: now,
222
- }),
223
- id,
224
- );
215
+ this.db.prepare("UPDATE mind_time_tasks SET checkpoint=? WHERE id=?").run(
216
+ JSON.stringify({
217
+ awaitedText: true,
218
+ expectedTextTitle: intent.topic,
219
+ awaitedAfter: now,
220
+ }),
221
+ id,
222
+ );
225
223
  this.wait(
226
224
  this.get(id),
227
225
  "等待约定的正文或资料",
@@ -511,6 +509,34 @@ export class Tasks {
511
509
  this.db.exec("RELEASE arrange_task");
512
510
  }
513
511
  }
512
+ // The earliest start at or after `startAt` that does not overlap anything
513
+ // at least as important. `acceptable` can reject a start, such as one that
514
+ // falls while she sleeps. Returns null when nothing fits within a week.
515
+ freeStart(
516
+ id,
517
+ startAt,
518
+ durationMinutes,
519
+ now = this.time.now(),
520
+ { acceptable = () => true, step = 15 * 60000 } = {},
521
+ ) {
522
+ const task = this.get(id);
523
+ if (!task) return null;
524
+ const length = durationMinutes * 60000;
525
+ const blocking = this.slots(now).filter(
526
+ (slot) => slot.id !== id && slot.priority >= task.priority,
527
+ );
528
+ let start = Math.max(now, startAt);
529
+ const limit = now + 7 * 86400000;
530
+ for (let guard = 0; guard < 2000 && start <= limit; guard++) {
531
+ const overlap = blocking.find(
532
+ (slot) => slot.startAt < start + length && slot.endAt > start,
533
+ );
534
+ if (overlap) start = overlap.endAt;
535
+ else if (!acceptable(start)) start += step;
536
+ else return start;
537
+ }
538
+ return null;
539
+ }
514
540
  slots(now = this.time.now()) {
515
541
  return this.db
516
542
  .prepare(