@lobehub/chat
Version:
Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.
105 lines (82 loc) • 3.35 kB
text/typescript
import { JWTPayload } from '@/const/auth';
import { AsyncTaskModel } from '@/database/models/asyncTask';
import { FileModel } from '@/database/models/file';
import { serverDB } from '@/database/server';
import { ChunkContentParams, ContentChunk } from '@/server/modules/ContentChunk';
import { createAsyncServerClient } from '@/server/routers/async';
import {
AsyncTaskError,
AsyncTaskErrorType,
AsyncTaskStatus,
AsyncTaskType,
} from '@/types/asyncTask';
export class ChunkService {
private userId: string;
private chunkClient: ContentChunk;
private fileModel: FileModel;
private asyncTaskModel: AsyncTaskModel;
constructor(userId: string) {
this.userId = userId;
this.chunkClient = new ContentChunk();
this.fileModel = new FileModel(serverDB, userId);
this.asyncTaskModel = new AsyncTaskModel(serverDB, userId);
}
async chunkContent(params: ChunkContentParams) {
return this.chunkClient.chunkContent(params);
}
async asyncEmbeddingFileChunks(fileId: string, payload: JWTPayload) {
const result = await this.fileModel.findById(fileId);
if (!result) return;
// 1. create a asyncTaskId
const asyncTaskId = await this.asyncTaskModel.create({
status: AsyncTaskStatus.Pending,
type: AsyncTaskType.Embedding,
});
await this.fileModel.update(fileId, { embeddingTaskId: asyncTaskId });
const asyncCaller = await createAsyncServerClient(this.userId, payload);
// trigger embedding task asynchronously
try {
await asyncCaller.file.embeddingChunks.mutate({ fileId, taskId: asyncTaskId });
} catch (e) {
console.error('[embeddingFileChunks] error:', e);
await this.asyncTaskModel.update(asyncTaskId, {
error: new AsyncTaskError(
AsyncTaskErrorType.TaskTriggerError,
'trigger chunk embedding async task error. Please make sure the APP_URL is available from your server. You can check the proxy config or WAF blocking',
),
status: AsyncTaskStatus.Error,
});
}
return asyncTaskId;
}
/**
* parse file to chunks with async task
*/
async asyncParseFileToChunks(fileId: string, payload: JWTPayload, skipExist?: boolean) {
const result = await this.fileModel.findById(fileId);
if (!result) return;
// skip if already exist chunk tasks
if (skipExist && result.chunkTaskId) return;
// 1. create a asyncTaskId
const asyncTaskId = await this.asyncTaskModel.create({
status: AsyncTaskStatus.Processing,
type: AsyncTaskType.Chunking,
});
await this.fileModel.update(fileId, { chunkTaskId: asyncTaskId });
const asyncCaller = await createAsyncServerClient(this.userId, payload);
// trigger parse file task asynchronously
asyncCaller.file.parseFileToChunks
.mutate({ fileId: fileId, taskId: asyncTaskId })
.catch(async (e) => {
console.error('[ParseFileToChunks] error:', e);
await this.asyncTaskModel.update(asyncTaskId, {
error: new AsyncTaskError(
AsyncTaskErrorType.TaskTriggerError,
'trigger chunk embedding async task error. Please make sure the APP_URL is available from your server. You can check the proxy config or WAF blocking',
),
status: AsyncTaskStatus.Error,
});
});
return asyncTaskId;
}
}