Skip to content

Commit 3468a45

Browse files
committed
integrate AI service for translating project and contributor names, and issue titles to Arabic
1 parent 28b3e56 commit 3468a45

File tree

2 files changed

+93
-15
lines changed

2 files changed

+93
-15
lines changed

api/src/digest/cron.ts

Lines changed: 76 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import { RepositoryRepository } from "src/repository/repository";
1414
import { SearchService } from "src/search/service";
1515
import { Service } from "typedi";
1616
import { TagRepository } from "src/tag/repository";
17+
import { AIService } from "src/ai/service";
18+
import { AIResponseTranslateNameDto, AIResponseTranslateTitleDto } from "./dto";
1719

1820
@Service()
1921
export class DigestCron {
@@ -29,7 +31,8 @@ export class DigestCron {
2931
private readonly contributionsRepository: ContributionRepository,
3032
private readonly contributorsRepository: ContributorRepository,
3133
private readonly searchService: SearchService,
32-
private readonly tagsRepository: TagRepository,
34+
private readonly tagRepository: TagRepository,
35+
private readonly aiService: AIService,
3336
) {
3437
const SentryCronJob = cron.instrumentCron(CronJob, "DigestCron");
3538
new SentryCronJob(
@@ -81,10 +84,29 @@ export class DigestCron {
8184
// or uncomment to skip the cron
8285
// if (Math.random()) return;
8386

87+
const projectTitleSystemPrompt = `user will give you an open-source project name, and you will translate it to Arabic.`;
88+
const contributorNameSystemPrompt = `user will give you an open-source contributor name, and you will translate it to Arabic.
89+
if the name contain both english and arabic only keep the parts related to the language.`;
90+
const issueTitleSystemPrompt = `user will give you an open-source issue/PR title, and you will translate it to Arabic.`;
91+
8492
for (const project of projectsFromDataFolder) {
85-
// todo: call AIService
86-
const name_en = project.name;
87-
const name_ar = `ar ${name_en}`;
93+
let name_en = project.name;
94+
let name_ar = name_en;
95+
96+
try {
97+
const aiRes = await this.aiService.query(
98+
[
99+
{ role: "system", content: projectTitleSystemPrompt },
100+
{ role: "user", content: name_en },
101+
],
102+
AIResponseTranslateNameDto,
103+
);
104+
105+
name_en = aiRes.name_en;
106+
name_ar = aiRes.name_ar;
107+
} catch (error) {
108+
captureException(error, { tags: { type: "CRON" } });
109+
}
88110

89111
const projectEntity: ProjectRow = {
90112
runId,
@@ -94,7 +116,7 @@ export class DigestCron {
94116
};
95117
const [{ id: projectId }] = await this.projectsRepository.upsert(projectEntity);
96118
for (const tagId of project.tags || []) {
97-
await this.tagsRepository.upsert({ id: tagId, runId });
119+
await this.tagRepository.upsert({ id: tagId, runId });
98120
await this.projectsRepository.upsertRelationWithTag({ projectId, tagId, runId });
99121
}
100122
await this.searchService.upsert("project", projectEntity);
@@ -133,9 +155,22 @@ export class DigestCron {
133155

134156
if (githubUser.type !== "User") continue;
135157

136-
// todo: call AIService
137-
const name_en = githubUser.name || githubUser.login;
138-
const name_ar = `ar ${name_en}`;
158+
let name_en = githubUser.name || githubUser.login;
159+
let name_ar = name_en;
160+
try {
161+
const aiRes = await this.aiService.query(
162+
[
163+
{ role: "system", content: contributorNameSystemPrompt },
164+
{ role: "user", content: name_en },
165+
],
166+
AIResponseTranslateNameDto,
167+
);
168+
169+
name_en = aiRes.name_en;
170+
name_ar = aiRes.name_ar;
171+
} catch (error) {
172+
captureException(error, { tags: { type: "CRON" } });
173+
}
139174

140175
const contributorEntity: ContributorRow = {
141176
name_en,
@@ -160,9 +195,22 @@ export class DigestCron {
160195

161196
const type = issue.pull_request ? "PULL_REQUEST" : "ISSUE";
162197

163-
// todo: call AIService
164-
const title_en = issue.title;
165-
const title_ar = `ar ${title_en}`;
198+
let title_en = issue.title;
199+
let title_ar = `ar ${title_en}`;
200+
try {
201+
const aiRes = await this.aiService.query(
202+
[
203+
{ role: "system", content: issueTitleSystemPrompt },
204+
{ role: "user", content: title_en },
205+
],
206+
AIResponseTranslateTitleDto,
207+
);
208+
209+
title_en = aiRes.title_en;
210+
title_ar = aiRes.title_ar;
211+
} catch (error) {
212+
captureException(error, { tags: { type: "CRON" } });
213+
}
166214

167215
const contributionEntity: ContributionRow = {
168216
title_en,
@@ -194,9 +242,22 @@ export class DigestCron {
194242
username: repoContributor.login,
195243
});
196244

197-
// todo: call AIService
198-
const name_en = contributor.name || contributor.login;
199-
const name_ar = `ar ${name_en}`;
245+
let name_en = contributor.name || contributor.login;
246+
let name_ar = `ar ${name_en}`;
247+
try {
248+
const aiRes = await this.aiService.query(
249+
[
250+
{ role: "system", content: contributorNameSystemPrompt },
251+
{ role: "user", content: name_en },
252+
],
253+
AIResponseTranslateNameDto,
254+
);
255+
256+
name_en = aiRes.name_en;
257+
name_ar = aiRes.name_ar;
258+
} catch (error) {
259+
captureException(error, { tags: { type: "CRON" } });
260+
}
200261

201262
const contributorEntity: ContributorRow = {
202263
name_en,
@@ -244,7 +305,7 @@ export class DigestCron {
244305
await this.projectsRepository.deleteAllRelationWithTagButWithRunId(runId);
245306
await this.projectsRepository.deleteAllButWithRunId(runId);
246307

247-
await this.tagsRepository.deleteAllButWithRunId(runId);
308+
await this.tagRepository.deleteAllButWithRunId(runId);
248309

249310
await Promise.all([
250311
this.searchService.deleteAllButWithRunId("project", runId),

api/src/digest/dto.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { IsString } from "class-validator";
2+
3+
export class AIResponseTranslateNameDto {
4+
@IsString()
5+
name_en!: string;
6+
7+
@IsString()
8+
name_ar!: string;
9+
}
10+
11+
export class AIResponseTranslateTitleDto {
12+
@IsString()
13+
title_en!: string;
14+
15+
@IsString()
16+
title_ar!: string;
17+
}

0 commit comments

Comments
 (0)