Shun Miyazawa 1 rok temu
rodzic
commit
a447a9692b

+ 1 - 1
apps/app/src/server/routes/apiv3/openai/rebuild-vector-store.ts

@@ -28,7 +28,7 @@ export const rebuildVectorStoreHandlersFactory: RebuildVectorStoreFactory = (cro
     async(req: Request, res: ApiV3Response) => {
     async(req: Request, res: ApiV3Response) => {
 
 
       try {
       try {
-        await openaiService.rebuildVectorStore();
+        await openaiService.rebuildVectorStoreAll();
         return res.apiv3({});
         return res.apiv3({});
 
 
       }
       }

+ 8 - 0
apps/app/src/server/routes/apiv3/page/update-page.ts

@@ -18,6 +18,8 @@ import { generateAddActivityMiddleware } from '~/server/middlewares/add-activity
 import { GlobalNotificationSettingEvent } from '~/server/models/GlobalNotificationSetting';
 import { GlobalNotificationSettingEvent } from '~/server/models/GlobalNotificationSetting';
 import type { PageDocument, PageModel } from '~/server/models/page';
 import type { PageDocument, PageModel } from '~/server/models/page';
 import { serializePageSecurely, serializeRevisionSecurely } from '~/server/models/serializers';
 import { serializePageSecurely, serializeRevisionSecurely } from '~/server/models/serializers';
+import { configManager } from '~/server/service/config-manager';
+import { openaiService } from '~/server/service/openai/openai';
 import { preNotifyService } from '~/server/service/pre-notify';
 import { preNotifyService } from '~/server/service/pre-notify';
 import { normalizeLatestRevisionIfBroken } from '~/server/service/revision/normalize-latest-revision-if-broken';
 import { normalizeLatestRevisionIfBroken } from '~/server/service/revision/normalize-latest-revision-if-broken';
 import { getYjsService } from '~/server/service/yjs';
 import { getYjsService } from '~/server/service/yjs';
@@ -114,6 +116,12 @@ export const updatePageHandlersFactory: UpdatePageHandlersFactory = (crowi) => {
         logger.error('Create user notification failed', err);
         logger.error('Create user notification failed', err);
       }
       }
     }
     }
+
+    // Rebuild vector store file
+    const aiEnabled = configManager.getConfig('crowi', 'app:aiEnabled');
+    if (aiEnabled) {
+      await openaiService.rebuildVectorStore(updatedPage);
+    }
   }
   }
 
 
   const addActivity = generateAddActivityMiddleware(crowi);
   const addActivity = generateAddActivityMiddleware(crowi);

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

@@ -1,6 +1,6 @@
 import { Readable } from 'stream';
 import { Readable } from 'stream';
 
 
-import { PageGrant } from '@growi/core';
+import { PageGrant, isPopulated } from '@growi/core';
 import type { HydratedDocument } from 'mongoose';
 import type { HydratedDocument } from 'mongoose';
 import mongoose from 'mongoose';
 import mongoose from 'mongoose';
 import { toFile } from 'openai';
 import { toFile } from 'openai';
@@ -11,7 +11,8 @@ import { configManager } from '~/server/service/config-manager';
 import OpenaiClient from './openai-client-delegator';
 import OpenaiClient from './openai-client-delegator';
 
 
 export interface IOpenaiService {
 export interface IOpenaiService {
-  rebuildVectorStore(): Promise<void>;
+  rebuildVectorStoreAll(): Promise<void>;
+  rebuildVectorStore(page: PageDocument): Promise<void>;
 }
 }
 class OpenaiService implements IOpenaiService {
 class OpenaiService implements IOpenaiService {
 
 
@@ -25,7 +26,7 @@ class OpenaiService implements IOpenaiService {
     this.client = new OpenaiClient();
     this.client = new OpenaiClient();
   }
   }
 
 
-  async rebuildVectorStore() {
+  async rebuildVectorStoreAll() {
     // TODO: https://redmine.weseek.co.jp/issues/154364
     // TODO: https://redmine.weseek.co.jp/issues/154364
 
 
     // Create all public pages VectorStoreFile
     // Create all public pages VectorStoreFile
@@ -47,6 +48,16 @@ class OpenaiService implements IOpenaiService {
     await this.client.uploadAndPoll(files);
     await this.client.uploadAndPoll(files);
   }
   }
 
 
+  async rebuildVectorStore(page: PageDocument) {
+    // delete vector store file
+
+    // create vector store file
+    if (page.grant === PageGrant.GRANT_PUBLIC && page.revision != null && isPopulated(page?.revision)) {
+      const file = await toFile(Readable.from(page.revision.body), `${page._id}.md`);
+      await this.client.uploadAndPoll([file]);
+    }
+  }
+
 }
 }
 
 
 export const openaiService = new OpenaiService();
 export const openaiService = new OpenaiService();