From 008fdfc2342ba3f998c05acc6bcc1970f2ece57c Mon Sep 17 00:00:00 2001 From: akumatus Date: Fri, 28 Feb 2025 12:24:58 +0000 Subject: [PATCH] feat(core): disable ai if value of sever copilot config is false (#10520) Fix issue [AF-2224](https://linear.app/affine-design/issue/AF-2224). --- .../src/blocksuite/ai/chat-panel/index.ts | 32 +++++++++++-------- .../src/blocksuite/ai/extensions/enable-ai.ts | 6 ++-- .../bi-directional-link-panel.tsx | 7 ++-- .../block-suite-editor/lit-adaper.tsx | 6 +++- .../extensions/entry/enable-editor.ts | 5 +-- .../components/affine/ai-onboarding/index.tsx | 9 ++---- .../components/hooks/affine/use-enable-ai.ts | 14 ++++++++ .../workspace/detail-page/detail-page.tsx | 6 ++-- 8 files changed, 52 insertions(+), 33 deletions(-) create mode 100644 packages/frontend/core/src/components/hooks/affine/use-enable-ai.ts diff --git a/packages/frontend/core/src/blocksuite/ai/chat-panel/index.ts b/packages/frontend/core/src/blocksuite/ai/chat-panel/index.ts index e112e4cbc..30ff53539 100644 --- a/packages/frontend/core/src/blocksuite/ai/chat-panel/index.ts +++ b/packages/frontend/core/src/blocksuite/ai/chat-panel/index.ts @@ -297,24 +297,28 @@ export class ChatPanel extends WithDisposable(ShadowlessElement) { }; private readonly _initPanel = async () => { - const userId = (await AIProvider.userInfo)?.id; - if (!userId) return; + try { + const userId = (await AIProvider.userInfo)?.id; + if (!userId) return; - const sessions = await AIProvider.session?.getSessions( - this.doc.workspace.id, - this.doc.id - ); - if (sessions?.length) { - this._chatSessionId = sessions?.[0].id; - await this._updateHistory(); - } - if (this._chatSessionId) { - this._chatContextId = await AIProvider.context?.getContextId( + const sessions = await AIProvider.session?.getSessions( this.doc.workspace.id, - this._chatSessionId + this.doc.id ); + if (sessions?.length) { + this._chatSessionId = sessions?.[0].id; + await this._updateHistory(); + } + if (this._chatSessionId) { + this._chatContextId = await AIProvider.context?.getContextId( + this.doc.workspace.id, + this._chatSessionId + ); + } + await this._updateChips(); + } catch (error) { + console.error(error); } - await this._updateChips(); }; protected override updated(_changedProperties: PropertyValues) { diff --git a/packages/frontend/core/src/blocksuite/ai/extensions/enable-ai.ts b/packages/frontend/core/src/blocksuite/ai/extensions/enable-ai.ts index 2d07fa809..6e4b0c79c 100644 --- a/packages/frontend/core/src/blocksuite/ai/extensions/enable-ai.ts +++ b/packages/frontend/core/src/blocksuite/ai/extensions/enable-ai.ts @@ -1,4 +1,3 @@ -import { FeatureFlagService } from '@affine/core/modules/feature-flag'; import { CodeBlockSpec, EdgelessRootBlockSpec, @@ -18,10 +17,9 @@ import { AIParagraphBlockSpec } from './ai-paragraph'; export function enableAIExtension( specBuilder: SpecBuilder, - framework: FrameworkProvider + framework: FrameworkProvider, + enableAI: boolean ) { - const featureFlagService = framework.get(FeatureFlagService); - const enableAI = featureFlagService.flags.enable_ai.value; if (!enableAI) { return; } diff --git a/packages/frontend/core/src/blocksuite/block-suite-editor/bi-directional-link-panel.tsx b/packages/frontend/core/src/blocksuite/block-suite-editor/bi-directional-link-panel.tsx index cdabedd6b..a56eab5d1 100644 --- a/packages/frontend/core/src/blocksuite/block-suite-editor/bi-directional-link-panel.tsx +++ b/packages/frontend/core/src/blocksuite/block-suite-editor/bi-directional-link-panel.tsx @@ -1,4 +1,5 @@ import { Button, Divider, useLitPortalFactory } from '@affine/component'; +import { useEnableAI } from '@affine/core/components/hooks/affine/use-enable-ai'; import { DocService } from '@affine/core/modules/doc'; import { type Backlink, @@ -143,11 +144,13 @@ const usePreviewExtensions = () => { }; }, [workspaceService]); + const enableAI = useEnableAI(); + const extensions = useMemo(() => { - const specs = enableEditorExtension(framework, 'page'); + const specs = enableEditorExtension(framework, 'page', enableAI); specs.extend([patchReferenceRenderer(reactToLit, referenceRenderer)]); return specs.value; - }, [reactToLit, referenceRenderer, framework]); + }, [reactToLit, referenceRenderer, framework, enableAI]); return [extensions, portals] as const; }; diff --git a/packages/frontend/core/src/blocksuite/block-suite-editor/lit-adaper.tsx b/packages/frontend/core/src/blocksuite/block-suite-editor/lit-adaper.tsx index 62a22d678..da25b82b0 100644 --- a/packages/frontend/core/src/blocksuite/block-suite-editor/lit-adaper.tsx +++ b/packages/frontend/core/src/blocksuite/block-suite-editor/lit-adaper.tsx @@ -6,6 +6,7 @@ import { LitEdgelessEditor, type PageEditor, } from '@affine/core/blocksuite/editors'; +import { useEnableAI } from '@affine/core/components/hooks/affine/use-enable-ai'; import type { DocCustomPropertyInfo } from '@affine/core/modules/db'; import { DocService, DocsService } from '@affine/core/modules/doc'; import type { @@ -129,8 +130,10 @@ const usePatchSpecs = (mode: DocMode) => { const confirmModal = useConfirmModal(); + const enableAI = useEnableAI(); + const patchedSpecs = useMemo(() => { - const builder = enableEditorExtension(framework, mode); + const builder = enableEditorExtension(framework, mode, enableAI); builder.extend( [ @@ -169,6 +172,7 @@ const usePatchSpecs = (mode: DocMode) => { reactToLit, referenceRenderer, featureFlagService, + enableAI, ]); return [ diff --git a/packages/frontend/core/src/blocksuite/extensions/entry/enable-editor.ts b/packages/frontend/core/src/blocksuite/extensions/entry/enable-editor.ts index a59d308c4..9d5e6afe8 100644 --- a/packages/frontend/core/src/blocksuite/extensions/entry/enable-editor.ts +++ b/packages/frontend/core/src/blocksuite/extensions/entry/enable-editor.ts @@ -6,11 +6,12 @@ import { type FrameworkProvider } from '@toeverything/infra'; export function enableEditorExtension( framework: FrameworkProvider, - mode: 'edgeless' | 'page' + mode: 'edgeless' | 'page', + enableAI: boolean ): SpecBuilder { const spec = SpecProvider._.getSpec(mode); enableAffineExtension(spec, framework); - enableAIExtension(spec, framework); + enableAIExtension(spec, framework, enableAI); return spec; } diff --git a/packages/frontend/core/src/components/affine/ai-onboarding/index.tsx b/packages/frontend/core/src/components/affine/ai-onboarding/index.tsx index ecf18f1f2..097f89f89 100644 --- a/packages/frontend/core/src/components/affine/ai-onboarding/index.tsx +++ b/packages/frontend/core/src/components/affine/ai-onboarding/index.tsx @@ -1,7 +1,6 @@ -import { FeatureFlagService } from '@affine/core/modules/feature-flag'; -import { useService } from '@toeverything/infra'; import { Suspense, useCallback, useEffect, useState } from 'react'; +import { useEnableAI } from '../../hooks/affine/use-enable-ai'; import { AIOnboardingEdgeless } from './edgeless.dialog'; import { AIOnboardingLocal } from './local.dialog'; import { AIOnboardingType } from './type'; @@ -28,8 +27,7 @@ const useDismiss = (key: AIOnboardingType) => { export const WorkspaceAIOnboarding = () => { const [dismissLocal] = useDismiss(AIOnboardingType.LOCAL); - const featureFlagService = useService(FeatureFlagService); - const enableAI = featureFlagService.flags.enable_ai.value; + const enableAI = useEnableAI(); return ( @@ -40,8 +38,7 @@ export const WorkspaceAIOnboarding = () => { export const PageAIOnboarding = () => { const [dismissEdgeless] = useDismiss(AIOnboardingType.EDGELESS); - const featureFlagService = useService(FeatureFlagService); - const enableAI = featureFlagService.flags.enable_ai.value; + const enableAI = useEnableAI(); return ( diff --git a/packages/frontend/core/src/components/hooks/affine/use-enable-ai.ts b/packages/frontend/core/src/components/hooks/affine/use-enable-ai.ts new file mode 100644 index 000000000..18115340b --- /dev/null +++ b/packages/frontend/core/src/components/hooks/affine/use-enable-ai.ts @@ -0,0 +1,14 @@ +import { ServerService } from '@affine/core/modules/cloud'; +import { FeatureFlagService } from '@affine/core/modules/feature-flag'; +import { useLiveData, useService } from '@toeverything/infra'; + +export const useEnableAI = () => { + const featureFlagService = useService(FeatureFlagService); + const aiFeature = useLiveData(featureFlagService.flags.enable_ai.$); + + const serverService = useService(ServerService); + const serverConfig = useLiveData(serverService.server.features$); + const aiConfig = serverConfig.copilot; + + return aiFeature && aiConfig; +}; diff --git a/packages/frontend/core/src/desktop/pages/workspace/detail-page/detail-page.tsx b/packages/frontend/core/src/desktop/pages/workspace/detail-page/detail-page.tsx index 2ffa6ed9b..02463469d 100644 --- a/packages/frontend/core/src/desktop/pages/workspace/detail-page/detail-page.tsx +++ b/packages/frontend/core/src/desktop/pages/workspace/detail-page/detail-page.tsx @@ -7,9 +7,9 @@ import { EditorOutlineViewer } from '@affine/core/blocksuite/outline-viewer'; import { PageAIOnboarding } from '@affine/core/components/affine/ai-onboarding'; import { DocPropertySidebar } from '@affine/core/components/doc-properties/sidebar'; import { useAppSettingHelper } from '@affine/core/components/hooks/affine/use-app-setting-helper'; +import { useEnableAI } from '@affine/core/components/hooks/affine/use-enable-ai'; import { DocService } from '@affine/core/modules/doc'; import { EditorService } from '@affine/core/modules/editor'; -import { FeatureFlagService } from '@affine/core/modules/feature-flag'; import { GlobalContextService } from '@affine/core/modules/global-context'; import { PeekViewService } from '@affine/core/modules/peek-view'; import { GuardService } from '@affine/core/modules/permissions'; @@ -72,7 +72,6 @@ const DetailPageImpl = memo(function DetailPageImpl() { docService, workspaceService, globalContextService, - featureFlagService, guardService, } = useServices({ WorkbenchService, @@ -81,7 +80,6 @@ const DetailPageImpl = memo(function DetailPageImpl() { DocService, WorkspaceService, GlobalContextService, - FeatureFlagService, GuardService, }); const workbench = workbenchService.workbench; @@ -107,7 +105,7 @@ const DetailPageImpl = memo(function DetailPageImpl() { // TODO(@eyhn): remove jotai here const [_, setActiveBlockSuiteEditor] = useActiveBlocksuiteEditor(); - const enableAI = featureFlagService.flags.enable_ai.value; + const enableAI = useEnableAI(); useEffect(() => { if (isActiveView) {