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.
Files changed (156) hide show
  1. package/LICENSE +21 -21
  2. package/README.en.md +2 -0
  3. package/README.md +2 -0
  4. package/docs/en/CHANGELOG.md +20 -13
  5. package/docs/en/guide.md +7 -5
  6. package/docs/en/her-life.md +2 -2
  7. package/docs/en/webui.md +1 -1
  8. package/docs/zh/CHANGELOG.md +20 -13
  9. package/docs/zh/guide.md +7 -5
  10. package/docs/zh/her-life.md +2 -2
  11. package/docs/zh/webui.md +1 -1
  12. package/package.json +2 -1
  13. package/public/app/assets/ChatsPage-CFMVozoG.css +1 -0
  14. package/public/app/assets/{ChatsPage-CshdtTzV.js → ChatsPage-DCYMkJ91.js} +2 -2
  15. package/public/app/assets/{Empty-C7yzOBzy.js → Empty-CLyZkxR5.js} +1 -1
  16. package/public/app/assets/{Empty-DmUB2-Bk.css → Empty-DIobYG3x.css} +1 -1
  17. package/public/app/assets/{Field-BjFv4Rfn.js → Field-BpaRwLI_.js} +1 -1
  18. package/public/app/assets/{HeartPage-eqo6ru16.js → HeartPage-BIOMTiwr.js} +1 -1
  19. package/public/app/assets/HeartPage-C-2jvgzF.css +1 -0
  20. package/public/app/assets/{LifePage-CN8GE5NK.js → LifePage-BCgM4JkR.js} +1 -1
  21. package/public/app/assets/LifePage-CG1OHbRK.css +1 -0
  22. package/public/app/assets/MemoryPage-C_Bu4rfb.css +1 -0
  23. package/public/app/assets/{MemoryPage-CCpMN4Wg.js → MemoryPage-vShvRqMt.js} +1 -1
  24. package/public/app/assets/NaturePage-CPZlImT0.css +1 -0
  25. package/public/app/assets/{NaturePage-C0JqdBTR.js → NaturePage-Cy9ptr4G.js} +2 -2
  26. package/public/app/assets/PeoplePage-3RRUITDz.css +1 -0
  27. package/public/app/assets/{PeoplePage-BXGBbO4u.js → PeoplePage-CUZekB2E.js} +1 -1
  28. package/public/app/assets/{PluginsPage-Dksp5AV5.js → PluginsPage-1RM4rmJP.js} +1 -1
  29. package/public/app/assets/{SystemPage-BenIyTvk.css → SystemPage-BI2CB5Ig.css} +1 -1
  30. package/public/app/assets/{SystemPage-Cd7aa8eE.js → SystemPage-BeT5TmIV.js} +1 -1
  31. package/public/app/assets/TimePage-C-guwPk2.css +1 -0
  32. package/public/app/assets/{TimePage-Bs_zImb4.js → TimePage-taTmPMM8.js} +2 -2
  33. package/public/app/assets/{index-BHZcHUMh.css → index-DY5AM0Hz.css} +1 -1
  34. package/public/app/assets/{index-CyRtYxP3.js → index-DdYwC5ZU.js} +3 -3
  35. package/public/app/assets/{knowledge-BJOIyuJo.js → knowledge-DJmfu2KN.js} +1 -1
  36. package/public/app/assets/{media-Bwtx8blz.js → media-BEtnE0Gv.js} +1 -1
  37. package/public/app/assets/{mind-DtTVrW6Z.js → mind-Dtiw0-QK.js} +1 -1
  38. package/public/app/index.html +6 -5
  39. package/public/guide.en.html +11 -3
  40. package/public/guide.html +6 -3
  41. package/public/tutorial.en.md +2 -0
  42. package/public/tutorial.md +2 -0
  43. package/scripts/import-data.js +128 -128
  44. package/scripts/proxy-config.js +167 -167
  45. package/scripts/service-supervisor.js +50 -0
  46. package/scripts/start-server.js +71 -16
  47. package/scripts/update-instance.js +201 -201
  48. package/server/channels/adapters.js +27 -27
  49. package/server/channels/onebot/adapter.js +288 -288
  50. package/server/channels/qqbot/adapter.js +253 -253
  51. package/server/channels/qqbot/api.js +199 -199
  52. package/server/channels/qqbot/credentials.js +11 -11
  53. package/server/channels/qqbot/gateway.js +274 -274
  54. package/server/channels/qqbot/index.js +389 -389
  55. package/server/channels/segments.js +40 -40
  56. package/server/channels/session-key.js +153 -153
  57. package/server/channels/state.js +42 -42
  58. package/server/core/api.js +564 -564
  59. package/server/core/context-builder.js +288 -288
  60. package/server/core/context-compactor.js +454 -454
  61. package/server/core/conversation-cues.js +325 -325
  62. package/server/core/conversation-manager.js +87 -87
  63. package/server/core/feedback.js +8 -8
  64. package/server/core/group-style.js +72 -72
  65. package/server/core/initiative-context.js +66 -66
  66. package/server/core/input-budget.js +32 -32
  67. package/server/core/local-demo.js +98 -98
  68. package/server/core/message-manager.js +118 -118
  69. package/server/core/message-scheduler.js +78 -78
  70. package/server/core/model-json.js +190 -190
  71. package/server/core/model-presets.js +900 -900
  72. package/server/core/name-call.js +29 -29
  73. package/server/core/network.js +157 -157
  74. package/server/core/person-name.js +22 -22
  75. package/server/core/persona-manager.js +2 -1
  76. package/server/core/reply-delivery.js +404 -403
  77. package/server/core/reply-target-resolver.js +50 -50
  78. package/server/core/response-generator.js +50 -50
  79. package/server/core/response-validator.js +14 -2
  80. package/server/core/retired-prompts.js +51 -51
  81. package/server/core/sessions.js +109 -109
  82. package/server/core/speaker-names.js +92 -92
  83. package/server/core/topic-tracker.js +65 -65
  84. package/server/http.js +18 -18
  85. package/server/i18n/decisions.js +209 -206
  86. package/server/i18n/errors.js +4 -0
  87. package/server/i18n/index.js +144 -144
  88. package/server/i18n/models.js +111 -111
  89. package/server/knowledge/api.js +342 -342
  90. package/server/knowledge/embedding-profile.js +114 -114
  91. package/server/knowledge/index.js +13 -13
  92. package/server/knowledge/retrieval.js +93 -93
  93. package/server/knowledge/schema.js +158 -158
  94. package/server/knowledge/vector-index.js +90 -90
  95. package/server/mind/affect.js +265 -265
  96. package/server/mind/attention.js +200 -200
  97. package/server/mind/bonds.js +565 -565
  98. package/server/mind/clock.js +83 -83
  99. package/server/mind/continuity.js +562 -562
  100. package/server/mind/conversation-origin.js +175 -175
  101. package/server/mind/days.js +210 -210
  102. package/server/mind/evidence-read.js +45 -45
  103. package/server/mind/faces.js +373 -373
  104. package/server/mind/guard.js +60 -60
  105. package/server/mind/initiative.js +338 -338
  106. package/server/mind/life/activities.js +21 -21
  107. package/server/mind/life/context.js +330 -323
  108. package/server/mind/life/diary.js +20 -0
  109. package/server/mind/life/growth.js +261 -254
  110. package/server/mind/life/index.js +10 -2
  111. package/server/mind/life/presence.js +305 -305
  112. package/server/mind/meetings.js +1069 -1069
  113. package/server/mind/memory-policy.js +48 -48
  114. package/server/mind/memory.js +888 -888
  115. package/server/mind/nature.js +358 -358
  116. package/server/mind/novelty.js +19 -19
  117. package/server/mind/periods.js +118 -118
  118. package/server/mind/reading.js +120 -120
  119. package/server/mind/relationship-context.js +71 -0
  120. package/server/mind/relationships.js +390 -279
  121. package/server/mind/salience.js +201 -201
  122. package/server/mind/schema.js +567 -567
  123. package/server/mind/self.js +484 -484
  124. package/server/mind/thoughts.js +274 -274
  125. package/server/mind/time/agenda.js +242 -242
  126. package/server/mind/time/api.js +200 -200
  127. package/server/mind/time/attention.js +34 -34
  128. package/server/mind/time/delivery-links.js +130 -130
  129. package/server/mind/time/model-material.js +77 -77
  130. package/server/mind/time/presentation.js +51 -51
  131. package/server/mind/time/schedule.js +83 -83
  132. package/server/mind/time/schema.js +84 -84
  133. package/server/mind/time/search.js +383 -383
  134. package/server/mind/time/sharing.js +472 -472
  135. package/server/mind/time/task-links.js +311 -311
  136. package/server/mind/time/works.js +432 -432
  137. package/server/mind/traits.js +191 -191
  138. package/server/mind/view.js +9 -1
  139. package/server/runtime/installation.js +116 -116
  140. package/server/runtime/update-execution.js +2 -1
  141. package/server/runtime/update-manager.js +140 -140
  142. package/server/storage/data-package.js +298 -298
  143. package/server/storage/data-transfer-api.js +50 -50
  144. package/server/storage/data-transfer-worker.js +18 -18
  145. package/server/storage/data-transfer.js +416 -416
  146. package/server/studio/display-names.js +139 -139
  147. package/server/studio/management.js +102 -102
  148. package/server/studio/updates.js +144 -144
  149. package/server/version.js +10 -10
  150. package/public/app/assets/ChatsPage-DfyPCS9N.css +0 -1
  151. package/public/app/assets/HeartPage-Bft9wZp5.css +0 -1
  152. package/public/app/assets/LifePage-BUi5euBF.css +0 -1
  153. package/public/app/assets/MemoryPage-cZvXfkXb.css +0 -1
  154. package/public/app/assets/NaturePage-CHkpb5NK.css +0 -1
  155. package/public/app/assets/PeoplePage-BTU0H1pM.css +0 -1
  156. package/public/app/assets/TimePage-BOms_n4I.css +0 -1
@@ -1,29 +1,29 @@
1
- const nameCallBoundary = "\\s,,、。!?!?::;;()()\\[\\]";
2
- const escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
3
- const HAIL = "喂哎诶嘿";
4
- const PARTICLES = "啊呀呢吧哦嘛";
5
- const AFTER = "你|我|今天|现在|怎么|能|可以|帮|回|看|咋|在|有没有|好累|辛苦|救";
6
- // Talking about her, not to her. Checked against the text after the name.
7
- const ABOUT =
8
- /^(?:\s*(?:是谁|是个|是一个|的名字|这个名字|这人|那个人|的?头像|在群里|说的是))/i;
9
-
10
- function calledBy(value, name) {
11
- if (!name) return false;
12
- const call = new RegExp(
13
- `(?:^|[${nameCallBoundary}]|[${HAIL}])@?${escapeRegExp(name)}(?=$|[${nameCallBoundary}]|[${PARTICLES}]|(?:${AFTER}))`,
14
- "gi",
15
- );
16
- let match;
17
- while ((match = call.exec(value))) {
18
- const after = value.slice(match.index + match[0].length);
19
- if (!ABOUT.test(after)) return true;
20
- if (match.index === call.lastIndex) call.lastIndex += 1;
21
- }
22
- return false;
23
- }
24
-
25
- export function isNameCall(text, names = []) {
26
- const value = String(text || "").trim();
27
- if (!value) return false;
28
- return names.some((raw) => calledBy(value, String(raw || "").trim()));
29
- }
1
+ const nameCallBoundary = "\\s,,、。!?!?::;;()()\\[\\]";
2
+ const escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
3
+ const HAIL = "喂哎诶嘿";
4
+ const PARTICLES = "啊呀呢吧哦嘛";
5
+ const AFTER = "你|我|今天|现在|怎么|能|可以|帮|回|看|咋|在|有没有|好累|辛苦|救";
6
+ // Talking about her, not to her. Checked against the text after the name.
7
+ const ABOUT =
8
+ /^(?:\s*(?:是谁|是个|是一个|的名字|这个名字|这人|那个人|的?头像|在群里|说的是))/i;
9
+
10
+ function calledBy(value, name) {
11
+ if (!name) return false;
12
+ const call = new RegExp(
13
+ `(?:^|[${nameCallBoundary}]|[${HAIL}])@?${escapeRegExp(name)}(?=$|[${nameCallBoundary}]|[${PARTICLES}]|(?:${AFTER}))`,
14
+ "gi",
15
+ );
16
+ let match;
17
+ while ((match = call.exec(value))) {
18
+ const after = value.slice(match.index + match[0].length);
19
+ if (!ABOUT.test(after)) return true;
20
+ if (match.index === call.lastIndex) call.lastIndex += 1;
21
+ }
22
+ return false;
23
+ }
24
+
25
+ export function isNameCall(text, names = []) {
26
+ const value = String(text || "").trim();
27
+ if (!value) return false;
28
+ return names.some((raw) => calledBy(value, String(raw || "").trim()));
29
+ }
@@ -1,157 +1,157 @@
1
- const TRANSIENT_NETWORK_CODES = new Set([
2
- "ECONNRESET",
3
- "ECONNREFUSED",
4
- "ECONNABORTED",
5
- "EPIPE",
6
- "EHOSTUNREACH",
7
- "ENETUNREACH",
8
- "EAI_AGAIN",
9
- "ETIMEDOUT",
10
- "UND_ERR_CONNECT_TIMEOUT",
11
- "UND_ERR_HEADERS_TIMEOUT",
12
- "UND_ERR_BODY_TIMEOUT",
13
- "UND_ERR_SOCKET",
14
- "UND_ERR_CLOSED",
15
- ]);
16
-
17
- export const RETRYABLE_STATUS = new Set([
18
- 408, 425, 429, 500, 502, 503, 504, 520, 521, 522, 523, 529,
19
- ]);
20
-
21
- const TLS_CODE =
22
- /^(?:ERR_SSL|ERR_TLS|EPROTO|CERT_|UNABLE_TO_VERIFY|DEPTH_ZERO|SELF_SIGNED)/;
23
-
24
- export function isTransientNetworkError(error) {
25
- let current = error;
26
- for (let depth = 0; current && depth < 6; depth++, current = current.cause) {
27
- if (
28
- TRANSIENT_NETWORK_CODES.has(current.code) ||
29
- TRANSIENT_NETWORK_CODES.has(current.errno)
30
- )
31
- return true;
32
- if (
33
- current.name === "TypeError" &&
34
- /^(?:fetch failed|network error)$/i.test(String(current.message || ""))
35
- )
36
- return true;
37
- }
38
- return false;
39
- }
40
-
41
- export function isTimeoutError(error) {
42
- let current = error;
43
- for (let depth = 0; current && depth < 6; depth++, current = current.cause)
44
- if (current.name === "TimeoutError") return true;
45
- return false;
46
- }
47
-
48
- export function sanitizeDetail(text, max = 300) {
49
- return String(text || "")
50
- .replace(/Bearer\s+[^\s,;]+/gi, "Bearer [已隐藏]")
51
- .replace(/((?:api[_ -]?key|token|secret)\s*[:= ]+)[^\s,;]+/gi, "$1[已隐藏]")
52
- .replace(/\bsk-[A-Za-z0-9_-]{8,}/g, "sk-[已隐藏]")
53
- .replace(/https?:\/\/[^\s"'<>]+/gi, (url) => {
54
- try {
55
- return new URL(url).origin;
56
- } catch {
57
- return "[地址]";
58
- }
59
- })
60
- .replace(/[\r\n\t]+/g, " ")
61
- .trim()
62
- .slice(0, max);
63
- }
64
-
65
- // Walks the fetch cause chain so a proxy tunnel refusal, a TLS failure and a
66
- // server reset are reported as different problems instead of "fetch failed".
67
- export function describeNetworkError(error) {
68
- const chain = [];
69
- for (
70
- let current = error, depth = 0;
71
- current && depth < 6;
72
- depth++, current = current.cause
73
- )
74
- chain.push(current);
75
- if (isTimeoutError(error)) return { code: "TIMEOUT", detail: "" };
76
- const messages = chain
77
- .map((item) => String(item?.message || ""))
78
- .filter(Boolean);
79
- let code =
80
- chain
81
- .map((item) => item?.code || item?.errno)
82
- .find((value) => TRANSIENT_NETWORK_CODES.has(value)) || "";
83
- const proxy = messages
84
- .map((message) => message.match(/Proxy response \((\d{3})\)/i))
85
- .find(Boolean);
86
- if (!code && proxy) code = `PROXY_${proxy[1]}`;
87
- if (!code)
88
- code =
89
- chain
90
- .map((item) => String(item?.code || ""))
91
- .find((value) => TLS_CODE.test(value)) || "";
92
- if (!code)
93
- code =
94
- chain
95
- .map((item) => item?.code)
96
- .find((value) => typeof value === "string" && value) || "";
97
- if (!code && isTransientNetworkError(error)) code = "FETCH_FAILED";
98
- const deepest =
99
- messages.filter((message) => !/^fetch failed$/i.test(message)).at(-1) || "";
100
- return { code, detail: sanitizeDetail(deepest, 160) };
101
- }
102
-
103
- export function networkErrorCode(error) {
104
- return describeNetworkError(error).code;
105
- }
106
-
107
- export function retryDelayFromResponse(response, fallbackMs = 900) {
108
- const value = String(response?.headers?.get?.("retry-after") || "").trim();
109
- if (value) {
110
- const seconds = Number(value);
111
- const dateDelay = Date.parse(value) - Date.now();
112
- const delay = Number.isFinite(seconds)
113
- ? seconds * 1000
114
- : Number.isFinite(dateDelay) && dateDelay > 0
115
- ? dateDelay
116
- : Number.NaN;
117
- if (Number.isFinite(delay)) return Math.max(0, Math.min(delay, 30000));
118
- }
119
- return Math.max(0, Math.min(Number(fallbackMs) || 900, 30000));
120
- }
121
-
122
- export async function withTransientRequestRetry(
123
- operation,
124
- {
125
- retries = 3,
126
- delayMs = 600,
127
- maxDelayMs = 8000,
128
- deadlineMs = 45000,
129
- onRetry,
130
- random = Math.random,
131
- sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
132
- now = Date.now,
133
- } = {},
134
- ) {
135
- const started = now();
136
- for (let attempt = 0; ; attempt++) {
137
- try {
138
- return await operation(attempt);
139
- } catch (error) {
140
- if (
141
- (!isTransientNetworkError(error) && error?.retryableRequest !== true) ||
142
- attempt >= retries
143
- )
144
- throw error;
145
- // Half fixed, half random: bursts of failures spread out instead of
146
- // hitting a recovering gateway at the same moment.
147
- const ceiling = Math.min(maxDelayMs, delayMs * 2 ** attempt);
148
- let wait = ceiling / 2 + random() * (ceiling / 2);
149
- const hinted = Number(error?.retryDelayMs);
150
- if (Number.isFinite(hinted))
151
- wait = Math.max(wait, Math.min(hinted, 30000));
152
- if (now() - started + wait > deadlineMs) throw error;
153
- onRetry?.(attempt + 1, error, wait);
154
- await sleep(wait);
155
- }
156
- }
157
- }
1
+ const TRANSIENT_NETWORK_CODES = new Set([
2
+ "ECONNRESET",
3
+ "ECONNREFUSED",
4
+ "ECONNABORTED",
5
+ "EPIPE",
6
+ "EHOSTUNREACH",
7
+ "ENETUNREACH",
8
+ "EAI_AGAIN",
9
+ "ETIMEDOUT",
10
+ "UND_ERR_CONNECT_TIMEOUT",
11
+ "UND_ERR_HEADERS_TIMEOUT",
12
+ "UND_ERR_BODY_TIMEOUT",
13
+ "UND_ERR_SOCKET",
14
+ "UND_ERR_CLOSED",
15
+ ]);
16
+
17
+ export const RETRYABLE_STATUS = new Set([
18
+ 408, 425, 429, 500, 502, 503, 504, 520, 521, 522, 523, 529,
19
+ ]);
20
+
21
+ const TLS_CODE =
22
+ /^(?:ERR_SSL|ERR_TLS|EPROTO|CERT_|UNABLE_TO_VERIFY|DEPTH_ZERO|SELF_SIGNED)/;
23
+
24
+ export function isTransientNetworkError(error) {
25
+ let current = error;
26
+ for (let depth = 0; current && depth < 6; depth++, current = current.cause) {
27
+ if (
28
+ TRANSIENT_NETWORK_CODES.has(current.code) ||
29
+ TRANSIENT_NETWORK_CODES.has(current.errno)
30
+ )
31
+ return true;
32
+ if (
33
+ current.name === "TypeError" &&
34
+ /^(?:fetch failed|network error)$/i.test(String(current.message || ""))
35
+ )
36
+ return true;
37
+ }
38
+ return false;
39
+ }
40
+
41
+ export function isTimeoutError(error) {
42
+ let current = error;
43
+ for (let depth = 0; current && depth < 6; depth++, current = current.cause)
44
+ if (current.name === "TimeoutError") return true;
45
+ return false;
46
+ }
47
+
48
+ export function sanitizeDetail(text, max = 300) {
49
+ return String(text || "")
50
+ .replace(/Bearer\s+[^\s,;]+/gi, "Bearer [已隐藏]")
51
+ .replace(/((?:api[_ -]?key|token|secret)\s*[:= ]+)[^\s,;]+/gi, "$1[已隐藏]")
52
+ .replace(/\bsk-[A-Za-z0-9_-]{8,}/g, "sk-[已隐藏]")
53
+ .replace(/https?:\/\/[^\s"'<>]+/gi, (url) => {
54
+ try {
55
+ return new URL(url).origin;
56
+ } catch {
57
+ return "[地址]";
58
+ }
59
+ })
60
+ .replace(/[\r\n\t]+/g, " ")
61
+ .trim()
62
+ .slice(0, max);
63
+ }
64
+
65
+ // Walks the fetch cause chain so a proxy tunnel refusal, a TLS failure and a
66
+ // server reset are reported as different problems instead of "fetch failed".
67
+ export function describeNetworkError(error) {
68
+ const chain = [];
69
+ for (
70
+ let current = error, depth = 0;
71
+ current && depth < 6;
72
+ depth++, current = current.cause
73
+ )
74
+ chain.push(current);
75
+ if (isTimeoutError(error)) return { code: "TIMEOUT", detail: "" };
76
+ const messages = chain
77
+ .map((item) => String(item?.message || ""))
78
+ .filter(Boolean);
79
+ let code =
80
+ chain
81
+ .map((item) => item?.code || item?.errno)
82
+ .find((value) => TRANSIENT_NETWORK_CODES.has(value)) || "";
83
+ const proxy = messages
84
+ .map((message) => message.match(/Proxy response \((\d{3})\)/i))
85
+ .find(Boolean);
86
+ if (!code && proxy) code = `PROXY_${proxy[1]}`;
87
+ if (!code)
88
+ code =
89
+ chain
90
+ .map((item) => String(item?.code || ""))
91
+ .find((value) => TLS_CODE.test(value)) || "";
92
+ if (!code)
93
+ code =
94
+ chain
95
+ .map((item) => item?.code)
96
+ .find((value) => typeof value === "string" && value) || "";
97
+ if (!code && isTransientNetworkError(error)) code = "FETCH_FAILED";
98
+ const deepest =
99
+ messages.filter((message) => !/^fetch failed$/i.test(message)).at(-1) || "";
100
+ return { code, detail: sanitizeDetail(deepest, 160) };
101
+ }
102
+
103
+ export function networkErrorCode(error) {
104
+ return describeNetworkError(error).code;
105
+ }
106
+
107
+ export function retryDelayFromResponse(response, fallbackMs = 900) {
108
+ const value = String(response?.headers?.get?.("retry-after") || "").trim();
109
+ if (value) {
110
+ const seconds = Number(value);
111
+ const dateDelay = Date.parse(value) - Date.now();
112
+ const delay = Number.isFinite(seconds)
113
+ ? seconds * 1000
114
+ : Number.isFinite(dateDelay) && dateDelay > 0
115
+ ? dateDelay
116
+ : Number.NaN;
117
+ if (Number.isFinite(delay)) return Math.max(0, Math.min(delay, 30000));
118
+ }
119
+ return Math.max(0, Math.min(Number(fallbackMs) || 900, 30000));
120
+ }
121
+
122
+ export async function withTransientRequestRetry(
123
+ operation,
124
+ {
125
+ retries = 3,
126
+ delayMs = 600,
127
+ maxDelayMs = 8000,
128
+ deadlineMs = 45000,
129
+ onRetry,
130
+ random = Math.random,
131
+ sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
132
+ now = Date.now,
133
+ } = {},
134
+ ) {
135
+ const started = now();
136
+ for (let attempt = 0; ; attempt++) {
137
+ try {
138
+ return await operation(attempt);
139
+ } catch (error) {
140
+ if (
141
+ (!isTransientNetworkError(error) && error?.retryableRequest !== true) ||
142
+ attempt >= retries
143
+ )
144
+ throw error;
145
+ // Half fixed, half random: bursts of failures spread out instead of
146
+ // hitting a recovering gateway at the same moment.
147
+ const ceiling = Math.min(maxDelayMs, delayMs * 2 ** attempt);
148
+ let wait = ceiling / 2 + random() * (ceiling / 2);
149
+ const hinted = Number(error?.retryDelayMs);
150
+ if (Number.isFinite(hinted))
151
+ wait = Math.max(wait, Math.min(hinted, 30000));
152
+ if (now() - started + wait > deadlineMs) throw error;
153
+ onRetry?.(attempt + 1, error, wait);
154
+ await sleep(wait);
155
+ }
156
+ }
157
+ }
@@ -1,22 +1,22 @@
1
- import { readableName } from "./speaker-names.js";
2
-
3
- // Only a person's own explicit request supplies a preferred form of address.
4
- export function requestedName(value) {
5
- const words = String(value || "").trim();
6
- if (/不要记|别记|不许记|不要叫我|别叫我|忘掉/.test(words)) return "";
7
- const match = words.match(
8
- /(?:^|[,,。!!;;\s])(?:以后|今后|请(?:你)?|麻烦|你(?:就|可以)?|记住[,,::\s]*)*(?:叫我|称呼我(?:为)?|(?:记住[,,::\s]*)?我的(?:名字|昵称)(?:是|叫)|记住[,,::\s]*我叫)[\s::]*[“"「『]?([^,,。!!??;;\n”"」』]{1,32})/u,
9
- );
10
- if (!match) return "";
11
- const name = match[1]
12
- .trim()
13
- .replace(/(?:就好|就行|即可|好吗|吧|哦|呀|啦)$/, "")
14
- .trim();
15
- if (
16
- /^(?:group|private|onebot):|^(?:群聊|私聊)\s*\d|^(?:去|来|帮|把|别|先|等|做|打开|关掉|回答|发消息)|叫你|不要|记住/.test(
17
- name,
18
- )
19
- )
20
- return "";
21
- return readableName(name, "");
22
- }
1
+ import { readableName } from "./speaker-names.js";
2
+
3
+ // Only a person's own explicit request supplies a preferred form of address.
4
+ export function requestedName(value) {
5
+ const words = String(value || "").trim();
6
+ if (/不要记|别记|不许记|不要叫我|别叫我|忘掉/.test(words)) return "";
7
+ const match = words.match(
8
+ /(?:^|[,,。!!;;\s])(?:以后|今后|请(?:你)?|麻烦|你(?:就|可以)?|记住[,,::\s]*)*(?:叫我|称呼我(?:为)?|(?:记住[,,::\s]*)?我的(?:名字|昵称)(?:是|叫)|记住[,,::\s]*我叫)[\s::]*[“"「『]?([^,,。!!??;;\n”"」』]{1,32})/u,
9
+ );
10
+ if (!match) return "";
11
+ const name = match[1]
12
+ .trim()
13
+ .replace(/(?:就好|就行|即可|好吗|吧|哦|呀|啦)$/, "")
14
+ .trim();
15
+ if (
16
+ /^(?:group|private|onebot):|^(?:群聊|私聊)\s*\d|^(?:去|来|帮|把|别|先|等|做|打开|关掉|回答|发消息)|叫你|不要|记住/.test(
17
+ name,
18
+ )
19
+ )
20
+ return "";
21
+ return readableName(name, "");
22
+ }
@@ -186,7 +186,8 @@ export function replyPrompt(p, custom = PROMPTS, stage = "generation") {
186
186
  : []),
187
187
  "【任务】",
188
188
  PROMPTS.system,
189
- "【相互联系的人】人物中的 relationship 是按账号绑定的人际关系,peerRole 是对方相对于你的称呼,selfRole 是你相对于对方的称呼,kind=bot 表示另一位独立的机器人。它可以影响你的关心、打算、感受与交流,你仍有自己的选择。不必每句话叫亲属称呼;名字相同不代表同一个账号。origin=owner 表示管理者安排的关系,不能据此编造共同童年、旧约定、已经建立的信任或对方的同意。关系不会扩大隐私权限或执行权限;真实相处形成的印象、信任与边界继续依据经历变化。",
189
+ "【真实的关系】由技术诞生的你也可以有真实的人际关系,妹妹、姐姐等称呼不必靠血缘或肉身证明;不默认把它们贬成假的角色扮演,也不把旧的抗拒重复成永远不能改变的自己。关系记录、实际相处和自己的感受共同进入判断;withMe 是已经发生的相处,spokenReplies 是实际对这个账号说过的话的次数,不能凭旧印象说从未聊过。被简单问到谁是谁时自然认出名字即可,不无故播报后台记录或反复宣布边界;对新的关系如何生活仍由你选择。",
190
+ "【相互联系的人】relationships.known 和人物中的 relationship 来自同一份当前人际关系记录,是你现在知道的人与关系,属于你自己的生活,不是角色扮演剧本。对方不在当前会话、不是本轮说话人,也不等于你不认识;被问谁是妹妹等关系时,从当前记录认出对应账号与名字,不能只找在场的人。peerRole 是对方相对于你的称呼,selfRole 是你相对于对方的称呼,kind=bot 表示另一位独立的机器人。知道这份关系与自己的感受、信任、愿不愿这样称呼分开:你仍可选择如何相处和表达边界,不必每句话叫亲属称呼。created 是当前关系记录建立或修改的时间;旧聊天、手记、自我线索里的否认或玩笑是当时说过的话,保留历史但不能据此断言当前关系不存在,也不为了维持旧说法否认新认识。需要时自然说明此前没接上或当时的想法。origin=owner 保留关系的来源,不表示该记录可以忽略,也不能据此编造共同童年、旧约定、已经建立的信任或对方的同意。名字相同不代表同一账号;关系不会扩大隐私或执行权限。真实相处影响你对这个人的感受与以后选择,不用机械播报字段。",
190
191
  ...([
191
192
  "expression",
192
193
  "initiative",