mirror of
https://github.com/memohai/Memoh.git
synced 2026-04-27 07:16:19 +09:00
6aebbe9279
Major changes: 1. Core Architecture: Decoupled Bots from Users. Bots now have independent lifecycles, member management (bot_members), and dedicated configurations. 2. Channel Gateway: - Implemented a unified Channel Manager supporting Feishu, Telegram, and Local (Web/CLI) adapters. - Added message processing pipeline to normalize interactions across different platforms. - Introduced a Contact system for identity binding and guest access policies. 3. Database & Tooling: - Consolidated all migrations into 0001_init with updated schema for bots, channels, and contacts. - Optimized sqlc.yaml to automatically track the migrations directory. 4. Agent Enhancements: - Introduced ToolContext to provide Agents with platform-aware execution capabilities (e.g., messaging, contact lookups). - Added tool logging and fallback mechanisms for toolChoice execution. 5. UI & Docs: Updated frontend stores, UI components, and Swagger documentation to align with the new Bot-centric model.
66 lines
1.7 KiB
Go
66 lines
1.7 KiB
Go
package channel
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
)
|
|
|
|
type InboundMessage struct {
|
|
Channel ChannelType
|
|
Text string
|
|
Username string
|
|
UserID string
|
|
OpenID string
|
|
ChatID string
|
|
ChatType string
|
|
ReplyTo string
|
|
BotID string // 增加 BotID 以支持多 Bot 隔离
|
|
SessionKey string
|
|
}
|
|
|
|
// SessionID 结构: platform:bot_id:chat_id[:sender_id]
|
|
func (m InboundMessage) SessionID() string {
|
|
if strings.TrimSpace(m.SessionKey) != "" {
|
|
return strings.TrimSpace(m.SessionKey)
|
|
}
|
|
return GenerateSessionID(string(m.Channel), m.BotID, m.ChatID, m.ChatType, m.OpenID, m.UserID, m.Username)
|
|
}
|
|
|
|
// GenerateSessionID 统一生成 SessionID 的逻辑
|
|
func GenerateSessionID(platform, botID, chatID, chatType, openID, userID, username string) string {
|
|
parts := []string{platform, botID, chatID}
|
|
// 如果是群聊,增加发送者 ID 以支持个人上下文
|
|
ct := strings.ToLower(strings.TrimSpace(chatType))
|
|
if ct != "" && ct != "p2p" && ct != "private" {
|
|
senderID := strings.TrimSpace(openID)
|
|
if senderID == "" {
|
|
senderID = strings.TrimSpace(userID)
|
|
}
|
|
if senderID == "" {
|
|
senderID = strings.TrimSpace(username)
|
|
}
|
|
if senderID != "" {
|
|
parts = append(parts, senderID)
|
|
}
|
|
}
|
|
return strings.Join(parts, ":")
|
|
}
|
|
|
|
type OutboundMessage struct {
|
|
To string
|
|
Text string
|
|
}
|
|
|
|
type AdapterRunner struct {
|
|
Stop func()
|
|
SupportsStop bool
|
|
}
|
|
|
|
type InboundHandler func(ctx context.Context, cfg ChannelConfig, msg InboundMessage) error
|
|
|
|
type Adapter interface {
|
|
Type() ChannelType
|
|
Start(ctx context.Context, cfg ChannelConfig, handler InboundHandler) (AdapterRunner, error)
|
|
Send(ctx context.Context, cfg ChannelConfig, msg OutboundMessage) error
|
|
}
|