Skip to content

Commit

Permalink
Merge pull request #8 from freemocap/jon/users
Browse files Browse the repository at this point in the history
Create User schema
  • Loading branch information
jonmatthis authored Jan 7, 2024
2 parents 1cd6ee3 + 7b7cc64 commit 8220107
Show file tree
Hide file tree
Showing 49 changed files with 331 additions and 408 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@ import { GcpModule } from '../../gcp/gcp.module';
import { LangchainService } from './langchain.service';
import { OpenaiModule } from '../openai/openai.module';
import { DatabaseModule } from '../../database/database.module';
import { LangchainChainService } from './langchain-chain.service';

@Module({
imports: [GcpModule, OpenaiModule, DatabaseModule],
providers: [LangchainService, LangchainChainService, Logger],
exports: [LangchainService, LangchainChainService],
providers: [LangchainService, Logger],
exports: [LangchainService],
})
export class LangchainModule {}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { BufferMemory } from 'langchain/memory';
import { RunnableSequence } from 'langchain/runnables';

@Injectable()
export class LangchainChainService {
export class LangchainService {
private _model: OpenAI<any>;

constructor(
Expand Down Expand Up @@ -62,7 +62,7 @@ export class LangchainChainService {
return { chain, memory };
}

private async demo(chain: RunnableSequence, memory?: BufferMemory) {
public async demo(chain: RunnableSequence, memory?: BufferMemory) {
if (memory) {
console.log(
`Current Memory - await memory.loadMemoryVariables({}): ${JSON.stringify(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { SecretsManagerService } from '../../gcp/secretsManager.service';
import { GcpSecretsService } from '../../gcp/gcp-secrets.service';
import { Injectable } from '@nestjs/common';

@Injectable()
export class OpenaiSecretsService {
constructor(private readonly _sms: SecretsManagerService) {}
constructor(private readonly _sms: GcpSecretsService) {}
async getOpenAIKey() {
const [secret] = await this._sms.getManager().accessSecretVersion({
const [secret] = await this._sms.getSecretsManager().accessSecretVersion({
name: 'projects/588063171007/secrets/OPENAI_API_KEY/versions/latest',
});
return secret.payload.data.toString();
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Logger, Module } from '@nestjs/common';
import { LangchainModule } from '../ai/langchain/langchain.module';
import { ChatbotService } from './chatbot.service';
import { BotService } from './bot.service';

@Module({
imports: [LangchainModule],
providers: [ChatbotService, Logger],
exports: [ChatbotService],
providers: [BotService, Logger],
exports: [BotService],
})
export class ChatbotModule {}
export class BotModule {}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Chatbot } from './chatbot.dto';
import { Chatbot } from './bot.dto';
import { LangchainService } from '../ai/langchain/langchain.service';
import { Injectable, Logger } from '@nestjs/common';
import { LangchainChainService } from '../ai/langchain/langchain-chain.service';

class StreamResponseOptions {
/**
Expand All @@ -11,37 +10,20 @@ class StreamResponseOptions {
}

@Injectable()
export class ChatbotService {
export class BotService {
private _chatbots: Map<string, Chatbot> = new Map();
constructor(
private readonly _logger: Logger,
private readonly _langchainChainService: LangchainChainService,
private readonly _langchainService: LangchainService,
) {}

public async createChatbot(chatbotId: string, modelName?: string) {
public async createBot(chatbotId: string, modelName?: string) {
this._logger.log(
`Creating chatbot with id: ${chatbotId} and model: ${modelName}`,
);
const chain =
await this._langchainService.createMongoMemoryChatChain(modelName);

// @ts-ignore
const chatbot = { chain } as Chatbot;
this._chatbots.set(chatbotId, chatbot);
this._logger.log(`Chatbot with id: ${chatbotId} created successfully`);

return chatbot;
}

public async createChatbot2(chatbotId: string, modelName?: string) {
this._logger.log(
`Creating chatbot with id: ${chatbotId} and model: ${modelName}`,
`Creating chatbot with id: ${chatbotId} and language model (llm): ${modelName}`,
);
const { chain, memory } =
await this._langchainChainService.createBufferMemoryChain(modelName);
await this._langchainService.createBufferMemoryChain(modelName);

// @ts-ignore
const chatbot = { chain, memory } as Chatbot;
this._chatbots.set(chatbotId, chatbot);
this._logger.log(`Chatbot with id: ${chatbotId} created successfully`);
Expand Down
17 changes: 17 additions & 0 deletions src/core/database/database.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { GcpModule } from '../gcp/gcp.module';
import { UsersModule } from './schema/users/users.module';
import { DatabaseConnectionService } from './services/database-connection.service';

@Module({
imports: [
GcpModule,
MongooseModule.forRoot('mongodb://localhost:27017/test'),
// CatsModule,
UsersModule,
],
providers: [],
exports: [UsersModule],
})
export class DatabaseModule {}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
6 changes: 6 additions & 0 deletions src/core/database/schema/users/user.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export class UserDto {
readonly favoriteColor?: string;
readonly slackID?: string;
readonly discordId?: string;
readonly metadata?: object;
}
35 changes: 35 additions & 0 deletions src/core/database/schema/users/user.schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';

@Schema({ timestamps: true })
export class User {
@Prop({ required: true, unique: true })
uuid: string;

@Prop({ required: true })
favoriteColor: string;

@Prop({ unique: true })
discordId: string;

@Prop({ unique: true })
slackId: string;

@Prop({ type: Object })
metadata: Record<string, unknown>;
}

export const UserSchema = SchemaFactory.createForClass(User);

function validateFavoriteColor(color: string) {
const regex = /^([A-Fa-f0-9]{6})$/;
return regex.test(`${color}`);
}

UserSchema.pre<User>('save', function (next) {
if (!validateFavoriteColor(this.favoriteColor)) {
throw new Error(
'User.favoriteColor should be a valid 6 digit hex color code (e.g. FF00FF)',
);
}
next();
});
13 changes: 13 additions & 0 deletions src/core/database/schema/users/users.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { UsersService } from './users.service';
import { User, UserSchema } from './user.schema';

@Module({
imports: [
MongooseModule.forFeature([{ name: User.name, schema: UserSchema }]),
],
providers: [UsersService],
exports: [UsersService],
})
export class UsersModule {}
84 changes: 84 additions & 0 deletions src/core/database/schema/users/users.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { User } from './user.schema';
import { UserDto } from './user.dto';
import { v4 as uuidv4 } from 'uuid';

@Injectable()
export class UsersService {
constructor(
@InjectModel(User.name)
private readonly userModel: Model<User>,
) {}

async findAll(): Promise<User[]> {
return this.userModel.find().exec();
}

async findOne(userDto: UserDto): Promise<User> {
let user: User;
if (userDto.discordId) {
user = await this.userModel
.findOne({ discordId: userDto.discordId })
.exec();
} else if (userDto.slackID) {
user = await this.userModel.findOne({ slackID: userDto.slackID }).exec();
}

return user;
}

async getOrCreate(userDto: UserDto): Promise<User> {
const existingUser = await this.findOne(userDto);

if (existingUser) {
return existingUser;
}

return this.create(userDto);
}

_generateHexColorId() {
const letters = '0123456789ABCDEF';
let color = '';
const digits = 6;
for (let i = 0; i < digits; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}

async create(userDto: UserDto): Promise<User> {
if (await this.findOne(userDto)) {
throw new HttpException('User ID already exists', HttpStatus.CONFLICT);
}

const createdUser = new this.userModel({
...userDto,
uuid: uuidv4(),
favoriteColor: this._generateHexColorId() || userDto.favoriteColor,
});
return createdUser.save();
}

async update(id: string, userDto: UserDto) {
const existingUser = await this.userModel.findOne({ id: id }).exec();
if (!existingUser) {
throw new Error(`User with id ${id} not found`);
}
return this.userModel
.findOneAndUpdate({ id: id }, userDto, { new: true })
.exec();
}

async delete(id: string) {
const deletedUser = await this.userModel
.findOneAndDelete({ id: id })
.exec();
if (!deletedUser) {
throw new Error(`User with id ${id} not found`);
}
return deletedUser;
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { Injectable } from '@nestjs/common';
import { NecordModuleOptions } from 'necord';
import { IntentsBitField } from 'discord.js';
import { SecretsManagerService } from '../../../../shared/gcp/secretsManager.service';
import { ConfigService } from '@nestjs/config';
import { GcpSecretsService } from '../../gcp/gcp-secrets.service';

@Injectable()
export class NecordConfigService {
export class DiscordConfigService {
private _tokenMap = {
DISCORD_BOT_TOKEN:
'projects/588063171007/secrets/DISCORD_BOT_TOKEN/versions/latest',
};
constructor(
private readonly sms: SecretsManagerService,
private readonly sms: GcpSecretsService,
private readonly _cfgService: ConfigService,
) {}

Expand All @@ -30,7 +30,7 @@ export class NecordConfigService {
private async _createTokenByNodeEnv() {
if (process.env.NODE_ENV === 'production') {
const secretName = this._tokenMap.DISCORD_BOT_TOKEN;
const [secret] = await this.sms.getManager().accessSecretVersion({
const [secret] = await this.sms.getSecretsManager().accessSecretVersion({
name: secretName,
});
return secret.payload.data.toString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import { SecretManagerServiceClient } from '@google-cloud/secret-manager';
* in the future, we'll have additional options for the secrets manager stuff from GCP.
*/
@Injectable()
export class SecretsManagerService {
getManager() {
export class GcpSecretsService {
getSecretsManager() {
return new SecretManagerServiceClient();
}
}
8 changes: 8 additions & 0 deletions src/core/gcp/gcp.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Module } from '@nestjs/common';
import { GcpSecretsService } from './gcp-secrets.service';

@Module({
providers: [GcpSecretsService],
exports: [GcpSecretsService],
})
export class GcpModule {}
26 changes: 0 additions & 26 deletions src/interfaces/chat/discord/discord-interface.module.ts

This file was deleted.

40 changes: 0 additions & 40 deletions src/interfaces/chat/discord/services/discordChat.service.ts

This file was deleted.

Loading

0 comments on commit 8220107

Please sign in to comment.