perf: 中断SSE、更换测试环境接口
This commit is contained in:
@ -2,6 +2,7 @@ import Http from '@/api';
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { glsWithCatch } from '@/utils/stroage';
|
import { glsWithCatch } from '@/utils/stroage';
|
||||||
import { useEnterpriseStore } from '@/stores/modules/enterprise';
|
import { useEnterpriseStore } from '@/stores/modules/enterprise';
|
||||||
|
export const BASE_PYTHON_URL = 'https://agent.lvfunai.com';
|
||||||
|
|
||||||
// 历史记录-列表
|
// 历史记录-列表
|
||||||
export const getAgentHistory = (id: string) => {
|
export const getAgentHistory = (id: string) => {
|
||||||
@ -28,7 +29,6 @@ export const getConversationList = (params: {}) => {
|
|||||||
return Http.get(`/v1/conversation/message/list`, params);
|
return Http.get(`/v1/conversation/message/list`, params);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const baseUrl = 'https://agent.lvfunai.com';
|
|
||||||
export const getHeaders = () => {
|
export const getHeaders = () => {
|
||||||
const store = useEnterpriseStore();
|
const store = useEnterpriseStore();
|
||||||
return {
|
return {
|
||||||
@ -43,7 +43,7 @@ export const getHeaders = () => {
|
|||||||
* 获取智能体信息
|
* 获取智能体信息
|
||||||
*/
|
*/
|
||||||
export const getAgentData = async () => {
|
export const getAgentData = async () => {
|
||||||
const { data } = await axios.get(`${baseUrl}/api/agent/info`, {
|
const { data } = await axios.get(`${BASE_PYTHON_URL}/api/agent/info`, {
|
||||||
headers: getHeaders(),
|
headers: getHeaders(),
|
||||||
});
|
});
|
||||||
return data;
|
return data;
|
||||||
@ -53,7 +53,7 @@ export const getAgentData = async () => {
|
|||||||
* 生成会话id
|
* 生成会话id
|
||||||
*/
|
*/
|
||||||
export const createSession = async () => {
|
export const createSession = async () => {
|
||||||
const { data } = await axios.get(`${baseUrl}/api/agent/create_session`, {
|
const { data } = await axios.get(`${BASE_PYTHON_URL}/api/agent/create_session`, {
|
||||||
headers: getHeaders(),
|
headers: getHeaders(),
|
||||||
});
|
});
|
||||||
return data;
|
return data;
|
||||||
|
|||||||
@ -24,7 +24,7 @@ export const ANSWER_STYLE = {
|
|||||||
|
|
||||||
export interface UseChatHandlerReturn {
|
export interface UseChatHandlerReturn {
|
||||||
roles?: BubbleListProps['roles'];
|
roles?: BubbleListProps['roles'];
|
||||||
currentTaskId?: Ref<string | null>;
|
generateTeamRunTaskId?: Ref<string | null>;
|
||||||
handleMessage?: (parsedData: { event: string; data: MESSAGE.Answer }) => void;
|
handleMessage?: (parsedData: { event: string; data: MESSAGE.Answer }) => void;
|
||||||
handleOpen?: (data: Response) => void;
|
handleOpen?: (data: Response) => void;
|
||||||
generateLoading?: Ref<boolean>;
|
generateLoading?: Ref<boolean>;
|
||||||
|
|||||||
@ -45,11 +45,16 @@ export default {
|
|||||||
initSse({ message });
|
initSse({ message });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const clearSseController = () => {
|
||||||
|
if (sseController.value) {
|
||||||
|
sseController.value.abort?.();
|
||||||
|
sseController.value = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
// 中止当前正在输出的回答
|
|
||||||
console.log('handleCancel', currentTaskId.value);
|
|
||||||
if (generateLoading.value) {
|
if (generateLoading.value) {
|
||||||
bubbleListRef.value?.abortTypingByKey(currentTaskId.value);
|
bubbleListRef.value?.abortTypingByKey(generateTeamRunTaskId.value);
|
||||||
sseController.value?.abort?.();
|
sseController.value?.abort?.();
|
||||||
}
|
}
|
||||||
if (showRightView.value) {
|
if (showRightView.value) {
|
||||||
@ -60,18 +65,15 @@ export default {
|
|||||||
antdMessage.info('取消生成');
|
antdMessage.info('取消生成');
|
||||||
};
|
};
|
||||||
|
|
||||||
const initSse = (inputInfo: CHAT.TInputInfo): void => {
|
const initSse = async (inputInfo: CHAT.TInputInfo): Promise<void> => {
|
||||||
if (sseController.value) {
|
clearSseController();
|
||||||
sseController.value.abort?.();
|
|
||||||
sseController.value = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { message } = inputInfo;
|
const { message } = inputInfo;
|
||||||
|
|
||||||
generateLoading.value = true;
|
generateLoading.value = true;
|
||||||
|
|
||||||
sseController.value = querySSE({
|
sseController.value = await querySSE({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
handleMessage,
|
handleMessage,
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
@ -93,13 +95,11 @@ export default {
|
|||||||
agent_id: chatStore.agentInfo.agent_id,
|
agent_id: chatStore.agentInfo.agent_id,
|
||||||
});
|
});
|
||||||
if (code === 200) {
|
if (code === 200) {
|
||||||
conversationList.value = [
|
const remoteData = (data.list?.flat(1) ?? []).map((v: any) => ({
|
||||||
...conversationList.value,
|
...v,
|
||||||
...(data.list?.flat(1) ?? []).map((v) => ({
|
teamRunTaskId: v.step_run_id,
|
||||||
...v,
|
}));
|
||||||
teamRunTaskId: v.step_run_id,
|
conversationList.value = [...conversationList.value, ...remoteData];
|
||||||
})),
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -107,7 +107,7 @@ export default {
|
|||||||
roles,
|
roles,
|
||||||
showRightView,
|
showRightView,
|
||||||
rightViewData,
|
rightViewData,
|
||||||
currentTaskId,
|
generateTeamRunTaskId,
|
||||||
handleMessage,
|
handleMessage,
|
||||||
conversationList,
|
conversationList,
|
||||||
generateLoading,
|
generateLoading,
|
||||||
@ -140,6 +140,10 @@ export default {
|
|||||||
{ immediate: true },
|
{ immediate: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
clearSseController();
|
||||||
|
})
|
||||||
|
|
||||||
return () => (
|
return () => (
|
||||||
<div class="chat-view-wrap w-full h-full flex">
|
<div class="chat-view-wrap w-full h-full flex">
|
||||||
<section class="flex-1 flex flex-col pt-20px justify-center relative px-16px">
|
<section class="flex-1 flex flex-col pt-20px justify-center relative px-16px">
|
||||||
|
|||||||
@ -44,7 +44,7 @@ export default function useChatHandler({ initSse }): UseChatHandlerReturn {
|
|||||||
const senderRef = ref(null);
|
const senderRef = ref(null);
|
||||||
const conversationList = ref<any[]>([]);
|
const conversationList = ref<any[]>([]);
|
||||||
const generateLoading = ref<boolean>(false);
|
const generateLoading = ref<boolean>(false);
|
||||||
const currentTaskId = ref<string | null>(null);
|
const generateTeamRunTaskId = ref<string | null>(null);
|
||||||
const showRightView = ref(false);
|
const showRightView = ref(false);
|
||||||
const rightViewData = ref<any>({});
|
const rightViewData = ref<any>({});
|
||||||
const lastTeamRunTaskId = ref<string | null>(null); // 最近一个对话的id
|
const lastTeamRunTaskId = ref<string | null>(null); // 最近一个对话的id
|
||||||
@ -74,9 +74,9 @@ export default function useChatHandler({ initSse }): UseChatHandlerReturn {
|
|||||||
placement: 'start',
|
placement: 'start',
|
||||||
variant: 'borderless',
|
variant: 'borderless',
|
||||||
typing: { step: 2, interval: 100 },
|
typing: { step: 2, interval: 100 },
|
||||||
onTypingComplete: () => {
|
// onTypingComplete: () => {
|
||||||
currentTaskId.value = null;
|
// generateTeamRunTaskId.value = null;
|
||||||
},
|
// },
|
||||||
style: ROLE_STYLE,
|
style: ROLE_STYLE,
|
||||||
},
|
},
|
||||||
[QUESTION_ROLE]: {
|
[QUESTION_ROLE]: {
|
||||||
@ -128,6 +128,7 @@ export default function useChatHandler({ initSse }): UseChatHandlerReturn {
|
|||||||
// 重置生成状态
|
// 重置生成状态
|
||||||
const resetGenerateStatus = () => {
|
const resetGenerateStatus = () => {
|
||||||
generateLoading.value = false;
|
generateLoading.value = false;
|
||||||
|
generateTeamRunTaskId.value = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRemoteRefresh = (item: MESSAGE.Answer) => {
|
const handleRemoteRefresh = (item: MESSAGE.Answer) => {
|
||||||
@ -192,7 +193,7 @@ export default function useChatHandler({ initSse }): UseChatHandlerReturn {
|
|||||||
// 过程节点开始
|
// 过程节点开始
|
||||||
const handleRunTaskStart = (data: MESSAGE.Answer) => {
|
const handleRunTaskStart = (data: MESSAGE.Answer) => {
|
||||||
const { run_id } = data;
|
const { run_id } = data;
|
||||||
currentTaskId.value = run_id;
|
// generateTeamRunTaskId.value = run_id;
|
||||||
conversationList.value.push({
|
conversationList.value.push({
|
||||||
run_id,
|
run_id,
|
||||||
key: run_id,
|
key: run_id,
|
||||||
@ -210,20 +211,15 @@ export default function useChatHandler({ initSse }): UseChatHandlerReturn {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{isFirstRunTask(run_id) && (
|
{isFirstRunTask(run_id) && (
|
||||||
<div class="flex items-center mb-8px">
|
<div
|
||||||
|
class="flex items-center mb-8px cursor-pointer"
|
||||||
|
onClick={() => setRunTaskCollapse(lastTeamRunTaskId.value, !isCollapse)}
|
||||||
|
>
|
||||||
<span class="font-family-medium color-#211F24 text-14px font-400 lh-22px mr-4px">智能思考</span>
|
<span class="font-family-medium color-#211F24 text-14px font-400 lh-22px mr-4px">智能思考</span>
|
||||||
{isCollapse ? (
|
{isCollapse ? (
|
||||||
<IconCaretUp
|
<IconCaretUp size={16} class="color-#211F24 " />
|
||||||
size={16}
|
|
||||||
class="color-#211F24 cursor-pointer"
|
|
||||||
onClick={() => setRunTaskCollapse(lastTeamRunTaskId.value, false)}
|
|
||||||
/>
|
|
||||||
) : (
|
) : (
|
||||||
<IconCaretDown
|
<IconCaretDown size={16} class="color-#211F24" />
|
||||||
size={16}
|
|
||||||
class="color-#211F24 cursor-pointer"
|
|
||||||
onClick={() => setRunTaskCollapse(lastTeamRunTaskId.value, true)}
|
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@ -269,7 +265,7 @@ export default function useChatHandler({ initSse }): UseChatHandlerReturn {
|
|||||||
const handleTeamRunTaskStart = (data: MESSAGE.Answer) => {
|
const handleTeamRunTaskStart = (data: MESSAGE.Answer) => {
|
||||||
const { run_id } = data;
|
const { run_id } = data;
|
||||||
lastTeamRunTaskId.value = run_id;
|
lastTeamRunTaskId.value = run_id;
|
||||||
currentTaskId.value = run_id;
|
generateTeamRunTaskId.value = run_id;
|
||||||
conversationList.value.push({
|
conversationList.value.push({
|
||||||
run_id,
|
run_id,
|
||||||
isTeamRunTask: true,
|
isTeamRunTask: true,
|
||||||
@ -390,7 +386,7 @@ export default function useChatHandler({ initSse }): UseChatHandlerReturn {
|
|||||||
return {
|
return {
|
||||||
roles,
|
roles,
|
||||||
senderRef,
|
senderRef,
|
||||||
currentTaskId,
|
generateTeamRunTaskId,
|
||||||
handleMessage,
|
handleMessage,
|
||||||
generateLoading,
|
generateLoading,
|
||||||
conversationList,
|
conversationList,
|
||||||
|
|||||||
@ -22,7 +22,7 @@ function isString(str: any): str is string {
|
|||||||
* 打字效果Hook
|
* 打字效果Hook
|
||||||
* 当启用打字效果时,返回渐进式显示的内容和打字状态
|
* 当启用打字效果时,返回渐进式显示的内容和打字状态
|
||||||
* 否则直接返回原始内容
|
* 否则直接返回原始内容
|
||||||
*
|
*
|
||||||
* @param content - 原始内容
|
* @param content - 原始内容
|
||||||
* @param typingEnabled - 是否启用打字效果
|
* @param typingEnabled - 是否启用打字效果
|
||||||
* @param typingStep - 每次显示的字符数
|
* @param typingStep - 每次显示的字符数
|
||||||
@ -51,7 +51,7 @@ const useTypedEffect = (
|
|||||||
const prevContentValue = unref(prevContent);
|
const prevContentValue = unref(prevContent);
|
||||||
// 更新上一次的内容记录
|
// 更新上一次的内容记录
|
||||||
setPrevContent(content.value);
|
setPrevContent(content.value);
|
||||||
|
|
||||||
// 如果未启用打字效果且内容为字符串
|
// 如果未启用打字效果且内容为字符串
|
||||||
if (!mergedTypingEnabled.value && isString(content.value)) {
|
if (!mergedTypingEnabled.value && isString(content.value)) {
|
||||||
// 若外部触发中止,则保持当前索引,不再自动跳到全文
|
// 若外部触发中止,则保持当前索引,不再自动跳到全文
|
||||||
|
|||||||
@ -94,7 +94,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
border-radius: 50px;
|
border-radius: 16px;
|
||||||
background-color: var(--BG-200, #f2f3f5);
|
background-color: var(--BG-200, #f2f3f5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,11 +2,9 @@ import { fetchEventSource } from '@microsoft/fetch-event-source';
|
|||||||
import type { EventSourceMessage } from '@microsoft/fetch-event-source';
|
import type { EventSourceMessage } from '@microsoft/fetch-event-source';
|
||||||
import { useEnterpriseStore } from '@/stores/modules/enterprise';
|
import { useEnterpriseStore } from '@/stores/modules/enterprise';
|
||||||
import { glsWithCatch } from '@/utils/stroage';
|
import { glsWithCatch } from '@/utils/stroage';
|
||||||
|
import { BASE_PYTHON_URL } from '@/api/all/chat';
|
||||||
|
|
||||||
const customHost = 'https://agent.lvfunai.com';
|
const DEFAULT_SSE_URL = `${BASE_PYTHON_URL}/api/agent/runs`;
|
||||||
//
|
|
||||||
// const customHost = 'http://localhost:3000';
|
|
||||||
const DEFAULT_SSE_URL = `${customHost}/api/agent/runs`;
|
|
||||||
|
|
||||||
const SSE_HEADERS = {
|
const SSE_HEADERS = {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
@ -42,10 +40,10 @@ export default async (config: SSEConfig, url: string = DEFAULT_SSE_URL): Promise
|
|||||||
handleClose,
|
handleClose,
|
||||||
} = config;
|
} = config;
|
||||||
const store = useEnterpriseStore();
|
const store = useEnterpriseStore();
|
||||||
|
|
||||||
// 创建AbortController实例用于中断请求
|
// 创建AbortController实例用于中断请求
|
||||||
const abortController = new AbortController();
|
const abortController = new AbortController();
|
||||||
|
|
||||||
fetchEventSource(url, {
|
fetchEventSource(url, {
|
||||||
method,
|
method,
|
||||||
// credentials: 'include',
|
// credentials: 'include',
|
||||||
@ -70,21 +68,21 @@ export default async (config: SSEConfig, url: string = DEFAULT_SSE_URL): Promise
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
onerror(error: Error) {
|
onerror(error: Error) {
|
||||||
// console.error('SSE error:', error);
|
// console.error('SSE error:', error);
|
||||||
handleError?.(error);
|
handleError?.(error);
|
||||||
},
|
},
|
||||||
onclose() {
|
onclose() {
|
||||||
// console.log('SSE connection closed');
|
// console.log('SSE connection closed');
|
||||||
handleClose?.();
|
handleClose?.();
|
||||||
},
|
},
|
||||||
async onopen(response: Response) {
|
async onopen(response: Response) {
|
||||||
// console.log('onopen', response);
|
// console.log('onopen', response);
|
||||||
handleOpen?.(response);
|
handleOpen?.(response);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// 返回abort方法供外部调用
|
// 返回abort方法供外部调用
|
||||||
return {
|
return {
|
||||||
abort: () => abortController.abort()
|
abort: () => abortController.abort(),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user