Răsfoiți Sursa

Add pagination support

Shun Miyazawa 1 an în urmă
părinte
comite
bc4db2c897

+ 11 - 2
apps/app/src/features/openai/server/routes/get-messages.ts

@@ -20,6 +20,9 @@ type GetMessagesFactory = (crowi: Crowi) => RequestHandler[];
 type ReqParam = {
   threadId: string,
   aiAssistantId: string,
+  before?: string,
+  after?: string,
+  limit?: number,
 }
 
 type Req = Request<ReqParam, Response, undefined> & {
@@ -32,6 +35,9 @@ export const getMessagesFactory: GetMessagesFactory = (crowi) => {
   const validator: ValidationChain[] = [
     param('threadId').isString().withMessage('threadId must be string'),
     param('aiAssistantId').isMongoId().withMessage('aiAssistantId must be string'),
+    param('limit').optional().isInt().withMessage('limit must be integer'),
+    param('before').optional().isString().withMessage('before must be string'),
+    param('after').optional().isString().withMessage('after must be string'),
   ];
 
   return [
@@ -43,14 +49,17 @@ export const getMessagesFactory: GetMessagesFactory = (crowi) => {
       }
 
       try {
-        const { threadId, aiAssistantId } = req.params;
+        const {
+          threadId, aiAssistantId, limit, before, after,
+        } = req.params;
 
         const isAiAssistantUsable = openaiService.isAiAssistantUsable(aiAssistantId, req.user);
         if (!isAiAssistantUsable) {
           return res.apiv3Err(new ErrorV3('The specified AI assistant is not usable'), 400);
         }
 
-        const messages = await openaiService.getMessageData(threadId, req.user.lang);
+        const options = { limit, before, after };
+        const messages = await openaiService.getMessageData(threadId, req.user.lang, options);
 
         return res.apiv3({ messages });
       }

+ 6 - 2
apps/app/src/features/openai/server/services/client-delegator/azure-openai-client-delegator.ts

@@ -38,8 +38,12 @@ export class AzureOpenaiClientDelegator implements IOpenaiClientDelegator {
     return this.client.beta.threads.del(threadId);
   }
 
-  async getMessages(threadId: string): Promise<OpenAI.Beta.Threads.Messages.MessagesPage> {
-    return this.client.beta.threads.messages.list(threadId);
+  async getMessages(threadId: string, options?: { before: string, after: string, limit: number }): Promise<OpenAI.Beta.Threads.Messages.MessagesPage> {
+    return this.client.beta.threads.messages.list(threadId, {
+      limit: options?.limit,
+      before: options?.before,
+      after: options?.after,
+    });
   }
 
   async createVectorStore(name: string): Promise<OpenAI.Beta.VectorStores.VectorStore> {

+ 1 - 1
apps/app/src/features/openai/server/services/client-delegator/interfaces.ts

@@ -5,7 +5,7 @@ export interface IOpenaiClientDelegator {
   createThread(vectorStoreId: string): Promise<OpenAI.Beta.Threads.Thread>
   retrieveThread(threadId: string): Promise<OpenAI.Beta.Threads.Thread>
   deleteThread(threadId: string): Promise<OpenAI.Beta.Threads.ThreadDeleted>
-  getMessages(threadId: string): Promise<OpenAI.Beta.Threads.Messages.MessagesPage>
+  getMessages(threadId: string, options?: { limit: number, before: string, after: string }): Promise<OpenAI.Beta.Threads.Messages.MessagesPage>
   retrieveVectorStore(vectorStoreId: string): Promise<OpenAI.Beta.VectorStores.VectorStore>
   createVectorStore(name: string): Promise<OpenAI.Beta.VectorStores.VectorStore>
   deleteVectorStore(vectorStoreId: string): Promise<OpenAI.Beta.VectorStores.VectorStoreDeleted>

+ 6 - 2
apps/app/src/features/openai/server/services/client-delegator/openai-client-delegator.ts

@@ -41,8 +41,12 @@ export class OpenaiClientDelegator implements IOpenaiClientDelegator {
     return this.client.beta.threads.del(threadId);
   }
 
-  async getMessages(threadId: string): Promise<OpenAI.Beta.Threads.Messages.MessagesPage> {
-    return this.client.beta.threads.messages.list(threadId);
+  async getMessages(threadId: string, options?: { before?: string, after?: string, limit?: number }): Promise<OpenAI.Beta.Threads.Messages.MessagesPage> {
+    return this.client.beta.threads.messages.list(threadId, {
+      limit: options?.limit,
+      before: options?.before,
+      after: options?.after,
+    });
   }
 
   async createVectorStore(name: string): Promise<OpenAI.Beta.VectorStores.VectorStore> {

+ 7 - 3
apps/app/src/features/openai/server/services/openai.ts

@@ -68,7 +68,9 @@ export interface IOpenaiService {
   // getOrCreateVectorStoreForPublicScope(): Promise<VectorStoreDocument>;
   deleteExpiredThreads(limit: number, apiCallInterval: number): Promise<void>; // for CronJob
   deleteObsolatedVectorStoreRelations(): Promise<void> // for CronJob
-  getMessageData(threadId: string, lang?: Lang): Promise<OpenAI.Beta.Threads.Messages.MessagesPage>;
+  getMessageData(
+    threadId: string, lang?: Lang, options?: { before?: string, after?: string, limit?: number }
+  ): Promise<OpenAI.Beta.Threads.Messages.MessagesPage>;
   getVectorStoreRelation(aiAssistantId: string): Promise<VectorStoreDocument>
   getVectorStoreRelationsByPageIds(pageId: Types.ObjectId[]): Promise<VectorStoreDocument[]>;
   createVectorStoreFile(vectorStoreRelation: VectorStoreDocument, pages: PageDocument[]): Promise<void>;
@@ -153,8 +155,10 @@ class OpenaiService implements IOpenaiService {
     await ThreadRelationModel.deleteMany({ threadId: { $in: deletedThreadIds } });
   }
 
-  async getMessageData(threadId: string, lang?: Lang): Promise<OpenAI.Beta.Threads.Messages.MessagesPage> {
-    const messages = await this.client.getMessages(threadId);
+  async getMessageData(
+      threadId: string, lang?: Lang, options?: { limit: number, before: string, after: string },
+  ): Promise<OpenAI.Beta.Threads.Messages.MessagesPage> {
+    const messages = await this.client.getMessages(threadId, options);
 
     for await (const message of messages.data) {
       for await (const content of message.content) {