refactor: unify kubernetes_ table prefix, merge CI/CD models, LLM session support
- Rename container_clusters → kubernetes_clusters, container_topology_layouts → kubernetes_topology_layouts - LLM: add session_id to chat history for multi-turn conversation support - CI/CD: add pipeline_id, deploy_type, artifact_url, k8s_cluster_id to AppRelease - Cleanup: remove deprecated playbook handler, simplify automation models - Database: optimize auto-migrate model list - Frontend: AIOps assistant improvements, api.ts updates
This commit is contained in:
1 parent
9365c1e9db
commit
732974d152
14 files changed
+121
-474
No files matched your search
@@ -157,6 +157,8 @@ export function AIOpsAssistant() {
|
||||
const [config, setConfig] = useState<LLMConfigData>(defaultConfig);
|
||||
const [configReady, setConfigReady] = useState(false); // 已配置且启用
|
||||
const [contextLoading, setContextLoading] = useState<string | null>(null); // 快捷操作拉取平台数据中
|
||||
// 会话 ID:前端生成 UUID,用于隔离多轮对话 // Logan.Li
|
||||
const [sessionId, setSessionId] = useState(() => crypto.randomUUID());
|
||||
const messagesEndRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
// 滚动到底部 // Logan.Li
|
||||
@@ -174,10 +176,10 @@ export function AIOpsAssistant() {
|
||||
}
|
||||
};
|
||||
|
||||
// 加载历史对话(按用户隔离,刷新后仍可见) // Logan.Li
|
||||
// 加载历史对话(按 session 隔离) // Logan.Li
|
||||
const loadHistory = async () => {
|
||||
try {
|
||||
const res = await aiApi.getHistory();
|
||||
const res = await aiApi.getHistory(sessionId);
|
||||
const items: ChatHistoryItem[] = (res as any)?.list || [];
|
||||
setMessages(
|
||||
items.map((m) => ({
|
||||
@@ -275,7 +277,7 @@ export function AIOpsAssistant() {
|
||||
m.id === assistantId ? { ...m, content: m.content + delta } : m,
|
||||
),
|
||||
);
|
||||
}, controller.signal);
|
||||
}, controller.signal, sessionId);
|
||||
} catch (e) {
|
||||
// 用户主动中止:保留已生成的部分内容,不当作错误 // Logan.Li
|
||||
if (controller.signal.aborted) {
|
||||
@@ -340,13 +342,15 @@ export function AIOpsAssistant() {
|
||||
await sendMessage(fullPrompt);
|
||||
};
|
||||
|
||||
// 新对话(清空本地 + 后端持久化历史) // Logan.Li
|
||||
// 新对话(生成新 session_id,清空本地 + 后端持久化历史) // Logan.Li
|
||||
const handleNewChat = async () => {
|
||||
try {
|
||||
await aiApi.clearHistory();
|
||||
} catch {
|
||||
// 清除失败不阻塞本地清空
|
||||
}
|
||||
const newSid = crypto.randomUUID();
|
||||
setSessionId(newSid);
|
||||
setMessages([]);
|
||||
setInput('');
|
||||
toast.success('已开始新对话');
|
||||
|
||||
@@ -892,6 +892,7 @@ export interface ChatResult {
|
||||
export interface ChatHistoryItem {
|
||||
id: number;
|
||||
user_id: number;
|
||||
session_id: string;
|
||||
role: 'user' | 'assistant';
|
||||
content: string;
|
||||
model?: string;
|
||||
@@ -905,15 +906,16 @@ export const aiApi = {
|
||||
saveConfig: (data: LLMConfigData) => http.put<LLMConfigData>('/aiops/llm-config', data),
|
||||
// 测试 LLM 连接(发送 ping)
|
||||
testConnection: () => http.post('/aiops/llm-config/test'),
|
||||
// AI 对话(messages 含历史 + 当前用户消息)
|
||||
chat: (messages: { role: 'user' | 'assistant'; content: string }[]) =>
|
||||
http.post<ChatResult>('/aiops/chat', { messages }),
|
||||
// AI 对话(messages 含历史 + 当前用户消息,session_id 区分多轮对话)
|
||||
chat: (messages: { role: 'user' | 'assistant'; content: string }[], sessionId?: string) =>
|
||||
http.post<ChatResult>('/aiops/chat', { messages, session_id: sessionId || '' }),
|
||||
// AI 流式对话(SSE)。逐块回调 onChunk,返回完整内容。错误抛出 Error。
|
||||
// 使用裸 fetch 绕过 http.ts(后者会 await json() 一次性消费) // Logan.Li
|
||||
chatStream: async (
|
||||
messages: { role: 'user' | 'assistant'; content: string }[],
|
||||
onChunk: (delta: string) => void,
|
||||
signal?: AbortSignal,
|
||||
sessionId?: string,
|
||||
): Promise<string> => {
|
||||
const token = useUserStore.getState().token;
|
||||
const res = await fetch('/api/v1/aiops/chat/stream', {
|
||||
@@ -922,7 +924,7 @@ export const aiApi = {
|
||||
'Content-Type': 'application/json',
|
||||
...(token ? { Authorization: `Bearer ${token}` } : {}),
|
||||
},
|
||||
body: JSON.stringify({ messages }),
|
||||
body: JSON.stringify({ messages, session_id: sessionId || '' }),
|
||||
signal,
|
||||
});
|
||||
if (res.status === 401) {
|
||||
@@ -980,8 +982,11 @@ export const aiApi = {
|
||||
}
|
||||
return fullContent;
|
||||
},
|
||||
// 获取当前用户对话历史(按时间正序,最近 100 条)
|
||||
getHistory: () => http.get<{ list: ChatHistoryItem[]; total: number }>('/aiops/chat-history'),
|
||||
// 获取当前用户对话历史(按 session_id 过滤,默认最新 session)
|
||||
getHistory: (sessionId?: string) => {
|
||||
const params = sessionId ? `?session_id=${encodeURIComponent(sessionId)}` : '';
|
||||
return http.get<{ list: ChatHistoryItem[]; total: number }>(`/aiops/chat-history${params}`);
|
||||
},
|
||||
// 清空当前用户对话历史
|
||||
clearHistory: () => http.delete('/aiops/chat-history'),
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user