From 79b86b069b9bed4726590dc813612658177666da Mon Sep 17 00:00:00 2001 From: Anthony LC Date: Tue, 1 Jul 2025 11:01:52 +0200 Subject: [PATCH] =?UTF-8?q?fixup!=20=E2=9C=A8(frontend)=20integrate=20new?= =?UTF-8?q?=20Blocknote=20AI=20feature?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../e2e/__tests__/app-impress/doc-editor.spec.ts | 4 ++++ src/frontend/apps/impress/package.json | 2 +- .../docs/doc-editor/components/AI/useAI.tsx | 12 +++++++----- .../features/docs/doc-editor/hook/useSaveDoc.tsx | 13 ++++++++++--- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-editor.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-editor.spec.ts index 2f1b1e8c..781dd77c 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-editor.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-editor.spec.ts @@ -493,6 +493,10 @@ test.describe('Doc Editor', () => { // Check Suggestion menu await page.locator('.bn-block-outer').last().fill('/'); await expect(page.getByText('Write with AI')).toBeVisible(); + + // Reload the page to check that the AI change is still there + await page.goto(page.url()); + await expect(editor.getByText('Bonjour le monde')).toBeVisible(); }); test(`it checks ai_proxy ability`, async ({ page, browserName }) => { diff --git a/src/frontend/apps/impress/package.json b/src/frontend/apps/impress/package.json index 085a7317..8a91d3b7 100644 --- a/src/frontend/apps/impress/package.json +++ b/src/frontend/apps/impress/package.json @@ -19,7 +19,7 @@ }, "dependencies": { "@ag-media/react-pdf-table": "2.0.3", - "@ai-sdk/openai": "1.3.22", + "@ai-sdk/openai-compatible": "0.2.14", "@blocknote/code-block": "0.45.0", "@blocknote/core": "0.45.0", "@blocknote/mantine": "0.45.0", diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/components/AI/useAI.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/components/AI/useAI.tsx index 2d20ad3b..b5df7675 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/components/AI/useAI.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/components/AI/useAI.tsx @@ -1,8 +1,8 @@ -import { createOpenAI } from '@ai-sdk/openai'; +import { createOpenAICompatible } from '@ai-sdk/openai-compatible'; import { createAIExtension, llmFormats } from '@blocknote/xl-ai'; import { useMemo } from 'react'; -import { fetchAPI } from '@/api'; +import { baseApiUrl, fetchAPI } from '@/api'; import { useConfig } from '@/core'; import { Doc } from '@/docs/doc-management'; @@ -17,8 +17,9 @@ export const useAI = (docId: Doc['id'], aiAllowed: boolean) => { return; } - const openai = createOpenAI({ - apiKey: '', // The API key will be set by the AI proxy + const openai = createOpenAICompatible({ + name: 'AI Proxy', + baseURL: `${baseApiUrl('1.0')}documents/${docId}/ai-proxy/`, // Necessary for initialization.. fetch: (input, init) => { // Create a new headers object without the Authorization header const headers = new Headers(init?.headers); @@ -30,7 +31,8 @@ export const useAI = (docId: Doc['id'], aiAllowed: boolean) => { }); }, }); - const model = openai.chat(conf.AI_MODEL); + + const model = openai.chatModel(conf.AI_MODEL); const extension = createAIExtension({ stream: conf.AI_STREAM, diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/hook/useSaveDoc.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/hook/useSaveDoc.tsx index fdbf3357..904f6e6a 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/hook/useSaveDoc.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/hook/useSaveDoc.tsx @@ -37,11 +37,18 @@ export const useSaveDoc = ( ) => { /** * When the AI edit the doc transaction.local is false, - * so we check if the origin is null to know if the change - * is local or not. + * so we check if the origin constructor to know where + * the transaction comes from. + * * TODO: see if we can get the local changes from the AI */ - setIsLocalChange(transaction.local || transaction.origin === null); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access + const transactionOrigin = transaction?.origin?.constructor?.name; + const AI_ORIGIN_CONSTRUCTOR = 'ao'; + + setIsLocalChange( + transaction.local || transactionOrigin === AI_ORIGIN_CONSTRUCTOR, + ); }; yDoc.on('update', onUpdate);