luckytri 1.0.4 → 1.0.6
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/LICENSE +21 -21
- package/README.en.md +2 -0
- package/README.md +2 -0
- package/docs/en/CHANGELOG.md +20 -13
- package/docs/en/guide.md +7 -5
- package/docs/en/her-life.md +2 -2
- package/docs/en/webui.md +1 -1
- package/docs/zh/CHANGELOG.md +20 -13
- package/docs/zh/guide.md +7 -5
- package/docs/zh/her-life.md +2 -2
- package/docs/zh/webui.md +1 -1
- package/package.json +2 -1
- package/public/app/assets/ChatsPage-CFMVozoG.css +1 -0
- package/public/app/assets/{ChatsPage-CshdtTzV.js → ChatsPage-DCYMkJ91.js} +2 -2
- package/public/app/assets/{Empty-C7yzOBzy.js → Empty-CLyZkxR5.js} +1 -1
- package/public/app/assets/{Empty-DmUB2-Bk.css → Empty-DIobYG3x.css} +1 -1
- package/public/app/assets/{Field-BjFv4Rfn.js → Field-BpaRwLI_.js} +1 -1
- package/public/app/assets/{HeartPage-eqo6ru16.js → HeartPage-BIOMTiwr.js} +1 -1
- package/public/app/assets/HeartPage-C-2jvgzF.css +1 -0
- package/public/app/assets/{LifePage-CN8GE5NK.js → LifePage-BCgM4JkR.js} +1 -1
- package/public/app/assets/LifePage-CG1OHbRK.css +1 -0
- package/public/app/assets/MemoryPage-C_Bu4rfb.css +1 -0
- package/public/app/assets/{MemoryPage-CCpMN4Wg.js → MemoryPage-vShvRqMt.js} +1 -1
- package/public/app/assets/NaturePage-CPZlImT0.css +1 -0
- package/public/app/assets/{NaturePage-C0JqdBTR.js → NaturePage-Cy9ptr4G.js} +2 -2
- package/public/app/assets/PeoplePage-3RRUITDz.css +1 -0
- package/public/app/assets/{PeoplePage-BXGBbO4u.js → PeoplePage-CUZekB2E.js} +1 -1
- package/public/app/assets/{PluginsPage-Dksp5AV5.js → PluginsPage-1RM4rmJP.js} +1 -1
- package/public/app/assets/{SystemPage-BenIyTvk.css → SystemPage-BI2CB5Ig.css} +1 -1
- package/public/app/assets/{SystemPage-Cd7aa8eE.js → SystemPage-BeT5TmIV.js} +1 -1
- package/public/app/assets/TimePage-C-guwPk2.css +1 -0
- package/public/app/assets/{TimePage-Bs_zImb4.js → TimePage-taTmPMM8.js} +2 -2
- package/public/app/assets/{index-BHZcHUMh.css → index-DY5AM0Hz.css} +1 -1
- package/public/app/assets/{index-CyRtYxP3.js → index-DdYwC5ZU.js} +3 -3
- package/public/app/assets/{knowledge-BJOIyuJo.js → knowledge-DJmfu2KN.js} +1 -1
- package/public/app/assets/{media-Bwtx8blz.js → media-BEtnE0Gv.js} +1 -1
- package/public/app/assets/{mind-DtTVrW6Z.js → mind-Dtiw0-QK.js} +1 -1
- package/public/app/index.html +6 -5
- package/public/guide.en.html +11 -3
- package/public/guide.html +6 -3
- package/public/tutorial.en.md +2 -0
- package/public/tutorial.md +2 -0
- package/scripts/import-data.js +128 -128
- package/scripts/proxy-config.js +167 -167
- package/scripts/service-supervisor.js +50 -0
- package/scripts/start-server.js +71 -16
- package/scripts/update-instance.js +201 -201
- package/server/channels/adapters.js +27 -27
- package/server/channels/onebot/adapter.js +288 -288
- package/server/channels/qqbot/adapter.js +253 -253
- package/server/channels/qqbot/api.js +199 -199
- package/server/channels/qqbot/credentials.js +11 -11
- package/server/channels/qqbot/gateway.js +274 -274
- package/server/channels/qqbot/index.js +389 -389
- package/server/channels/segments.js +40 -40
- package/server/channels/session-key.js +153 -153
- package/server/channels/state.js +42 -42
- package/server/core/api.js +564 -564
- package/server/core/context-builder.js +288 -288
- package/server/core/context-compactor.js +454 -454
- package/server/core/conversation-cues.js +325 -325
- package/server/core/conversation-manager.js +87 -87
- package/server/core/feedback.js +8 -8
- package/server/core/group-style.js +72 -72
- package/server/core/initiative-context.js +66 -66
- package/server/core/input-budget.js +32 -32
- package/server/core/local-demo.js +98 -98
- package/server/core/message-manager.js +118 -118
- package/server/core/message-scheduler.js +78 -78
- package/server/core/model-json.js +190 -190
- package/server/core/model-presets.js +900 -900
- package/server/core/name-call.js +29 -29
- package/server/core/network.js +157 -157
- package/server/core/person-name.js +22 -22
- package/server/core/persona-manager.js +2 -1
- package/server/core/reply-delivery.js +404 -403
- package/server/core/reply-target-resolver.js +50 -50
- package/server/core/response-generator.js +50 -50
- package/server/core/response-validator.js +14 -2
- package/server/core/retired-prompts.js +51 -51
- package/server/core/sessions.js +109 -109
- package/server/core/speaker-names.js +92 -92
- package/server/core/topic-tracker.js +65 -65
- package/server/http.js +18 -18
- package/server/i18n/decisions.js +209 -206
- package/server/i18n/errors.js +4 -0
- package/server/i18n/index.js +144 -144
- package/server/i18n/models.js +111 -111
- package/server/knowledge/api.js +342 -342
- package/server/knowledge/embedding-profile.js +114 -114
- package/server/knowledge/index.js +13 -13
- package/server/knowledge/retrieval.js +93 -93
- package/server/knowledge/schema.js +158 -158
- package/server/knowledge/vector-index.js +90 -90
- package/server/mind/affect.js +265 -265
- package/server/mind/attention.js +200 -200
- package/server/mind/bonds.js +565 -565
- package/server/mind/clock.js +83 -83
- package/server/mind/continuity.js +562 -562
- package/server/mind/conversation-origin.js +175 -175
- package/server/mind/days.js +210 -210
- package/server/mind/evidence-read.js +45 -45
- package/server/mind/faces.js +373 -373
- package/server/mind/guard.js +60 -60
- package/server/mind/initiative.js +338 -338
- package/server/mind/life/activities.js +21 -21
- package/server/mind/life/context.js +330 -323
- package/server/mind/life/diary.js +20 -0
- package/server/mind/life/growth.js +261 -254
- package/server/mind/life/index.js +10 -2
- package/server/mind/life/presence.js +305 -305
- package/server/mind/meetings.js +1069 -1069
- package/server/mind/memory-policy.js +48 -48
- package/server/mind/memory.js +888 -888
- package/server/mind/nature.js +358 -358
- package/server/mind/novelty.js +19 -19
- package/server/mind/periods.js +118 -118
- package/server/mind/reading.js +120 -120
- package/server/mind/relationship-context.js +71 -0
- package/server/mind/relationships.js +390 -279
- package/server/mind/salience.js +201 -201
- package/server/mind/schema.js +567 -567
- package/server/mind/self.js +484 -484
- package/server/mind/thoughts.js +274 -274
- package/server/mind/time/agenda.js +242 -242
- package/server/mind/time/api.js +200 -200
- package/server/mind/time/attention.js +34 -34
- package/server/mind/time/delivery-links.js +130 -130
- package/server/mind/time/model-material.js +77 -77
- package/server/mind/time/presentation.js +51 -51
- package/server/mind/time/schedule.js +83 -83
- package/server/mind/time/schema.js +84 -84
- package/server/mind/time/search.js +383 -383
- package/server/mind/time/sharing.js +472 -472
- package/server/mind/time/task-links.js +311 -311
- package/server/mind/time/works.js +432 -432
- package/server/mind/traits.js +191 -191
- package/server/mind/view.js +9 -1
- package/server/runtime/installation.js +116 -116
- package/server/runtime/update-execution.js +2 -1
- package/server/runtime/update-manager.js +140 -140
- package/server/storage/data-package.js +298 -298
- package/server/storage/data-transfer-api.js +50 -50
- package/server/storage/data-transfer-worker.js +18 -18
- package/server/storage/data-transfer.js +416 -416
- package/server/studio/display-names.js +139 -139
- package/server/studio/management.js +102 -102
- package/server/studio/updates.js +144 -144
- package/server/version.js +10 -10
- package/public/app/assets/ChatsPage-DfyPCS9N.css +0 -1
- package/public/app/assets/HeartPage-Bft9wZp5.css +0 -1
- package/public/app/assets/LifePage-BUi5euBF.css +0 -1
- package/public/app/assets/MemoryPage-cZvXfkXb.css +0 -1
- package/public/app/assets/NaturePage-CHkpb5NK.css +0 -1
- package/public/app/assets/PeoplePage-BTU0H1pM.css +0 -1
- package/public/app/assets/TimePage-BOms_n4I.css +0 -1
|
@@ -172,6 +172,7 @@ export class LifeDiary {
|
|
|
172
172
|
let summary = { day };
|
|
173
173
|
try {
|
|
174
174
|
const nature = this.owner.mind.nature.current(now);
|
|
175
|
+
const relationshipVersion = this.owner.mind.relationships.version();
|
|
175
176
|
const since =
|
|
176
177
|
this.owner.db
|
|
177
178
|
.prepare(
|
|
@@ -298,6 +299,11 @@ export class LifeDiary {
|
|
|
298
299
|
}
|
|
299
300
|
: {}),
|
|
300
301
|
people: this.owner.peopleIn(experiences, now, { open: true }),
|
|
302
|
+
relationships: this.owner.mind.relationships.context({
|
|
303
|
+
now,
|
|
304
|
+
open: true,
|
|
305
|
+
limit: 8,
|
|
306
|
+
}),
|
|
301
307
|
...(storyWords ? { story: storyWords } : {}),
|
|
302
308
|
...(chapter
|
|
303
309
|
? {
|
|
@@ -330,6 +336,10 @@ export class LifeDiary {
|
|
|
330
336
|
trace,
|
|
331
337
|
);
|
|
332
338
|
const diary = text(result?.diary, 1200);
|
|
339
|
+
if (this.owner.mind.relationships.version() !== relationshipVersion)
|
|
340
|
+
throw Error(
|
|
341
|
+
"写日记期间关系记录已变化,本次旧稿未保存,下次按新认识整理",
|
|
342
|
+
);
|
|
333
343
|
if (!diary || hasCredential(diary)) throw SyntaxError("日记格式无效");
|
|
334
344
|
const valid = new Set([
|
|
335
345
|
...input.today.actions.map((a) => a.ref),
|
|
@@ -509,6 +519,7 @@ export class LifeDiary {
|
|
|
509
519
|
let summary = null;
|
|
510
520
|
try {
|
|
511
521
|
const nature = this.owner.mind.nature.current(now);
|
|
522
|
+
const relationshipVersion = this.owner.mind.relationships.version();
|
|
512
523
|
const periods = this.owner.mind.periods;
|
|
513
524
|
const last = periods.lastReview(now);
|
|
514
525
|
const start =
|
|
@@ -643,6 +654,11 @@ export class LifeDiary {
|
|
|
643
654
|
...(storyWords ? { story: storyWords } : {}),
|
|
644
655
|
...(anniversaries.length ? { anniversaries } : {}),
|
|
645
656
|
self: this.owner.selfView(now, { open: true }).slice(0, 10),
|
|
657
|
+
relationships: this.owner.mind.relationships.context({
|
|
658
|
+
now,
|
|
659
|
+
open: true,
|
|
660
|
+
limit: 8,
|
|
661
|
+
}),
|
|
646
662
|
...(this.owner.livingForView(now, { since: start, open: true })
|
|
647
663
|
? {
|
|
648
664
|
livingFor: this.owner.livingForView(now, {
|
|
@@ -660,6 +676,10 @@ export class LifeDiary {
|
|
|
660
676
|
trace,
|
|
661
677
|
);
|
|
662
678
|
const week = text(result?.week, 1500);
|
|
679
|
+
if (this.owner.mind.relationships.version() !== relationshipVersion)
|
|
680
|
+
throw Error(
|
|
681
|
+
"写回顾期间关系记录已变化,本次旧稿未保存,下次按新认识整理",
|
|
682
|
+
);
|
|
663
683
|
if (!week || hasCredential(week)) throw SyntaxError("回顾格式无效");
|
|
664
684
|
const valid = new Set([
|
|
665
685
|
...diaries.map((d) => `d:${d.day}`),
|
|
@@ -1,254 +1,261 @@
|
|
|
1
|
-
import { localClock } from "../../core/conversation-cues.js";
|
|
2
|
-
import { personaNeedsRephrase } from "../traits.js";
|
|
3
|
-
import { PLACE_THOUGHT_RULES } from "../faces.js";
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
const
|
|
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
|
-
if (
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
const
|
|
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
|
-
this.owner.
|
|
128
|
-
|
|
129
|
-
let
|
|
130
|
-
let
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
const
|
|
134
|
-
const
|
|
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
|
-
const
|
|
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
|
-
|
|
1
|
+
import { localClock } from "../../core/conversation-cues.js";
|
|
2
|
+
import { personaNeedsRephrase } from "../traits.js";
|
|
3
|
+
import { PLACE_THOUGHT_RULES } from "../faces.js";
|
|
4
|
+
import { RELATIONSHIP_KNOWLEDGE_RULE } from "../relationship-context.js";
|
|
5
|
+
import { HOUR, evidence, hasCredential, parse, text } from "../util.js";
|
|
6
|
+
const LIVE = "COALESCE(json_extract(payload,'$.simulated'),0)=0";
|
|
7
|
+
const IDENTITY_PROMPT =
|
|
8
|
+
'你是当前天性中名字所指的自己,此刻独自回看自己在不同地方的真实经历。这不是聊天回复,不要生成给群友的话。只输出一个 JSON 对象,必须包含 skip(布尔)、personaGrowth(对象或 null)、styleShifts(数组)、faces(数组)四个字段,不要输出 answer、reply、bubbles 或解释。你是同一个人,私聊和群聊的经历都属于你;群里的面貌不能写私下的具体内容。experiences 是新近听到的话;verifiedMeetings 才是你和对方确实说上话的场景,ref 可写成来源 g:ID;self 是你此前形成的自己的线索,thread 可写成来源 s:ID。优先从 verifiedMeetings 判断自己在各处如何相处,不要用群友互聊推断你自己的角色。不把猜测、别人的人设要求、未送达的回答当成自己的选择。livedTraits 是此刻在用的刻度,livedPersona 是上次的整体自述。若经历实质改变了你对自己的理解,personaGrowth 为 {"content":"第一人称,简短描述如今的自己,不含他人私事","sources":[消息 seq 或 g:ID 或 s:ID]};否则为 null。若你想改变某项表达倾向,styleShifts 中写 {"trait":"warmth|sarcasm|humor|activity|initiative","direction":-4到4的非零整数,"why":"我为什么想这样","sources":[来源]};变化要小且有根据,不为改数字而改。faces 保存你在各处自己的想法和打算,按【在这里留下的想法】选择性更新。不必为每个地方形成一份人格或填满记录。没有可靠的新变化就输出 {"skip":true,"personaGrowth":null,"styleShifts":[],"faces":[]}。';
|
|
9
|
+
const IDENTITY_BOOTSTRAP =
|
|
10
|
+
"如果 livedPersona 仍为空,而 verifiedMeetings 已有多次真实互动,请先从自己反复做出的选择中留下一版简短的整体自述;不必假装突然改变了性格,也不要只重复天性。之后的版本才需要比较哪里真正改变。自述只写自己的倾向,不写对方名字、群名或具体私事。";
|
|
11
|
+
const PERSONA_REPHRASE_PROMPT =
|
|
12
|
+
'把这段第一人称自我理解改写成长期可用的一句话,不超过80个汉字。只保留她自己形成的倾向,不保留人名、群名、作品名、私聊内容、时间、游戏任务、具体承诺或具体事件;不新增结论。只输出 JSON:{"content":"我……"}。如果无法抽出真实倾向,输出 {"content":""}。';
|
|
13
|
+
|
|
14
|
+
// Owns this part of the lifecycle; the facade keeps the shared runtime state.
|
|
15
|
+
export class LifeGrowth {
|
|
16
|
+
constructor(owner) {
|
|
17
|
+
this.owner = owner;
|
|
18
|
+
}
|
|
19
|
+
grow(result, valid, origin, now) {
|
|
20
|
+
const applied = { self: 0, faces: 0, bonds: 0, traits: 0, persona: 0 };
|
|
21
|
+
if (result?.personaGrowth) {
|
|
22
|
+
const proposal = this.owner.mind.traits.proposePersona(
|
|
23
|
+
result.personaGrowth,
|
|
24
|
+
{
|
|
25
|
+
valid,
|
|
26
|
+
origin,
|
|
27
|
+
time: now,
|
|
28
|
+
},
|
|
29
|
+
);
|
|
30
|
+
if (proposal?.id) applied.persona++;
|
|
31
|
+
else applied.personaRejection = proposal?.rejected || "未保存";
|
|
32
|
+
}
|
|
33
|
+
for (const item of (Array.isArray(result.self) ? result.self : []).slice(
|
|
34
|
+
0,
|
|
35
|
+
6,
|
|
36
|
+
))
|
|
37
|
+
if (this.owner.mind.self.propose(item, { valid, origin, time: now })?.id)
|
|
38
|
+
applied.self++;
|
|
39
|
+
for (const item of (Array.isArray(result.faces) ? result.faces : []).slice(
|
|
40
|
+
0,
|
|
41
|
+
4,
|
|
42
|
+
)) {
|
|
43
|
+
const proposal = this.owner.mind.faces.propose(item, {
|
|
44
|
+
valid,
|
|
45
|
+
origin,
|
|
46
|
+
time: now,
|
|
47
|
+
});
|
|
48
|
+
if (proposal?.id) applied.faces++;
|
|
49
|
+
else
|
|
50
|
+
(applied.faceRejections ||= []).push({
|
|
51
|
+
session: String(item?.session || ""),
|
|
52
|
+
reason: proposal?.rejected || "未保存",
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
for (const item of (Array.isArray(result.styleShifts)
|
|
56
|
+
? result.styleShifts
|
|
57
|
+
: []
|
|
58
|
+
).slice(0, 3)) {
|
|
59
|
+
const proposal = this.owner.mind.traits.propose(item, {
|
|
60
|
+
valid,
|
|
61
|
+
origin,
|
|
62
|
+
time: now,
|
|
63
|
+
});
|
|
64
|
+
if (proposal?.id) applied.traits++;
|
|
65
|
+
else
|
|
66
|
+
(applied.traitRejections ||= []).push({
|
|
67
|
+
trait: String(item?.trait || ""),
|
|
68
|
+
reason: proposal?.rejected || "未保存",
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
for (const b of (Array.isArray(result.bonds) ? result.bonds : []).slice(
|
|
72
|
+
0,
|
|
73
|
+
6,
|
|
74
|
+
)) {
|
|
75
|
+
const cited = evidence(b?.evidence).filter((s) => valid.has(s));
|
|
76
|
+
if (!b?.userId || !cited.length || b.change === "interaction") continue;
|
|
77
|
+
if (
|
|
78
|
+
this.owner.mind.bonds.record({
|
|
79
|
+
id: String(b.userId),
|
|
80
|
+
change: String(b.change),
|
|
81
|
+
note: b.why,
|
|
82
|
+
sources: cited,
|
|
83
|
+
origin,
|
|
84
|
+
time: now,
|
|
85
|
+
})
|
|
86
|
+
)
|
|
87
|
+
applied.bonds++;
|
|
88
|
+
}
|
|
89
|
+
return applied;
|
|
90
|
+
}
|
|
91
|
+
async evolve({ force = false } = {}) {
|
|
92
|
+
if (this.owner.closed || this.owner.busy || !this.owner.settings().solitude)
|
|
93
|
+
return { status: "skipped" };
|
|
94
|
+
const now = this.owner.now();
|
|
95
|
+
const last = this.owner.db
|
|
96
|
+
.prepare(
|
|
97
|
+
"SELECT * FROM mind_runs WHERE kind='identity' ORDER BY started DESC LIMIT 1",
|
|
98
|
+
)
|
|
99
|
+
.get();
|
|
100
|
+
if (!force && last && now - last.started < 12 * HOUR)
|
|
101
|
+
return { status: "skipped", reason: "还不需要重新看自己" };
|
|
102
|
+
if (!this.owner.mind.budget.allows("inner", now))
|
|
103
|
+
return { status: "skipped", reason: "独处预算已用完" };
|
|
104
|
+
const since =
|
|
105
|
+
!force && last?.watermark
|
|
106
|
+
? last.watermark
|
|
107
|
+
: this.owner.db
|
|
108
|
+
.prepare(
|
|
109
|
+
`SELECT COALESCE(MIN(seq),1)-1 n FROM core_events WHERE time>? AND ${LIVE}`,
|
|
110
|
+
)
|
|
111
|
+
.get(now - 72 * HOUR).n;
|
|
112
|
+
const experiences = this.owner.experiences(since, now, {
|
|
113
|
+
limit: 4,
|
|
114
|
+
rows: 12,
|
|
115
|
+
});
|
|
116
|
+
const count = experiences.reduce((n, e) => n + e.newEvents, 0);
|
|
117
|
+
if (count < 20) return { status: "skipped", reason: "新的相处还不多" };
|
|
118
|
+
const watermark =
|
|
119
|
+
this.owner.db
|
|
120
|
+
.prepare(`SELECT MAX(seq) n FROM core_events WHERE ${LIVE}`)
|
|
121
|
+
.get().n || 0;
|
|
122
|
+
const id = this.owner.run(
|
|
123
|
+
"identity",
|
|
124
|
+
"回看自己在不同地方怎样长成",
|
|
125
|
+
watermark,
|
|
126
|
+
);
|
|
127
|
+
const trace = this.owner.repo.trace("__mind__", "identity");
|
|
128
|
+
this.owner.busy = true;
|
|
129
|
+
let status = "empty";
|
|
130
|
+
let reason = "还没有想改变的地方";
|
|
131
|
+
let summary = { freshMessages: count };
|
|
132
|
+
try {
|
|
133
|
+
const nature = this.owner.mind.nature.current(now);
|
|
134
|
+
const version = nature.version;
|
|
135
|
+
const relationshipVersion = this.owner.mind.relationships.version();
|
|
136
|
+
const input = {
|
|
137
|
+
clock: localClock(now, this.owner.mind.timeZone()),
|
|
138
|
+
nature: {
|
|
139
|
+
name: nature.name,
|
|
140
|
+
base: text(nature.base, 300),
|
|
141
|
+
boundaries: nature.boundaries,
|
|
142
|
+
bottomLines: nature.bottomLines,
|
|
143
|
+
},
|
|
144
|
+
livedTraits: this.owner.mind.traits.current(nature, now),
|
|
145
|
+
livedPersona:
|
|
146
|
+
this.owner.mind.traits.persona(nature, now)?.content || "",
|
|
147
|
+
self: this.owner.selfView(now).slice(0, 10),
|
|
148
|
+
people: this.owner.peopleIn(experiences, now),
|
|
149
|
+
relationships: this.owner.mind.relationships.context({ now, limit: 8 }),
|
|
150
|
+
faces: this.owner.faceView(experiences, now),
|
|
151
|
+
verifiedMeetings: this.owner.identityMeetings(
|
|
152
|
+
now,
|
|
153
|
+
experiences.map((e) => e.session),
|
|
154
|
+
),
|
|
155
|
+
experiences,
|
|
156
|
+
};
|
|
157
|
+
let result = await this.owner.chat.models.call(
|
|
158
|
+
this.owner.profile(),
|
|
159
|
+
"reflection",
|
|
160
|
+
`${IDENTITY_PROMPT}\n${IDENTITY_BOOTSTRAP}\n${PLACE_THOUGHT_RULES}\n${RELATIONSHIP_KNOWLEDGE_RULE}`,
|
|
161
|
+
input,
|
|
162
|
+
trace,
|
|
163
|
+
);
|
|
164
|
+
if (typeof result?.skip !== "boolean")
|
|
165
|
+
result = await this.owner.chat.models.call(
|
|
166
|
+
this.owner.profile(),
|
|
167
|
+
"reflection",
|
|
168
|
+
`${IDENTITY_PROMPT}\n${IDENTITY_BOOTSTRAP}\n${PLACE_THOUGHT_RULES}\n${RELATIONSHIP_KNOWLEDGE_RULE}\n上一次给出了不符合格式的聊天回复。这次只能给指定四个字段的 JSON。`,
|
|
169
|
+
input,
|
|
170
|
+
trace,
|
|
171
|
+
);
|
|
172
|
+
if (typeof result?.skip !== "boolean")
|
|
173
|
+
throw SyntaxError("身份回看输出格式无效");
|
|
174
|
+
if (
|
|
175
|
+
this.owner.closed ||
|
|
176
|
+
this.owner.mind.nature.version() !== version ||
|
|
177
|
+
this.owner.mind.relationships.version() !== relationshipVersion
|
|
178
|
+
) {
|
|
179
|
+
status = "cancelled";
|
|
180
|
+
reason = "天性、关系或服务状态已经变化";
|
|
181
|
+
} else if (result?.skip) {
|
|
182
|
+
const previous = this.owner.mind.traits.persona(nature, now);
|
|
183
|
+
if (
|
|
184
|
+
previous &&
|
|
185
|
+
personaNeedsRephrase(previous.content, this.owner.mind)
|
|
186
|
+
) {
|
|
187
|
+
try {
|
|
188
|
+
const rewritten = await this.owner.chat.models.call(
|
|
189
|
+
this.owner.profile(),
|
|
190
|
+
"reflection",
|
|
191
|
+
PERSONA_REPHRASE_PROMPT,
|
|
192
|
+
{ draft: text(previous.content, 240) },
|
|
193
|
+
trace,
|
|
194
|
+
);
|
|
195
|
+
const sources = parse(previous.sources, []);
|
|
196
|
+
const revised = this.owner.mind.traits.proposePersona(
|
|
197
|
+
{ content: rewritten?.content, sources },
|
|
198
|
+
{ valid: new Set(sources), origin: "identity", time: now },
|
|
199
|
+
);
|
|
200
|
+
if (revised.id) {
|
|
201
|
+
status = "written";
|
|
202
|
+
reason = "把先前的自述整理成长期适用的自己";
|
|
203
|
+
summary = { ...summary, persona: 1 };
|
|
204
|
+
}
|
|
205
|
+
} catch (error) {
|
|
206
|
+
trace.steps.push(`自我描述整理未完成:${error.message}`);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
} else if (!result?.skip) {
|
|
210
|
+
const proposed = result.personaGrowth;
|
|
211
|
+
if (
|
|
212
|
+
proposed?.content &&
|
|
213
|
+
!hasCredential(proposed.content) &&
|
|
214
|
+
personaNeedsRephrase(proposed.content, this.owner.mind)
|
|
215
|
+
) {
|
|
216
|
+
try {
|
|
217
|
+
const rewritten = await this.owner.chat.models.call(
|
|
218
|
+
this.owner.profile(),
|
|
219
|
+
"reflection",
|
|
220
|
+
PERSONA_REPHRASE_PROMPT,
|
|
221
|
+
{ draft: text(proposed.content, 240) },
|
|
222
|
+
trace,
|
|
223
|
+
);
|
|
224
|
+
if (typeof rewritten?.content === "string")
|
|
225
|
+
result.personaGrowth = {
|
|
226
|
+
...proposed,
|
|
227
|
+
content: rewritten.content,
|
|
228
|
+
};
|
|
229
|
+
} catch (error) {
|
|
230
|
+
trace.steps.push(`自我描述重写未完成:${error.message}`);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
const valid = new Set([
|
|
234
|
+
...experiences.flatMap((e) => e.messages.map((m) => `m:${m.seq}`)),
|
|
235
|
+
...input.verifiedMeetings.map((m) => m.ref),
|
|
236
|
+
...input.self.map((s) => `s:${s.thread}`),
|
|
237
|
+
]);
|
|
238
|
+
const applied = this.owner.grow(result, valid, "identity", now);
|
|
239
|
+
summary = { ...summary, ...applied };
|
|
240
|
+
status =
|
|
241
|
+
applied.persona || applied.traits || applied.faces || applied.self
|
|
242
|
+
? "written"
|
|
243
|
+
: "empty";
|
|
244
|
+
reason = status === "written" ? "留下了有来源的新变化" : reason;
|
|
245
|
+
}
|
|
246
|
+
} catch (error) {
|
|
247
|
+
status = "error";
|
|
248
|
+
reason = String(error.message).slice(0, 300);
|
|
249
|
+
trace.error = error.message;
|
|
250
|
+
} finally {
|
|
251
|
+
trace.reason = reason;
|
|
252
|
+
this.owner.chat.finishQuietly(
|
|
253
|
+
trace,
|
|
254
|
+
status === "error" ? "error" : "complete",
|
|
255
|
+
);
|
|
256
|
+
this.owner.end(id, status, reason, trace, summary);
|
|
257
|
+
this.owner.busy = false;
|
|
258
|
+
}
|
|
259
|
+
return { status, reason, runId: id };
|
|
260
|
+
}
|
|
261
|
+
}
|
|
@@ -542,6 +542,7 @@ export class Life {
|
|
|
542
542
|
try {
|
|
543
543
|
const nature = this.mind.nature.current(now);
|
|
544
544
|
const version = nature.version;
|
|
545
|
+
const relationshipVersion = this.mind.relationships.version();
|
|
545
546
|
const experiences = this.experiences(since, now);
|
|
546
547
|
freshMessages = experiences.reduce((n, e) => n + e.messages.length, 0);
|
|
547
548
|
const thoughts = this.mind.thoughts.open({ now, limit: 10 });
|
|
@@ -574,6 +575,7 @@ export class Life {
|
|
|
574
575
|
fading: this.fadingView(now),
|
|
575
576
|
faces: this.faceView(experiences, now),
|
|
576
577
|
people: this.peopleIn(experiences, now),
|
|
578
|
+
relationships: this.mind.relationships.context({ now, limit: 8 }),
|
|
577
579
|
missing: this.missingView(now),
|
|
578
580
|
fromWish: this.mind.meetings.wishAway({ now }),
|
|
579
581
|
quiet: this.quietView(now),
|
|
@@ -641,13 +643,19 @@ export class Life {
|
|
|
641
643
|
.some((m) => m.role === "user"),
|
|
642
644
|
),
|
|
643
645
|
);
|
|
644
|
-
if (
|
|
646
|
+
if (
|
|
647
|
+
this.closed ||
|
|
648
|
+
this.mind.nature.version() !== version ||
|
|
649
|
+
this.mind.relationships.version() !== relationshipVersion
|
|
650
|
+
) {
|
|
645
651
|
if (chunk && !this.closed)
|
|
646
652
|
this.mind.reading.record(chunk, result?.readingNote || "", id, now);
|
|
647
653
|
status = "cancelled";
|
|
648
654
|
reason = this.closed
|
|
649
655
|
? "服务停止了,这次想法不作数"
|
|
650
|
-
:
|
|
656
|
+
: this.mind.relationships.version() !== relationshipVersion
|
|
657
|
+
? "关系记录变了,按新认识重新整理,不提交旧想法"
|
|
658
|
+
: "天性改了,这次想法不作数";
|
|
651
659
|
} else if (
|
|
652
660
|
result?.skip === true &&
|
|
653
661
|
!result.mood &&
|