Files
synapse/internal/components/meridian/meridian.go
2026-06-28 03:24:26 +08:00

352 lines
8.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Package meridian 灵脉 - 寻址与路由层
//
// 取中医"经脉"之意。Agent 之间虽有空隙(灵隙),
// 但暗中有能量流动的轨迹(脉)。
//
// 此层负责维护全局路由表,让新 Agent "通脉"入网,
// 旧 Agent "断脉"离场,不死不休。
package meridian
import (
"context"
"encoding/json"
"fmt"
"log"
"sync"
"time"
"synapse/pkg/types"
)
// =============================================================================
// Agent Registry - Agent 注册发现
// =============================================================================
// AgentRegistry Agent 注册表
type AgentRegistry struct {
mu sync.RWMutex
agents map[string]*types.AgentEndpoint // agent_id -> endpoint
ttl map[string]time.Time // agent_id -> 过期时间
config *RegistryConfig
}
// RegistryConfig 注册表配置
type RegistryConfig struct {
DefaultTTL time.Duration // 默认存活时间
}
// DefaultRegistryConfig 返回默认注册表配置
func DefaultRegistryConfig() *RegistryConfig {
return &RegistryConfig{
DefaultTTL: 5 * time.Minute,
}
}
// NewAgentRegistry 创建 Agent 注册表
func NewAgentRegistry(config *RegistryConfig) *AgentRegistry {
if config == nil {
config = DefaultRegistryConfig()
}
return &AgentRegistry{
agents: make(map[string]*types.AgentEndpoint),
ttl: make(map[string]time.Time),
config: config,
}
}
// Register 注册 Agent(通脉)
func (r *AgentRegistry) Register(endpoint types.AgentEndpoint) error {
if endpoint.AgentID == "" {
return fmt.Errorf("agent_id is required")
}
r.mu.Lock()
defer r.mu.Unlock()
r.agents[endpoint.AgentID] = &endpoint
r.ttl[endpoint.AgentID] = time.Now().Add(r.config.DefaultTTL)
log.Printf("[灵脉] Agent 通脉入网: %s (%s)", endpoint.AgentID, endpoint.AgentName)
return nil
}
// Unregister 注销 Agent(断脉)
func (r *AgentRegistry) Unregister(agentID string) error {
r.mu.Lock()
defer r.mu.Unlock()
if _, ok := r.agents[agentID]; !ok {
return fmt.Errorf("agent %s not found", agentID)
}
delete(r.agents, agentID)
delete(r.ttl, agentID)
log.Printf("[灵脉] Agent 断脉离场: %s", agentID)
return nil
}
// GetAgent 获取 Agent 端点
func (r *AgentRegistry) GetAgent(agentID string) (*types.AgentEndpoint, error) {
r.mu.RLock()
defer r.mu.RUnlock()
agent, ok := r.agents[agentID]
if !ok {
return nil, fmt.Errorf("agent %s not found", agentID)
}
// 检查是否过期
if time.Now().After(r.ttl[agentID]) {
return nil, fmt.Errorf("agent %s has expired", agentID)
}
return agent, nil
}
// ListAgents 列出所有活跃 Agent
func (r *AgentRegistry) ListAgents() []types.AgentEndpoint {
r.mu.RLock()
defer r.mu.RUnlock()
agents := make([]types.AgentEndpoint, 0, len(r.agents))
now := time.Now()
for id, agent := range r.agents {
if now.Before(r.ttl[id]) {
agents = append(agents, *agent)
}
}
return agents
}
// Heartbeat 心跳保活
func (r *AgentRegistry) Heartbeat(agentID string) error {
r.mu.Lock()
defer r.mu.Unlock()
if _, ok := r.agents[agentID]; !ok {
return fmt.Errorf("agent %s not registered", agentID)
}
r.ttl[agentID] = time.Now().Add(r.config.DefaultTTL)
return nil
}
// FindByCapability 按能力查找 Agent
func (r *AgentRegistry) FindByCapability(capability string) []types.AgentEndpoint {
r.mu.RLock()
defer r.mu.RUnlock()
var result []types.AgentEndpoint
now := time.Now()
for id, agent := range r.agents {
if now.Before(r.ttl[id]) {
// 简化处理,实际需要查询能力
result = append(result, *agent)
}
}
return result
}
// =============================================================================
// Message Router - 消息路由
// =============================================================================
// Router 消息路由器
type Router struct {
registry *AgentRegistry
// 协议处理器
handlers map[string]MessageHandler
mu sync.RWMutex
config *RouterConfig
}
// MessageHandler 消息处理器接口
type MessageHandler interface {
HandleMessage(ctx context.Context, msg *types.UnifiedSynapseMessage) (*types.UnifiedSynapseMessage, error)
}
// RouterConfig 路由器配置
type RouterConfig struct {
MaxHops int // 最大跳数
EnableCaching bool // 启用路由缓存
}
// DefaultRouterConfig 返回默认路由器配置
func DefaultRouterConfig() *RouterConfig {
return &RouterConfig{
MaxHops: 10,
EnableCaching: true,
}
}
// NewRouter 创建消息路由器
func NewRouter(registry *AgentRegistry, config *RouterConfig) *Router {
if config == nil {
config = DefaultRouterConfig()
}
if registry == nil {
registry = NewAgentRegistry(nil)
}
return &Router{
registry: registry,
handlers: make(map[string]MessageHandler),
config: config,
}
}
// RegisterHandler 注册消息类型处理器
func (r *Router) RegisterHandler(msgType string, handler MessageHandler) {
r.mu.Lock()
defer r.mu.Unlock()
r.handlers[msgType] = handler
}
// Route 路由消息
func (r *Router) Route(ctx context.Context, msg *types.UnifiedSynapseMessage) (*types.UnifiedSynapseMessage, error) {
if msg.Receiver == nil {
return nil, fmt.Errorf("receiver is required")
}
// 查找接收方
_, err := r.registry.GetAgent(msg.Receiver.AgentID)
if err != nil {
return nil, fmt.Errorf("route failed: agent not found: %w", err)
}
// 查找处理器
r.mu.RLock()
handler, ok := r.handlers[msg.Type]
r.mu.RUnlock()
if !ok {
return nil, fmt.Errorf("no handler for message type: %s", msg.Type)
}
log.Printf("[灵脉] 路由消息: %s -> %s (类型: %s)",
msg.Sender.AgentID, msg.Receiver.AgentID, msg.Type)
return handler.HandleMessage(ctx, msg)
}
// =============================================================================
// Topology Manager - 拓扑管理
// =============================================================================
// TopologyType 拓扑类型
type TopologyType string
const (
TopologyStar TopologyType = "star" // 星型拓扑
TopologyMesh TopologyType = "mesh" // 网状拓扑
TopologyRing TopologyType = "ring" // 环形拓扑
TopologyTree TopologyType = "tree" // 树形拓扑
TopologyHybrid TopologyType = "hybrid" // 混合拓扑
)
// TopologyManager 拓扑管理器
type TopologyManager struct {
mu sync.RWMutex
topologies map[string]*NetworkTopology
}
// NetworkTopology 网络拓扑
type NetworkTopology struct {
ID string `json:"id"`
Name string `json:"name"`
Type TopologyType `json:"type"`
Nodes map[string]bool `json:"nodes"`
Edges map[string][]string `json:"edges"` // node_id -> connected_nodes
Config map[string]interface{} `json:"config"`
}
// NewTopologyManager 创建拓扑管理器
func NewTopologyManager() *TopologyManager {
return &TopologyManager{
topologies: make(map[string]*NetworkTopology),
}
}
// CreateTopology 创建拓扑
func (tm *TopologyManager) CreateTopology(id, name string, topologyType TopologyType) *NetworkTopology {
tm.mu.Lock()
defer tm.mu.Unlock()
topo := &NetworkTopology{
ID: id,
Name: name,
Type: topologyType,
Nodes: make(map[string]bool),
Edges: make(map[string][]string),
Config: make(map[string]interface{}),
}
tm.topologies[id] = topo
log.Printf("[灵脉] 创建拓扑: %s (%s, %s)", id, name, topologyType)
return topo
}
// AddNode 添加节点
func (tm *TopologyManager) AddNode(topologyID, nodeID string) error {
tm.mu.Lock()
defer tm.mu.Unlock()
topo, ok := tm.topologies[topologyID]
if !ok {
return fmt.Errorf("topology %s not found", topologyID)
}
topo.Nodes[nodeID] = true
if _, ok := topo.Edges[nodeID]; !ok {
topo.Edges[nodeID] = []string{}
}
return nil
}
// AddEdge 添加边
func (tm *TopologyManager) AddEdge(topologyID, from, to string) error {
tm.mu.Lock()
defer tm.mu.Unlock()
topo, ok := tm.topologies[topologyID]
if !ok {
return fmt.Errorf("topology %s not found", topologyID)
}
if !topo.Nodes[from] || !topo.Nodes[to] {
return fmt.Errorf("node not found in topology")
}
topo.Edges[from] = append(topo.Edges[from], to)
topo.Edges[to] = append(topo.Edges[to], from)
return nil
}
// GetNeighbors 获取邻居节点
func (tm *TopologyManager) GetNeighbors(topologyID, nodeID string) ([]string, error) {
tm.mu.RLock()
defer tm.mu.RUnlock()
topo, ok := tm.topologies[topologyID]
if !ok {
return nil, fmt.Errorf("topology %s not found", topologyID)
}
neighbors, ok := topo.Edges[nodeID]
if !ok {
return []string{}, nil
}
return neighbors, nil
}
// ToJSON 导出为 JSON
func (t *NetworkTopology) ToJSON() string {
data, _ := json.MarshalIndent(t, "", " ")
return string(data)
}