@musnows/scriverse 0.6.8 → 0.6.9
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/dist/ai.js +72 -23
- package/dist/ai.js.map +1 -1
- package/dist/app.js +10 -2
- package/dist/app.js.map +1 -1
- package/dist/database.js +132 -1
- package/dist/database.js.map +1 -1
- package/dist/hybrid-search.js +2 -1
- package/dist/hybrid-search.js.map +1 -1
- package/dist/public/app.js +27 -11
- package/dist/public/display-labels.js +2 -1
- package/dist/public/global-search.d.ts +3 -1
- package/dist/public/global-search.js +22 -0
- package/dist/public/index.html +4 -3
- package/dist/public/styles.css +2 -1
- package/dist/store.js +67 -12
- package/dist/store.js.map +1 -1
- package/dist/user-auth.js +6 -2
- package/dist/user-auth.js.map +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/ai.js
CHANGED
|
@@ -1477,38 +1477,47 @@ export class AiManager {
|
|
|
1477
1477
|
const normalizedQuery = normalizeRelationshipSearchText(query).trim();
|
|
1478
1478
|
if (!normalizedQuery)
|
|
1479
1479
|
return [];
|
|
1480
|
-
await this.ensureRelationshipSearchIndex(workId);
|
|
1481
1480
|
const requestedTypes = options.type ? new Set([options.type]) : new Set(HYBRID_SEARCH_TYPES);
|
|
1481
|
+
if (options.includeAgentHistory === false)
|
|
1482
|
+
requestedTypes.delete("agent-history");
|
|
1483
|
+
if (requestedTypes.size === 0)
|
|
1484
|
+
return [];
|
|
1485
|
+
const hasIndexedSourceTypes = [...requestedTypes].some((type) => type !== "chapter" && type !== "agent-history");
|
|
1486
|
+
if (requestedTypes.has("chapter") || hasIndexedSourceTypes)
|
|
1487
|
+
await this.ensureRelationshipSearchIndex(workId);
|
|
1482
1488
|
const resultLimit = Math.min(100, Math.max(1, Math.trunc(options.limit ?? 50)));
|
|
1483
1489
|
const channelLimit = Math.min(200, Math.max(50, resultLimit * 4));
|
|
1484
1490
|
const accepts = (type) => requestedTypes.has(type);
|
|
1485
1491
|
const metadataDetails = new Map();
|
|
1486
|
-
const metadataCandidates =
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1492
|
+
const metadataCandidates = [...requestedTypes].some((type) => type !== "agent-history")
|
|
1493
|
+
? this.store.search(workId, normalizedQuery).flatMap((item) => {
|
|
1494
|
+
const type = String(item.type);
|
|
1495
|
+
const itemId = String(item.id ?? "");
|
|
1496
|
+
if (!itemId || !accepts(type))
|
|
1497
|
+
return [];
|
|
1498
|
+
const key = `${type}:${itemId}`;
|
|
1499
|
+
const { type: _type, id: _id, title: _title, snippet: _snippet, ...details } = item;
|
|
1500
|
+
metadataDetails.set(key, { ...(metadataDetails.get(key) ?? {}), ...details });
|
|
1501
|
+
return [{
|
|
1502
|
+
key,
|
|
1503
|
+
type,
|
|
1504
|
+
id: itemId,
|
|
1505
|
+
title: String(item.title ?? "未命名资料"),
|
|
1506
|
+
subtitle: typeof item.category === "string" ? item.category : undefined,
|
|
1507
|
+
snippet: buildHybridSearchSnippet(String(item.snippet ?? ""), normalizedQuery),
|
|
1508
|
+
sectionId: typeof item.sectionId === "string" ? item.sectionId : undefined,
|
|
1509
|
+
matchKind: "metadata"
|
|
1510
|
+
}];
|
|
1511
|
+
}).slice(0, channelLimit)
|
|
1512
|
+
: [];
|
|
1505
1513
|
const exactCandidates = [
|
|
1506
1514
|
...(requestedTypes.has("chapter") ? this.hybridChapterMatches(workId, normalizedQuery, "exact", channelLimit) : []),
|
|
1507
|
-
...this.hybridIndexedSourceMatches(workId, normalizedQuery, "exact", requestedTypes, channelLimit)
|
|
1515
|
+
...(hasIndexedSourceTypes ? this.hybridIndexedSourceMatches(workId, normalizedQuery, "exact", requestedTypes, channelLimit) : []),
|
|
1516
|
+
...(requestedTypes.has("agent-history") ? this.hybridAgentHistoryMatches(workId, normalizedQuery, channelLimit) : [])
|
|
1508
1517
|
];
|
|
1509
1518
|
const phoneticCandidates = [
|
|
1510
1519
|
...(requestedTypes.has("chapter") ? this.hybridChapterMatches(workId, normalizedQuery, "phonetic", channelLimit) : []),
|
|
1511
|
-
...this.hybridIndexedSourceMatches(workId, normalizedQuery, "phonetic", requestedTypes, channelLimit)
|
|
1520
|
+
...(hasIndexedSourceTypes ? this.hybridIndexedSourceMatches(workId, normalizedQuery, "phonetic", requestedTypes, channelLimit) : [])
|
|
1512
1521
|
];
|
|
1513
1522
|
return fuseHybridSearchChannels([
|
|
1514
1523
|
{ weight: 1.4, candidates: metadataCandidates },
|
|
@@ -1519,6 +1528,44 @@ export class AiManager {
|
|
|
1519
1528
|
...item
|
|
1520
1529
|
}));
|
|
1521
1530
|
}
|
|
1531
|
+
hybridAgentHistoryMatches(workId, query, limit) {
|
|
1532
|
+
const columns = `SELECT history.source_type, history.source_id, history.conversation_id, history.message_id,
|
|
1533
|
+
history.role, history.content, conversation.title AS conversation_title
|
|
1534
|
+
FROM ai_history_search history
|
|
1535
|
+
JOIN ai_conversations conversation ON conversation.id = history.conversation_id`;
|
|
1536
|
+
const rows = [...query].length < 3
|
|
1537
|
+
? this.store.db.all(`${columns}
|
|
1538
|
+
JOIN ai_history_search_short_terms term ON term.search_id = history.id
|
|
1539
|
+
WHERE history.work_id = ? AND term.term = ?
|
|
1540
|
+
ORDER BY history.created_at DESC, history.id DESC
|
|
1541
|
+
LIMIT ?`, workId, query, limit)
|
|
1542
|
+
: this.store.db.all(`${columns}
|
|
1543
|
+
JOIN ai_history_search_fts fts ON fts.rowid = history.id
|
|
1544
|
+
WHERE history.work_id = ? AND ai_history_search_fts MATCH ?
|
|
1545
|
+
ORDER BY bm25(ai_history_search_fts), history.created_at DESC, history.id DESC
|
|
1546
|
+
LIMIT ?`, workId, `"${query.replaceAll('"', '""')}"`, limit);
|
|
1547
|
+
return rows.map((row) => {
|
|
1548
|
+
const sourceType = String(row.source_type ?? "");
|
|
1549
|
+
const sourceId = String(row.source_id ?? "");
|
|
1550
|
+
const conversationId = String(row.conversation_id ?? "");
|
|
1551
|
+
const messageId = sourceType === "message" ? String(row.message_id ?? "") : "";
|
|
1552
|
+
const title = String(row.conversation_title ?? "新对话");
|
|
1553
|
+
const isMessage = sourceType === "message";
|
|
1554
|
+
const role = String(row.role ?? "");
|
|
1555
|
+
const content = String(row.content ?? "");
|
|
1556
|
+
return {
|
|
1557
|
+
key: `agent-history:${sourceType}:${sourceId}`,
|
|
1558
|
+
type: "agent-history",
|
|
1559
|
+
id: sourceId,
|
|
1560
|
+
title,
|
|
1561
|
+
subtitle: isMessage ? (role === "assistant" ? "Agent 回复" : "作者指令") : "对话标题与摘要",
|
|
1562
|
+
snippet: buildHybridSearchSnippet(isMessage ? content : `对话标题:${title}${content ? ` · ${content}` : ""}`, query),
|
|
1563
|
+
conversationId,
|
|
1564
|
+
...(messageId ? { messageId } : {}),
|
|
1565
|
+
matchKind: "exact"
|
|
1566
|
+
};
|
|
1567
|
+
}).filter((candidate) => candidate.id && candidate.conversationId);
|
|
1568
|
+
}
|
|
1522
1569
|
hybridChapterMatches(workId, query, matchKind, limit) {
|
|
1523
1570
|
let rows;
|
|
1524
1571
|
if (matchKind === "phonetic") {
|
|
@@ -3650,7 +3697,7 @@ export class AiManager {
|
|
|
3650
3697
|
const character = this.store.getCharacter(roleplayCharacterId);
|
|
3651
3698
|
if (String(character.workId) !== workId)
|
|
3652
3699
|
throw new Error("Roleplay character belongs to a different work");
|
|
3653
|
-
const characterList = this.store.listCharacters(workId
|
|
3700
|
+
const characterList = this.store.listCharacters(workId);
|
|
3654
3701
|
const characters = new Map(characterList.map((item) => [String(item.id), item]));
|
|
3655
3702
|
const characterSearchText = (item) => {
|
|
3656
3703
|
if (!item)
|
|
@@ -6766,6 +6813,8 @@ export class AiManager {
|
|
|
6766
6813
|
const item = this.store.getCharacter(sourceId);
|
|
6767
6814
|
if (String(item.workId) !== workId)
|
|
6768
6815
|
return null;
|
|
6816
|
+
if (item.mergedIntoCharacterId)
|
|
6817
|
+
return null;
|
|
6769
6818
|
return source(`人物档案:${String(item.name)}`, {
|
|
6770
6819
|
name: item.name, isDead: item.isDead, aliases: item.aliases, code: item.code, species: item.species, race: item.race,
|
|
6771
6820
|
organizations: item.organizations, attributes: item.attributes, profile: item.profile,
|