Просмотр исходного кода

Reorganize thread creation process

Shun Miyazawa 11 месяцев назад
Родитель
Сommit
160e0f8733

+ 31 - 10
apps/app/src/features/openai/client/components/AiAssistant/AiAssistantSidebar/AiAssistantSidebar.tsx

@@ -8,8 +8,6 @@ import { useTranslation } from 'react-i18next';
 import { Collapse, UncontrolledTooltip } from 'reactstrap';
 import { Collapse, UncontrolledTooltip } from 'reactstrap';
 import SimpleBar from 'simplebar-react';
 import SimpleBar from 'simplebar-react';
 
 
-
-import { apiv3Post } from '~/client/util/apiv3-client';
 import { toastError } from '~/client/util/toastr';
 import { toastError } from '~/client/util/toastr';
 import { useGrowiCloudUri, useIsEnableUnifiedMergeView } from '~/stores-universal/context';
 import { useGrowiCloudUri, useIsEnableUnifiedMergeView } from '~/stores-universal/context';
 import { useEditorMode, EditorMode } from '~/stores-universal/ui';
 import { useEditorMode, EditorMode } from '~/stores-universal/ui';
@@ -17,7 +15,6 @@ import loggerFactory from '~/utils/logger';
 
 
 import type { AiAssistantHasId } from '../../../../interfaces/ai-assistant';
 import type { AiAssistantHasId } from '../../../../interfaces/ai-assistant';
 import { MessageErrorCode, StreamErrorCode } from '../../../../interfaces/message-error';
 import { MessageErrorCode, StreamErrorCode } from '../../../../interfaces/message-error';
-import { ThreadType } from '../../../../interfaces/thread-relation';
 import type { IThreadRelationHasId } from '../../../../interfaces/thread-relation';
 import type { IThreadRelationHasId } from '../../../../interfaces/thread-relation';
 import { useEditorAssistant } from '../../../services/editor-assistant';
 import { useEditorAssistant } from '../../../services/editor-assistant';
 import { useKnowledgeAssistant } from '../../../services/knowledge-assistant';
 import { useKnowledgeAssistant } from '../../../services/knowledge-assistant';
@@ -76,8 +73,14 @@ const AiAssistantSidebarSubstance: React.FC<AiAssistantSidebarSubstanceProps> =
   const { trigger: mutateThreadData } = useSWRMUTxThreads(aiAssistantData?._id);
   const { trigger: mutateThreadData } = useSWRMUTxThreads(aiAssistantData?._id);
   const { trigger: mutateMessageData } = useSWRMUTxMessages(aiAssistantData?._id, threadData?.threadId);
   const { trigger: mutateMessageData } = useSWRMUTxMessages(aiAssistantData?._id, threadData?.threadId);
 
 
-  const { postMessage: postMessageForKnowledgeAssistant, processMessage: processMessageForKnowledgeAssistant } = useKnowledgeAssistant();
   const {
   const {
+    createThread: createThreadForKnowledgeAssistant,
+    postMessage: postMessageForKnowledgeAssistant,
+    processMessage: processMessageForKnowledgeAssistant,
+  } = useKnowledgeAssistant();
+
+  const {
+    createThread: createThreadForEditorAssistant,
     postMessage: postMessageForEditorAssistant,
     postMessage: postMessageForEditorAssistant,
     processMessage: processMessageForEditorAssistant,
     processMessage: processMessageForEditorAssistant,
     accept,
     accept,
@@ -116,6 +119,19 @@ const AiAssistantSidebarSubstance: React.FC<AiAssistantSidebarSubstanceProps> =
     }
     }
   }, [mutateMessageData, threadData]);
   }, [mutateMessageData, threadData]);
 
 
+  const createThread = useCallback(async(initialUserMessage: string) => {
+    if (isEditorAssistant) {
+      const thread = await createThreadForEditorAssistant(selectedAiAssistant?._id);
+      return thread;
+    }
+
+    if (aiAssistantData == null) {
+      return;
+    }
+    const thread = await createThreadForKnowledgeAssistant(aiAssistantData._id, initialUserMessage);
+    return thread;
+  }, [aiAssistantData, createThreadForEditorAssistant, createThreadForKnowledgeAssistant, isEditorAssistant, selectedAiAssistant?._id]);
+
   const isActionButtonShown = useCallback((messageId: string) => {
   const isActionButtonShown = useCallback((messageId: string) => {
     if (!isEditorAssistant) {
     if (!isEditorAssistant) {
       return false;
       return false;
@@ -187,13 +203,18 @@ const AiAssistantSidebarSubstance: React.FC<AiAssistantSidebarSubstanceProps> =
     let currentThreadId_ = currentThreadId;
     let currentThreadId_ = currentThreadId;
     if (currentThreadId_ == null) {
     if (currentThreadId_ == null) {
       try {
       try {
-        const res = await apiv3Post<IThreadRelationHasId>('/openai/thread', {
-          type: isEditorAssistant ? ThreadType.EDITOR : ThreadType.KNOWLEDGE,
-          aiAssistantId: isEditorAssistant ? selectedAiAssistant?._id : aiAssistantData?._id,
-          initialUserMessage: isEditorAssistant ? undefined : newUserMessage.content,
-        });
+        // const res = await apiv3Post<IThreadRelationHasId>('/openai/thread', {
+        //   type: isEditorAssistant ? ThreadType.EDITOR : ThreadType.KNOWLEDGE,
+        //   aiAssistantId: isEditorAssistant ? selectedAiAssistant?._id : aiAssistantData?._id,
+        //   initialUserMessage: isEditorAssistant ? undefined : newUserMessage.content,
+        // });
+
+        const thread = await createThread(newUserMessage.content);
+        if (thread == null) {
+          return;
+        }
 
 
-        const thread = res.data;
+        // const thread = res.data;
 
 
         setCurrentThreadId(thread.threadId);
         setCurrentThreadId(thread.threadId);
         setCurrentThreadTitle(thread.title);
         setCurrentThreadTitle(thread.title);

+ 17 - 0
apps/app/src/features/openai/client/services/editor-assistant.ts

@@ -10,6 +10,7 @@ import { useCodeMirrorEditorIsolated } from '@growi/editor/dist/client/stores/co
 import { useSecondaryYdocs } from '@growi/editor/dist/client/stores/use-secondary-ydocs';
 import { useSecondaryYdocs } from '@growi/editor/dist/client/stores/use-secondary-ydocs';
 import { type Text as YText } from 'yjs';
 import { type Text as YText } from 'yjs';
 
 
+import { apiv3Post } from '~/client/util/apiv3-client';
 import {
 import {
   SseMessageSchema,
   SseMessageSchema,
   SseDetectedDiffSchema,
   SseDetectedDiffSchema,
@@ -26,6 +27,12 @@ import { handleIfSuccessfullyParsed } from '~/features/openai/utils/handle-if-su
 import { useIsEnableUnifiedMergeView } from '~/stores-universal/context';
 import { useIsEnableUnifiedMergeView } from '~/stores-universal/context';
 import { useCurrentPageId } from '~/stores/page';
 import { useCurrentPageId } from '~/stores/page';
 
 
+import type { IThreadRelationHasId } from '../../interfaces/thread-relation';
+import { ThreadType } from '../../interfaces/thread-relation';
+
+interface CreateThread {
+  (aiAssistantId?: string): Promise<IThreadRelationHasId>;
+}
 interface PostMessage {
 interface PostMessage {
   (threadId: string, userMessage: string): Promise<Response>;
   (threadId: string, userMessage: string): Promise<Response>;
 }
 }
@@ -44,6 +51,7 @@ type DetectedDiff = Array<{
 }>
 }>
 
 
 type UseEditorAssistant = () => {
 type UseEditorAssistant = () => {
+  createThread: CreateThread,
   postMessage: PostMessage,
   postMessage: PostMessage,
   processMessage: ProcessMessage,
   processMessage: ProcessMessage,
   accept: () => void,
   accept: () => void,
@@ -119,6 +127,14 @@ export const useEditorAssistant: UseEditorAssistant = () => {
   const yDocs = useSecondaryYdocs(isEnableUnifiedMergeView ?? false, { pageId: currentPageId ?? undefined, useSecondary: isEnableUnifiedMergeView ?? false });
   const yDocs = useSecondaryYdocs(isEnableUnifiedMergeView ?? false, { pageId: currentPageId ?? undefined, useSecondary: isEnableUnifiedMergeView ?? false });
 
 
   // Functions
   // Functions
+  const createThread: CreateThread = useCallback(async(aiAssistantId) => {
+    const response = await apiv3Post<IThreadRelationHasId>('/openai/thread', {
+      type: ThreadType.EDITOR,
+      aiAssistantId,
+    });
+    return response.data;
+  }, []);
+
   const postMessage: PostMessage = useCallback(async(threadId, userMessage) => {
   const postMessage: PostMessage = useCallback(async(threadId, userMessage) => {
     const response = await fetch('/_api/v3/openai/edit', {
     const response = await fetch('/_api/v3/openai/edit', {
       method: 'POST',
       method: 'POST',
@@ -251,6 +267,7 @@ export const useEditorAssistant: UseEditorAssistant = () => {
   }, [codeMirrorEditor, detectedDiff, selectedText, yDocs?.secondaryDoc]);
   }, [codeMirrorEditor, detectedDiff, selectedText, yDocs?.secondaryDoc]);
 
 
   return {
   return {
+    createThread,
     postMessage,
     postMessage,
     processMessage,
     processMessage,
     accept,
     accept,

+ 28 - 1
apps/app/src/features/openai/client/services/knowledge-assistant.ts

@@ -1,18 +1,44 @@
 import { useCallback } from 'react';
 import { useCallback } from 'react';
 
 
+import { apiv3Post } from '~/client/util/apiv3-client';
 import { SseMessageSchema, type SseMessage } from '~/features/openai/interfaces/knowledge-assistant/sse-schemas';
 import { SseMessageSchema, type SseMessage } from '~/features/openai/interfaces/knowledge-assistant/sse-schemas';
 import { handleIfSuccessfullyParsed } from '~/features/openai/utils/handle-if-successfully-parsed';
 import { handleIfSuccessfullyParsed } from '~/features/openai/utils/handle-if-successfully-parsed';
 
 
+import type { IThreadRelationHasId } from '../../interfaces/thread-relation';
+import { ThreadType } from '../../interfaces/thread-relation';
+
+interface CreateThread {
+  (aiAssistantId: string, initialUserMessage: string): Promise<IThreadRelationHasId>;
+}
+
 interface PostMessage {
 interface PostMessage {
   (aiAssistantId: string, threadId: string, userMessage: string, summaryMode?: boolean): Promise<Response>;
   (aiAssistantId: string, threadId: string, userMessage: string, summaryMode?: boolean): Promise<Response>;
 }
 }
+
 interface ProcessMessage {
 interface ProcessMessage {
   (data: unknown, handler: {
   (data: unknown, handler: {
     onMessage: (data: SseMessage) => void}
     onMessage: (data: SseMessage) => void}
   ): void;
   ): void;
 }
 }
 
 
-export const useKnowledgeAssistant = (): { postMessage: PostMessage, processMessage: ProcessMessage } => {
+type UseKnowledgeAssistant = () => {
+  createThread: CreateThread
+  postMessage: PostMessage
+  processMessage: ProcessMessage
+}
+
+export const useKnowledgeAssistant: UseKnowledgeAssistant = () => {
+
+  const createThread: CreateThread = useCallback(async(aiAssistantId, initialUserMessage) => {
+    const response = await apiv3Post<IThreadRelationHasId>('/openai/thread', {
+      type: ThreadType.KNOWLEDGE,
+      aiAssistantId,
+      initialUserMessage,
+    });
+    const thread = response.data;
+    return thread;
+  }, []);
+
   const postMessage: PostMessage = useCallback(async(aiAssistantId, threadId, userMessage, summaryMode) => {
   const postMessage: PostMessage = useCallback(async(aiAssistantId, threadId, userMessage, summaryMode) => {
     const response = await fetch('/_api/v3/openai/message', {
     const response = await fetch('/_api/v3/openai/message', {
       method: 'POST',
       method: 'POST',
@@ -34,6 +60,7 @@ export const useKnowledgeAssistant = (): { postMessage: PostMessage, processMess
   }, []);
   }, []);
 
 
   return {
   return {
+    createThread,
     postMessage,
     postMessage,
     processMessage,
     processMessage,
   };
   };