Browse Source

implement getPageBodyForContext

Yuki Takei 9 months ago
parent
commit
129c18aa9f

+ 42 - 0
apps/app/src/features/openai/client/services/editor-assistant/get-page-body-for-context.ts

@@ -0,0 +1,42 @@
+import type { UseCodeMirrorEditor } from '@growi/editor/dist/client/services/use-codemirror-editor';
+
+/**
+ * Get page body text for AI context processing
+ * @param codeMirrorEditor - CodeMirror editor instance
+ * @param maxLengthBeforeCursor - Maximum number of characters to include before cursor position
+ * @param maxLengthAfterCursor - Maximum number of characters to include after cursor position
+ * @returns Page body text optimized for AI context, or undefined if editor is not available
+ */
+export const getPageBodyForContext = (
+    codeMirrorEditor: UseCodeMirrorEditor | undefined,
+    maxLengthBeforeCursor: number,
+    maxLengthAfterCursor: number,
+): string | undefined => {
+  const doc = codeMirrorEditor?.getDoc();
+  const length = doc?.length ?? 0;
+
+  const maxTotalLength = maxLengthBeforeCursor + maxLengthAfterCursor;
+
+  if (length > maxTotalLength) {
+    // Get cursor position
+    const cursorPos = codeMirrorEditor?.view?.state.selection.main.head ?? 0;
+
+    // Calculate how many characters are available after cursor
+    const availableAfterCursor = length - cursorPos;
+    const charsAfterCursor = Math.min(maxLengthAfterCursor, availableAfterCursor);
+
+    // If chars after cursor is less than maxLengthAfterCursor, add the difference to chars before cursor
+    const shortfall = maxLengthAfterCursor - charsAfterCursor;
+    const charsBeforeCursor = maxLengthBeforeCursor + shortfall;
+
+    // Calculate start position (cursor - charsBeforeCursor, but not less than 0)
+    const startPos = Math.max(0, cursorPos - charsBeforeCursor);
+
+    // Calculate end position
+    const endPos = cursorPos + charsAfterCursor;
+
+    return doc?.slice(startPos, endPos).toString();
+  }
+
+  return codeMirrorEditor?.getDocString();
+};

+ 2 - 12
apps/app/src/features/openai/client/services/editor-assistant/use-editor-assistant.tsx

@@ -34,6 +34,7 @@ import { QuickMenuList } from '../../components/AiAssistant/AiAssistantSidebar/Q
 import { useAiAssistantSidebar } from '../../stores/ai-assistant';
 import { useClientEngineIntegration, shouldUseClientProcessing } from '../client-engine-integration';
 
+import { getPageBodyForContext } from './get-page-body-for-context';
 import { performSearchReplace } from './search-replace-engine';
 
 interface CreateThread {
@@ -156,17 +157,6 @@ export const useEditorAssistant: UseEditorAssistant = () => {
   }, [selectedAiAssistant?._id]);
 
   const postMessage: PostMessage = useCallback(async(threadId, formData) => {
-    const getPageBody = (): string | undefined => {
-      const length = codeMirrorEditor?.getDoc().length ?? 0;
-
-      if (length > 10000) {
-        // TODO: カーソル位置を基準に、カーソル前2000文字、カーソル後8000文字を取得する
-        return codeMirrorEditor?.getDoc().slice(0, 10000).toString();
-      }
-
-      return codeMirrorEditor?.getDocString();
-    };
-
     // Disable UnifiedMergeView when a Form is submitted with UnifiedMergeView enabled
     mutateIsEnableUnifiedMergeView(false);
 
@@ -177,7 +167,7 @@ export const useEditorAssistant: UseEditorAssistant = () => {
         threadId,
         userMessage: formData.input,
         selectedText,
-        pageBody: getPageBody(),
+        pageBody: getPageBodyForContext(codeMirrorEditor, 2000, 8000),
       }),
     });