ai-assistant.ts 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. import { type IGrantedGroup, GroupType } from '@growi/core';
  2. import { type Model, type Document, Schema } from 'mongoose';
  3. import { getOrCreateModel } from '~/server/util/mongoose-utils';
  4. import { type AiAssistant, AiAssistantShareScope, AiAssistantAccessScope } from '../../interfaces/ai-assistant';
  5. import { generateGlobPatterns } from '../utils/generate-glob-patterns';
  6. export interface AiAssistantDocument extends AiAssistant, Document {}
  7. interface AiAssistantModel extends Model<AiAssistantDocument> {
  8. findByPagePaths(pagePaths: string[]): Promise<AiAssistantDocument[]>;
  9. }
  10. /*
  11. * Schema Definition
  12. */
  13. const schema = new Schema<AiAssistantDocument>(
  14. {
  15. name: {
  16. type: String,
  17. required: true,
  18. },
  19. description: {
  20. type: String,
  21. required: true,
  22. default: '',
  23. },
  24. additionalInstruction: {
  25. type: String,
  26. required: true,
  27. default: '',
  28. },
  29. pagePathPatterns: [{
  30. type: String,
  31. required: true,
  32. }],
  33. vectorStore: {
  34. type: Schema.Types.ObjectId,
  35. ref: 'VectorStore',
  36. required: true,
  37. },
  38. owner: {
  39. type: Schema.Types.ObjectId,
  40. ref: 'User',
  41. required: true,
  42. },
  43. grantedGroupsForShareScope: {
  44. type: [{
  45. type: {
  46. type: String,
  47. enum: Object.values(GroupType),
  48. required: true,
  49. default: 'UserGroup',
  50. },
  51. item: {
  52. type: Schema.Types.ObjectId,
  53. refPath: 'grantedGroupsForShareScope.type',
  54. required: true,
  55. index: true,
  56. },
  57. }],
  58. validate: [function(arr: IGrantedGroup[]): boolean {
  59. if (arr == null) return true;
  60. const uniqueItemValues = new Set(arr.map(e => e.item));
  61. return arr.length === uniqueItemValues.size;
  62. }, 'grantedGroups contains non unique item'],
  63. default: [],
  64. },
  65. grantedGroupsForAccessScope: {
  66. type: [{
  67. type: {
  68. type: String,
  69. enum: Object.values(GroupType),
  70. required: true,
  71. default: 'UserGroup',
  72. },
  73. item: {
  74. type: Schema.Types.ObjectId,
  75. refPath: 'grantedGroupsForAccessScope.type',
  76. required: true,
  77. index: true,
  78. },
  79. }],
  80. validate: [function(arr: IGrantedGroup[]): boolean {
  81. if (arr == null) return true;
  82. const uniqueItemValues = new Set(arr.map(e => e.item));
  83. return arr.length === uniqueItemValues.size;
  84. }, 'grantedGroups contains non unique item'],
  85. default: [],
  86. },
  87. shareScope: {
  88. type: String,
  89. enum: Object.values(AiAssistantShareScope),
  90. required: true,
  91. },
  92. accessScope: {
  93. type: String,
  94. enum: Object.values(AiAssistantAccessScope),
  95. required: true,
  96. },
  97. },
  98. {
  99. timestamps: true,
  100. },
  101. );
  102. schema.statics.findByPagePaths = async function(pagePaths: string[]): Promise<AiAssistantDocument[]> {
  103. const pagePathsWithGlobPattern = pagePaths.map(pagePath => generateGlobPatterns(pagePath)).flat();
  104. const assistants = await this.find({
  105. $or: [
  106. // Case 1: Exact match
  107. { pagePathPatterns: { $in: pagePaths } },
  108. // Case 2: Glob pattern match
  109. { pagePathPatterns: { $in: pagePathsWithGlobPattern } },
  110. ],
  111. }).populate('vectorStore');
  112. return assistants;
  113. };
  114. export default getOrCreateModel<AiAssistantDocument, AiAssistantModel>('AiAssistant', schema);