实现每机器人独立 LLM 消息队列

主要变更:
- 后端:为 botNodeRecord 添加 llm_queue_enabled 和 llm_include_channel_messages 字段
- 后端:移除全局 LLM 队列开关,完全基于每个机器人的设置
- 后端:重写 enqueueChannelMessageToLLM,为每个启用了「包含频道消息」的机器人创建独立队列记录
- 后端:频道消息不再使用 bot_id=0,每条消息都有明确的机器人归属
- 前端:AdminLLM.vue 完全重写,添加机器人 LLM 设置面板
- 前端:消息列表表格新增「机器人」列,显示机器人名称和节点 ID
- 前端:消息类型判断逻辑改为使用 channel_id 区分频道/私聊
- 前后端类型同步更新
This commit is contained in:
2026-06-17 20:51:22 +08:00
parent e2bf6aa173
commit b0a9f52096
6 changed files with 253 additions and 112 deletions
+4 -2
View File
@@ -19,6 +19,8 @@ type botNodeRequest struct {
PSK string `json:"psk"`
NodeInfoBroadcastEnabled bool `json:"nodeinfo_broadcast_enabled"`
NodeInfoBroadcastIntervalSeconds int64 `json:"nodeinfo_broadcast_interval_seconds"`
LLMQueueEnabled bool `json:"llm_queue_enabled"`
LLMIncludeChannelMessages bool `json:"llm_include_channel_messages"`
}
type botSendMessageRequest struct {
@@ -253,7 +255,7 @@ func registerAdminBotRoutes(r gin.IRouter, store *store, sender botTextSender) {
}
func botNodeInputFromRequest(req botNodeRequest) botNodeInput {
return botNodeInput{NodeNum: req.NodeNum, LongName: req.LongName, ShortName: req.ShortName, Enabled: req.Enabled, DefaultChannelID: req.DefaultChannelID, TopicPrefix: req.TopicPrefix, PSK: req.PSK, NodeInfoBroadcastEnabled: req.NodeInfoBroadcastEnabled, NodeInfoBroadcastIntervalSeconds: req.NodeInfoBroadcastIntervalSeconds}
return botNodeInput{NodeNum: req.NodeNum, LongName: req.LongName, ShortName: req.ShortName, Enabled: req.Enabled, DefaultChannelID: req.DefaultChannelID, TopicPrefix: req.TopicPrefix, PSK: req.PSK, NodeInfoBroadcastEnabled: req.NodeInfoBroadcastEnabled, NodeInfoBroadcastIntervalSeconds: req.NodeInfoBroadcastIntervalSeconds, LLMQueueEnabled: req.LLMQueueEnabled, LLMIncludeChannelMessages: req.LLMIncludeChannelMessages}
}
func parseBotID(c *gin.Context, message string) (uint64, bool) {
@@ -299,7 +301,7 @@ func writeBotNodeMutationResponse(c *gin.Context, status int, row *botNodeRecord
}
func botNodeDTO(row botNodeRecord) gin.H {
return gin.H{"id": row.ID, "node_id": row.NodeID, "node_num": row.NodeNum, "long_name": row.LongName, "short_name": row.ShortName, "enabled": row.Enabled, "default_channel_id": row.DefaultChannelID, "topic_prefix": row.TopicPrefix, "psk": row.PSK, "public_key": row.PublicKey, "private_key_set": row.PrivateKey != "", "nodeinfo_broadcast_enabled": row.NodeInfoBroadcastEnabled, "nodeinfo_broadcast_interval_seconds": row.NodeInfoBroadcastIntervalSeconds, "last_nodeinfo_broadcast_at": row.LastNodeInfoBroadcastAt, "created_at": row.CreatedAt, "updated_at": row.UpdatedAt}
return gin.H{"id": row.ID, "node_id": row.NodeID, "node_num": row.NodeNum, "long_name": row.LongName, "short_name": row.ShortName, "enabled": row.Enabled, "default_channel_id": row.DefaultChannelID, "topic_prefix": row.TopicPrefix, "psk": row.PSK, "public_key": row.PublicKey, "private_key_set": row.PrivateKey != "", "nodeinfo_broadcast_enabled": row.NodeInfoBroadcastEnabled, "nodeinfo_broadcast_interval_seconds": row.NodeInfoBroadcastIntervalSeconds, "last_nodeinfo_broadcast_at": row.LastNodeInfoBroadcastAt, "llm_queue_enabled": row.LLMQueueEnabled, "llm_include_channel_messages": row.LLMIncludeChannelMessages, "created_at": row.CreatedAt, "updated_at": row.UpdatedAt}
}
func botMessageDTO(row botMessageRecord) gin.H {