fix(core): doc reference error in ai answer (#13141)

Close [AI-303](https://linear.app/affine-design/issue/AI-303)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Introduced a new AI configuration hook to streamline AI-related
features and integrations.
* Integrated enhanced AI specifications into chat components for
improved AI chat experiences.

* **Refactor**
* Updated chat panels to use the new AI configuration hook, simplifying
extension management and improving maintainability.

* **Chores**
* Improved options handling in the editor view extension for more
flexible configuration.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Wu Yue
2025-07-10 19:44:30 +08:00
committed by GitHub
parent f655e6e8bf
commit 9d5c7dd1e9
4 changed files with 80 additions and 15 deletions

View File

@@ -44,6 +44,8 @@ const optionsSchema = z.object({
.args(z.custom<ConfirmModalProps>().optional(), z.any().optional()),
closeConfirmModal: z.function(),
}),
scope: z.enum(['doc', 'workspace']).optional(),
});
export type AffineEditorViewOptions = z.infer<typeof optionsSchema>;
@@ -93,16 +95,7 @@ export class AffineEditorViewExtension extends ViewExtensionProvider<AffineEdito
if (!options) {
return;
}
const {
framework,
reactToLit,
confirmModal,
} = options;
const docService = framework.get(DocService);
const docsService = framework.get(DocsService);
const editorService = framework.get(EditorService);
const { framework, reactToLit, confirmModal, scope = 'doc' } = options;
const referenceRenderer = this._getCustomReferenceRenderer(framework);
@@ -112,12 +105,20 @@ export class AffineEditorViewExtension extends ViewExtensionProvider<AffineEdito
patchNotificationService(confirmModal),
patchOpenDocExtension(),
patchSideBarService(framework),
patchDocModeService(docService, docsService, editorService),
patchFileSizeLimitExtension(framework),
buildDocDisplayMetaExtension(framework),
patchForAudioEmbedView(reactToLit),
])
.register(patchDocUrlExtensions(framework))
.register(patchQuickSearchService(framework));
if (scope === 'doc') {
const docService = framework.get(DocService);
const docsService = framework.get(DocsService);
const editorService = framework.get(EditorService);
context.register([
patchDocModeService(docService, docsService, editorService),
]);
}
}
}

View File

@@ -0,0 +1,60 @@
import { useConfirmModal, useLitPortalFactory } from '@affine/component';
import { getViewManager } from '@affine/core/blocksuite/manager/view';
import { FeatureFlagService } from '@affine/core/modules/feature-flag';
import { WorkspaceService } from '@affine/core/modules/workspace';
import { useFramework, useLiveData, useServices } from '@toeverything/infra';
import { useMemo } from 'react';
import { useEnableAI } from './use-enable-ai';
export const useAISpecs = () => {
const framework = useFramework();
const enableAI = useEnableAI();
const confirmModal = useConfirmModal();
const [reactToLit, _portals] = useLitPortalFactory();
const { workspaceService, featureFlagService } = useServices({
WorkspaceService,
FeatureFlagService,
});
const enablePDFEmbedPreview = useLiveData(
featureFlagService.flags.enable_pdf_embed_preview.$
);
const isCloud = workspaceService.workspace.flavour !== 'local';
const specs = useMemo(() => {
const manager = getViewManager()
.config.init()
.foundation(framework)
.ai(enableAI, framework)
.editorConfig(framework)
.editorView({
framework,
reactToLit,
confirmModal,
scope: 'workspace',
})
.cloud(framework, isCloud)
.pdf(enablePDFEmbedPreview, reactToLit)
.database(framework)
.linkedDoc(framework)
.paragraph(enableAI)
.mobile(framework)
.electron(framework)
.linkPreview(framework)
.codeBlockHtmlPreview(framework).value;
return manager.get('page');
}, [
framework,
reactToLit,
enableAI,
enablePDFEmbedPreview,
isCloud,
confirmModal,
]);
return specs;
};

View File

@@ -9,6 +9,7 @@ import { AIChatToolbar } from '@affine/core/blocksuite/ai/components/ai-chat-too
import type { PromptKey } from '@affine/core/blocksuite/ai/provider/prompt';
import { NotificationServiceImpl } from '@affine/core/blocksuite/view-extensions/editor-view/notification-service';
import { useAIChatConfig } from '@affine/core/components/hooks/affine/use-ai-chat-config';
import { useAISpecs } from '@affine/core/components/hooks/affine/use-ai-specs';
import {
EventSourceService,
FetchService,
@@ -139,6 +140,7 @@ export const Component = () => {
}, []);
const confirmModal = useConfirmModal();
const specs = useAISpecs();
// init or update ai-chat-content
useEffect(() => {
@@ -154,6 +156,7 @@ export const Component = () => {
content.session = currentSession;
content.workspaceId = workspaceId;
content.extensions = specs;
content.docDisplayConfig = docDisplayConfig;
content.searchMenuConfig = searchMenuConfig;
content.networkSearchConfig = networkSearchConfig;
@@ -191,6 +194,7 @@ export const Component = () => {
workspaceId,
confirmModal,
onContextChange,
specs,
]);
// init or update header ai-chat-toolbar

View File

@@ -3,11 +3,11 @@ import { AIProvider, ChatPanel } from '@affine/core/blocksuite/ai';
import type { AffineEditorContainer } from '@affine/core/blocksuite/block-suite-editor';
import { NotificationServiceImpl } from '@affine/core/blocksuite/view-extensions/editor-view/notification-service';
import { useAIChatConfig } from '@affine/core/components/hooks/affine/use-ai-chat-config';
import { useAISpecs } from '@affine/core/components/hooks/affine/use-ai-specs';
import { WorkspaceDialogService } from '@affine/core/modules/dialogs';
import { FeatureFlagService } from '@affine/core/modules/feature-flag';
import { AppThemeService } from '@affine/core/modules/theme';
import { WorkbenchService } from '@affine/core/modules/workbench';
import { ViewExtensionManagerIdentifier } from '@blocksuite/affine/ext-loader';
import { RefNodeSlotsProvider } from '@blocksuite/affine/inlines/reference';
import { DocModeProvider } from '@blocksuite/affine/shared/services';
import { createSignalFromObservable } from '@blocksuite/affine/shared/utils';
@@ -55,6 +55,7 @@ export const EditorChatPanel = forwardRef(function EditorChatPanel(
playgroundConfig,
} = useAIChatConfig();
const confirmModal = useConfirmModal();
const specs = useAISpecs();
useEffect(() => {
if (!editor || !editor.host) return;
@@ -81,9 +82,7 @@ export const EditorChatPanel = forwardRef(function EditorChatPanel(
chatPanelRef.current.networkSearchConfig = networkSearchConfig;
chatPanelRef.current.reasoningConfig = reasoningConfig;
chatPanelRef.current.playgroundConfig = playgroundConfig;
chatPanelRef.current.extensions = editor.host.std
.get(ViewExtensionManagerIdentifier)
.get('preview-page');
chatPanelRef.current.extensions = specs;
chatPanelRef.current.affineFeatureFlagService =
framework.get(FeatureFlagService);
chatPanelRef.current.affineWorkspaceDialogService = framework.get(
@@ -127,6 +126,7 @@ export const EditorChatPanel = forwardRef(function EditorChatPanel(
reasoningConfig,
playgroundConfig,
confirmModal,
specs,
]);
const [autoResized, setAutoResized] = useState(false);