Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/Sma1lboy/codefox into featu…
Browse files Browse the repository at this point in the history
…re-backend-error-handling-strategy
  • Loading branch information
NarwhalChen committed Jan 12, 2025
2 parents ce77412 + a78d34f commit 988b0ba
Show file tree
Hide file tree
Showing 11 changed files with 710 additions and 687 deletions.
5 changes: 4 additions & 1 deletion backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,21 +41,24 @@
"@types/fs-extra": "^11.0.4",
"@types/normalize-path": "^3.0.2",
"@types/toposort": "^2.0.7",
"toposort": "^2.0.2",
"axios": "^1.7.7",
"bcrypt": "^5.1.1",
"class-validator": "^0.14.1",
"dotenv": "^16.4.7",
"fastembed": "^1.14.1",
"fs-extra": "^11.2.0",
"graphql": "^16.9.0",
"graphql-subscriptions": "^2.0.0",
"graphql-ws": "^5.16.0",
"lodash": "^4.17.21",
"markdown-to-txt": "^2.0.1",
"normalize-path": "^3.0.0",
"openai": "^4.77.0",
"reflect-metadata": "^0.2.2",
"rxjs": "^7.8.1",
"sqlite3": "^5.1.7",
"subscriptions-transport-ws": "^0.11.0",
"toposort": "^2.0.2",
"typeorm": "^0.3.20",
"uuid": "^10.0.0"
},
Expand Down
3 changes: 2 additions & 1 deletion backend/src/chat/chat.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ export class Chat extends SystemBaseModel {
@Column({ nullable: true })
title: string;

@Field({ nullable: true })
// 修改这里
@Field(() => [Message], { nullable: true })
@Column('simple-json', { nullable: true, default: '[]' })
messages: Message[];

Expand Down
9 changes: 2 additions & 7 deletions backend/src/chat/chat.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,9 @@ import { ChatGuard } from '../guard/chat.guard';
import { AuthModule } from '../auth/auth.module';
import { UserService } from 'src/user/user.service';
import { PubSub } from 'graphql-subscriptions';
import { ModelProvider } from 'src/common/model-provider';

@Module({
imports: [
HttpModule,
TypeOrmModule.forFeature([Chat, User, Message]),
AuthModule,
],
imports: [TypeOrmModule.forFeature([Chat, User, Message]), AuthModule],
providers: [
ChatResolver,
ChatProxyService,
Expand All @@ -31,6 +26,6 @@ import { ModelProvider } from 'src/common/model-provider';
useValue: new PubSub(),
},
],
exports: [ChatService, ChatGuard, ModelProvider],
exports: [ChatService, ChatGuard],
})
export class ChatModule {}
5 changes: 2 additions & 3 deletions backend/src/chat/chat.resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ import {
UpdateChatTitleInput,
} from './dto/chat.input';
import { GetUserIdFromToken } from 'src/decorator/get-auth-token.decorator';
import { Inject, Logger, UseGuards } from '@nestjs/common';
import { ChatGuard, MessageGuard } from 'src/guard/chat.guard';
import { Inject, Logger } from '@nestjs/common';
import { JWTAuth } from 'src/decorator/jwt-auth.decorator';
import { PubSubEngine } from 'graphql-subscriptions';
@Resolver('Chat')
Expand Down Expand Up @@ -76,7 +75,7 @@ export class ChatResolver {
await this.chatService.saveMessage(
input.chatId,
accumulatedContent,
MessageRole.Model,
MessageRole.Assistant,
);

return true;
Expand Down
15 changes: 10 additions & 5 deletions backend/src/chat/chat.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,21 @@ import { ModelProvider } from 'src/common/model-provider';
@Injectable()
export class ChatProxyService {
private readonly logger = new Logger('ChatProxyService');
private readonly models: ModelProvider = ModelProvider.getInstance();

constructor(
private httpService: HttpService,
private readonly models: ModelProvider,
) {}
constructor() {}

streamChat(
input: ChatInput,
): CustomAsyncIterableIterator<ChatCompletionChunk> {
return this.models.chat(input.message, input.model, input.chatId);
return this.models.chat(
{
messages: [{ role: MessageRole.User, content: input.message }],
model: input.model,
},
input.model,
input.chatId,
);
}

async fetchModelTags(): Promise<any> {
Expand Down
1 change: 1 addition & 0 deletions backend/src/config/config-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import * as _ from 'lodash';
import { getConfigPath } from './common-path';
import { ConfigType } from 'src/downloader/universal-utils';
import { Logger } from '@nestjs/common';
import * as path from 'path';

export interface ModelConfig {
model: string;
Expand Down
5 changes: 1 addition & 4 deletions backend/src/embedding/openai-embbeding-provider.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { Logger } from '@nestjs/common';
import { EmbeddingModel } from 'fastembed';
import openai, { OpenAI } from 'openai';
import { EmbeddingDownloader } from 'src/downloader/embedding-downloader';
import { OpenAI } from 'openai';

export class OpenAIEmbProvider {
private logger = new Logger(OpenAIEmbProvider.name);
Expand All @@ -26,7 +24,6 @@ export class OpenAIEmbProvider {
input: message,
encoding_format: 'float',
});
console.log(embedding.data[0].embedding);
return embedding.data[0].embedding;
}

Expand Down
94 changes: 47 additions & 47 deletions backend/src/guard/chat.guard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,53 +54,53 @@ export class ChatGuard implements CanActivate {
}
}

@Injectable()
export class MessageGuard implements CanActivate {
constructor(
private readonly chatService: ChatService, // Inject ChatService to fetch chat details
private readonly jwtService: JwtService, // JWT Service to verify tokens
) {}

async canActivate(context: ExecutionContext): Promise<boolean> {
const gqlContext = GqlExecutionContext.create(context);
const request = gqlContext.getContext().req;

// Extract the authorization header
const authHeader = request.headers.authorization;
if (!authHeader || !authHeader.startsWith('Bearer ')) {
throw new UnauthorizedException('Authorization token is missing');
}

// Decode the token to get user information
const token = authHeader.split(' ')[1];
let user: any;
try {
user = this.jwtService.verify(token);
} catch (error) {
throw new UnauthorizedException('Invalid token');
}

// Extract chatId from the request arguments
const args = gqlContext.getArgs();
const { messageId } = args;

// Fetch the message and its associated chat
const message = await this.chatService.getMessageById(messageId);
if (!message) {
throw new UnauthorizedException('Message not found');
}

// Ensure that the user is part of the chat the message belongs to
const chat = message.chat;
if (chat.user.id !== user.userId) {
throw new UnauthorizedException(
'User is not authorized to access this message',
);
}

return true;
}
}
// @Injectable()
// export class MessageGuard implements CanActivate {
// constructor(
// private readonly chatService: ChatService, // Inject ChatService to fetch chat details
// private readonly jwtService: JwtService, // JWT Service to verify tokens
// ) {}

// async canActivate(context: ExecutionContext): Promise<boolean> {
// const gqlContext = GqlExecutionContext.create(context);
// const request = gqlContext.getContext().req;

// // Extract the authorization header
// const authHeader = request.headers.authorization;
// if (!authHeader || !authHeader.startsWith('Bearer ')) {
// throw new UnauthorizedException('Authorization token is missing');
// }

// // Decode the token to get user information
// const token = authHeader.split(' ')[1];
// let user: any;
// try {
// user = this.jwtService.verify(token);
// } catch (error) {
// throw new UnauthorizedException('Invalid token');
// }

// // Extract chatId from the request arguments
// const args = gqlContext.getArgs();
// const { messageId } = args;

// // Fetch the message and its associated chat
// const message = await this.chatService.getMessageById(messageId);
// if (!message) {
// throw new UnauthorizedException('Message not found');
// }

// // Ensure that the user is part of the chat the message belongs to
// const chat = message.chat;
// if (chat.user.id !== user.userId) {
// throw new UnauthorizedException(
// 'User is not authorized to access this message',
// );
// }

// return true;
// }
// }

@Injectable()
export class ChatSubscriptionGuard implements CanActivate {
Expand Down
2 changes: 1 addition & 1 deletion backend/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { downloadAll } from './downloader/universal-utils';
import * as dotenv from 'dotenv';

async function bootstrap() {
dotenv.config(); // 加载 .env 文件中的环境变量
dotenv.config();
const app = await NestFactory.create(AppModule);
app.enableCors({
origin: '*',
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/graphql/schema.gql
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,6 @@ type Query {
getChatDetails(chatId: String!): Chat
getChatHistory(chatId: String!): [Message!]!
getHello: String!
getMessageDetail(messageId: String!): Message
getProjectDetails(projectId: String!): Project!
getUserChats: [Chat!]
getUserProjects: [Project!]!
Expand All @@ -138,7 +137,8 @@ input RegisterUserInput {
}

enum Role {
Model
Assistant
System
User
}

Expand Down
Loading

0 comments on commit 988b0ba

Please sign in to comment.