Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: AiAssistantModel #9494

Open
wants to merge 14 commits into
base: feat/growi-ai-next
Choose a base branch
from
142 changes: 142 additions & 0 deletions apps/app/src/features/openai/server/models/ai-assistant.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import {
type IGrantedGroup, GroupType, type IPage, type IUser, type Ref,
} from '@growi/core';
import { type Model, type Document, Schema } from 'mongoose';

import { getOrCreateModel } from '~/server/util/mongoose-utils';

/*
* Objects
*/
const AiAssistantType = {
KNOWLEDGE: 'knowledge',
// EDITOR: 'editor',
// LEARNING: 'learning',
} as const;

const AiAssistantSharingScope = {
PUBLIC: 'public',
ONLY_ME: 'onlyMe',
USER_GROUP: 'userGroup',
} as const;

const AiAssistantLearningScope = {
PUBLIC: 'public',
ONLY_ME: 'onlyMe',
USER_GROUP: 'userGroup',
} as const;


/*
* Interfaces
*/
type AiAssistantType = typeof AiAssistantType[keyof typeof AiAssistantType];
type AiAssistantSharingScope = typeof AiAssistantSharingScope[keyof typeof AiAssistantSharingScope];
type AiAssistantLearningScope = typeof AiAssistantLearningScope[keyof typeof AiAssistantLearningScope];

interface AiAssistant {
name: string;
description: string
additionalInstruction: string
vectorStoreId: string // VectorStoreId of OpenAI Specify (https://platform.openai.com/docs/api-reference/vector-stores/object)
types: AiAssistantType[]
owner: Ref<IUser>
grantedGroups?: IGrantedGroup[];
pages: Ref<IPage>[]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pages って何用途だろ?
個別にページへの参照を追加できるというのも thread 作ったときに便利そうではあるが、vector store 利用との一貫性はないので今使い分けをするのかきちんと設計しておきたい

sharingScope: AiAssistantSharingScope
learningScope: AiAssistantLearningScope
isDeleted: boolean
}

interface AiAssistantDocument extends AiAssistant, Document {}

type AiAssistantModel = Model<AiAssistantDocument>


/*
* Schema Definition
*/
const schema = new Schema<AiAssistantDocument>(
{
name: {
type: String,
required: true,
},
description: {
type: String,
required: true,
default: '',
},
additionalInstruction: {
type: String,
required: true,
default: '',
},
vectorStoreId: {
type: String,
required: true,
},
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VectorStore model を踏襲

vectorStoreId: {
type: String,
required: true,
unique: true,
},

types: [{
type: String,
enum: Object.values(AiAssistantType),
required: true,
}],
owner: {
type: Schema.Types.ObjectId,
ref: 'User',
required: true,
},
pages: [{
type: Schema.Types.ObjectId,
ref: 'Page',
required: true,
}],
grantedGroups: {
type: [{
type: {
type: String,
enum: Object.values(GroupType),
required: true,
default: 'UserGroup',
},
item: {
type: Schema.Types.ObjectId,
refPath: 'grantedGroups.type',
required: true,
index: true,
},
}],
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Page mode を踏襲

type: [{
type: {
type: String,
enum: Object.values(GroupType),
required: true,
default: 'UserGroup',
},
item: {
type: Schema.Types.ObjectId,
refPath: 'grantedGroups.type',
required: true,
index: true,
},
}],
validate: [function(arr) {
if (arr == null) return true;
const uniqueItemValues = new Set(arr.map(e => e.item));
return arr.length === uniqueItemValues.size;
}, 'grantedGroups contains non unique item'],
default: [],
required: true,
},

validate: [function(arr: IGrantedGroup[]): boolean {
if (arr == null) return true;
const uniqueItemValues = new Set(arr.map(e => e.item));
return arr.length === uniqueItemValues.size;
}, 'grantedGroups contains non unique item'],
default: [],
},
sharingScope: {
type: String,
enum: Object.values(AiAssistantSharingScope),
required: true,
},
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

共有範囲

learningScope: {
type: String,
enum: Object.values(AiAssistantLearningScope),
required: true,
},
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 学習範囲
    • VectorStore に保存する権限の範囲を指定
    • アシスタント作成者が閲覧可能な範囲が指定できる

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

名前変えたほうがいいかも。e-learning のためのフィールドと勘違いする。
かといって「実行ユーザー」というのが適当とも思わないんだけどね

あとこれは enum だけではなく UserGroup への参照が必要なのではないか?

isDeleted: {
type: Boolean,
default: false,
required: true,
},
},
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VectorStore model を踏襲

isDeleted: {
type: Boolean,
default: false,
required: true,
},

{
timestamps: true,
},
);

schema.methods.markAsDeleted = async function(): Promise<void> {
this.isDeleted = true;
await this.save();
};
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VectorStore model 踏襲

schema.methods.markAsDeleted = async function(): Promise<void> {
this.isDeleted = true;
await this.save();
};


export default getOrCreateModel<AiAssistantDocument, AiAssistantModel>('AiAssistant', schema);
Loading