Skip to content

Commit cfde73f

Browse files
authored
Merge pull request #389 from Quickchive/feat/add-groq
feat: add groq service
2 parents 0ba0126 + b047d8b commit cfde73f

File tree

13 files changed

+121
-38
lines changed

13 files changed

+121
-38
lines changed

package-lock.json

Lines changed: 29 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
"cross-env": "^7.0.3",
5757
"crypto-js": "^4.1.1",
5858
"form-data": "^4.0.0",
59+
"groq-sdk": "^0.15.0",
5960
"ioredis": "^5.3.2",
6061
"joi": "^17.6.0",
6162
"openai": "^4.80.0",

src/ai/ai.service.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export interface AiService {
2+
chat(chatRequest: {
3+
messages: any[];
4+
model: string;
5+
temperature: number;
6+
responseType: string;
7+
}): Promise<string | null>;
8+
}
9+
10+
export const AiService = Symbol('AiService');

src/ai/groq/groq.service.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { Injectable } from '@nestjs/common';
2+
import { ConfigService } from '@nestjs/config';
3+
import Groq from 'groq-sdk';
4+
import { AiService } from '../ai.service';
5+
6+
@Injectable()
7+
export class GroqService implements AiService {
8+
private readonly groq: Groq;
9+
10+
constructor(private readonly configService: ConfigService) {
11+
this.groq = new Groq({
12+
apiKey: this.configService.get('GROQ_API_KEY'),
13+
});
14+
}
15+
async chat({
16+
messages,
17+
model,
18+
temperature,
19+
responseType,
20+
}: {
21+
messages: any[];
22+
model: string;
23+
temperature: number;
24+
responseType: string;
25+
}): Promise<string | null> {
26+
const response = await this.groq.chat.completions.create({
27+
messages,
28+
model,
29+
temperature,
30+
response_format: {
31+
type: responseType as 'text' | 'json_object' | undefined,
32+
},
33+
});
34+
35+
return response.choices[0].message.content;
36+
}
37+
}

src/ai/openai.module.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { Module } from '@nestjs/common';
2+
import { GroqService } from './groq/groq.service';
3+
import { AiService } from './ai.service';
4+
5+
@Module({
6+
providers: [{ provide: AiService, useClass: GroqService }],
7+
exports: [{ provide: AiService, useClass: GroqService }],
8+
})
9+
export class AiModule {}
File renamed without changes.

src/openai/openai.service.ts renamed to src/ai/openai/openai.service.ts

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
import { Injectable } from '@nestjs/common';
22
import { ConfigService } from '@nestjs/config';
33

4-
import { CreateCompletionBodyDto } from './dto/create-completion.dto';
54
import OpenAI from 'openai';
6-
import { ChatCompletion } from 'openai/resources';
5+
import {
6+
ResponseFormatJSONObject,
7+
ResponseFormatJSONSchema,
8+
ResponseFormatText,
9+
} from 'openai/resources';
10+
import { AiService } from '../ai.service';
711

812
@Injectable()
9-
export class OpenaiService {
13+
export class OpenaiService implements AiService {
1014
private readonly openAIApi: OpenAI;
1115
constructor(private readonly configService: ConfigService) {
1216
this.openAIApi = new OpenAI({
@@ -15,26 +19,31 @@ export class OpenaiService {
1519
});
1620
}
1721

18-
async createChatCompletion({
19-
question,
22+
async chat({
23+
messages,
2024
model,
2125
temperature,
2226
responseType,
23-
}: CreateCompletionBodyDto): Promise<ChatCompletion> {
27+
}: {
28+
messages: any[];
29+
model: string;
30+
temperature: number;
31+
responseType: string;
32+
}): Promise<string | null> {
2433
try {
2534
const response = await this.openAIApi.chat.completions.create({
2635
model: model || 'gpt-4o-mini',
27-
messages: [
28-
{
29-
role: 'user',
30-
content: question,
31-
},
32-
],
36+
messages,
3337
temperature: temperature || 0.1,
34-
...(responseType && { response_format: responseType }),
38+
...(responseType && {
39+
response_format: responseType as unknown as
40+
| ResponseFormatText
41+
| ResponseFormatJSONObject
42+
| ResponseFormatJSONSchema,
43+
}),
3544
});
3645

37-
return response;
46+
return response.choices[0].message.content;
3847
} catch (e) {
3948
throw e;
4049
}

src/app.module.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { CollectionsModule } from './collections/collections.module';
1212
import { BatchModule } from './batch/batch.module';
1313
import { SummaryModule } from './summary/summary.module';
1414
import { TypeOrmConfigService } from './database/typerom-config.service';
15-
import { OpenaiModule } from './openai/openai.module';
15+
import { AiModule } from './ai/openai.module';
1616
import { AppController } from './app.controller';
1717
import { AopModule } from './common/aop/aop.module';
1818
import { InfraModule } from './infra/infra.module';
@@ -106,7 +106,6 @@ import { InfraModule } from './infra/infra.module';
106106
? process.env.NAVER_CLOVA_SUMMARY_REQUEST_URL
107107
: '',
108108
}),
109-
OpenaiModule,
110109
AopModule,
111110
InfraModule,
112111
],

src/categories/category.module.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Module } from '@nestjs/common';
22
import { ContentsModule } from '../contents/contents.module';
33
import { CategoryService } from './category.service';
4-
import { OpenaiModule } from '../openai/openai.module';
4+
import { AiModule } from '../ai/openai.module';
55
import { UsersModule } from '../users/users.module';
66
import { TypeOrmModule } from '@nestjs/typeorm';
77
import { Category } from './category.entity';
@@ -14,7 +14,7 @@ import { CategoryV2Controller } from './v2/category.v2.controller';
1414
imports: [
1515
TypeOrmModule.forFeature([Category]),
1616
ContentsModule,
17-
OpenaiModule,
17+
AiModule,
1818
UsersModule,
1919
],
2020
controllers: [CategoryController, CategoryV2Controller],

0 commit comments

Comments
 (0)