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

Manage environment variables with config-manager

Shun Miyazawa 1 год назад
Родитель
Сommit
c4cc4045db

+ 2 - 1
apps/app/src/server/routes/apiv3/openai/chat.ts

@@ -3,6 +3,7 @@ import type { ValidationChain } from 'express-validator';
 import { body } from 'express-validator';
 import { body } from 'express-validator';
 
 
 import type Crowi from '~/server/crowi';
 import type Crowi from '~/server/crowi';
+import { configManager } from '~/server/service/config-manager';
 import { openaiClient } from '~/server/service/openai';
 import { openaiClient } from '~/server/service/openai';
 import { getOrCreateChatAssistant } from '~/server/service/openai/assistant';
 import { getOrCreateChatAssistant } from '~/server/service/openai/assistant';
 import loggerFactory from '~/utils/logger';
 import loggerFactory from '~/utils/logger';
@@ -33,7 +34,7 @@ export const chatHandlersFactory: ChatHandlersFactory = (crowi) => {
   return [
   return [
     accessTokenParser, loginRequiredStrictly, validator, apiV3FormValidator,
     accessTokenParser, loginRequiredStrictly, validator, apiV3FormValidator,
     async(req: Req, res: ApiV3Response) => {
     async(req: Req, res: ApiV3Response) => {
-      const vectorStoreId = process.env.OPENAI_VECTOR_STORE_ID;
+      const vectorStoreId = configManager.getConfig('crowi', 'app:openaiVectorStoreId');
       if (vectorStoreId == null) {
       if (vectorStoreId == null) {
         return res.apiv3Err('OPENAI_VECTOR_STORE_ID is not setup', 503);
         return res.apiv3Err('OPENAI_VECTOR_STORE_ID is not setup', 503);
       }
       }

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

@@ -736,6 +736,42 @@ const ENV_VAR_NAME_TO_CONFIG_INFO = {
     type: ValueType.NUMBER,
     type: ValueType.NUMBER,
     default: 172800, // 2 days
     default: 172800, // 2 days
   },
   },
+  OPENAI_API_KEY: {
+    ns: 'crowi',
+    key: 'app:openaiApiKey',
+    type: ValueType.STRING,
+    default: null,
+  },
+  OPENAI_DIMENSIONS: {
+    ns: 'crowi',
+    key: 'app:openaiDimensions',
+    type: ValueType.NUMBER,
+    default: null,
+  },
+  OPENAI_SEARCH_ASSISTANT_INSTRUCTIONS: {
+    ns: 'crowi',
+    key: 'app:openaiSearchAssistantInstructions',
+    type: ValueType.STRING,
+    default: null,
+  },
+  OPENAI_CHAT_ASSISTANT_INSTRUCTIONS: {
+    ns: 'crowi',
+    key: 'app:openaiChatAssistantInstructions',
+    type: ValueType.STRING,
+    default: null,
+  },
+  OPENAI_ASSISTANT_NAME_SUFFIX: {
+    ns: 'crowi',
+    key: 'app:openaiAssistantNameSuffix',
+    type: ValueType.STRING,
+    default: null,
+  },
+  OPENAI_VECTOR_STORE_ID: {
+    ns: 'crowi',
+    key: 'app:openaiVectorStoreId',
+    type: ValueType.STRING,
+    default: null,
+  },
 };
 };
 
 
 
 

+ 3 - 3
apps/app/src/server/service/openai/assistant/assistant.ts

@@ -35,7 +35,7 @@ const findAssistantByName = async(assistantName: string): Promise<OpenAI.Beta.As
 
 
 const getOrCreateAssistant = async(type: AssistantType): Promise<OpenAI.Beta.Assistant> => {
 const getOrCreateAssistant = async(type: AssistantType): Promise<OpenAI.Beta.Assistant> => {
   const appSiteUrl = configManager.getConfig('crowi', 'app:siteUrl');
   const appSiteUrl = configManager.getConfig('crowi', 'app:siteUrl');
-  const assistantName = `GROWI ${type} Assistant for ${appSiteUrl} ${process.env.OPENAI_ASSISTANT_NAME_SUFFIX}`;
+  const assistantName = `GROWI ${type} Assistant for ${appSiteUrl} ${configManager.getConfig('crowi', 'app:openaiAssistantNameSuffix')}}`;
 
 
   const assistantOnRemote = await findAssistantByName(assistantName);
   const assistantOnRemote = await findAssistantByName(assistantName);
   if (assistantOnRemote != null) {
   if (assistantOnRemote != null) {
@@ -58,7 +58,7 @@ export const getOrCreateSearchAssistant = async(): Promise<OpenAI.Beta.Assistant
 
 
   searchAssistant = await getOrCreateAssistant(AssistantType.SEARCH);
   searchAssistant = await getOrCreateAssistant(AssistantType.SEARCH);
   openaiClient.beta.assistants.update(searchAssistant.id, {
   openaiClient.beta.assistants.update(searchAssistant.id, {
-    instructions: process.env.OPENAI_SEARCH_ASSISTANT_INSTRUCTIONS,
+    instructions: configManager.getConfig('crowi', 'app:openaiSearchAssistantInstructions'),
     tools: [{ type: 'file_search' }],
     tools: [{ type: 'file_search' }],
   });
   });
 
 
@@ -74,7 +74,7 @@ export const getOrCreateChatAssistant = async(): Promise<OpenAI.Beta.Assistant>
 
 
   chatAssistant = await getOrCreateAssistant(AssistantType.CHAT);
   chatAssistant = await getOrCreateAssistant(AssistantType.CHAT);
   openaiClient.beta.assistants.update(chatAssistant.id, {
   openaiClient.beta.assistants.update(chatAssistant.id, {
-    instructions: process.env.OPENAI_CHAT_ASSISTANT_INSTRUCTIONS,
+    instructions: configManager.getConfig('crowi', 'app:openaiChatAssistantInstructions'),
     tools: [{ type: 'file_search' }],
     tools: [{ type: 'file_search' }],
   });
   });
 
 

+ 3 - 1
apps/app/src/server/service/openai/client.ts

@@ -1,5 +1,7 @@
 import OpenAI from 'openai';
 import OpenAI from 'openai';
 
 
+import { configManager } from '~/server/service/config-manager';
+
 export const openaiClient = new OpenAI({
 export const openaiClient = new OpenAI({
-  apiKey: process.env.OPENAI_API_KEY, // This is the default and can be omitted
+  apiKey: configManager?.getConfig('crowi', 'app:openaiApiKey'), // This is the default and can be omitted
 });
 });

+ 3 - 1
apps/app/src/server/service/openai/embeddings.ts

@@ -2,6 +2,8 @@ import crypto from 'crypto';
 
 
 import type { OpenAI } from 'openai';
 import type { OpenAI } from 'openai';
 
 
+import { configManager } from '~/server/service/config-manager';
+
 import { openaiClient } from './client';
 import { openaiClient } from './client';
 
 
 
 
@@ -17,7 +19,7 @@ export const embed = async(input: string, username?: string): Promise<OpenAI.Emb
   const result = await openaiClient.embeddings.create({
   const result = await openaiClient.embeddings.create({
     input,
     input,
     model: 'text-embedding-3-large',
     model: 'text-embedding-3-large',
-    dimensions: Number(process.env.OPENAI_DIMENSIONS),
+    dimensions: configManager.getConfig('crowi', 'app:openaiDimensions'),
     user,
     user,
   });
   });
 
 

+ 3 - 1
apps/app/src/server/service/openai/file-upload.ts

@@ -3,12 +3,14 @@ import { Readable } from 'stream';
 import type { IPageHasId } from '@growi/core';
 import type { IPageHasId } from '@growi/core';
 import { toFile } from 'openai';
 import { toFile } from 'openai';
 
 
+import { configManager } from '~/server/service/config-manager';
+
 import { openaiClient } from './client';
 import { openaiClient } from './client';
 
 
 type PageToUpload = Omit<IPageHasId, 'revision'> & { revision: { body: string } };
 type PageToUpload = Omit<IPageHasId, 'revision'> & { revision: { body: string } };
 
 
 export const fileUpload = async(pages: PageToUpload[]): Promise<void> => {
 export const fileUpload = async(pages: PageToUpload[]): Promise<void> => {
-  const vectorStoreId = process.env.OPENAI_VECTOR_STORE_ID;
+  const vectorStoreId = configManager.getConfig('crowi', 'app:openaiVectorStoreId');
   if (vectorStoreId == null) {
   if (vectorStoreId == null) {
     return;
     return;
   }
   }