first build nexus

This commit is contained in:
billyshen
2026-03-23 20:57:45 +08:00
parent acb58c5684
commit e312026141
400 changed files with 52448 additions and 0 deletions

View File

@@ -0,0 +1,191 @@
# -*- coding: utf-8 -*-
"""
意图解析模块 - Intent Parser
将自然语言指令转换为结构化任务
"""
import re
from typing import Dict, Optional
class IntentParser:
"""意图解析器"""
# 指令模式定义
PATTERNS = {
"code_review": {
"keywords": ["审查", "review", "代码审查", "review code"],
"target": "yunce",
"action": "code_review",
"param_extractor": "extract_repo_info"
},
"deploy": {
"keywords": ["部署", "deploy", "发布"],
"target": "prometheus",
"action": "deploy",
"param_extractor": "extract_deploy_info"
},
"status_check": {
"keywords": ["检查状态", "status", "查看状态", "状态"],
"target": "atlas",
"action": "status_check",
"param_extractor": "extract_target"
},
"data_analysis": {
"keywords": ["分析", "analysis", "数据分析"],
"target": "atlas",
"action": "data_analysis",
"param_extractor": "extract_data_info"
},
"file_operation": {
"keywords": ["复制", "移动", "删除", "copy", "move", "delete"],
"target": "oracle",
"action": "file_operation",
"param_extractor": "extract_file_info"
}
}
def parse_intent(self, user_input: str) -> Dict:
"""
解析用户输入,返回结构化意图
Args:
user_input: 用户输入的自然语言
Returns:
{
"action": "code_review",
"target": "yunce",
"params": {...}
}
"""
user_input = user_input.strip()
# 遍历所有模式,匹配关键词
for pattern_name, pattern_config in self.PATTERNS.items():
for keyword in pattern_config["keywords"]:
if keyword in user_input:
# 提取参数
extractor_name = pattern_config["param_extractor"]
extractor = getattr(self, extractor_name)
params = extractor(user_input)
return {
"action": pattern_config["action"],
"target": pattern_config["target"],
"params": params
}
# 无法识别
return {
"error": "无法理解指令",
"original_input": user_input
}
def extract_repo_info(self, text: str) -> Dict:
"""从文本中提取仓库信息"""
result = {}
# 提取仓库名
repo_match = re.search(r'(?:仓库|repo|项目)[:\s]*(\S+)', text)
if not repo_match:
repo_match = re.search(r'(?:审查|review)\s+(\S+)', text)
if repo_match:
result["repo"] = repo_match.group(1).strip(',。')
# 提取分支
branch_match = re.search(r'(?:分支|branch)[:\s]*(\S+)', text)
if branch_match:
result["branch"] = branch_match.group(1).strip(',。')
else:
result["branch"] = "main"
return result
def extract_deploy_info(self, text: str) -> Dict:
"""从文本中提取部署信息"""
result = {}
# 提取服务名
service_match = re.search(r'(?:服务|service|部署)[:\s]*(\S+)', text)
if not service_match:
service_match = re.search(r'部署\s+(\S+)', text)
if service_match:
result["service"] = service_match.group(1).strip(',。')
# 提取环境
if "生产" in text or "prod" in text.lower():
result["env"] = "prod"
elif "测试" in text or "test" in text.lower():
result["env"] = "test"
else:
result["env"] = "dev"
return result
def extract_target(self, text: str) -> Dict:
"""提取目标信息"""
result = {}
# 尝试提取目标名称
target_match = re.search(r'(?:服务器|server|目标)[:\s]*(\S+)', text)
if not target_match:
target_match = re.search(r'检查\s+(\S+)', text)
if target_match:
result["target"] = target_match.group(1).strip(',。')
return result
def extract_data_info(self, text: str) -> Dict:
"""提取数据分析信息"""
result = {}
# 提取数据源
data_match = re.search(r'(?:数据|data|分析)[:\s]*(\S+)', text)
if not data_match:
data_match = re.search(r'分析\s+(\S+)', text)
if data_match:
result["data"] = data_match.group(1).strip(',。')
return result
def extract_file_info(self, text: str) -> Dict:
"""提取文件操作信息"""
result = {}
# 提取文件路径
path_match = re.search(r'[:\s](\S+\.\S+)', text)
if path_match:
result["path"] = path_match.group(1)
# 提取操作类型
if "复制" in text or "copy" in text.lower():
result["operation"] = "copy"
elif "移动" in text or "move" in text.lower():
result["operation"] = "move"
elif "删除" in text or "delete" in text.lower():
result["operation"] = "delete"
return result
# 测试
if __name__ == "__main__":
parser = IntentParser()
test_cases = [
"帮我审查 my-project 仓库",
"部署 test-server 到生产",
"检查服务器状态",
"分析销售数据"
]
for test in test_cases:
result = parser.parse_intent(test)
print(f"输入: {test}")
print(f"输出: {result}")
print("-" * 40)

View File

@@ -0,0 +1,204 @@
# -*- coding: utf-8 -*-
"""
消息构建模块 - Message Builder
将意图解析结果转换为标准的 RabbitMQ 消息格式
"""
import json
import uuid
from datetime import datetime
from typing import Dict, Optional
class MessageBuilder:
"""消息构建器"""
# 高优先级动作
HIGH_PRIORITY_ACTIONS = ["code_review", "deploy", "security_check", "data_analysis"]
# 默认超时时间 (毫秒)
DEFAULT_TIMEOUT = 3600000 # 1小时
def __init__(self, source: str = "xingyao", default_timeout: int = None):
"""
初始化消息构建器
Args:
source: 消息来源 Agent 名称
default_timeout: 默认超时时间 (毫秒)
"""
self.source = source
self.default_timeout = default_timeout or self.DEFAULT_TIMEOUT
def build_task_message(self, intent: Dict, priority: str = None) -> Dict:
"""
构建任务消息
Args:
intent: 意图解析结果
priority: 优先级 (high/normal/low),如果为 None 则自动判断
Returns:
标准任务消息 JSON
"""
if "error" in intent:
return {"error": intent["error"]}
# 自动判断优先级
if priority is None:
priority = self._detect_priority(intent.get("action", ""))
# 生成任务ID
task_id = self._generate_task_id()
message = {
"taskId": task_id,
"type": "task",
"source": self.source,
"target": intent["target"],
"priority": priority,
"content": {
"action": intent["action"],
"params": intent.get("params", {})
},
"metadata": {
"createdAt": datetime.now().isoformat() + "Z",
"expireAt": None,
"retryCount": 0,
"maxRetries": 3,
"timeout": self.default_timeout
}
}
return message
def build_result_message(self, task_id: str, target: str,
status: str, content: Dict) -> Dict:
"""
构建结果消息 (由子 Agent 使用)
Args:
task_id: 原始任务ID
target: 目标 Agent (通常是星枢)
status: 执行状态 (success/error/partial)
content: 结果内容
Returns:
标准结果消息 JSON
"""
message = {
"taskId": task_id,
"type": "result",
"source": self.source,
"target": target,
"status": status,
"content": content,
"metadata": {
"completedAt": datetime.now().isoformat() + "Z"
}
}
return message
def build_heartbeat_message(self, agent_name: str,
status: str = "idle",
current_task: str = None) -> Dict:
"""
构建心跳消息
Args:
agent_name: Agent 名称
status: 当前状态 (idle/busy/error)
current_task: 当前执行的任务ID
Returns:
心跳消息 JSON
"""
message = {
"type": "heartbeat",
"agent": agent_name,
"status": status,
"currentTask": current_task,
"timestamp": datetime.now().isoformat() + "Z"
}
return message
def build_error_message(self, task_id: str, target: str,
error: str, details: Dict = None) -> Dict:
"""
构建错误消息
Args:
task_id: 任务ID
target: 目标 Agent
error: 错误描述
details: 错误详情
Returns:
错误消息 JSON
"""
message = {
"taskId": task_id,
"type": "error",
"source": self.source,
"target": target,
"error": error,
"content": details or {},
"metadata": {
"occurredAt": datetime.now().isoformat() + "Z"
}
}
return message
def _detect_priority(self, action: str) -> str:
"""根据动作自动判断优先级"""
return "high" if action in self.HIGH_PRIORITY_ACTIONS else "normal"
def _generate_task_id(self) -> str:
"""生成唯一任务ID"""
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
unique_id = uuid.uuid4().hex[:6]
return f"task_{timestamp}_{unique_id}"
def to_json(self, message: Dict) -> str:
"""转换为 JSON 字符串"""
return json.dumps(message, ensure_ascii=False, indent=2)
def from_json(self, json_str: str) -> Dict:
"""从 JSON 字符串解析"""
return json.loads(json_str)
# 测试
if __name__ == "__main__":
builder = MessageBuilder()
# 测试任务消息
intent = {
"action": "code_review",
"target": "yunce",
"params": {"repo": "my-project", "branch": "main"}
}
task_msg = builder.build_task_message(intent)
print("任务消息:")
print(builder.to_json(task_msg))
print("-" * 40)
# 测试心跳消息
heartbeat = builder.build_heartbeat_message("yunce", "idle")
print("心跳消息:")
print(builder.to_json(heartbeat))
print("-" * 40)
# 测试结果消息
result_msg = builder.build_result_message(
task_id=task_msg["taskId"],
target="xingyao",
status="success",
content={"summary": "审查完成", "findings": []}
)
print("结果消息:")
print(builder.to_json(result_msg))

View File

@@ -0,0 +1,248 @@
# -*- coding: utf-8 -*-
"""
RabbitMQ 发送模块 - RabbitMQ Sender
连接到 RabbitMQ 并发送消息
"""
import pika
import json
import logging
from typing import Dict, Optional
from datetime import datetime
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
class RabbitMQSender:
"""RabbitMQ 消息发送器"""
DEFAULT_CONFIG = {
"host": "192.168.3.189",
"port": 5672,
"username": "guest",
"password": "guest",
"exchange": "task_exchange",
"result_exchange": "result_exchange",
"heartbeat": 600,
"blocked_connection_timeout": 300
}
def __init__(self, config: Dict = None):
"""
初始化 RabbitMQ 发送器
Args:
config: RabbitMQ 配置,包含 host, port, username, password 等
"""
self.config = {**self.DEFAULT_CONFIG, **(config or {})}
self.connection = None
self.channel = None
self._connect()
def _connect(self):
"""建立 RabbitMQ 连接"""
credentials = pika.PlainCredentials(
self.config["username"],
self.config["password"]
)
parameters = pika.ConnectionParameters(
host=self.config["host"],
port=self.config["port"],
credentials=credentials,
heartbeat=self.config["heartbeat"],
blocked_connection_timeout=self.config["blocked_connection_timeout"]
)
try:
self.connection = pika.BlockingConnection(parameters)
self.channel = self.connection.channel()
# 声明交换机
self.channel.exchange_declare(
exchange=self.config["exchange"],
exchange_type="topic",
durable=True
)
self.channel.exchange_declare(
exchange=self.config["result_exchange"],
exchange_type="topic",
durable=True
)
logger.info(f"✅ RabbitMQ 连接成功: {self.config['host']}:{self.config['port']}")
except Exception as e:
logger.error(f"❌ RabbitMQ 连接失败: {e}")
raise
def send_task(self, message: Dict, priority: str = None) -> str:
"""
发送任务消息
Args:
message: 任务消息 (由 MessageBuilder 构建)
priority: 优先级覆盖 (high/normal/low)
Returns:
task_id
"""
if "error" in message:
raise ValueError(f"无法发送错误消息: {message['error']}")
target = message.get("target", "unknown")
task_id = message.get("taskId", "unknown")
routing_key = f"task.{target}"
# 确定优先级
priority_value = self._get_priority_value(
priority or message.get("priority", "normal")
)
try:
self.channel.basic_publish(
exchange=self.config["exchange"],
routing_key=routing_key,
body=json.dumps(message, ensure_ascii=False),
properties=pika.BasicProperties(
delivery_mode=2, # 消息持久化
content_type="application/json",
priority=priority_value,
timestamp=int(datetime.now().timestamp())
)
)
logger.info(f"✅ 任务已发送: {task_id} -> {target} (routing: {routing_key})")
return task_id
except Exception as e:
logger.error(f"❌ 发送任务失败: {e}")
raise
def send_result(self, message: Dict) -> str:
"""
发送结果消息
Args:
message: 结果消息 (由 MessageBuilder 构建)
Returns:
task_id
"""
source = message.get("source", "unknown")
task_id = message.get("taskId", "unknown")
routing_key = f"result.{source}"
try:
self.channel.basic_publish(
exchange=self.config["result_exchange"],
routing_key=routing_key,
body=json.dumps(message, ensure_ascii=False),
properties=pika.BasicProperties(
delivery_mode=2,
content_type="application/json"
)
)
logger.info(f"✅ 结果已发送: {task_id} from {source}")
return task_id
except Exception as e:
logger.error(f"❌ 发送结果失败: {e}")
raise
def send_heartbeat(self, message: Dict) -> bool:
"""
发送心跳消息
Args:
message: 心跳消息
Returns:
是否发送成功
"""
agent = message.get("agent", "unknown")
routing_key = f"heartbeat.{agent}"
try:
self.channel.basic_publish(
exchange=self.config["exchange"],
routing_key=routing_key,
body=json.dumps(message, ensure_ascii=False),
properties=pika.BasicProperties(
delivery_mode=2,
content_type="application/json"
)
)
logger.debug(f"💓 心跳已发送: {agent}")
return True
except Exception as e:
logger.error(f"❌ 发送心跳失败: {e}")
return False
def _get_priority_value(self, priority: str) -> int:
"""将优先级字符串转换为 RabbitMQ 数值"""
priority_map = {
"high": 10,
"normal": 5,
"low": 1
}
return priority_map.get(priority.lower(), 5)
def is_connected(self) -> bool:
"""检查连接状态"""
return self.connection is not None and self.connection.is_open
def reconnect(self):
"""重新连接"""
self.close()
self._connect()
def close(self):
"""关闭连接"""
if self.connection and self.connection.is_open:
self.connection.close()
logger.info("🔌 RabbitMQ 连接已关闭")
# 便捷函数
def send_task_quick(message: Dict, config: Dict = None) -> str:
"""
快速发送任务 (自动创建和关闭连接)
Args:
message: 任务消息
config: RabbitMQ 配置
Returns:
task_id
"""
sender = RabbitMQSender(config)
task_id = sender.send_task(message)
sender.close()
return task_id
# 测试
if __name__ == "__main__":
from message_builder import MessageBuilder
from intent_parser import IntentParser
# 解析意图
parser = IntentParser()
intent = parser.parse_intent("帮我审查 my-project 仓库")
# 构建消息
builder = MessageBuilder()
message = builder.build_task_message(intent)
# 发送 (需要配置实际的 RabbitMQ 地址)
# sender = RabbitMQSender({"host": "192.168.1.100", "username": "admin", "password": "password"})
# task_id = sender.send_task(message)
# sender.close()
print("消息构建成功:")
print(builder.to_json(message))