dsh-fish-soul 0.14.0 → 0.14.1
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/README.md +1 -1
- package/lib/db.js +11 -0
- package/lib/index.js +16 -9
- package/lib/llm.js +3 -1
- package/package.json +3 -3
package/README.md
CHANGED
package/lib/db.js
CHANGED
|
@@ -400,6 +400,17 @@ export function randomCanonicalId() {
|
|
|
400
400
|
return `p_${Math.floor(Math.random() * 0xffffffff).toString(16).padStart(8, '0')}`;
|
|
401
401
|
}
|
|
402
402
|
|
|
403
|
+
/** 桌面端 / 主人兜底:拿到 canonical_id='master' 的 person 行,没有就建一个。 */
|
|
404
|
+
export function ensureMasterPerson(db, nowMs) {
|
|
405
|
+
const row = db.prepare("SELECT * FROM person WHERE canonical_id = 'master'").get();
|
|
406
|
+
if (row) return row;
|
|
407
|
+
db.prepare(`
|
|
408
|
+
INSERT INTO person (canonical_id, display_name, relation_stage, interaction_count, first_seen_at, last_seen_at)
|
|
409
|
+
VALUES ('master', '主人', 'close', 0, ?, ?)
|
|
410
|
+
`).run(nowMs, nowMs);
|
|
411
|
+
return db.prepare("SELECT * FROM person WHERE canonical_id = 'master'").get();
|
|
412
|
+
}
|
|
413
|
+
|
|
403
414
|
/**
|
|
404
415
|
* person 原子自动注册(审查 #05):按 qq_uin Upsert。
|
|
405
416
|
* 主人 QQ 固定映射 canonical_id='master'、relation_stage='close'。
|
package/lib/index.js
CHANGED
|
@@ -14,7 +14,7 @@ import { readFileSync, writeFileSync, existsSync, renameSync } from 'node:fs';
|
|
|
14
14
|
import { loadHostDeps } from './hostdeps.mjs';
|
|
15
15
|
import {
|
|
16
16
|
openDatabase, configPath, fishSoulDir, resolveOrCreatePerson, resolveOrCreateBiliPerson, resolveOrCreatePlatformPerson,
|
|
17
|
-
findPersonByQq, findPersonByBili, findPersonByDouyin, readVecMeta, getKv, setKv, getProfile
|
|
17
|
+
findPersonByQq, findPersonByBili, findPersonByDouyin, readVecMeta, getKv, setKv, getProfile, ensureMasterPerson
|
|
18
18
|
} from './db.js';
|
|
19
19
|
import { BackupService, applyPendingRestore } from './backup.js';
|
|
20
20
|
import { HistoryImporter } from './history-import.js';
|
|
@@ -450,22 +450,28 @@ async function startup(ctx, config, { log, gate }) {
|
|
|
450
450
|
sp = list.find((x) => x.displayName === want || x.userId === want) ??
|
|
451
451
|
list.find((x) => x.displayName.includes(want) || want.includes(x.displayName)) ?? sp;
|
|
452
452
|
}
|
|
453
|
+
const ch = session?.channel ?? 'dsh';
|
|
454
|
+
let ownerId = sp?.ownerId ?? UNKNOWN_OWNER;
|
|
455
|
+
let person = sp?.person ?? null;
|
|
456
|
+
// #57:桌面端(dsh channel)认作主人——DSH 桌面端是主人自己的环境,没有"别人"。
|
|
457
|
+
if (ch === 'dsh' && ownerId === UNKNOWN_OWNER) {
|
|
458
|
+
person = ensureMasterPerson(db, clock.now());
|
|
459
|
+
ownerId = `user:${person.canonical_id}`;
|
|
460
|
+
}
|
|
453
461
|
return {
|
|
454
|
-
ownerId
|
|
455
|
-
person
|
|
462
|
+
ownerId,
|
|
463
|
+
person,
|
|
456
464
|
query: sp?.query ?? '',
|
|
457
|
-
displayName: sp?.displayName ?? '对方',
|
|
458
|
-
channel:
|
|
465
|
+
displayName: person?.display_name ?? sp?.displayName ?? '对方',
|
|
466
|
+
channel: ch,
|
|
459
467
|
channelId: session?.channelId ?? ''
|
|
460
468
|
};
|
|
461
469
|
}
|
|
462
470
|
|
|
463
|
-
const UNKNOWN_VIEW = { ownerId: UNKNOWN_OWNER, person: null, displayName: '对方', channel: 'dsh', channelId: '' };
|
|
464
|
-
|
|
465
471
|
/** 工具调用:按调用所在会话(toolCtx.agent.id)认人;认不出就是 unknown(不读写任何人的记忆)。 */
|
|
466
472
|
function sessionForTool(toolCtx, speakerName) {
|
|
467
473
|
const session = sessionFor(toolCtx?.agent?.id ?? toolCtx?.sessionId);
|
|
468
|
-
return session === undefined ?
|
|
474
|
+
return session === undefined ? speakerView(undefined, speakerName) : speakerView(session, speakerName);
|
|
469
475
|
}
|
|
470
476
|
|
|
471
477
|
const retrievalCfg = () => ({
|
|
@@ -696,10 +702,11 @@ async function startup(ctx, config, { log, gate }) {
|
|
|
696
702
|
});
|
|
697
703
|
if (person !== null) life.noteInteraction(ownerOf(person));
|
|
698
704
|
const groupId = source.groupId ?? source.group_id ?? null;
|
|
705
|
+
// #56:桌面端(person=null)也把消息文本传进去——世界书扫描要用,身份仍是 unknown。
|
|
699
706
|
beginTurn(agentId, {
|
|
700
707
|
channel: person === null ? 'dsh' : (groupId != null ? 'qq-group' : 'qq-private'),
|
|
701
708
|
channelId: person === null ? '' : (groupId != null ? `group:${groupId}` : `private:${qqUin}`),
|
|
702
|
-
speakers:
|
|
709
|
+
speakers: [{ person, userId: qqUin, displayName: person?.display_name ?? '对方', text: messageText(message) }],
|
|
703
710
|
workspacePath: ''
|
|
704
711
|
});
|
|
705
712
|
// #41:别的插件把自己的 QQ 消息转进它建的会话 —— 那个会话不走我们的 create/resume,人格卡没挂上。
|
package/lib/llm.js
CHANGED
|
@@ -142,7 +142,9 @@ export class LlmRouter {
|
|
|
142
142
|
return [{ type: 'text', text: prompt }];
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
-
|
|
145
|
+
// #58:默认 600 对推理模型太小——光思考就 1000+ token,第一次必然白卷还白烧思考费。
|
|
146
|
+
// 提到 1500 让大多数推理模型的第一轮能容下思考;maxTokens 是上限不是必花,普通模型不受影响。
|
|
147
|
+
async call(prompt, { signal, maxTokens = 1500, feature = 'other', thinkFallback = false, images = [], _target, _tried } = {}) {
|
|
146
148
|
const llm = this.llm();
|
|
147
149
|
if (llm === null) return null;
|
|
148
150
|
const f = FEATURE_IDS.has(feature) ? feature : 'other';
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-fish-soul",
|
|
3
|
-
"version": "0.14.
|
|
4
|
-
"description": "鱼 · 人格、按人记忆(可纠正、有印象、能导入旧聊天记录)、日程自走与主动开口,直连 SnowLuma 收发 QQ(群里会自己插话),B站 / 抖音小号私信与自己刷视频;按功能选模型并统计用量花费,能听会说 QQ 语音、收藏表情包、学群里的梗,可选上网查;心情影响说话、去 AI 味、每个群的设定、按聊天选模型、每晚写日记(DSH 插件,单角色 feiyu ,v0.14.
|
|
3
|
+
"version": "0.14.1",
|
|
4
|
+
"description": "鱼 · 人格、按人记忆(可纠正、有印象、能导入旧聊天记录)、日程自走与主动开口,直连 SnowLuma 收发 QQ(群里会自己插话),B站 / 抖音小号私信与自己刷视频;按功能选模型并统计用量花费,能听会说 QQ 语音、收藏表情包、学群里的梗,可选上网查;心情影响说话、去 AI 味、每个群的设定、按聊天选模型、每晚写日记(DSH 插件,单角色 feiyu ,v0.14.1)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
7
7
|
"files": [
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
}
|
|
63
63
|
},
|
|
64
64
|
"scripts": {
|
|
65
|
-
"test": "node test/smoke.mjs && node test/douyin-browser.mjs && node test/startup-gate.mjs && node test/outbox.mjs && node test/import-coverage.mjs && node test/update-check.mjs && node test/issue-fixes.mjs && node test/import-resume.mjs && node test/maibot-extras.mjs && node test/worldinfo.mjs && node test/memory-bulk.mjs && node test/backup-restore.mjs && node test/douyin-group.mjs && node test/review-fixes.mjs && node test/at-reads-video.mjs && node test/search-source.mjs && node test/followups.mjs && node test/detail-config.mjs && node test/qq-send-any-image.mjs && node test/qq-read-attachment.mjs && node test/qq-batch-window.mjs && node test/comment-video.mjs && node test/frames.mjs && node test/face-name.mjs && node test/comment-reply.mjs && node test/chat-comment.mjs && node test/at-target.mjs && node test/client-lint.mjs",
|
|
65
|
+
"test": "node test/smoke.mjs && node test/douyin-browser.mjs && node test/startup-gate.mjs && node test/outbox.mjs && node test/import-coverage.mjs && node test/update-check.mjs && node test/issue-fixes.mjs && node test/import-resume.mjs && node test/maibot-extras.mjs && node test/worldinfo.mjs && node test/memory-bulk.mjs && node test/backup-restore.mjs && node test/douyin-group.mjs && node test/review-fixes.mjs && node test/at-reads-video.mjs && node test/search-source.mjs && node test/followups.mjs && node test/detail-config.mjs && node test/qq-send-any-image.mjs && node test/qq-read-attachment.mjs && node test/qq-batch-window.mjs && node test/comment-video.mjs && node test/frames.mjs && node test/face-name.mjs && node test/comment-reply.mjs && node test/chat-comment.mjs && node test/at-target.mjs && node test/client-lint.mjs && node test/dsh-desktop.mjs",
|
|
66
66
|
"eval": "node test/eval/persona-eval.mjs"
|
|
67
67
|
}
|
|
68
68
|
}
|