feat(core): add ai model switch ui (#12266)

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

![截屏2025-05-14 11.32.41.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/sJGviKxfE3Ap685cl5bj/b92d5c32-fa5a-4afd-93e6-3699347575be.png)

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

## Summary by CodeRabbit

- **New Features**
  - Introduced AI model switching in chat, allowing users to select from multiple AI models during conversations.
  - Added a floating menu for easy AI model selection within the chat interface.
  - Enabled visibility of the AI model switcher through a new experimental feature flag, configurable in workspace settings (canary builds only).

- **Enhancements**
  - Improved session management in the chat panel for smoother model switching and state handling.
  - Updated localization to support the new AI model switch feature in settings.

- **Bug Fixes**
  - None.

- **Chores**
  - Registered new components and services to support AI model switching functionality.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
akumatus
2025-05-15 06:29:37 +00:00
parent 6a13d69dea
commit 9fee8147cb
18 changed files with 271 additions and 25 deletions
@@ -1,4 +1,5 @@
// packages/frontend/core/src/blocksuite/ai/hooks/useChatPanelConfig.ts
import { AIModelSwitchService } from '@affine/core/modules/ai-button/services/model-switch';
import { AINetworkSearchService } from '@affine/core/modules/ai-button/services/network-search';
import { AIReasoningService } from '@affine/core/modules/ai-button/services/reasoning';
import { CollectionService } from '@affine/core/modules/collection';
@@ -21,6 +22,7 @@ export function useAIChatConfig() {
const searchService = framework.get(AINetworkSearchService);
const reasoningService = framework.get(AIReasoningService);
const modelSwitchService = framework.get(AIModelSwitchService);
const docDisplayMetaService = framework.get(DocDisplayMetaService);
const workspaceService = framework.get(WorkspaceService);
const searchMenuService = framework.get(SearchMenuService);
@@ -40,6 +42,10 @@ export function useAIChatConfig() {
setEnabled: reasoningService.setEnabled,
};
const modelSwitchConfig = {
visible: modelSwitchService.visible,
};
const docDisplayConfig = {
getIcon: (docId: string) => {
return docDisplayMetaService.icon$(docId, { type: 'lit' }).value;
@@ -124,5 +130,6 @@ export function useAIChatConfig() {
reasoningConfig,
docDisplayConfig,
searchMenuConfig,
modelSwitchConfig,
};
}