dify
This commit is contained in:
238
schoolNewsWeb/src/apis/ai/chat.ts
Normal file
238
schoolNewsWeb/src/apis/ai/chat.ts
Normal 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;
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user