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
132 changes: 132 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,132 @@
import { type IGrantedGroup, GroupType } from '@growi/core';
import type mongoose from 'mongoose';
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
instruction?: string
Copy link
Member

Choose a reason for hiding this comment

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

特化型アシスタントになったことで、実際使う時の instruction はシステム側で入れると思うんだよね
ナレッジアシスタントとかエディタアシスタントのそれぞれの役割になるように

ユーザーが指定できるのはサブの instruction になるので、additionalInstruction にしておいた方がいいかも

あと description も instruction も not optional でいいと思う。初期値は空文字列にすればいいので。

Copy link
Member Author

Choose a reason for hiding this comment

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

修正済み

vectorStoreId: string // VectorStoreId of OpenAI Specify (https://platform.openai.com/docs/api-reference/vector-stores/object)
types: AiAssistantType[]
grantedGroups: IGrantedGroup[];
pages: mongoose.Types.ObjectId[]
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,
},
instruction: {
type: String,
},
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,
}],
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: [],
required: true,
},
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