|
|
@@ -0,0 +1,105 @@
|
|
|
+import { Injectable, Logger } from '@nestjs/common'
|
|
|
+import { InjectRepository } from '@nestjs/typeorm'
|
|
|
+import { StoryTemplate } from './entities/story-template.entitiy'
|
|
|
+import { Repository } from 'typeorm'
|
|
|
+import { paginate } from 'nestjs-typeorm-paginate'
|
|
|
+import { ChatOpenAI } from 'langchain/chat_models/openai'
|
|
|
+import { CallbackManager } from 'langchain/callbacks'
|
|
|
+import { Serialized } from 'langchain/dist/load/serializable'
|
|
|
+import { LLMResult } from 'langchain/schema'
|
|
|
+
|
|
|
+@Injectable()
|
|
|
+export class StoryService {
|
|
|
+ private readonly logger = new Logger(StoryService.name)
|
|
|
+ constructor(
|
|
|
+ @InjectRepository(StoryTemplate)
|
|
|
+ private readonly storyTemplateRepository: Repository<StoryTemplate>
|
|
|
+ ) {}
|
|
|
+
|
|
|
+ public async findAllTemplates(req) {
|
|
|
+ return await paginate<StoryTemplate>(this.storyTemplateRepository, req.page, req.search)
|
|
|
+ }
|
|
|
+
|
|
|
+ public async createTemplate(dto) {
|
|
|
+ return await this.storyTemplateRepository.save(dto)
|
|
|
+ }
|
|
|
+
|
|
|
+ public async findById(id: number) {
|
|
|
+ return await this.storyTemplateRepository.findBy({ id })
|
|
|
+ }
|
|
|
+
|
|
|
+ public async updateTemplate(id: number, dto) {
|
|
|
+ return await this.storyTemplateRepository.update(id, dto)
|
|
|
+ }
|
|
|
+
|
|
|
+ public async deleteTemplate(id: number) {
|
|
|
+ return await this.storyTemplateRepository.delete(id)
|
|
|
+ }
|
|
|
+
|
|
|
+ public createLLM() {
|
|
|
+ const self = this
|
|
|
+ const cb = CallbackManager.fromHandlers({
|
|
|
+ async handleLLMStart(llm: Serialized, prompts: string[]) {
|
|
|
+ self.logger.log(`[LLM Start]LLM: ${JSON.stringify(llm)}`)
|
|
|
+ self.logger.log(`['LLM Start]Prompts: ${prompts.join('\n')}`)
|
|
|
+ },
|
|
|
+ async handleLLMEnd(output: LLMResult) {
|
|
|
+ self.logger.log(
|
|
|
+ `[LLM End]${output.generations
|
|
|
+ .reduce((acc, cur) => acc.concat(cur), [])
|
|
|
+ .map((i) => i.text)
|
|
|
+ .join('\n')}`
|
|
|
+ )
|
|
|
+ self.logger.log(`[LLM End]${JSON.stringify(output.llmOutput)}`)
|
|
|
+ },
|
|
|
+ async handleLLMError(error: Error) {
|
|
|
+ self.logger.error(error)
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ const onFailedAttempt = (error) => {
|
|
|
+ self.logger.error(error)
|
|
|
+ }
|
|
|
+
|
|
|
+ const baseParam = {
|
|
|
+ openAIApiKey: process.env.OPENAI_API_KEY,
|
|
|
+ modelName: 'gpt-3.5-turbo-0613',
|
|
|
+ callbackManager: cb,
|
|
|
+ onFailedAttempt,
|
|
|
+ timeout: 60000
|
|
|
+ }
|
|
|
+ return new ChatOpenAI({
|
|
|
+ ...baseParam,
|
|
|
+ modelName: 'gpt-3.5-turbo-0613',
|
|
|
+ configuration: {
|
|
|
+ baseURL: 'https://openai.c8c.top/v1'
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ public async start(body) {
|
|
|
+ const template = await this.storyTemplateRepository.findOne(body.templateId)
|
|
|
+ if (!template) throw new Error('Template not found')
|
|
|
+ const llm = this.createLLM().bind({
|
|
|
+ response_format: {
|
|
|
+ type: 'json_object'
|
|
|
+ }
|
|
|
+ })
|
|
|
+ return (
|
|
|
+ await llm.invoke([
|
|
|
+ ['system', ''],
|
|
|
+ ['human', '']
|
|
|
+ ])
|
|
|
+ ).content
|
|
|
+ }
|
|
|
+
|
|
|
+ public async next(body) {
|
|
|
+ const template = await this.storyTemplateRepository.findOne(body.templateId)
|
|
|
+ if (!template) throw new Error('Template not found')
|
|
|
+ }
|
|
|
+
|
|
|
+ public async end(body) {
|
|
|
+ const template = await this.storyTemplateRepository.findOne(body.templateId)
|
|
|
+ if (!template) throw new Error('Template not found')
|
|
|
+ }
|
|
|
+}
|