fix: refresh meme prompt on reload

This commit is contained in:
2026-08-08 14:21:32 +08:00
parent 9ab4432450
commit e3e296bd5e
3 changed files with 64 additions and 24 deletions
@@ -18,6 +18,7 @@ import top.jie65535.mirai.JChatGPT.reload
import top.jie65535.mirai.config.PluginConfig
import top.jie65535.mirai.config.ModelConfig
import top.jie65535.mirai.config.ModelConfigMigration
import top.jie65535.mirai.conversation.ConversationContext
import top.jie65535.mirai.data.PluginData
import top.jie65535.mirai.data.SkillStore
import top.jie65535.mirai.data.TokenUsageStore
@@ -58,6 +59,7 @@ object PluginCommands : CompositeCommand(
ProfileAutoMaintenance.clear()
}
SkillStore.reload()
ConversationContext.invalidateMemePromptCache()
sendMessage("OK")
}
@@ -72,6 +72,39 @@ internal class ReplyIndex {
fun indexOfIds(ids: String): Int? = indexByIds[ids]
}
internal class MemePromptCache {
private var prompt: String? = null
fun get(directoryPath: String): String = synchronized(this) {
prompt ?: buildPrompt(directoryPath).also { prompt = it }
}
fun clear() {
synchronized(this) { prompt = null }
}
private fun buildPrompt(directoryPath: String): String {
if (directoryPath.isEmpty()) return ""
return buildString {
val directory = File(directoryPath)
if (!directory.isDirectory) {
append("配置的meme路径不存在!")
return@buildString
}
append("memes文件夹地址为:").appendLine(directoryPath)
val memes = directory.list().orEmpty()
if (memes.isEmpty()) {
append("暂无表情包~")
} else {
memes.forEach { append("- ").appendLine(it) }
appendLine()
append("表情包示例:![").append(memes[0]).append("](")
.append(File(directory, memes[0]).absoluteFile).appendLine(")")
}
}
}
}
internal object ConversationContext {
private val chronologicalRecordOrder = compareBy<ChatMessageRecord> { it.time }
.thenBy { if (it.id == 0L) Long.MAX_VALUE else it.id }
@@ -81,16 +114,21 @@ internal object ConversationContext {
private val dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd E HH:mm:ss")
private val shortTimeFormatter = DateTimeFormatter.ofPattern("HH:mm")
.withZone(ZoneOffset.systemDefault())
private var memePrompt: String? = null
private val memePromptCache = MemePromptCache()
fun clearCache() {
synchronized(contextCache) { contextCache.clear() }
}
fun invalidateMemePromptCache() {
memePromptCache.clear()
}
fun clearAll() {
synchronized(contextCache) { contextCache.clear() }
synchronized(replyIndexes) { replyIndexes.clear() }
synchronized(imageIndexes) { imageIndexes.clear() }
memePromptCache.clear()
}
fun cache(subjectId: Long): ConversationCache? = synchronized(contextCache) {
@@ -150,7 +188,7 @@ internal object ConversationContext {
replace("{skills}") {
if (PluginConfig.skillsEnabled) SkillStore.buildIndexPrompt() else "暂无技能"
}
replace("{meme}") { buildMemePrompt() }
replace("{meme}") { memePromptCache.get(PluginConfig.memeDir) }
return prompt.toString()
}
@@ -258,28 +296,6 @@ internal object ConversationContext {
imageIndexes.getOrPut(subjectId) { ImageIndex() }
}
private fun buildMemePrompt(): String {
memePrompt?.let { return it }
if (PluginConfig.memeDir.isEmpty()) return ""
return buildString {
val directory = File(PluginConfig.memeDir)
if (!directory.isDirectory) {
append("配置的meme路径不存在!")
return@buildString
}
append("memes文件夹地址为:").appendLine(PluginConfig.memeDir)
val memes = directory.list().orEmpty()
if (memes.isEmpty()) {
append("暂无表情包~")
} else {
memes.forEach { append("- ").appendLine(it) }
appendLine()
append("表情包示例:![").append(memes[0]).append("](")
.append(File(directory, memes[0]).absoluteFile).appendLine(")")
}
}.also { memePrompt = it }
}
private fun appendUserProfileContext(
target: StringBuilder,
history: List<ChatMessageRecord>,
@@ -1,9 +1,12 @@
package top.jie65535.mirai.conversation
import java.nio.file.Files
import net.mamoe.mirai.message.data.MessageSourceKind
import top.jie65535.mirai.data.ChatMessageRecord
import kotlin.test.Test
import kotlin.test.assertContains
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertNull
class ConversationContextTest {
@@ -22,6 +25,25 @@ class ConversationContextTest {
assertNull(index.indexOfIds("missing"))
}
@Test
fun memePromptCacheRefreshesDirectoryListingAfterClear() {
val directory = Files.createTempDirectory("jchatgpt-meme-prompt-test-")
try {
Files.createFile(directory.resolve("before.png"))
val cache = MemePromptCache()
assertContains(cache.get(directory.toString()), "before.png")
Files.createFile(directory.resolve("after.png"))
assertFalse(cache.get(directory.toString()).contains("after.png"))
cache.clear()
assertContains(cache.get(directory.toString()), "after.png")
} finally {
directory.toFile().deleteRecursively()
}
}
private fun record(ids: String?, time: Int) = ChatMessageRecord(
botId = 1,
fromId = 2,