mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-07-23 00:46:42 +08:00
fix: skip canvas SSE fetch in chat shared page to eliminate spurious 103 error (#14190)
## What does this PR do?
Fixes the `hint : 103 Only owner of canvas authorized for this
operation` error that appears when opening a **Chat** shared link
(`/chats/share?shared_id=...&from=chat`).
## Root Cause
The Chat shared page (`web/src/pages/next-chats/share/index.tsx`)
unconditionally calls `useFetchFlowSSE()`, which requests
`/api/canvas/getsse/{sharedId}`. This is an Agent Canvas endpoint that
validates canvas ownership. When sharing a **Chat** dialog (not an
Agent):
1. `sharedId` is a `dialog_id`, not a `canvas_id`
2. The API token's `tenant_id` doesn't match any canvas owner
3. The backend returns `code: 103, message: "Only owner of canvas
authorized for this operation."`
4. The global error interceptor in `request.ts` displays it as a
notification: `hint : 103 Only owner of canvas authorized for this
operation.`
## Changes
- **`web/src/hooks/use-agent-request.ts`**: Added an `enabled` parameter
to `useFetchFlowSSE` so callers can conditionally skip the query.
- **`web/src/pages/next-chats/share/index.tsx`**: Only enable
`useFetchFlowSSE` when `from === SharedFrom.Agent`. For Chat shares, the
hook is disabled, avoiding the unnecessary canvas API call entirely.
## Related Issue
Closes #14115
### Type of change
- [x] Bug Fix (non-breaking change which fixes an issue)
---------
Signed-off-by: noob <yixiao121314@outlook.com>
This commit is contained in:
@@ -794,7 +794,7 @@ export function useCancelConversation() {
|
||||
return { data, loading, cancelConversation: mutateAsync };
|
||||
}
|
||||
|
||||
export const useFetchSharedAgent = (): {
|
||||
export const useFetchFlowSSE = (): {
|
||||
data: IFlow;
|
||||
loading: boolean;
|
||||
refetch: () => void;
|
||||
@@ -808,6 +808,7 @@ export const useFetchSharedAgent = (): {
|
||||
} = useQuery({
|
||||
queryKey: [AgentApiAction.FetchSharedAgent, sharedId],
|
||||
initialData: {} as IFlow,
|
||||
enabled: !!sharedId,
|
||||
refetchOnReconnect: false,
|
||||
refetchOnMount: false,
|
||||
refetchOnWindowFocus: false,
|
||||
|
||||
@@ -1265,7 +1265,8 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于
|
||||
includeHeadingContentTip:
|
||||
'启用后,标题下的直接内容将作为一个独立的块保留。子块仅保留标题路径。',
|
||||
rootAsHeading: '将首个切片设为 H0 标题',
|
||||
rootAsHeadingTip: '将首个切片设为全局标题,以确保整个文档层级结构中拥有一致的上下文信息。该功能尤其适用于首段包含关键信息的简历。',
|
||||
rootAsHeadingTip:
|
||||
'将首个切片设为全局标题,以确保整个文档层级结构中拥有一致的上下文信息。该功能尤其适用于首段包含关键信息的简历。',
|
||||
hierarchyTip: `构建标题树并生成独立的块,每个块携带其完整的祖先标题路径(例如 第1部分 › 第3章 › 第2节 + 正文)。\n
|
||||
适用场景:具有独立的、结构性重要章节的文档——如法律条款、法规、合同和技术规范——其中每个块即使没有上下文也能通过其结构位置来识别。`,
|
||||
groupTip: `在选定的标题级别将文档扁平分割,并自动合并相邻的小节以保持内容连续性。不注入父标题路径。\n
|
||||
|
||||
@@ -4,8 +4,7 @@ import MessageItem from '@/components/message-item';
|
||||
import PdfSheet from '@/components/pdf-drawer';
|
||||
import { useClickDrawer } from '@/components/pdf-drawer/hooks';
|
||||
import { useSyncThemeFromParams } from '@/components/theme-provider';
|
||||
import { MessageType, SharedFrom } from '@/constants/chat';
|
||||
import { useFetchSharedAgent } from '@/hooks/use-agent-request';
|
||||
import { MessageType } from '@/constants/chat';
|
||||
import { useFetchExternalChatInfo } from '@/hooks/use-chat-request';
|
||||
import i18n, { changeLanguageAsync } from '@/locales/config';
|
||||
import { buildMessageUuidWithRole } from '@/utils/chat';
|
||||
@@ -20,7 +19,6 @@ import { buildMessageItemReference } from '../utils';
|
||||
const ChatContainer = () => {
|
||||
const {
|
||||
sharedId: conversationId,
|
||||
from,
|
||||
locale,
|
||||
theme,
|
||||
visibleAvatar,
|
||||
@@ -44,15 +42,13 @@ const ChatContainer = () => {
|
||||
const sendDisabled = useSendButtonDisabled(value);
|
||||
const { data: chatInfo } = useFetchExternalChatInfo();
|
||||
|
||||
const { data: flowData } = useFetchSharedAgent();
|
||||
React.useEffect(() => {
|
||||
if (locale && i18n.language !== locale) {
|
||||
changeLanguageAsync(locale);
|
||||
}
|
||||
}, [locale, visibleAvatar]);
|
||||
|
||||
const avatarDialogSrc =
|
||||
from === SharedFrom.Agent ? flowData?.avatar : chatInfo.avatar;
|
||||
const avatarDialogSrc = chatInfo.avatar;
|
||||
|
||||
if (!conversationId) {
|
||||
return <div>empty</div>;
|
||||
|
||||
@@ -144,7 +144,7 @@ const SourceDetailPage = () => {
|
||||
];
|
||||
}, [detail, runSchedule]);
|
||||
|
||||
const { addLoading, handleAddOk } = useAddDataSource({isEdit:true});
|
||||
const { addLoading, handleAddOk } = useAddDataSource({ isEdit: true });
|
||||
|
||||
const onSubmit = useCallback(() => {
|
||||
formRef?.current?.submit();
|
||||
|
||||
@@ -3,7 +3,8 @@ import { useSetModalState } from '@/hooks/common-hooks';
|
||||
import { useGetPaginationWithRouter } from '@/hooks/logic-hooks';
|
||||
import dataSourceService, {
|
||||
dataSourceRebuild,
|
||||
dataSourceResume, dataSourceUpdate,
|
||||
dataSourceResume,
|
||||
dataSourceUpdate,
|
||||
deleteDataSource,
|
||||
featchDataSourceDetail,
|
||||
getDataSourceLogs,
|
||||
@@ -68,7 +69,7 @@ export const useListDataSource = () => {
|
||||
return { list, categorizedList: updatedDataSourceTemplates, isFetching };
|
||||
};
|
||||
|
||||
export const useAddDataSource = ({isEdit=false}:{isEdit?:boolean} ) => {
|
||||
export const useAddDataSource = ({ isEdit = false }: { isEdit?: boolean }) => {
|
||||
const [addSource, setAddSource] = useState<IDataSorceInfo | undefined>(
|
||||
undefined,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user