feat(server): add cron job for session cleanup (#13181)

fix AI-338
This commit is contained in:
DarkSky
2025-07-13 21:53:38 +08:00
committed by GitHub
parent 3ee82bd9ce
commit b6187718ea
11 changed files with 508 additions and 8 deletions

View File

@@ -0,0 +1,67 @@
import { Injectable, Logger } from '@nestjs/common';
import { Cron, CronExpression } from '@nestjs/schedule';
import { JobQueue, OneDay, OnJob } from '../../base';
import { Models } from '../../models';
declare global {
interface Jobs {
'copilot.session.cleanupEmptySessions': {};
'copilot.session.generateMissingTitles': {};
}
}
const GENERATE_TITLES_BATCH_SIZE = 100;
@Injectable()
export class CopilotCronJobs {
private readonly logger = new Logger(CopilotCronJobs.name);
constructor(
private readonly models: Models,
private readonly jobs: JobQueue
) {}
@Cron(CronExpression.EVERY_DAY_AT_MIDNIGHT)
async dailyCleanupJob() {
await this.jobs.add(
'copilot.session.cleanupEmptySessions',
{},
{ jobId: 'daily-copilot-cleanup-empty-sessions' }
);
await this.jobs.add(
'copilot.session.generateMissingTitles',
{},
{ jobId: 'daily-copilot-generate-missing-titles' }
);
}
@OnJob('copilot.session.cleanupEmptySessions')
async cleanupEmptySessions() {
const { removed, cleaned } =
await this.models.copilotSession.cleanupEmptySessions(
new Date(Date.now() - OneDay)
);
this.logger.log(
`Cleanup completed: ${removed} sessions deleted, ${cleaned} sessions marked as deleted`
);
}
@OnJob('copilot.session.generateMissingTitles')
async generateMissingTitles() {
const sessions = await this.models.copilotSession.toBeGenerateTitle(
GENERATE_TITLES_BATCH_SIZE
);
for (const session of sessions) {
await this.jobs.add('copilot.session.generateTitle', {
sessionId: session.id,
});
}
this.logger.log(
`Scheduled title generation for ${sessions.length} sessions`
);
}
}

View File

@@ -15,6 +15,7 @@ import {
CopilotContextService,
} from './context';
import { CopilotController } from './controller';
import { CopilotCronJobs } from './cron';
import { CopilotEmbeddingJob } from './embedding';
import { ChatMessageCache } from './message';
import { PromptService } from './prompt';
@@ -64,6 +65,8 @@ import {
CopilotContextResolver,
CopilotContextService,
CopilotEmbeddingJob,
// cron jobs
CopilotCronJobs,
// transcription
CopilotTranscriptionService,
CopilotTranscriptionResolver,

View File

@@ -304,6 +304,7 @@ const textActions: Prompt[] = [
name: 'Transcript audio',
action: 'Transcript audio',
model: 'gemini-2.5-flash',
optionalModels: ['gemini-2.5-flash', 'gemini-2.5-pro'],
messages: [
{
role: 'system',