diff --git a/packages/frontend/core/src/blocksuite/presets/ai/_common/config.ts b/packages/frontend/core/src/blocksuite/presets/ai/_common/config.ts index 3b978913e..55504d827 100644 --- a/packages/frontend/core/src/blocksuite/presets/ai/_common/config.ts +++ b/packages/frontend/core/src/blocksuite/presets/ai/_common/config.ts @@ -13,6 +13,7 @@ import { } from '@blocksuite/affine/blocks'; import type { TemplateResult } from 'lit'; +import { TOGGLE_EMPTY_INPUT_ACTIONS } from '../actions/consts'; import { actionToHandler } from '../actions/doc-handler'; import { actionToHandler as edgelessActionToHandler } from '../actions/edgeless-handler'; import { @@ -251,10 +252,17 @@ function edgelessHandler( if (!edgeless) { AIProvider.slots.requestRunInEdgeless.emit({ host }); } else { + const selectedElements = edgeless.service.selection.selectedElements; + if (!selectedElements.length) return; + edgeless.gfx.tool.setTool({ type: 'copilot' }); const currentController = edgeless.gfx.tool.currentTool$.peek() as CopilotTool; - const selectedElements = edgeless.service.selection.selectedElements; + if (!currentController) { + edgeless.gfx.tool.setTool({ type: 'default' }); + return; + } + currentController.updateDragPointsWith(selectedElements, 10); currentController.draggingAreaUpdated.emit(false); // do not show edgeless panel @@ -276,7 +284,8 @@ function edgelessHandler( content: sendAttachments ? '' : markdown, }; }, - trackerOptions + trackerOptions, + TOGGLE_EMPTY_INPUT_ACTIONS.includes(id) )(host); } }; diff --git a/packages/frontend/core/src/blocksuite/presets/ai/actions/consts.ts b/packages/frontend/core/src/blocksuite/presets/ai/actions/consts.ts index f69ca9e0c..340fde432 100644 --- a/packages/frontend/core/src/blocksuite/presets/ai/actions/consts.ts +++ b/packages/frontend/core/src/blocksuite/presets/ai/actions/consts.ts @@ -27,3 +27,4 @@ export const generatingStages: { }; export const INSERT_ABOVE_ACTIONS = ['createHeadings']; +export const TOGGLE_EMPTY_INPUT_ACTIONS = ['createImage', 'makeItReal']; diff --git a/packages/frontend/core/src/blocksuite/presets/ai/actions/edgeless-handler.ts b/packages/frontend/core/src/blocksuite/presets/ai/actions/edgeless-handler.ts index 28a15e201..dbbedffa1 100644 --- a/packages/frontend/core/src/blocksuite/presets/ai/actions/edgeless-handler.ts +++ b/packages/frontend/core/src/blocksuite/presets/ai/actions/edgeless-handler.ts @@ -16,6 +16,7 @@ import { } from '@blocksuite/affine/blocks'; import { assertExists } from '@blocksuite/affine/global/utils'; import { Slice } from '@blocksuite/affine/store'; +import { GfxControllerIdentifier } from '@blocksuite/block-std/gfx'; import { AIChatBlockModel } from '@toeverything/infra'; import type { TemplateResult } from 'lit'; @@ -216,7 +217,8 @@ function actionToStream( attachments?: (string | Blob)[]; seed?: string; } | void>, - trackerOptions?: BlockSuitePresets.TrackerOptions + trackerOptions?: BlockSuitePresets.TrackerOptions, + panelInput?: string ) { const action = AIProvider.actions[id]; @@ -233,7 +235,7 @@ function actionToStream( const options = { ...variants, signal, - input: '', + input: panelInput ?? '', stream: true, control, where, @@ -243,6 +245,12 @@ function actionToStream( workspaceId: host.doc.collection.id, } as Parameters[0]; + const content = ctx.get().content; + if (typeof content === 'string' && !content.length && panelInput) { + ctx.set({ + content: panelInput, + }); + } const data = await extract(host, ctx); if (data) { Object.assign(options, data); @@ -305,6 +313,7 @@ function actionToGeneration( ) { return (host: EditorHost, ctx: CtxRecord) => { return ({ + input, signal, update, finish, @@ -324,7 +333,8 @@ function actionToGeneration( signal, variants, extract, - trackerOptions + trackerOptions, + input )?.(host, ctx); if (!stream) return; @@ -416,7 +426,8 @@ export function actionToHandler( attachments?: (string | Blob)[]; seed?: string; } | void>, - trackerOptions?: BlockSuitePresets.TrackerOptions + trackerOptions?: BlockSuitePresets.TrackerOptions, + toggleEmptyInput?: boolean ) { return (host: EditorHost) => { const aiPanel = getAIPanel(host); @@ -466,14 +477,20 @@ export function actionToHandler( } else if (!isEmpty) { const lastSelected = selectedElements.at(-1)?.id; assertExists(lastSelected); - referenceElement = getSelectedNoteAnchor(host, lastSelected); + const noteAnchor = getSelectedNoteAnchor(host, lastSelected); + referenceElement = noteAnchor; } - if (!referenceElement) return; + if (!referenceElement) { + const gfx = host.std.get(GfxControllerIdentifier); + gfx?.tool.setTool({ type: 'default' }); + edgelessCopilot.lockToolbar(false); + return; + } if (isCreateImageAction || isMakeItRealAction) { togglePanel = async () => { - if (isEmpty) return true; + if (isEmpty || toggleEmptyInput) return true; const { notes, shapes, images, edgelessTexts, embedSyncedDocs } = BlocksUtils.splitElements(selectedElements); const blocks = [ @@ -494,7 +511,11 @@ export function actionToHandler( togglePanel() .then(isEmpty => { - aiPanel.toggle(referenceElement, isEmpty ? undefined : 'placeholder'); + aiPanel.toggle( + referenceElement, + isEmpty ? undefined : 'placeholder', + false + ); }) .catch(console.error); }; diff --git a/packages/frontend/core/src/blocksuite/presets/ai/utils/selection-utils.ts b/packages/frontend/core/src/blocksuite/presets/ai/utils/selection-utils.ts index 5c1a5c608..b203712de 100644 --- a/packages/frontend/core/src/blocksuite/presets/ai/utils/selection-utils.ts +++ b/packages/frontend/core/src/blocksuite/presets/ai/utils/selection-utils.ts @@ -269,7 +269,7 @@ export const getSelectedImagesAsBlobs = async (host: EditorHost) => { }; export const getSelectedNoteAnchor = (host: EditorHost, id: string) => { - return host.querySelector(`[data-portal-block-id="${id}"] .note-background`); + return host.querySelector(`affine-edgeless-note[data-block-id="${id}"]`); }; export function getCopilotSelectedElems(