@musnows/scriverse 0.8.1 → 0.8.2
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-conversation-export.js +3 -1
- package/dist/ai-conversation-export.js.map +1 -1
- package/dist/ai.js +50 -4
- package/dist/ai.js.map +1 -1
- package/dist/app.js +9 -4
- package/dist/app.js.map +1 -1
- package/dist/database.js +26 -2
- package/dist/database.js.map +1 -1
- package/dist/public/app.js +165 -19
- package/dist/public/index.html +10 -5
- package/dist/public/relationship-graph.js +11 -3
- package/dist/public/styles.css +14 -4
- package/dist/store.js +40 -6
- package/dist/store.js.map +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/store.js
CHANGED
|
@@ -5561,6 +5561,7 @@ export class Store {
|
|
|
5561
5561
|
return {
|
|
5562
5562
|
workId,
|
|
5563
5563
|
roleplayCharacterId: optionalString(conversation, "roleplay_character_id"),
|
|
5564
|
+
roleplayUserCharacterId: optionalString(conversation, "roleplay_user_character_id"),
|
|
5564
5565
|
summary: requiredString(conversation, "compacted_summary"),
|
|
5565
5566
|
compactedMessageCount,
|
|
5566
5567
|
totalMessageCount,
|
|
@@ -5704,14 +5705,27 @@ export class Store {
|
|
|
5704
5705
|
this.audit(workId, "ai-conversation.deleted", "ai-conversation", conversationId, {});
|
|
5705
5706
|
});
|
|
5706
5707
|
}
|
|
5707
|
-
setAiConversationRoleplayCharacter(conversationId, characterId) {
|
|
5708
|
+
setAiConversationRoleplayCharacter(conversationId, characterId, userCharacterId) {
|
|
5708
5709
|
const conversation = this.db.get("SELECT * FROM ai_conversations WHERE id = ?", conversationId);
|
|
5709
5710
|
if (!conversation)
|
|
5710
5711
|
throw notFound("AI 对话");
|
|
5711
5712
|
const workId = requiredString(conversation, "work_id");
|
|
5712
5713
|
const previousCharacterId = optionalString(conversation, "roleplay_character_id");
|
|
5713
|
-
|
|
5714
|
+
const previousUserCharacterId = optionalString(conversation, "roleplay_user_character_id");
|
|
5715
|
+
if (!characterId && userCharacterId) {
|
|
5716
|
+
throw new AppError(400, "ROLEPLAY_USER_CHARACTER_REQUIRES_AI", "请先选择 AI 扮演的角色");
|
|
5717
|
+
}
|
|
5718
|
+
const nextUserCharacterId = !characterId
|
|
5719
|
+
? null
|
|
5720
|
+
: userCharacterId === undefined
|
|
5721
|
+
? previousCharacterId === characterId ? previousUserCharacterId : null
|
|
5722
|
+
: userCharacterId;
|
|
5723
|
+
if (characterId && characterId === nextUserCharacterId) {
|
|
5724
|
+
throw new AppError(400, "ROLEPLAY_CHARACTER_SAME_AS_USER", "AI 扮演角色与用户扮演角色不能相同");
|
|
5725
|
+
}
|
|
5726
|
+
if (previousCharacterId === characterId && previousUserCharacterId === nextUserCharacterId) {
|
|
5714
5727
|
return this.getAiConversationSummary(conversationId);
|
|
5728
|
+
}
|
|
5715
5729
|
const messageCount = Number(this.db.get("SELECT COUNT(*) AS count FROM ai_conversation_messages WHERE conversation_id = ?", conversationId)?.count ?? 0);
|
|
5716
5730
|
if (messageCount > 0) {
|
|
5717
5731
|
throw new AppError(409, previousCharacterId ? "ROLEPLAY_CHARACTER_LOCKED" : "ROLEPLAY_CONVERSATION_STARTED", previousCharacterId ? "角色扮演对话开始后不能退出模式或更换角色卡" : "当前对话已经开始,不能中途切换为角色扮演");
|
|
@@ -5725,11 +5739,22 @@ export class Store {
|
|
|
5725
5739
|
throw new AppError(409, "ROLEPLAY_CHARACTER_MERGED", "已合并角色不能用于角色扮演");
|
|
5726
5740
|
}
|
|
5727
5741
|
}
|
|
5742
|
+
if (nextUserCharacterId) {
|
|
5743
|
+
const userCharacter = this.getCharacter(nextUserCharacterId);
|
|
5744
|
+
if (String(userCharacter.workId) !== workId) {
|
|
5745
|
+
throw new AppError(400, "ROLEPLAY_USER_CHARACTER_WORK_MISMATCH", "用户扮演的角色不属于当前作品");
|
|
5746
|
+
}
|
|
5747
|
+
if (userCharacter.mergedIntoCharacterId) {
|
|
5748
|
+
throw new AppError(409, "ROLEPLAY_USER_CHARACTER_MERGED", "已合并角色不能用于关系扮演");
|
|
5749
|
+
}
|
|
5750
|
+
}
|
|
5728
5751
|
this.db.transaction(() => {
|
|
5729
|
-
this.db.run("UPDATE ai_conversations SET roleplay_character_id = ?, task_type = CASE WHEN ? IS NOT NULL THEN 'roleplay' ELSE task_type END, updated_at = ? WHERE id = ?", characterId, characterId, now(), conversationId);
|
|
5752
|
+
this.db.run("UPDATE ai_conversations SET roleplay_character_id = ?, roleplay_user_character_id = ?, task_type = CASE WHEN ? IS NOT NULL THEN 'roleplay' ELSE task_type END, updated_at = ? WHERE id = ?", characterId, nextUserCharacterId, characterId, now(), conversationId);
|
|
5730
5753
|
this.audit(workId, "ai-conversation.roleplay-updated", "ai-conversation", conversationId, {
|
|
5731
5754
|
previousCharacterId,
|
|
5732
|
-
characterId
|
|
5755
|
+
characterId,
|
|
5756
|
+
previousUserCharacterId,
|
|
5757
|
+
userCharacterId: nextUserCharacterId
|
|
5733
5758
|
});
|
|
5734
5759
|
});
|
|
5735
5760
|
return this.getAiConversationSummary(conversationId);
|
|
@@ -5748,7 +5773,7 @@ export class Store {
|
|
|
5748
5773
|
throw new AppError(409, "AI_CONVERSATION_TASK_LOCKED", "对话开始后不能切换任务类型");
|
|
5749
5774
|
}
|
|
5750
5775
|
this.db.transaction(() => {
|
|
5751
|
-
this.db.run("UPDATE ai_conversations SET task_type = ?, roleplay_character_id = CASE WHEN ? = 'roleplay' THEN roleplay_character_id ELSE NULL END, updated_at = ? WHERE id = ?", taskType, taskType, now(), conversationId);
|
|
5776
|
+
this.db.run("UPDATE ai_conversations SET task_type = ?, roleplay_character_id = CASE WHEN ? = 'roleplay' THEN roleplay_character_id ELSE NULL END, roleplay_user_character_id = CASE WHEN ? = 'roleplay' THEN roleplay_user_character_id ELSE NULL END, updated_at = ? WHERE id = ?", taskType, taskType, taskType, now(), conversationId);
|
|
5752
5777
|
this.audit(workId, "ai-conversation.task-type-updated", "ai-conversation", conversationId, {
|
|
5753
5778
|
previousTaskType,
|
|
5754
5779
|
taskType
|
|
@@ -6041,7 +6066,7 @@ export class Store {
|
|
|
6041
6066
|
?? JSON.stringify(EMPTY_AI_INJECTED_ENTITIES);
|
|
6042
6067
|
const systemClockText = optionalString(conversation, "system_clock_text") ?? "";
|
|
6043
6068
|
this.db.transaction(() => {
|
|
6044
|
-
this.db.run("INSERT INTO ai_conversations (id, work_id, roleplay_character_id, task_type, context_scope_json, title, compacted_summary, compacted_message_count, agent_tools_json, injected_entities_json, system_clock_text, created_at, updated_at, created_by_user_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", forkId, workId, optionalString(conversation, "roleplay_character_id"), optionalString(conversation, "task_type"), optionalString(conversation, "context_scope_json"), title.slice(0, 200), forkSummary, forkCompactedCount, conversation.agent_tools_json == null
|
|
6069
|
+
this.db.run("INSERT INTO ai_conversations (id, work_id, roleplay_character_id, roleplay_user_character_id, task_type, context_scope_json, title, compacted_summary, compacted_message_count, agent_tools_json, injected_entities_json, system_clock_text, created_at, updated_at, created_by_user_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", forkId, workId, optionalString(conversation, "roleplay_character_id"), optionalString(conversation, "roleplay_user_character_id"), optionalString(conversation, "task_type"), optionalString(conversation, "context_scope_json"), title.slice(0, 200), forkSummary, forkCompactedCount, conversation.agent_tools_json == null
|
|
6045
6070
|
? JSON.stringify(normalizeWorkAgentTools(this.getWorkAiSettings(workId).agentTools))
|
|
6046
6071
|
: String(conversation.agent_tools_json), injectedEntitiesJson, systemClockText, timestamp, timestamp, currentRequestActor()?.userId ?? null);
|
|
6047
6072
|
for (const message of messages.slice(0, targetIndex + 1)) {
|
|
@@ -6084,6 +6109,7 @@ export class Store {
|
|
|
6084
6109
|
}
|
|
6085
6110
|
mapAiConversation(row) {
|
|
6086
6111
|
const roleplayCharacterId = optionalString(row, "roleplay_character_id");
|
|
6112
|
+
const roleplayUserCharacterId = optionalString(row, "roleplay_user_character_id");
|
|
6087
6113
|
const firstUserMessage = this.db.get(`SELECT metadata_json FROM ai_conversation_messages
|
|
6088
6114
|
WHERE conversation_id = ? AND role = 'user'
|
|
6089
6115
|
ORDER BY created_at, rowid
|
|
@@ -6097,6 +6123,9 @@ export class Store {
|
|
|
6097
6123
|
const roleplayCharacter = roleplayCharacterId
|
|
6098
6124
|
? this.db.get("SELECT id, name, code FROM characters WHERE id = ? AND work_id = ?", roleplayCharacterId, requiredString(row, "work_id"))
|
|
6099
6125
|
: undefined;
|
|
6126
|
+
const roleplayUserCharacter = roleplayCharacterId && roleplayUserCharacterId
|
|
6127
|
+
? this.db.get("SELECT id, name, code FROM characters WHERE id = ? AND work_id = ?", roleplayUserCharacterId, requiredString(row, "work_id"))
|
|
6128
|
+
: undefined;
|
|
6100
6129
|
return {
|
|
6101
6130
|
id: requiredString(row, "id"),
|
|
6102
6131
|
workId: requiredString(row, "work_id"),
|
|
@@ -6115,6 +6144,11 @@ export class Store {
|
|
|
6115
6144
|
name: requiredString(roleplayCharacter, "name"),
|
|
6116
6145
|
code: requiredString(roleplayCharacter, "code")
|
|
6117
6146
|
} : null,
|
|
6147
|
+
roleplayUserCharacter: roleplayUserCharacter ? {
|
|
6148
|
+
id: requiredString(roleplayUserCharacter, "id"),
|
|
6149
|
+
name: requiredString(roleplayUserCharacter, "name"),
|
|
6150
|
+
code: requiredString(roleplayUserCharacter, "code")
|
|
6151
|
+
} : null,
|
|
6118
6152
|
agentTools: row.agent_tools_json == null || row.agent_tools_json === undefined
|
|
6119
6153
|
? null
|
|
6120
6154
|
: normalizeWorkAgentTools(row.agent_tools_json),
|