This commit is contained in:
2025-11-04 18:49:37 +08:00
parent b95fff224b
commit 8850a06fea
103 changed files with 15337 additions and 771 deletions

View File

@@ -0,0 +1,238 @@
/**
* @description AI对话相关API
* @author AI Assistant
* @since 2025-11-04
*/
import { api } from '@/apis/index';
import type {
AiConversation,
AiMessage,
ChatRequest,
ChatResponse,
ResultDomain,
StreamCallback
} from '@/types';
/**
* AI对话API服务
*/
export const chatApi = {
/**
* 流式对话SSE
* @param request 对话请求
* @param callback 流式回调
* @returns Promise<ResultDomain<AiMessage>>
*/
async streamChat(request: ChatRequest, callback?: StreamCallback): Promise<ResultDomain<AiMessage>> {
return new Promise((resolve, reject) => {
const eventSource = new EventSource(
`${api.defaults.baseURL}/ai/chat/stream?` +
new URLSearchParams({
agentId: request.agentId,
conversationId: request.conversationId || '',
query: request.query,
knowledgeIds: request.knowledgeIds?.join(',') || ''
})
);
let fullMessage = '';
eventSource.addEventListener('message', (event) => {
const data = event.data;
fullMessage += data;
callback?.onMessage?.(data);
});
eventSource.addEventListener('end', (event) => {
const metadata = JSON.parse(event.data);
callback?.onMessageEnd?.(metadata);
eventSource.close();
resolve({
success: true,
data: metadata as AiMessage,
message: '对话成功'
});
});
eventSource.addEventListener('error', (event: any) => {
const error = new Error(event.data || '对话失败');
callback?.onError?.(error);
eventSource.close();
reject(error);
});
eventSource.onerror = (error) => {
callback?.onError?.(error as Error);
eventSource.close();
reject(error);
};
});
},
/**
* 阻塞式对话(非流式)
* @param request 对话请求
* @returns Promise<ResultDomain<AiMessage>>
*/
async blockingChat(request: ChatRequest): Promise<ResultDomain<AiMessage>> {
const response = await api.post<AiMessage>('/ai/chat/blocking', request);
return response.data;
},
/**
* 停止对话生成
* @param messageId 消息ID
* @returns Promise<ResultDomain<boolean>>
*/
async stopChat(messageId: string): Promise<ResultDomain<boolean>> {
const response = await api.post<boolean>(`/ai/chat/stop/${messageId}`);
return response.data;
},
/**
* 创建新会话
* @param agentId 智能体ID
* @param title 会话标题(可选)
* @returns Promise<ResultDomain<AiConversation>>
*/
async createConversation(agentId: string, title?: string): Promise<ResultDomain<AiConversation>> {
const response = await api.post<AiConversation>('/ai/chat/conversation', {
agentId,
title
});
return response.data;
},
/**
* 获取会话信息
* @param conversationId 会话ID
* @returns Promise<ResultDomain<AiConversation>>
*/
async getConversation(conversationId: string): Promise<ResultDomain<AiConversation>> {
const response = await api.get<AiConversation>(`/ai/chat/conversation/${conversationId}`);
return response.data;
},
/**
* 更新会话
* @param conversation 会话信息
* @returns Promise<ResultDomain<AiConversation>>
*/
async updateConversation(conversation: AiConversation): Promise<ResultDomain<AiConversation>> {
const response = await api.put<AiConversation>('/ai/chat/conversation', conversation);
return response.data;
},
/**
* 删除会话
* @param conversationId 会话ID
* @returns Promise<ResultDomain<boolean>>
*/
async deleteConversation(conversationId: string): Promise<ResultDomain<boolean>> {
const response = await api.delete<boolean>(`/ai/chat/conversation/${conversationId}`);
return response.data;
},
/**
* 获取用户的会话列表
* @param agentId 智能体ID可选
* @returns Promise<ResultDomain<AiConversation[]>>
*/
async listUserConversations(agentId?: string): Promise<ResultDomain<AiConversation[]>> {
const response = await api.get<AiConversation[]>('/ai/chat/conversations', {
params: { agentId }
});
return response.data;
},
/**
* 获取会话的消息列表
* @param conversationId 会话ID
* @returns Promise<ResultDomain<AiMessage[]>>
*/
async listMessages(conversationId: string): Promise<ResultDomain<AiMessage[]>> {
const response = await api.get<AiMessage[]>(`/ai/chat/conversation/${conversationId}/messages`);
return response.data;
},
/**
* 获取单条消息
* @param messageId 消息ID
* @returns Promise<ResultDomain<AiMessage>>
*/
async getMessage(messageId: string): Promise<ResultDomain<AiMessage>> {
const response = await api.get<AiMessage>(`/ai/chat/message/${messageId}`);
return response.data;
},
/**
* 重新生成回答
* @param messageId 原消息ID
* @param callback 流式回调(可选)
* @returns Promise<ResultDomain<AiMessage>>
*/
async regenerateAnswer(messageId: string, callback?: StreamCallback): Promise<ResultDomain<AiMessage>> {
if (callback) {
// 使用流式方式重新生成
return new Promise((resolve, reject) => {
const eventSource = new EventSource(
`${api.defaults.baseURL}/ai/chat/regenerate/${messageId}?stream=true`
);
eventSource.addEventListener('message', (event) => {
callback.onMessage?.(event.data);
});
eventSource.addEventListener('end', (event) => {
const metadata = JSON.parse(event.data);
callback.onMessageEnd?.(metadata);
eventSource.close();
resolve({
success: true,
data: metadata as AiMessage,
message: '重新生成成功'
});
});
eventSource.addEventListener('error', (event: any) => {
const error = new Error(event.data || '重新生成失败');
callback.onError?.(error);
eventSource.close();
reject(error);
});
});
} else {
// 使用阻塞方式重新生成
const response = await api.post<AiMessage>(`/ai/chat/regenerate/${messageId}`);
return response.data;
}
},
/**
* 异步生成会话摘要
* @param conversationId 会话ID
* @returns Promise<ResultDomain<boolean>>
*/
async generateSummary(conversationId: string): Promise<ResultDomain<boolean>> {
const response = await api.post<boolean>(`/ai/chat/conversation/${conversationId}/summary`);
return response.data;
},
/**
* 评价消息
* @param messageId 消息ID
* @param rating 评分1=好评,-1=差评0=取消评价)
* @param feedback 反馈内容(可选)
* @returns Promise<ResultDomain<boolean>>
*/
async rateMessage(messageId: string, rating: number, feedback?: string): Promise<ResultDomain<boolean>> {
const response = await api.post<boolean>(`/ai/chat/message/${messageId}/rate`, {
rating,
feedback
});
return response.data;
}
};