feat: 同平台多账号支持 — adapter_name 贯穿全链路

- UnifiedMessage 新增 AdapterName 字段
- router 从适配器 ConfigName() 捕获 adapter 实例名
- forwardToAICore source 新增 adapter_name
- ai-core SetBotUID key 优先用 adapter_name,回退 platform
- 更新优化大纲加入 P4.1

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-06-22 20:53:40 +08:00
parent 41f653b672
commit 2b17bb5b03
5 changed files with 64 additions and 6 deletions
+17 -3
View File
@@ -871,7 +871,8 @@ func handleChat(
SenderName string `json:"sender_name"`
OriginalUID string `json:"original_uid"`
BotUID string `json:"bot_uid"`
GroupName string `json:"group_name,omitempty"`
GroupName string
AdapterName string `json:"group_name,omitempty"`
} `json:"source,omitempty"`
}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
@@ -888,9 +889,18 @@ func handleChat(
if thinker != nil {
thinker.RecordUserMessage(req.SessionID)
if req.Source.Platform != "" && req.Source.BotUID != "" {
thinker.SetBotUID(req.Source.Platform, req.Source.BotUID)
adapterKey := req.Source.Platform
if req.Source.AdapterName != "" {
adapterKey = req.Source.AdapterName
}
thinker.SetBotUID(adapterKey, req.Source.BotUID)
}
if req.Source.Platform != "" && req.Source.ChannelID != "" {
adapterKey := req.Source.Platform
if req.Source.AdapterName != "" {
adapterKey = req.Source.AdapterName
}
thinker.SetBotUID(adapterKey, req.Source.BotUID)
thinker.AddOrUpdatePlatformChannel(req.Source.Platform, req.Source.ChannelType, req.Source.ChannelID, req.Source.GroupName)
}
}
@@ -924,7 +934,11 @@ func handleChat(
if thinker != nil {
thinker.RecordUserMessage(req.SessionID)
if req.Source.Platform != "" && req.Source.BotUID != "" {
thinker.SetBotUID(req.Source.Platform, req.Source.BotUID)
adapterKey := req.Source.Platform
if req.Source.AdapterName != "" {
adapterKey = req.Source.AdapterName
}
thinker.SetBotUID(adapterKey, req.Source.BotUID)
}
if req.Source.Platform != "" && req.Source.ChannelID != "" {
thinker.AddOrUpdatePlatformChannel(req.Source.Platform, req.Source.ChannelType, req.Source.ChannelID, req.Source.GroupName)
+1
View File
@@ -665,6 +665,7 @@ func forwardToAICore(cfg *config.Config, msg *bridge.UnifiedMessage, mode, userI
"original_uid": msg.OriginalSenderUID,
"bot_uid": msg.BotUID,
"group_name": msg.GroupName,
"adapter_name": msg.AdapterName,
},
}
if len(images) > 0 {
@@ -150,6 +150,11 @@ func (r *PlatformRouter) RouteMessage(adapterKey string, rawMsg interface{}) (*U
unified.BotUID = selfAware.SelfID()
}
// Capture adapter config name for multi-account routing.
if named, ok := a.(interface{ ConfigName() string }); ok {
unified.AdapterName = named.ConfigName()
}
// Resolve identity (nil for unknown users; caller decides routing).
// Use platform type (e.g. "qq") for identity resolution, not adapter key.
identity := r.mapper.ResolveOrNil(a.PlatformName(), unified.SenderID)
@@ -29,6 +29,7 @@ type UnifiedMessage struct {
GroupName string `json:"group_name,omitempty"` // resolved group name for group chats
OriginalRawMessage interface{} `json:"-"` // preserved for SendMessage wiring
BotUID string `json:"-"` // bot's own platform UID, set by router
AdapterName string `json:"-"` // adapter config name (e.g. "qq-main"), set by router
}
// Attachment represents a file/image/voice/video attachment.
+40 -3
View File
@@ -181,6 +181,42 @@ QQ 平台标识(`【QQ群聊:xxx】`、`【QQ私聊:xxx】`)硬编码在 `th
---
### 5.1 P4.1 — 同平台多账号支持
#### 现状
Platform-Bridge 已支持同一平台注册多个 adapter 实例(如 `qq-main`, `qq-secondary`),但 ai-core 侧的 key 系统用 platform 类型字符串(`"qq"`)而非 adapter config name
| 位置 | 当前 key | 问题 |
|---|---|---|
| `botUIDs` | `"qq"` → UID | 多个 OBv11 账号只能存一个 UID |
| `ProactiveTarget.Platform` | `"qq"` | 主动消息不知道发给哪个 adapter |
| `platform_qq_xxx` session ID | `"qq"` | ✅ 正确,同群聊多账号应共享上下文 |
#### 目标
将 ai-core 内部的 platform 标识从"协议类型"改为"adapter 实例名",使多个同平台账号独立工作。
#### 要点
- **platform-bridge `forwardToAICore`**source.platform 传 adapter config name`"qq-main"`)而非 `"qq"`
- **ai-core `SetBotUID`**key 改为 adapter name,允许多个同平台 Bot
- **`ProactiveTarget.Platform`**:传 adapter nameplatform-bridge 直接用它查 router
- **platform-bridge `sendProactive` handler**:直接用 platform 字段作为 adapter name
- **`PlatformFormat` 注册表**key 保持 platform 类型(`"qq"`),格式与协议绑定,不绑定账号
- **session ID prefix**:保持 `platform_qq_`,同群聊多账号共享上下文
#### 涉及文件
| 文件 | 改动 |
|---|---|
| `platform-bridge/cmd/main.go` | forwardToAICore 传 adapter name |
| `platform-bridge/internal/handler/bridge_handler.go` | sendProactive 直接用 platform 查 adapter |
| `ai-core/cmd/main.go` | SetBotUID key 用 adapter name |
| `ai-core/background/thinker.go` | ProactiveTarget + botUIDs 适配 |
---
## 6. P5 — 工具子会话增强
### 6.1 子会话返回时间戳
@@ -204,17 +240,18 @@ QQ 平台标识(`【QQ群聊:xxx】`、`【QQ私聊:xxx】`)硬编码在 `th
## 7. 实施顺序建议
```
Phase A (本节可做) ─────────────────────────────
Phase A (本节可做) ───────────────────────────── ✅ 已完成
P2.2 对话后思考可追加 ~10 行改动
P2.1 自主思考后触发记忆整理 ~5 行改动
P5.1 子会话返回时间戳 ~20 行改动
Phase B (需要跨服务协调) ───────────────────────
Phase B (需要跨服务协调) ─────────────────────── ✅ 已完成
P1 LLM 可自主操作提醒与日程 新建 1 文件 + 注册工具
P0 自主思考分层 重构 thinker 核心循环
Phase C (架构级改动) ───────────────────────────
P4 多平台前缀统一抽象 跨 ai-core + platform-bridge
P4 QQ→OBv11 重命名 + PlatformFormat 抽象 ✅ 已完成
P4.1 同平台多账号支持 跨 ai-core + platform-bridge ← 当前
P3 群聊并发(协会议话) 跨 ai-core + platform-bridge
Phase D (后续优化) ─────────────────────────────