大改,未验证
This commit is contained in:
@@ -185,20 +185,20 @@ def get_agent_tools_stats():
|
||||
try:
|
||||
from src.web.service_manager import service_manager
|
||||
agent_assistant = service_manager.get_agent_assistant()
|
||||
tools = agent_assistant.agent_core.tool_manager.get_available_tools()
|
||||
performance = agent_assistant.agent_core.tool_manager.get_tool_performance_report()
|
||||
react_status = agent_assistant.react_agent.get_status()
|
||||
tools = agent_assistant.react_agent.get_tool_definitions()
|
||||
history = agent_assistant.react_agent.get_execution_history(20)
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"tools": tools,
|
||||
"performance": performance
|
||||
"status": react_status,
|
||||
"recent_history": history
|
||||
})
|
||||
except Exception as e:
|
||||
# 返回默认工具列表,避免500错误
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"tools": [],
|
||||
"performance": {},
|
||||
"error": "工具统计暂时不可用"
|
||||
"error": str(e)
|
||||
})
|
||||
|
||||
|
||||
@@ -213,15 +213,23 @@ def execute_agent_tool():
|
||||
if not tool_name:
|
||||
return jsonify({"error": "缺少工具名称tool"}), 400
|
||||
|
||||
result = service_manager.get_agent_assistant().agent_core.tool_manager.execute_tool_sync(tool_name, parameters)
|
||||
return jsonify(result)
|
||||
agent = service_manager.get_agent_assistant()
|
||||
loop = asyncio.new_event_loop()
|
||||
asyncio.set_event_loop(loop)
|
||||
try:
|
||||
result = loop.run_until_complete(
|
||||
agent.react_agent._execute_tool(tool_name, parameters)
|
||||
)
|
||||
finally:
|
||||
loop.close()
|
||||
return jsonify({"success": True, "result": result})
|
||||
except Exception as e:
|
||||
return jsonify({"error": str(e)}), 500
|
||||
|
||||
|
||||
@agent_bp.route('/tools/register', methods=['POST'])
|
||||
def register_custom_tool():
|
||||
"""注册自定义工具(仅登记元数据,函数为占位符)"""
|
||||
"""注册自定义工具(仅登记元数据)"""
|
||||
try:
|
||||
from src.web.service_manager import service_manager
|
||||
data = request.get_json() or {}
|
||||
@@ -230,14 +238,9 @@ def register_custom_tool():
|
||||
if not name:
|
||||
return jsonify({"error": "缺少工具名称"}), 400
|
||||
|
||||
def _placeholder_tool(**kwargs):
|
||||
return {"message": f"自定义工具 {name} 已登记(占位),当前不可执行", "params": kwargs}
|
||||
|
||||
service_manager.get_agent_assistant().agent_core.tool_manager.register_tool(
|
||||
name,
|
||||
_placeholder_tool,
|
||||
metadata={"description": description, "custom": True}
|
||||
)
|
||||
agent = service_manager.get_agent_assistant()
|
||||
agent.register_tool(name, lambda **kw: {"message": f"自定义工具 {name} 占位", "params": kw},
|
||||
metadata={"description": description, "custom": True})
|
||||
return jsonify({"success": True, "message": "工具已注册"})
|
||||
except Exception as e:
|
||||
return jsonify({"error": str(e)}), 500
|
||||
@@ -248,7 +251,7 @@ def unregister_custom_tool(name):
|
||||
"""注销自定义工具"""
|
||||
try:
|
||||
from src.web.service_manager import service_manager
|
||||
success = service_manager.get_agent_assistant().agent_core.tool_manager.unregister_tool(name)
|
||||
success = service_manager.get_agent_assistant().unregister_tool(name)
|
||||
return jsonify({"success": success})
|
||||
except Exception as e:
|
||||
return jsonify({"error": str(e)}), 500
|
||||
|
||||
@@ -349,3 +349,68 @@ def get_conversation_analytics():
|
||||
except Exception as e:
|
||||
logger.error(f"获取对话分析数据失败: {e}")
|
||||
return jsonify({"error": str(e)}), 500
|
||||
|
||||
|
||||
# ==================== 会话管理 API ====================
|
||||
|
||||
@conversations_bp.route('/sessions')
|
||||
def get_sessions():
|
||||
"""获取会话列表(分页)"""
|
||||
try:
|
||||
page = request.args.get('page', 1, type=int)
|
||||
per_page = request.args.get('per_page', 20, type=int)
|
||||
status = request.args.get('status', '') # active, ended, 空=全部
|
||||
search = request.args.get('search', '')
|
||||
date_filter = request.args.get('date_filter', '')
|
||||
|
||||
result = history_manager.get_sessions_paginated(
|
||||
page=page,
|
||||
per_page=per_page,
|
||||
status=status or None,
|
||||
search=search,
|
||||
date_filter=date_filter
|
||||
)
|
||||
|
||||
return jsonify(result)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"获取会话列表失败: {e}")
|
||||
return jsonify({"error": str(e)}), 500
|
||||
|
||||
|
||||
@conversations_bp.route('/sessions/<session_id>')
|
||||
def get_session_detail(session_id):
|
||||
"""获取某个会话的完整消息列表"""
|
||||
try:
|
||||
limit = request.args.get('limit', 100, type=int)
|
||||
offset = request.args.get('offset', 0, type=int)
|
||||
|
||||
result = history_manager.get_session_messages(
|
||||
session_id=session_id,
|
||||
limit=limit,
|
||||
offset=offset
|
||||
)
|
||||
|
||||
if 'error' in result:
|
||||
return jsonify(result), 404
|
||||
|
||||
return jsonify({'success': True, **result})
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"获取会话详情失败: {e}")
|
||||
return jsonify({"error": str(e)}), 500
|
||||
|
||||
|
||||
@conversations_bp.route('/sessions/<session_id>', methods=['DELETE'])
|
||||
def delete_session(session_id):
|
||||
"""删除会话及其所有消息"""
|
||||
try:
|
||||
success = history_manager.delete_session(session_id)
|
||||
if success:
|
||||
return jsonify({"success": True, "message": "会话已删除"})
|
||||
else:
|
||||
return jsonify({"error": "删除失败"}), 500
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"删除会话失败: {e}")
|
||||
return jsonify({"error": str(e)}), 500
|
||||
|
||||
@@ -437,7 +437,6 @@ def get_error_log():
|
||||
).limit(50).all()
|
||||
|
||||
errors = []
|
||||
error_id = 1
|
||||
|
||||
for conv in conversations:
|
||||
error_type = None
|
||||
@@ -460,14 +459,17 @@ def get_error_log():
|
||||
# 只记录有错误的对话
|
||||
if error_type:
|
||||
errors.append({
|
||||
'id': error_id,
|
||||
'id': conv.id,
|
||||
'timestamp': conv.timestamp.isoformat() if conv.timestamp else None,
|
||||
'error_type': error_type,
|
||||
'error_message': error_message,
|
||||
'model': 'qwen-turbo', # 实际使用的模型
|
||||
'user_id': f'user_{conv.id}'
|
||||
'model': 'qwen-turbo',
|
||||
'user_id': f'user_{conv.id}',
|
||||
'user_message': (conv.user_message or '')[:100],
|
||||
'assistant_response': (conv.assistant_response or '')[:200],
|
||||
'confidence_score': conv.confidence_score,
|
||||
'response_time': conv.response_time,
|
||||
})
|
||||
error_id += 1
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
@@ -476,6 +478,31 @@ def get_error_log():
|
||||
except Exception as e:
|
||||
return jsonify({"error": str(e)}), 500
|
||||
|
||||
|
||||
@monitoring_bp.route('/ai-monitor/error-log/<int:conv_id>')
|
||||
def get_error_detail(conv_id):
|
||||
"""获取单条错误详情"""
|
||||
try:
|
||||
with db_manager.get_session() as session:
|
||||
conv = session.query(Conversation).filter_by(id=conv_id).first()
|
||||
if not conv:
|
||||
return jsonify({"error": "记录不存在"}), 404
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'detail': {
|
||||
'id': conv.id,
|
||||
'timestamp': conv.timestamp.isoformat() if conv.timestamp else None,
|
||||
'user_message': conv.user_message,
|
||||
'assistant_response': conv.assistant_response,
|
||||
'confidence_score': conv.confidence_score,
|
||||
'response_time': conv.response_time,
|
||||
'category': conv.category,
|
||||
'source': conv.source,
|
||||
}
|
||||
})
|
||||
except Exception as e:
|
||||
return jsonify({"error": str(e)}), 500
|
||||
|
||||
@monitoring_bp.route('/ai-monitor/error-log', methods=['DELETE'])
|
||||
def clear_error_log():
|
||||
"""清空错误日志"""
|
||||
|
||||
@@ -3863,6 +3863,44 @@ class TSPDashboard {
|
||||
}
|
||||
}
|
||||
|
||||
async viewErrorDetail(convId) {
|
||||
const modal = new bootstrap.Modal(document.getElementById('errorDetailModal'));
|
||||
const body = document.getElementById('errorDetailBody');
|
||||
body.innerHTML = '<div class="text-center text-muted"><i class="fas fa-spinner fa-spin me-2"></i>加载中...</div>';
|
||||
modal.show();
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/ai-monitor/error-log/${convId}`);
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
const d = data.detail;
|
||||
body.innerHTML = `
|
||||
<table class="table table-bordered mb-0">
|
||||
<tr><th style="width:120px">记录ID</th><td>${d.id}</td></tr>
|
||||
<tr><th>时间</th><td>${d.timestamp ? new Date(d.timestamp).toLocaleString() : '-'}</td></tr>
|
||||
<tr><th>分类</th><td>${d.category || '-'}</td></tr>
|
||||
<tr><th>来源</th><td>${d.source || '-'}</td></tr>
|
||||
<tr><th>置信度</th><td>${d.confidence_score != null ? d.confidence_score : '-'}</td></tr>
|
||||
<tr><th>响应时间</th><td>${d.response_time != null ? d.response_time + ' ms' : '-'}</td></tr>
|
||||
<tr><th>用户消息</th><td><pre class="mb-0" style="white-space:pre-wrap">${this.escapeHtml(d.user_message || '-')}</pre></td></tr>
|
||||
<tr><th>助手回复</th><td><pre class="mb-0" style="white-space:pre-wrap">${this.escapeHtml(d.assistant_response || '-')}</pre></td></tr>
|
||||
</table>
|
||||
`;
|
||||
} else {
|
||||
body.innerHTML = `<div class="alert alert-danger">${data.error || '加载失败'}</div>`;
|
||||
}
|
||||
} catch (error) {
|
||||
body.innerHTML = `<div class="alert alert-danger">请求失败: ${error.message}</div>`;
|
||||
}
|
||||
}
|
||||
|
||||
escapeHtml(text) {
|
||||
const div = document.createElement('div');
|
||||
div.textContent = text;
|
||||
return div.innerHTML;
|
||||
}
|
||||
|
||||
// 系统优化
|
||||
async loadSystemOptimizer() {
|
||||
try {
|
||||
|
||||
@@ -2469,6 +2469,24 @@
|
||||
<!-- 通知容器 -->
|
||||
<div id="notificationContainer" class="position-fixed top-0 end-0 p-3" style="z-index: 1050;"></div>
|
||||
|
||||
<!-- 错误详情模态框 -->
|
||||
<div class="modal fade" id="errorDetailModal" tabindex="-1">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title"><i class="fas fa-bug me-2"></i>错误详情</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body" id="errorDetailBody">
|
||||
<div class="text-center text-muted"><i class="fas fa-spinner fa-spin me-2"></i>加载中...</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 脚本 -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@3.9.1/dist/chart.min.js"></script>
|
||||
|
||||
Reference in New Issue
Block a user