feat(core): handle AI subscription for pro models (#13682)

<img width="576" height="251" alt="截屏2025-09-30 14 55 20"
src="https://github.com/user-attachments/assets/947a4ab3-8b34-434d-94a6-afb5dad3d32c"
/>


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

- **New Features**
- Added “Subscribe to AI” action across chat experiences (panel,
content, composer, input, playground, peek view) that launches an in-app
checkout flow.
- Chat content now refreshes subscription status when opened; desktop
chat pages wire the subscription action for seamless checkout.

- **Style**
  - Polished hover state for the subscription icon in chat preferences.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Wu Yue
2025-09-30 18:47:59 +08:00
committed by GitHub
parent 4b3ebd899b
commit 03ef4625bc
11 changed files with 125 additions and 3 deletions
@@ -11,6 +11,7 @@ import { getViewManager } from '@affine/core/blocksuite/manager/view';
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 { useAISubscribe } from '@affine/core/components/hooks/affine/use-ai-subscribe';
import {
AIDraftService,
AIToolsConfigService,
@@ -197,6 +198,7 @@ export const Component = () => {
const confirmModal = useConfirmModal();
const specs = useAISpecs();
const mockStd = useMockStd();
const handleAISubscribe = useAISubscribe();
// init or update ai-chat-content
useEffect(() => {
@@ -233,6 +235,8 @@ export const Component = () => {
content.aiToolsConfigService = framework.get(AIToolsConfigService);
content.subscriptionService = framework.get(SubscriptionService);
content.aiModelService = framework.get(AIModelService);
content.onAISubscribe = handleAISubscribe;
content.createSession = createSession;
content.onOpenDoc = onOpenDoc;
@@ -260,6 +264,7 @@ export const Component = () => {
onContextChange,
specs,
onOpenDoc,
handleAISubscribe,
]);
// init or update header ai-chat-toolbar
@@ -4,6 +4,7 @@ import type { AffineEditorContainer } from '@affine/core/blocksuite/block-suite-
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 { useAISubscribe } from '@affine/core/components/hooks/affine/use-ai-subscribe';
import {
AIDraftService,
AIToolsConfigService,
@@ -63,6 +64,7 @@ export const EditorChatPanel = forwardRef(function EditorChatPanel(
} = useAIChatConfig();
const confirmModal = useConfirmModal();
const specs = useAISpecs();
const handleAISubscribe = useAISubscribe();
useEffect(() => {
if (!editor || !editor.host) return;
@@ -109,6 +111,7 @@ export const EditorChatPanel = forwardRef(function EditorChatPanel(
chatPanelRef.current.subscriptionService =
framework.get(SubscriptionService);
chatPanelRef.current.aiModelService = framework.get(AIModelService);
chatPanelRef.current.onAISubscribe = handleAISubscribe;
containerRef.current?.append(chatPanelRef.current);
} else {
@@ -141,6 +144,7 @@ export const EditorChatPanel = forwardRef(function EditorChatPanel(
playgroundConfig,
confirmModal,
specs,
handleAISubscribe,
]);
const [autoResized, setAutoResized] = useState(false);