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

Merge remote-tracking branch 'origin/master' into feat/opentelemetry

Yuki Takei 1 год назад
Родитель
Сommit
9a65036f9b

+ 17 - 24
apps/app/src/features/openai/chat/components/AiChatModal/AiChatModal.tsx

@@ -59,29 +59,6 @@ const AiChatModalSubstance = (): JSX.Element => {
 
   const isGenerating = generatingAnswerMessage != null;
 
-  useEffect(() => {
-    // do nothing when the modal is closed or threadId is already set
-    if (threadId != null) {
-      return;
-    }
-
-    const createThread = async() => {
-      // create thread
-      try {
-        const res = await apiv3Post('/openai/thread');
-        const thread = res.data.thread;
-
-        setThreadId(thread.id);
-      }
-      catch (err) {
-        logger.error(err.toString());
-        toastError(t('modal_aichat.failed_to_create_or_retrieve_thread'));
-      }
-    };
-
-    createThread();
-  }, [t, threadId]);
-
   const submit = useCallback(async(data: FormData) => {
     // do nothing when the assistant is generating an answer
     if (isGenerating) {
@@ -107,12 +84,28 @@ const AiChatModalSubstance = (): JSX.Element => {
     const newAnswerMessage = { id: (logLength + 1).toString(), content: '' };
     setGeneratingAnswerMessage(newAnswerMessage);
 
+    // create thread
+    let currentThreadId = threadId;
+    if (threadId == null) {
+      try {
+        const res = await apiv3Post('/openai/thread');
+        const thread = res.data.thread;
+
+        setThreadId(thread.id);
+        currentThreadId = thread.id;
+      }
+      catch (err) {
+        logger.error(err.toString());
+        toastError(t('modal_aichat.failed_to_create_or_retrieve_thread'));
+      }
+    }
+
     // post message
     try {
       const response = await fetch('/_api/v3/openai/message', {
         method: 'POST',
         headers: { 'Content-Type': 'application/json' },
-        body: JSON.stringify({ userMessage: data.input, threadId, summaryMode: data.summaryMode }),
+        body: JSON.stringify({ userMessage: data.input, threadId: currentThreadId, summaryMode: data.summaryMode }),
       });
 
       if (!response.ok) {

+ 15 - 4
apps/app/src/features/openai/server/services/assistant/assistant.ts

@@ -10,6 +10,16 @@ const AssistantType = {
   CHAT: 'Chat',
 } as const;
 
+const AssistantDefaultModelMap: Record<AssistantType, OpenAI.Chat.ChatModel> = {
+  [AssistantType.SEARCH]: 'gpt-4o-mini',
+  [AssistantType.CHAT]: 'gpt-4o-mini',
+};
+
+const getAssistantModelByType = (type: AssistantType): OpenAI.Chat.ChatModel => {
+  const configKey = `openai:assistantModel:${type.toLowerCase()}`;
+  return configManager.getConfig('crowi', configKey) ?? AssistantDefaultModelMap[type];
+};
+
 type AssistantType = typeof AssistantType[keyof typeof AssistantType];
 
 
@@ -34,22 +44,23 @@ const findAssistantByName = async(assistantName: string): Promise<OpenAI.Beta.As
   return findAssistant(storedAssistants);
 };
 
-const getOrCreateAssistant = async(type: AssistantType): Promise<OpenAI.Beta.Assistant> => {
+const getOrCreateAssistant = async(type: AssistantType, nameSuffix?: string): Promise<OpenAI.Beta.Assistant> => {
   const appSiteUrl = configManager.getConfig('crowi', 'app:siteUrl');
-  const assistantNameSuffix = configManager.getConfig('crowi', 'openai:assistantNameSuffix');
-  const assistantName = `GROWI ${type} Assistant for ${appSiteUrl}${assistantNameSuffix != null ? ` ${assistantNameSuffix}` : ''}`;
+  const assistantName = `GROWI ${type} Assistant for ${appSiteUrl}${nameSuffix != null ? ` ${nameSuffix}` : ''}`;
+  const assistantModel = getAssistantModelByType(type);
 
   const assistant = await findAssistantByName(assistantName)
     ?? (
       await openaiClient.beta.assistants.create({
         name: assistantName,
-        model: 'gpt-4o',
+        model: assistantModel,
       }));
 
   // update instructions
   const instructions = configManager.getConfig('crowi', 'openai:chatAssistantInstructions');
   openaiClient.beta.assistants.update(assistant.id, {
     instructions,
+    model: assistantModel,
     tools: [{ type: 'file_search' }],
   });
 

+ 2 - 2
apps/app/src/server/service/config-loader.ts

@@ -823,9 +823,9 @@ Guideline as a RAG:
     ].join(''),
   },
   /* eslint-enable max-len */
-  OPENAI_ASSISTANT_NAME_SUFFIX: {
+  OPENAI_CHAT_ASSISTANT_MODEL: {
     ns: 'crowi',
-    key: 'openai:assistantNameSuffix',
+    key: 'openai:assistantModel:chat',
     type: ValueType.STRING,
     default: null,
   },