|
|
@@ -1,11 +1,9 @@
|
|
|
-import { CreateCharactorDto } from './dto/create-charactor.dto'
|
|
|
import { Inject, Injectable, Logger, NotFoundException, OnModuleInit, forwardRef } from '@nestjs/common'
|
|
|
import { InjectRepository } from '@nestjs/typeorm'
|
|
|
import { Repository } from 'typeorm'
|
|
|
import { Game } from './entities/game.entity'
|
|
|
import { GameRound } from './entities/game-round.entity'
|
|
|
import { Charactor } from './entities/charactors.entity'
|
|
|
-import { LLMChain } from 'langchain/chains'
|
|
|
import { ChatOpenAI } from 'langchain/chat_models/openai'
|
|
|
import { CreateGameDto } from './dto/create-game.dto'
|
|
|
import { Pagination, paginate } from 'nestjs-typeorm-paginate'
|
|
|
@@ -29,6 +27,8 @@ import { HumanMessage, LLMResult, SystemMessage } from 'langchain/schema'
|
|
|
import { CallbackManager } from 'langchain/callbacks'
|
|
|
import { setTimeout } from 'timers/promises'
|
|
|
import { EventsGateway } from '../events/events.gateway'
|
|
|
+import { PromptService } from '../prompt/prompt.service'
|
|
|
+import { PromptName } from '../prompt/entities/prompt.entity'
|
|
|
|
|
|
@Injectable()
|
|
|
export class GameService implements OnModuleInit {
|
|
|
@@ -43,6 +43,7 @@ export class GameService implements OnModuleInit {
|
|
|
private readonly charactorRepository: Repository<Charactor>,
|
|
|
@Inject(forwardRef(() => EventsGateway))
|
|
|
private readonly eventsGateway: EventsGateway,
|
|
|
+ private readonly promptService: PromptService
|
|
|
) {}
|
|
|
|
|
|
onModuleInit() {
|
|
|
@@ -122,10 +123,7 @@ export class GameService implements OnModuleInit {
|
|
|
)
|
|
|
const formatInstructions = parser.getFormatInstructions()
|
|
|
const prompt = new PromptTemplate({
|
|
|
- template: dedent`You are a creative assistant that generates engaging fantasy novel plots.
|
|
|
- {format_instructions}
|
|
|
- Please imagine {num} charactors, base on the background story:
|
|
|
- {background}`,
|
|
|
+ template: await this.promptService.getPromptByName(PromptName.GenCharacter),
|
|
|
inputVariables: ['num', 'background'],
|
|
|
partialVariables: { format_instructions: formatInstructions }
|
|
|
})
|
|
|
@@ -224,16 +222,7 @@ export class GameService implements OnModuleInit {
|
|
|
})
|
|
|
|
|
|
const prompt = new PromptTemplate({
|
|
|
- template: dedent`你是一个富有想象力的写作助手,能够帮我创作引人入胜的奇幻小说情节。请根据以下故事背景以及角色,帮我创作这个故事的开头部分。
|
|
|
-------------
|
|
|
-背景故事:
|
|
|
-{background}
|
|
|
-------------
|
|
|
-角色:
|
|
|
-{charactors}
|
|
|
-------------
|
|
|
-情节不必太长,尽量控制在100字以内,但是要吸引人。
|
|
|
-{datetime},开始:`,
|
|
|
+ template: await this.promptService.getPromptByName(PromptName.FirstPlot),
|
|
|
inputVariables: ['background', 'charactors', 'datetime']
|
|
|
})
|
|
|
const input = await prompt.format({
|
|
|
@@ -285,22 +274,7 @@ export class GameService implements OnModuleInit {
|
|
|
|
|
|
let summary = this.formatSummary(history)
|
|
|
let prompt = new PromptTemplate({
|
|
|
- template: dedent`你是一个富有想象力的写作助手,能够帮我创作引人入胜的谍战小说情节。请根据以下故事背景、角色,帮我继续创作这个故事。
|
|
|
-情节不必太长,尽量控制在100字以内,但是要吸引人。剧情的时间跨度不超过一天。不要急于给出结局,我们会在后面的剧情中给出结局。
|
|
|
-------------
|
|
|
-背景故事:
|
|
|
-{background}
|
|
|
-------------
|
|
|
-角色:
|
|
|
-{charactors}
|
|
|
-------------
|
|
|
-历史情节概要:
|
|
|
-{summary}
|
|
|
-{choice}
|
|
|
-------------
|
|
|
-{death}
|
|
|
-{newCharactor}
|
|
|
-{datetime},新的故事情节:`,
|
|
|
+ template: await this.promptService.getPromptByName(PromptName.NextPlot),
|
|
|
inputVariables: ['background', 'charactors', 'datetime', 'summary', 'choice', 'death', 'newCharactor']
|
|
|
})
|
|
|
const formatedCharactors = this.formatCharactors(gameRound.charactors)
|
|
|
@@ -369,14 +343,7 @@ export class GameService implements OnModuleInit {
|
|
|
const parser = StructuredOutputParser.fromZodSchema(z.array(z.string().describe('剧情发展方向')))
|
|
|
const formatInstructions = parser.getFormatInstructions()
|
|
|
const prompt = new PromptTemplate({
|
|
|
- template: dedent`你是一个富有想象力的写作助手,能够帮我创作引人入胜的谍战小说情节。
|
|
|
-{format_instructions}
|
|
|
-请根据以下故事背景、角色,帮我想象4个不同的剧情发展方向,每个选项不超过50字。
|
|
|
-剧情发展方向不一定是好的,但是要有趣。
|
|
|
-------------
|
|
|
-{text}
|
|
|
-------------
|
|
|
-请根据提供的JSON格式给出4个不同的剧情发展方向:`,
|
|
|
+ template: await this.promptService.getPromptByName(PromptName.GenChoice),
|
|
|
inputVariables: ['text'],
|
|
|
partialVariables: { format_instructions: formatInstructions }
|
|
|
})
|
|
|
@@ -414,11 +381,7 @@ export class GameService implements OnModuleInit {
|
|
|
let input
|
|
|
if (i < 0) {
|
|
|
const prompt = new PromptTemplate({
|
|
|
- template: dedent`请给我的小说情节总结出一个简短的摘要
|
|
|
-------------
|
|
|
-{text}
|
|
|
-------------
|
|
|
-摘要:`,
|
|
|
+ template: await this.promptService.getPromptByName(PromptName.Summarize),
|
|
|
inputVariables: ['text']
|
|
|
})
|
|
|
input = await prompt.format({
|
|
|
@@ -426,15 +389,7 @@ export class GameService implements OnModuleInit {
|
|
|
})
|
|
|
} else {
|
|
|
const prompt = new PromptTemplate({
|
|
|
- template: `您的任务是为我的小说剧情产生一个最终摘要
|
|
|
-我们已经提供了一个到某个剧情节点的摘要: "{existing_answer}"
|
|
|
-现在,我们提供了一些新的剧情信息,可以用来完善原始摘要(如果有用的话)
|
|
|
-------------
|
|
|
-"{text}"
|
|
|
-------------
|
|
|
-根据新的剧情,完善原始摘要
|
|
|
-如果新的剧情没有用处,返回原始摘要。
|
|
|
-完善的摘要:`,
|
|
|
+ template: await this.promptService.getPromptByName(PromptName.Refine),
|
|
|
inputVariables: ['existing_answer', 'text']
|
|
|
})
|
|
|
input = await prompt.format({
|
|
|
@@ -469,13 +424,7 @@ export class GameService implements OnModuleInit {
|
|
|
)
|
|
|
const formatInstructions = parser.getFormatInstructions()
|
|
|
const prompt = new PromptTemplate({
|
|
|
- template: dedent`{format_instructions}
|
|
|
-请根据以下故事背景,和基本信息帮我想象一个角色:
|
|
|
-背景:{background}
|
|
|
-
|
|
|
-基本信息:{base}
|
|
|
-
|
|
|
-请根据提供的JSON格式给我这个角色的信息:`,
|
|
|
+ template: await this.promptService.getPromptByName(PromptName.NewCharacter),
|
|
|
inputVariables: ['base', 'background'],
|
|
|
partialVariables: { format_instructions: formatInstructions }
|
|
|
})
|
|
|
@@ -505,18 +454,7 @@ export class GameService implements OnModuleInit {
|
|
|
)
|
|
|
const formatInstructions = parser.getFormatInstructions()
|
|
|
const prompt = new PromptTemplate({
|
|
|
- template: dedent`{format_instructions}
|
|
|
-
|
|
|
-角色信息:
|
|
|
-{charactors}
|
|
|
-历史剧情摘要:
|
|
|
-{summary}
|
|
|
-当前剧情:
|
|
|
-{text}
|
|
|
-
|
|
|
-HP最大值为100,最小值为0,如果HP值为0,角色将会死亡。
|
|
|
-不必给每个角色都调整HP值。
|
|
|
-请根据提供的JSON格式给我角色HP值的调整:`,
|
|
|
+ template: await this.promptService.getPromptByName(PromptName.ModifyHp),
|
|
|
inputVariables: ['charactors', 'summary', 'text'],
|
|
|
partialVariables: { format_instructions: formatInstructions }
|
|
|
})
|