feat(server): add generate title cron resolver (#13189)

fix AI-350

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added a new option to manually trigger the generation of missing
session titles via a GraphQL query.

* **Improvements**
* The process for generating missing session titles now considers all
eligible sessions, without limiting the number processed at a time.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
DarkSky
2025-07-14 17:19:21 +08:00
committed by GitHub
parent 7b53641a94
commit 9a3e44c6d6
6 changed files with 25 additions and 12 deletions

View File

@@ -431,9 +431,7 @@ Generated by [AVA](https://avajs.dev).
],
modelCalls: [
{
args: [
100,
],
args: [],
},
],
}

View File

@@ -1078,7 +1078,7 @@ test('should get sessions for title generation correctly', async t => {
})
);
const result = await copilotSession.toBeGenerateTitle(10);
const result = await copilotSession.toBeGenerateTitle();
t.snapshot(
{

View File

@@ -613,7 +613,7 @@ export class CopilotSessionModel extends BaseModel {
}
@Transactional()
async toBeGenerateTitle(take: number) {
async toBeGenerateTitle() {
const sessions = await this.db.aiSession
.findMany({
where: {
@@ -628,7 +628,6 @@ export class CopilotSessionModel extends BaseModel {
// count assistant messages
_count: { select: { messages: { where: { role: 'assistant' } } } },
},
take,
orderBy: { updatedAt: 'desc' },
})
.then(s => s.filter(s => s._count.messages > 0));

View File

@@ -11,8 +11,6 @@ declare global {
}
}
const GENERATE_TITLES_BATCH_SIZE = 100;
@Injectable()
export class CopilotCronJobs {
private readonly logger = new Logger(CopilotCronJobs.name);
@@ -37,6 +35,14 @@ export class CopilotCronJobs {
);
}
async triggerGenerateMissingTitles() {
await this.jobs.add(
'copilot.session.generateMissingTitles',
{},
{ jobId: 'trigger-copilot-generate-missing-titles' }
);
}
@OnJob('copilot.session.cleanupEmptySessions')
async cleanupEmptySessions() {
const { removed, cleaned } =
@@ -51,9 +57,7 @@ export class CopilotCronJobs {
@OnJob('copilot.session.generateMissingTitles')
async generateMissingTitles() {
const sessions = await this.models.copilotSession.toBeGenerateTitle(
GENERATE_TITLES_BATCH_SIZE
);
const sessions = await this.models.copilotSession.toBeGenerateTitle();
for (const session of sessions) {
await this.jobs.add('copilot.session.generateTitle', {

View File

@@ -37,6 +37,7 @@ import { Admin } from '../../core/common';
import { AccessController } from '../../core/permission';
import { UserType } from '../../core/user';
import type { ListSessionOptions, UpdateChatSession } from '../../models';
import { CopilotCronJobs } from './cron';
import { PromptService } from './prompt';
import { PromptMessage, StreamObject } from './providers';
import { ChatSessionService } from './session';
@@ -773,7 +774,18 @@ class CreateCopilotPromptInput {
@Admin()
@Resolver(() => String)
export class PromptsManagementResolver {
constructor(private readonly promptService: PromptService) {}
constructor(
private readonly cron: CopilotCronJobs,
private readonly promptService: PromptService
) {}
@Query(() => Boolean, {
description: 'Trigger generate missing titles cron job',
})
async triggerGenerateTitleCron() {
await this.cron.triggerGenerateMissingTitles();
return true;
}
@Query(() => [CopilotPromptType], {
description: 'List all copilot prompts',