mirror of
https://github.com/jie65535/JChatGPT.git
synced 2026-09-15 02:56:10 +08:00
profile: add progressive user profiles
Add cache-expiry profile maintenance and contextual injection, reorganize runtime code by responsibility, remove automatic favorability decay, and prepare version 1.15.0.
This commit is contained in:
@@ -0,0 +1,264 @@
|
||||
package top.jie65535.mirai.config
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import net.mamoe.mirai.console.data.AutoSavePluginConfig
|
||||
import net.mamoe.mirai.console.data.ValueDescription
|
||||
import net.mamoe.mirai.console.data.value
|
||||
|
||||
/**
|
||||
* 聊天模型备用接入点。用于主接入点(openAiApi/openAiToken/chatModel)连续失败时容灾切换。
|
||||
* 任一字段留空则继承主接入点对应配置,因此可只换 API KEY、只换模型、或整体换一个服务商。
|
||||
*/
|
||||
@Serializable
|
||||
data class ChatFallbackEndpoint(
|
||||
val api: String = "",
|
||||
val token: String = "",
|
||||
val model: String = "",
|
||||
val extraBody: String = "",
|
||||
)
|
||||
|
||||
object PluginConfig : AutoSavePluginConfig("Config") {
|
||||
@ValueDescription("主人QQ,AI可以通过工具向主人发起请求,会等待一段时间")
|
||||
val ownerId: Long by value()
|
||||
|
||||
@ValueDescription("OpenAI API base url")
|
||||
val openAiApi: String by value("https://dashscope.aliyuncs.com/compatible-mode/v1/")
|
||||
|
||||
@ValueDescription("OpenAI API Token")
|
||||
var openAiToken: String by value("")
|
||||
|
||||
@ValueDescription("Chat模型")
|
||||
var chatModel: String by value("qwen-max")
|
||||
|
||||
@ValueDescription("Chat模型温度,默认为null")
|
||||
var chatTemperature: Double? by value(null)
|
||||
|
||||
@ValueDescription("推理模型API")
|
||||
var reasoningModelApi: String by value("https://dashscope.aliyuncs.com/compatible-mode/v1/")
|
||||
|
||||
@ValueDescription("推理模型Token")
|
||||
var reasoningModelToken: String by value("")
|
||||
|
||||
@ValueDescription("推理模型")
|
||||
var reasoningModel: String by value("qwq-plus")
|
||||
|
||||
@ValueDescription("视觉模型API")
|
||||
var visualModelApi: String by value("https://dashscope.aliyuncs.com/compatible-mode/v1/")
|
||||
|
||||
@ValueDescription("视觉模型Token")
|
||||
var visualModelToken: String by value("")
|
||||
|
||||
@ValueDescription("视觉模型")
|
||||
var visualModel: String by value("qwen-vl-plus")
|
||||
|
||||
@ValueDescription("聊天模型额外请求体JSON,会合并到请求体中。例如DeepSeek关闭思维: {\"thinking\": {\"type\": \"disabled\"}}")
|
||||
val chatModelExtraBody: String by value("")
|
||||
|
||||
@ValueDescription("聊天模型备用接入点列表(容灾)。主接入点连续失败时按顺序切换;每项留空的字段会继承主接入点,例如只换API KEY就只填token,只换模型就只填model")
|
||||
val chatFallbacks: List<ChatFallbackEndpoint> by value()
|
||||
|
||||
@ValueDescription("是否启用实验性的历史用户画像分析")
|
||||
val profileEnabled: Boolean by value(true)
|
||||
|
||||
@ValueDescription("画像分析模型API。留空时继承聊天模型API")
|
||||
val profileModelApi: String by value("")
|
||||
|
||||
@ValueDescription("画像分析模型Token。留空时继承聊天模型Token")
|
||||
val profileModelToken: String by value("")
|
||||
|
||||
@ValueDescription("画像分析模型。留空时继承聊天模型")
|
||||
val profileModel: String by value("")
|
||||
|
||||
@ValueDescription("画像分析模型温度。留空时继承聊天模型温度")
|
||||
val profileModelTemperature: Double? by value(null)
|
||||
|
||||
@ValueDescription("画像分析模型额外请求体JSON。留空时继承聊天模型额外请求体")
|
||||
val profileModelExtraBody: String by value("")
|
||||
|
||||
@ValueDescription("画像分析提示词文件路径,相对于插件配置目录")
|
||||
val profilePromptFile: String by value("ProfilePrompt.md")
|
||||
|
||||
@ValueDescription("闭合群聊多人画像提示词文件路径,相对于插件配置目录")
|
||||
val profileConversationPromptFile: String by value("ProfileConversationPrompt.md")
|
||||
|
||||
@ValueDescription("画像分析使用的聊天记录SQLite路径。留空时使用插件自己的chat-history.sqlite;本地实验可填写历史库绝对路径")
|
||||
val profileHistoryDatabasePath: String by value("")
|
||||
|
||||
@ValueDescription("每个画像分析批次最多读取目标用户多少条消息")
|
||||
val profileBatchTargetMessages: Int by value(120)
|
||||
|
||||
@ValueDescription("每个画像分析批次最多包含多少个离散对话片段;同一秒的消息仍会一起处理")
|
||||
val profileBatchMaxEpisodes: Int by value(16)
|
||||
|
||||
@ValueDescription("目标用户相邻发言超过多少分钟时划分为新的对话片段")
|
||||
val profileEpisodeGapMinutes: Int by value(60)
|
||||
|
||||
@ValueDescription("每个对话片段最多附带多少条前置上下文")
|
||||
val profileContextBeforeMessages: Int by value(30)
|
||||
|
||||
@ValueDescription("每个对话片段最多附带多少条后续上下文")
|
||||
val profileContextAfterMessages: Int by value(30)
|
||||
|
||||
@ValueDescription("画像分析单批次最多保留多少条非目标用户上下文消息")
|
||||
val profileContextCoreMessages: Int by value(300)
|
||||
|
||||
@ValueDescription("画像分析中单条消息最多保留的字符数")
|
||||
val profileMaxMessageChars: Int by value(1000)
|
||||
|
||||
@ValueDescription("画像模型响应无效时的最大重试次数,取值0~3")
|
||||
val profileRetryMax: Int by value(2)
|
||||
|
||||
@ValueDescription("单条画像结论的最大字符数")
|
||||
val profileSummaryMaxLength: Int by value(500)
|
||||
|
||||
@ValueDescription("是否在群聊会话结束后静默自动维护相关用户画像")
|
||||
val profileAutoUpdateEnabled: Boolean by value(true)
|
||||
|
||||
@ValueDescription("自动画像分析一次闭合会话最多读取多少条最近消息")
|
||||
val profileAutoConversationMessageLimit: Int by value(150)
|
||||
|
||||
@ValueDescription("用户在会话中至少包含多少个本人文本字符才调用画像模型")
|
||||
val profileAutoMinAuthoredTextChars: Int by value(20)
|
||||
|
||||
@ValueDescription("是否在普通群聊上下文中自动注入相关用户的画像摘要")
|
||||
val profileAutoInjectEnabled: Boolean by value(true)
|
||||
|
||||
@ValueDescription("一次普通对话最多自动注入多少名相关用户的画像摘要")
|
||||
val profileAutoInjectMaxUsers: Int by value(4)
|
||||
|
||||
@ValueDescription("普通对话中每名用户的画像摘要最多注入多少字符")
|
||||
val profileAutoInjectSummaryMaxChars: Int by value(300)
|
||||
|
||||
@ValueDescription("备用接入点冷却时间(分钟)。某接入点失败后在此时间内会被排到重试队尾,避免每条消息都先卡在故障接入点上。设为0禁用,默认5分钟")
|
||||
val fallbackCooldownMinutes: Long by value(5L)
|
||||
|
||||
@ValueDescription("推理模型额外请求体JSON,会合并到请求体中。例如DeepSeek启用思维: {\"thinking\": {\"type\": \"enabled\"}}")
|
||||
val reasoningModelExtraBody: String by value("")
|
||||
|
||||
@ValueDescription("视觉模型额外请求体JSON,会合并到请求体中。")
|
||||
val visualModelExtraBody: String by value("")
|
||||
|
||||
@ValueDescription("视觉模型是否先由机器人下载图片并以Base64上传。建议开启,可避免百炼下载QQ临时图片链接失败")
|
||||
val visualImageBase64Enabled: Boolean by value(true)
|
||||
|
||||
@ValueDescription("视觉模型单次工具调用的最大尝试次数,取值1~3,默认2次。图片只下载和编码一次,重试仅重新请求模型")
|
||||
val visualRetryMax: Int by value(2)
|
||||
|
||||
@ValueDescription("百炼平台API KEY")
|
||||
val dashScopeApiKey: String by value("")
|
||||
|
||||
@ValueDescription("百炼平台图像模型,支持文生图与图像编辑。可选:qwen-image-2.0 / qwen-image-2.0-pro / qwen-image-edit-max / qwen-image-edit-plus 等")
|
||||
val imageModel: String by value("qwen-image-2.0")
|
||||
|
||||
@ValueDescription("是否在生成的图片右下角添加 Qwen-Image 水印")
|
||||
val imageWatermark: Boolean by value(false)
|
||||
|
||||
@ValueDescription("百炼平台TTS模型。qwen3-tts-instruct-flash 支持 instructions 指令控制;纯发音可用 qwen3-tts-flash 或 qwen-tts")
|
||||
val ttsModel: String by value("qwen3-tts-instruct-flash")
|
||||
|
||||
@ValueDescription("Jina API Key")
|
||||
val jinaApiKey by value("")
|
||||
|
||||
@ValueDescription("SearXNG 搜索引擎地址,如 http://127.0.0.1:8080/search 必须启用允许json格式返回")
|
||||
val searXngUrl: String by value("")
|
||||
|
||||
@ValueDescription("在线运行代码 glot.io 的 api token,在官网注册账号即可获取。")
|
||||
val glotToken: String by value("")
|
||||
|
||||
@ValueDescription("和风天气专属 API Host,例如 abc1234xyz.def.qweatherapi.com")
|
||||
val qWeatherApiHost: String by value("")
|
||||
|
||||
@ValueDescription("和风天气项目 ID,用于 JWT 的 sub")
|
||||
val qWeatherProjectId: String by value("")
|
||||
|
||||
@ValueDescription("和风天气凭据 ID,用于 JWT 的 kid")
|
||||
val qWeatherCredentialId: String by value("")
|
||||
|
||||
@ValueDescription("和风天气 Ed25519 私钥文件路径,相对于插件配置目录,也可以填写绝对路径")
|
||||
val qWeatherPrivateKeyPath: String by value("qweather-ed25519-private.pem")
|
||||
|
||||
@ValueDescription("群管理是否自动拥有对话权限,默认是")
|
||||
val groupOpHasChatPermission: Boolean by value(true)
|
||||
|
||||
@ValueDescription("好友是否自动拥有对话权限,默认是")
|
||||
val friendHasChatPermission: Boolean by value(true)
|
||||
|
||||
@ValueDescription("机器人是否可以禁言别人,默认禁止")
|
||||
val canMute: Boolean by value(false)
|
||||
|
||||
@ValueDescription("群荣誉等级权限门槛,达到这个等级相当于自动拥有对话权限。")
|
||||
val temperaturePermission: Int by value(50)
|
||||
|
||||
@ValueDescription("等待响应超时时间(整个请求的总超时与socket读超时),单位毫秒,默认60秒")
|
||||
val timeout: Long by value(60000L)
|
||||
|
||||
@ValueDescription("首块响应超时时间,单位毫秒,默认10秒。若连接建立后在此时间内没收到首块data:则中断走重试")
|
||||
val firstChunkTimeout: Long by value(10000L)
|
||||
|
||||
@ValueDescription("视觉模型首块响应超时时间,单位毫秒,默认120秒。视觉模型需先下载图片再出首块,比对话天然慢,故单独放宽")
|
||||
val visualFirstChunkTimeout: Long by value(120000L)
|
||||
|
||||
@ValueDescription("推理模型首块响应超时时间,单位毫秒,默认90秒。推理模型出首块前常有思考预热,比对话慢,故单独放宽")
|
||||
val reasoningFirstChunkTimeout: Long by value(90000L)
|
||||
|
||||
@ValueDescription("画像分析模型首块响应超时时间,单位毫秒,默认180秒")
|
||||
val profileFirstChunkTimeout: Long by value(180000L)
|
||||
|
||||
@Deprecated("使用外部文件而不是在配置文件内保存提示词")
|
||||
@ValueDescription("系统提示词,该字段已弃用,使用提示词文件而不是在这里修改")
|
||||
var prompt: String by value("你是一个乐于助人的助手")
|
||||
|
||||
@ValueDescription("系统提示词文件路径,相对于插件配置目录")
|
||||
val promptFile: String by value("SystemPrompt.md")
|
||||
|
||||
@ValueDescription("创建Prompt时取最近多少分钟内的消息")
|
||||
val historyWindowMin: Int by value(10)
|
||||
|
||||
@ValueDescription("创建Prompt时取最多几条消息")
|
||||
val historyMessageLimit: Int by value(20)
|
||||
|
||||
@ValueDescription("启用对话上下文内存缓存,允许在短时间内保持上下文连续")
|
||||
val enableContextCache by value(true)
|
||||
|
||||
@ValueDescription("上下文缓存有效期(分钟),超过此时间未活动则重新创建上下文")
|
||||
val contextCacheTimeoutMinutes by value(10)
|
||||
|
||||
@ValueDescription("是否打印Prompt便于调试")
|
||||
val logPrompt by value(false)
|
||||
|
||||
@ValueDescription("达到需要合并转发消息的阈值")
|
||||
val messageMergeThreshold by value(150)
|
||||
|
||||
@ValueDescription("最大循环次数,至少2次")
|
||||
val retryMax: Int by value(5)
|
||||
|
||||
@ValueDescription("关键字呼叫,支持正则表达式")
|
||||
val callKeyword by value("[小筱][林淋月玥]")
|
||||
|
||||
@ValueDescription("是否显示工具调用消息,默认是")
|
||||
val showToolCallingMessage by value(true)
|
||||
|
||||
@ValueDescription("是否启用记忆编辑功能,记忆存在data目录,提示词中需要加上{memory}来填充记忆,每个群都有独立记忆")
|
||||
val memoryEnabled by value(true)
|
||||
|
||||
@ValueDescription("是否启用技能系统,技能存在data/skills目录(全局跨群),提示词中需要加上{skills}来注入技能索引")
|
||||
val skillsEnabled by value(true)
|
||||
|
||||
@ValueDescription("是否启用好感度系统")
|
||||
val enableFavorabilitySystem by value(true)
|
||||
|
||||
@ValueDescription("表情包路径,配置后会加载目录下的文件名,提示词中需要用{meme}来插入上下文")
|
||||
val memeDir: String by value("")
|
||||
|
||||
@ValueDescription("请求主人回复等待时间,单位毫秒,默认300秒")
|
||||
val requestOwnerWaitTimeout: Long by value(300000L)
|
||||
|
||||
@ValueDescription("单个工具调用返回内容的最大字符数,超过将被截断并标注")
|
||||
val maxToolOutputLength: Int by value(15000)
|
||||
|
||||
@ValueDescription("聊天记录搜索最大天数")
|
||||
val searchHistoryMaxDays: Int by value(30)
|
||||
|
||||
@ValueDescription("聊天记录搜索最大查询条数,防止内存溢出")
|
||||
val searchHistoryMaxRecords: Int by value(5000)
|
||||
}
|
||||
Reference in New Issue
Block a user