thread.ts 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. import type { IUserHasId } from '@growi/core/dist/interfaces';
  2. import { ErrorV3 } from '@growi/core/dist/models';
  3. import type { Request, RequestHandler } from 'express';
  4. import type { ValidationChain } from 'express-validator';
  5. import { body } from 'express-validator';
  6. import type Crowi from '~/server/crowi';
  7. import { accessTokenParser } from '~/server/middlewares/access-token-parser';
  8. import { apiV3FormValidator } from '~/server/middlewares/apiv3-form-validator';
  9. import type { ApiV3Response } from '~/server/routes/apiv3/interfaces/apiv3-response';
  10. import loggerFactory from '~/utils/logger';
  11. import { getOpenaiService } from '../services/openai';
  12. import { certifyAiService } from './middlewares/certify-ai-service';
  13. const logger = loggerFactory('growi:routes:apiv3:openai:thread');
  14. type ReqBody = {
  15. aiAssistantId: string,
  16. initialUserMessage: string,
  17. }
  18. type CreateThreadReq = Request<undefined, ApiV3Response, ReqBody> & { user: IUserHasId };
  19. type CreateThreadFactory = (crowi: Crowi) => RequestHandler[];
  20. export const createThreadHandlersFactory: CreateThreadFactory = (crowi) => {
  21. const loginRequiredStrictly = require('~/server/middlewares/login-required')(crowi);
  22. const validator: ValidationChain[] = [
  23. body('aiAssistantId').isMongoId().withMessage('aiAssistantId must be string'),
  24. body('initialUserMessage').isString().withMessage('initialUserMessage must be string'),
  25. ];
  26. return [
  27. accessTokenParser(), loginRequiredStrictly, certifyAiService, validator, apiV3FormValidator,
  28. async(req: CreateThreadReq, res: ApiV3Response) => {
  29. const openaiService = getOpenaiService();
  30. if (openaiService == null) {
  31. return res.apiv3Err(new ErrorV3('GROWI AI is not enabled'), 501);
  32. }
  33. try {
  34. const { aiAssistantId, initialUserMessage } = req.body;
  35. const isAiAssistantUsable = await openaiService.isAiAssistantUsable(aiAssistantId, req.user);
  36. if (!isAiAssistantUsable) {
  37. return res.apiv3Err(new ErrorV3('The specified AI assistant is not usable'), 400);
  38. }
  39. const thread = await openaiService.createThread(req.user._id, aiAssistantId, initialUserMessage);
  40. return res.apiv3(thread);
  41. }
  42. catch (err) {
  43. logger.error(err);
  44. return res.apiv3Err(err);
  45. }
  46. },
  47. ];
  48. };