koishi-plugin-chatluna-affinity 0.0.3 → 0.0.4

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.
@@ -46,6 +46,7 @@ function extendModel(ctx) {
46
46
  platform: 'string',
47
47
  selfId: { type: 'string', nullable: true },
48
48
  userId: 'string',
49
+ nickname: { type: 'string', nullable: true },
49
50
  affinity: 'integer',
50
51
  affinityInited: 'boolean',
51
52
  relation: { type: 'string', nullable: true },
@@ -142,7 +143,15 @@ function createAffinityStore(ctx, config, log) {
142
143
  const existing = await ctx.database.get(MODEL_NAME, { id });
143
144
  const current = existing?.[0];
144
145
  const now = new Date();
145
- const relationText = relation !== undefined && relation !== null ? String(relation).trim() : undefined;
146
+ const manual = findManualRelationship(identity.platform, identity.userId);
147
+ let relationText;
148
+ if (relation === undefined || relation === null) {
149
+ relationText = manual?.relation ?? current?.relation ?? '';
150
+ } else {
151
+ const trimmed = String(relation).trim();
152
+ relationText = trimmed ? trimmed : manual?.relation ?? current?.relation ?? '';
153
+ }
154
+ const nickname = seed?.nickname || seed?.authorNickname || seed?.session?.nickname || seed?.session?.author?.nickname || seed?.session?.author?.name || '';
146
155
 
147
156
  const payload = {
148
157
  id,
@@ -151,11 +160,16 @@ function createAffinityStore(ctx, config, log) {
151
160
  userId: identity.userId,
152
161
  affinity: typeof value === 'number' ? value : current?.affinity ?? defaultInitialValue(),
153
162
  affinityInited: inited ?? current?.affinityInited ?? false,
154
- relation: relationText !== undefined ? relationText : current?.relation ?? '',
163
+ relation: relationText,
164
+ nickname: nickname || current?.nickname || manual?.relationNickname || '',
155
165
  updatedAt: now,
156
166
  relationUpdatedAt: relationText !== undefined ? now : current?.relationUpdatedAt ?? now
157
167
  };
158
168
 
169
+ if (nickname && (!current || nickname !== current.nickname)) {
170
+ payload.nickname = nickname;
171
+ }
172
+
159
173
  await ctx.database.upsert(MODEL_NAME, [payload]);
160
174
  return payload;
161
175
  };
@@ -271,14 +285,17 @@ function createAffinityStore(ctx, config, log) {
271
285
  : manual?.initialAffinity ?? rollInitial();
272
286
  const initial = clampFn(base, config.min, config.max);
273
287
  const level = resolveLevelByAffinity(initial);
274
- await save({ platform, userId, selfId: session?.selfId }, initial, true, level?.relation ?? '');
288
+ const desiredRelation = manual?.relation ?? level?.relation ?? '';
289
+ await save({ platform, userId, selfId: session?.selfId, session }, initial, true, desiredRelation);
275
290
  return { affinity: initial, isNew: true };
276
291
  }
277
292
 
278
293
  const normalized = clampFn(record.affinity ?? defaultInitialValue(), config.min, config.max);
279
294
  if (normalized !== record.affinity) {
280
295
  const level = resolveLevelByAffinity(normalized);
281
- await save({ platform, userId, selfId: session?.selfId }, normalized, record.affinityInited, level?.relation ?? record.relation ?? '');
296
+ const manual = findManualRelationship(platform, userId);
297
+ const desiredRelation = manual?.relation ?? level?.relation ?? record.relation ?? '';
298
+ await save({ platform, userId, selfId: session?.selfId, session }, normalized, record.affinityInited, desiredRelation);
282
299
  }
283
300
  return { affinity: normalized, isNew: false };
284
301
  };
package/lib/middleware.js CHANGED
@@ -128,6 +128,7 @@ function createAnalysisMiddleware(ctx, config, { store, history, cache, getModel
128
128
  const jsonCandidate = typeof text === 'string' ? text : String(text ?? '');
129
129
  const match = jsonCandidate.match(/\{[\s\S]*\}/);
130
130
  let delta = 0;
131
+ const nickname = session?.author?.nickname || session?.author?.name || session?.user?.nickname || session?.user?.name || session?.username || session?.nickname || '';
131
132
  if (match) {
132
133
  try {
133
134
  const parsed = JSON.parse(match[0]);
@@ -137,7 +138,7 @@ function createAnalysisMiddleware(ctx, config, { store, history, cache, getModel
137
138
  if (action === 'increase' && delta <= 0) delta = Math.max(1, Math.abs(delta));
138
139
  if (action === 'decrease' && delta >= 0) delta = -Math.max(1, Math.abs(delta));
139
140
  if (action === 'hold') delta = 0;
140
- if (debugEnabled) log('info', '模型返回', { raw: parsed, parsedDelta: delta, action, userId: session.userId, platform: session.platform });
141
+ if (debugEnabled) log('info', '模型返回', { raw: parsed, parsedDelta: delta, action, userId: session.userId, platform: session.platform, nickname });
141
142
  } catch (error) {
142
143
  log('warn', '解析模型响应失败', { text: jsonCandidate, error });
143
144
  }
@@ -149,11 +150,12 @@ function createAnalysisMiddleware(ctx, config, { store, history, cache, getModel
149
150
  ? Math.min(delta, positiveLimit)
150
151
  : Math.max(delta, -negativeLimit);
151
152
  const nextAffinity = clampValue(oldAffinity + limitedDelta, config.min, config.max);
153
+
152
154
  if (nextAffinity !== oldAffinity) {
153
155
  const level = store.resolveLevelByAffinity(nextAffinity);
154
- await store.save({ platform: session.platform, userId: session.userId, selfId: session?.selfId }, nextAffinity, true, level?.relation ?? '');
156
+ await store.save({ platform: session.platform, userId: session.userId, selfId: session?.selfId, session }, nextAffinity, true, level?.relation ?? '');
155
157
  cache.set(session.platform, session.userId, nextAffinity);
156
- log('info', '好感度已更新', { oldAffinity, delta: limitedDelta, nextAffinity, userId: session.userId, platform: session.platform });
158
+ log('info', '好感度已更新', { oldAffinity, delta: limitedDelta, nextAffinity, userId: session.userId, platform: session.platform, nickname });
157
159
  } else if (config.useLastAffinity) {
158
160
  cache.set(session.platform, session.userId, oldAffinity);
159
161
  }
package/lib/schema.js CHANGED
@@ -36,7 +36,7 @@ const AffinitySchema = Schema.object({
36
36
  analysisPrompt: Schema.string()
37
37
  .role('textarea')
38
38
  .default(
39
- '你是好感度管家,需要根据上下文评估是否调整好感度。\n- 关注最近若干条群聊消息,判断整体语气与语境;\n- 当用户友善、感谢、积极互动时,适度增加;\n- 当用户正常交流且无明显倾向时,保持不变;\n- 当用户冒犯、敷衍、重复打扰时,减少;\n- 增加幅度不超过 {{maxIncreasePerMessage}} ,减少幅度不超过 {{maxDecreasePerMessage}} ,并保持在提供的范围内;\n- 使用 action 表示行为:increase 增加、decrease 减少、hold 保持。\n\n角色设定:{{personaPrompt}}\n\n当前好感度:{{currentAffinity}} (范围 {{minAffinity}} ~ {{maxAffinity}})\n最近 {{historyCount}} 条消息(旧 -> 新):\n{{historyText}}\n\n本次用户消息:\n{{userMessage}}\n\n请仅输出 JSON:{"delta": 整数, "action": "increase|decrease|hold", "reason": "简短中文原因"}。'
39
+ '你是好感度管家,需要根据上下文评估是否调整好感度。\n- 仔细阅读最近若干条群聊消息,聚焦语气、内容、语境与互动意图;\n- 只有当用户展现出明确、具体的善意或贡献时(如感谢、称赞、帮助解决问题、分享价值信息、表达真诚关心),才考虑增加;\n- 若用户只是礼貌问候、例行回应、轻度调侃或重复旧话题,可保持不变;\n- 对于冒犯、敷衍、抄袭、频繁打扰、传播负面情绪或破坏氛围的行为,应减少;\n- 增加幅度不超过 {{maxIncreasePerMessage}} ,减少幅度不超过 {{maxDecreasePerMessage}} ,并保持在提供的范围内;\n- 在总结理由时,指明触发增减的具体言辞或行为;\n- 使用 action 表示行为:increase 增加、decrease 减少、hold 保持。\n\n角色设定:{{personaPrompt}}\n\n当前好感度:{{currentAffinity}} (范围 {{minAffinity}} ~ {{maxAffinity}})\n最近 {{historyCount}} 条消息(旧 -> 新):\n{{historyText}}\n\n本次用户消息:\n{{userMessage}}\n\n请仅输出 JSON:{"delta": 整数, "action": "increase|decrease|hold", "reason": "简短中文原因"}。'
40
40
  )
41
41
  .description('好感度分析主提示词'),
42
42
  personaPrompt: Schema.string()
package/lib/tools.js CHANGED
@@ -20,7 +20,7 @@ function createAffinityTool(options) {
20
20
  if (!platform || !userId) return 'Missing platform or user ID. Unable to adjust affinity.';
21
21
  const value = options.clamp(input.affinity);
22
22
  const level = options.resolveLevelByAffinity(value);
23
- await options.save({ platform, userId, selfId: session?.selfId }, value, true, level?.relation ?? options.defaultRelation);
23
+ await options.save({ platform, userId, selfId: session?.selfId, session }, value, true, level?.relation ?? options.defaultRelation);
24
24
  options.cache.set(platform, userId, value);
25
25
  if (level?.relation) {
26
26
  return `Affinity for ${platform}/${userId} set to ${value}. Relationship updated to ${level.relation}.`;
@@ -58,7 +58,7 @@ function createRelationshipTool(options) {
58
58
  }
59
59
  const baseValue = level ? level.min : options.defaultInitial();
60
60
  const base = options.clamp(baseValue);
61
- await options.save({ platform, userId, selfId: session?.selfId }, base, true, relationName);
61
+ await options.save({ platform, userId, selfId: session?.selfId, session }, base, true, relationName);
62
62
  options.cache.set(platform, userId, base);
63
63
  options.updateRelationshipConfig(userId, relationName, base);
64
64
  if (level) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-chatluna-affinity",
3
- "description": "为 ChatLuna 提供{好感度}与{关系}变量并提供对应的工具调用和低好感自动拉黑功能。",
4
- "version": "0.0.3",
3
+ "description": "为 ChatLuna 提供{好感度}与{关系}变量并提供对应的工具调用和低好感自动拉黑功能。仅测试过伪装插件。",
4
+ "version": "0.0.4",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [