feat(core): add ai workspace all docs switch (#13345)

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

<img width="272" height="186" alt="截屏2025-07-29 11 54 20"
src="https://github.com/user-attachments/assets/e171fb57-66cf-4244-894d-c27b18cbe83a"
/>


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

* **New Features**
* Introduced an AI tools configuration service, allowing users to
customize AI tool usage (e.g., workspace search, reading docs) in chat
and AI features.
* Added a toggle in chat preferences for enabling or disabling
workspace-wide document search.
* AI chat components now respect user-configured tool settings across
chat, retry, and playground scenarios.

* **Improvements**
* Enhanced chat and AI interfaces to propagate and honor user tool
configuration throughout the frontend and backend.
* Made draft and tool configuration services optional and safely handled
their absence in chat components.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Wu Yue
2025-07-30 10:10:39 +08:00
committed by GitHub
parent 091bac1047
commit f7a094053e
23 changed files with 321 additions and 61 deletions

View File

@@ -1,6 +1,10 @@
export { AIButtonProvider } from './provider/ai-button';
export { AIButtonService } from './services/ai-button';
export { AIDraftService } from './services/ai-draft';
export {
type AIToolsConfig,
AIToolsConfigService,
} from './services/tools-config';
import type { Framework } from '@toeverything/infra';
@@ -13,6 +17,7 @@ import { AIDraftService } from './services/ai-draft';
import { AINetworkSearchService } from './services/network-search';
import { AIPlaygroundService } from './services/playground';
import { AIReasoningService } from './services/reasoning';
import { AIToolsConfigService } from './services/tools-config';
export const configureAIButtonModule = (framework: Framework) => {
framework.service(AIButtonService, container => {
@@ -40,3 +45,7 @@ export function configureAIDraftModule(framework: Framework) {
.scope(WorkspaceScope)
.service(AIDraftService, [GlobalStateService, CacheStorage]);
}
export function configureAIToolsConfigModule(framework: Framework) {
framework.service(AIToolsConfigService, [GlobalStateService]);
}

View File

@@ -0,0 +1,50 @@
import {
createSignalFromObservable,
type Signal,
} from '@blocksuite/affine/shared/utils';
import { LiveData, Service } from '@toeverything/infra';
import { map } from 'rxjs';
import type { GlobalStateService } from '../../storage';
const AI_TOOLS_CONFIG_KEY = 'AIToolsConfig';
export interface AIToolsConfig {
searchWorkspace?: boolean;
readingDocs?: boolean;
}
export class AIToolsConfigService extends Service {
constructor(private readonly globalStateService: GlobalStateService) {
super();
const { signal, cleanup: enabledCleanup } =
createSignalFromObservable<AIToolsConfig>(this.config$, {
searchWorkspace: true,
readingDocs: true,
});
this.config = signal;
this.disposables.push(enabledCleanup);
}
config: Signal<AIToolsConfig>;
private readonly config$ = LiveData.from(
this.globalStateService.globalState.watch<AIToolsConfig>(
AI_TOOLS_CONFIG_KEY
),
undefined
).pipe(
map(config => ({
searchWorkspace: config?.searchWorkspace ?? true,
readingDocs: config?.readingDocs ?? true,
}))
);
setConfig = (data: Partial<AIToolsConfig>) => {
this.globalStateService.globalState.set(AI_TOOLS_CONFIG_KEY, {
...this.config.value,
...data,
});
};
}