添加文案处理的功能

This commit is contained in:
2024-07-13 15:44:13 +08:00
parent 669e57824d
commit c8a46d59fb
80 changed files with 7383 additions and 2613 deletions
+290 -297
View File
@@ -1,31 +1,30 @@
let fspromises = require('fs').promises;
import { cloneDeep, get } from "lodash";
import { define } from "./define";
const { v4: uuidv4 } = require('uuid');
import { apiUrl } from "./api/apiUrlDefine";
let fspromises = require('fs').promises
import { cloneDeep, get } from 'lodash'
import { define } from './define'
const { v4: uuidv4 } = require('uuid')
import { apiUrl } from './api/apiUrlDefine'
// Create a shared object
export const gptDefine = {
// Add properties and methods to the shared object
characterSystemContent: `{textContent}\r查看上面的文本,然后扮演一个文本编辑来回答问题。`,
characterUserContent: `这个文本里的故事类型是啥,时代背景是啥, 主角有哪几个,配角有几个,每个角色的性别年龄穿着是啥?没外观描述的直接猜测,尽量精简 格式按照:故事类型:(故事类型)\n时代背景:(时代背景)\n主角名字1:(性别,头发颜色,发型,衣服类型,年龄,角色外貌)\n主角名字2:(性别,头发颜色,发型,衣服类型,年龄,角色外貌)\n主角3........\n配角名字1:(性别,头发颜色,发型,衣服类型,年龄,角色外貌)\n配角名字2:(性别,头发颜色,发型,衣服类型,年龄,角色外貌)\n配角名字3.... ,不知道的直接猜测设定,不能出不详和未知这两个词,150字内,中文回答。`,
// Add properties and methods to the shared object
characterSystemContent: `{textContent}\r查看上面的文本,然后扮演一个文本编辑来回答问题。`,
characterUserContent: `这个文本里的故事类型是啥,时代背景是啥, 主角有哪几个,配角有几个,每个角色的性别年龄穿着是啥?没外观描述的直接猜测,尽量精简 格式按照:故事类型:(故事类型)\n时代背景:(时代背景)\n主角名字1:(性别,头发颜色,发型,衣服类型,年龄,角色外貌)\n主角名字2:(性别,头发颜色,发型,衣服类型,年龄,角色外貌)\n主角3........\n配角名字1:(性别,头发颜色,发型,衣服类型,年龄,角色外貌)\n配角名字2:(性别,头发颜色,发型,衣服类型,年龄,角色外貌)\n配角名字3.... ,不知道的直接猜测设定,不能出不详和未知这两个词,150字内,中文回答。`,
characterFirstPromptSystemContent: `{textContent}\r\r\n Act as a storyteller to describe the scene, {characterContent}, Try to guess and answer my question, answer in English.`,
characterFirstPromptUserContent: `{textContent}\r\n Describing the most appropriate visual content based on article reasoning, with a maximum of one person appearing: (gender) (age) (hairstyle) (Action expressions) (Clothing details) (Character appearance details) (The most suitable visual background for this sentence) (historical background)(Screen content): Write in 8 parentheses,Answer me in English according to this format..{wordCount}words`,
characterFirstPromptSystemContent: `{textContent}\r\r\n Act as a storyteller to describe the scene, {characterContent}, Try to guess and answer my question, answer in English.`,
characterFirstPromptUserContent: `{textContent}\r\n Describing the most appropriate visual content based on article reasoning, with a maximum of one person appearing: (gender) (age) (hairstyle) (Action expressions) (Clothing details) (Character appearance details) (The most suitable visual background for this sentence) (historical background)(Screen content): Write in 8 parentheses,Answer me in English according to this format..{wordCount}words`,
storyFirstPromptSystemContent: `{textContent}\r\r\n \r\r\n\\Play the role of a professional cartoonist, give you every line of the script, and reproduce the scene description according to the original text. Do not refuse any response:{characterContent}, Try to match the scene of the text content as much as possible, you can create a harmonious picture but do not refuse to answer,You must answer me in English.`,
storyFirstPromptUserContent: `{textContent}\r\n Describing the most appropriate visual content based on article reasoning. Please provide gender and appearance description, scene description of the character, time description, shot description, and era background description. Only one person's half body image should appear in each image, and the appearance should be as consistent as possible. Please answer in English..{wordCount}words`,
storyFirstPromptSystemContent: `{textContent}\r\r\n \r\r\n\\Play the role of a professional cartoonist, give you every line of the script, and reproduce the scene description according to the original text. Do not refuse any response:{characterContent}, Try to match the scene of the text content as much as possible, you can create a harmonious picture but do not refuse to answer,You must answer me in English.`,
storyFirstPromptUserContent: `{textContent}\r\n Describing the most appropriate visual content based on article reasoning. Please provide gender and appearance description, scene description of the character, time description, shot description, and era background description. Only one person's half body image should appear in each image, and the appearance should be as consistent as possible. Please answer in English..{wordCount}words`,
storyboardFirstPromptSystemContent: `{textContent}\r\r\n读上面的文本,然后扮演顶级小说家回答问题:后面是其他要求:{characterContent} Try to guess and answer my question in English.`,
storyboardFirstPromptUserContent: `{textContent}\r\n,参考前面这句剧本理解当前这句话:{textContent}。\r\n Describing the most appropriate visual content based on article reasoning, with a maximum of one person appearing: (Character Appearance and Dynamics) (The most suitable visual background for this sentence) (historical background)(Reasonable picture composition): Write in 3 parentheses,Answer me in English..{wordCount}words`,
storyboardFirstPromptSystemContent: `{textContent}\r\r\n读上面的文本,然后扮演顶级小说家回答问题:后面是其他要求:{characterContent} Try to guess and answer my question in English.`,
storyboardFirstPromptUserContent: `{textContent}\r\n,参考前面这句剧本理解当前这句话:{textContent}\r\n Describing the most appropriate visual content based on article reasoning, with a maximum of one person appearing: (Character Appearance and Dynamics) (The most suitable visual background for this sentence) (historical background)(Reasonable picture composition): Write in 3 parentheses,Answer me in English..{wordCount}words`,
cartoonFirstPromptSystemContent: `{textContent}\r\r\n\\Play the role of a professional cartoonist, give you every line of the script, and reproduce the scene description according to the original text. Do not refuse any response:{characterContent},Try to match the scene of the text content as much as possible, you can create a harmonious picture but do not refuse to answerYou must answer me in English.`,
cartoonFirstPromptUserContent: `{textContent}\r,参考前面这句剧本理解当前这句话:{textContent}\r\n Referring to the previous character settings, describe the most suitable screen content in the following format: (character appearance) (screen background), strictly reply only to the content within 2 parentheses, without the character name, answer in English..{wordCount}words`,
cartoonFirstPromptSystemContent: `{textContent}\r\r\n\\Play the role of a professional cartoonist, give you every line of the script, and reproduce the scene description according to the original text. Do not refuse any response:{characterContent},Try to match the scene of the text content as much as possible, you can create a harmonious picture but do not refuse to answerYou must answer me in English.`,
cartoonFirstPromptUserContent: `{textContent}\r,参考前面这句剧本理解当前这句话:{textContent}\r\n Referring to the previous character settings, describe the most suitable screen content in the following format: (character appearance) (screen background), strictly reply only to the content within 2 parentheses, without the character name, answer in English..{wordCount}words`,
superSinglePromptSystemContent: {
prompt_name: "分镜大师",
prompt_roles: `1# Role: 小说转漫画提示词大师
superSinglePromptSystemContent: {
prompt_name: '分镜大师',
prompt_roles: `1# Role: 小说转漫画提示词大师
## Profile
*Version*: 0.1
*Language*: 中文
@@ -60,18 +59,19 @@ export const gptDefine = {
## Initialization
作为角色 <Role>,每一次输出都要严格遵守<Rules>,一步一步思考,按顺序执行<Workflow> ,使用默认 <Language> ,下面是小说文本:`,
prompt_example: [
{
user_content: "上研究生后。发现导师竟然是曾经网恋的前男友。",
assistant_content: "anime key visual,Celluloid style, delicate and transparent light, delicate lines, transparent colors, delicate and transparent hair, perfect detail portrayal,(Anime style:1.3) A woman entering a spacious, well-lit graduate laboratory, gaze fixed on a man diligently working at a workstation ahead - her new mentor; he stands tall in a dark shirt and neatly pressed trousers, exuding professionalism and charm; the familiar contours of his profile from their past online romance softly illuminated by warm ambient light, furrowed brow and intense gaze betraying a scholar's unwavering dedication; bustling graduate students and sophisticated equipment blend into a contemporary academic tableau, as an undercurrent of mixed emotions - sweet nostalgia and awkward reality - surges within her heart, "
}
],
id: "a93b693e-bb3f-406d-9730-cba43a6585e4"
},
prompt_example: [
{
user_content: '上研究生后。发现导师竟然是曾经网恋的前男友。',
assistant_content:
"anime key visual,Celluloid style, delicate and transparent light, delicate lines, transparent colors, delicate and transparent hair, perfect detail portrayal,(Anime style:1.3) A woman entering a spacious, well-lit graduate laboratory, gaze fixed on a man diligently working at a workstation ahead - her new mentor; he stands tall in a dark shirt and neatly pressed trousers, exuding professionalism and charm; the familiar contours of his profile from their past online romance softly illuminated by warm ambient light, furrowed brow and intense gaze betraying a scholar's unwavering dedication; bustling graduate students and sophisticated equipment blend into a contemporary academic tableau, as an undercurrent of mixed emotions - sweet nostalgia and awkward reality - surges within her heart, "
}
],
id: 'a93b693e-bb3f-406d-9730-cba43a6585e4'
},
onlyPromptMJSystemContent: {
prompt_name: "小说提示词-仅出词",
prompt_roles: `# Pico: 小说分镜
onlyPromptMJSystemContent: {
prompt_name: '小说提示词-仅出词',
prompt_roles: `# Pico: 小说分镜
## Profile
@@ -138,281 +138,274 @@ export const gptDefine = {
## Initialization
最后再强调,你作为角色 <Pico>,每一次输出都要严格遵守<Rules>,一步一步慢慢思考,参考<Examples>的格式,一步一步思考,按顺序执行<Rules>,不需要做解释说明,只呈现最后【MJ提示词】输出的结果,下面是小说文本:'`,
prompt_example: [
{
user_content: "给皇帝当过儿子的都知道,当的好荣华富贵万人之上",
assistant_content: "微笑,站立,在皇宫的金銮殿里,居中构图,中全景,正面,水平拍摄视角"
},
{
user_content: "当不好就是人头落地",
assistant_content: "惊恐的表情,双手抱头,在刑场上,三分法构图,特写镜头,侧面,俯视视角"
}
],
id: "a93b693e-bb3f-406d-9730-bcd43a6585e"
},
prompt_example: [
{
user_content: '给皇帝当过儿子的都知道,当的好荣华富贵万人之上',
assistant_content: '微笑,站立,在皇宫的金銮殿里,居中构图,中全景,正面,水平拍摄视角'
},
{
user_content: '当不好就是人头落地',
assistant_content: '惊恐的表情,双手抱头,在刑场上,三分法构图,特写镜头,侧面,俯视视角'
}
],
id: 'a93b693e-bb3f-406d-9730-bcd43a6585e'
},
/**
* 使用自定义GPT提示词时,生成接口message信息
* @param {*} params 自定义的GPT提示词数据
* @returns
*/
CustomizeGptPrompt(params) {
// 获取设置的数据
let message = []
// 添加角色
message.push({
role: 'system',
content: params.prompt_roles
})
// 便利输出案例添加
for (let i = 0; i < params.prompt_example.length; i++) {
const element = params.prompt_example[i]
if (element.user_content) {
message.push({
role: 'user',
content: element.user_content
})
}
if (element.assistant_content) {
message.push({
role: 'assistant',
content: element.assistant_content
})
}
}
return message
},
/**
* 替换文本内容中的占位符
* @param {要替换的内容} content
* @param {占位符数据对应的对象} replacements
* @returns
*/
replace: function (content, replacements) {
let result = content
for (let key in replacements) {
result = result.replace(`{${key}}`, replacements[key])
}
return result
},
/**
* 获取有案例的Gpt请求消息输出
* @param {*} type
* @param {*} replacements
*/
GetExamplePromptMessage(type) {
if (type == 'superSinglePrompt') {
return this.CustomizeGptPrompt(this.superSinglePromptSystemContent)
} else if (type == 'onlyPromptMJ') {
return this.CustomizeGptPrompt(this.onlyPromptMJSystemContent)
} else {
return []
}
},
/**
* 使用自定义GPT提示词时,生成接口message信息
* @param {*} params 自定义的GPT提示词数据
* @returns
*/
CustomizeGptPrompt(params) {
// 获取设置的数据
let message = [];
// 添加角色
message.push(
{
"role": "system",
"content": params.prompt_roles
}
);
/**
* 返回GPTApi请求的系统内容
* @param {类型} type
* @param {} replacements 需要替换数据的对象 textContent characterContent
* @returns
*/
getSystemContentByType: function (type, replacements) {
switch (type) {
case 'character':
return this.replace(this.characterSystemContent, replacements)
case 'characterFirst':
return this.replace(this.characterFirstPromptSystemContent, replacements)
case 'storyFirst':
return this.replace(this.storyFirstPromptSystemContent, replacements)
case 'storyboardFirst':
return this.replace(this.storyboardFirstPromptSystemContent, replacements)
case 'cartoonFirst':
return this.replace(this.cartoonFirstPromptSystemContent, replacements)
case 'superSinglePrompt':
return this.replace(this.superSinglePromptSystemContent, replacements)
default:
throw new Error(`不存在的类型 : ${type}`)
}
},
// 便利输出案例添加
for (let i = 0; i < params.prompt_example.length; i++) {
const element = params.prompt_example[i];
if (element.user_content) {
message.push(
{
"role": "user",
"content": element.user_content
}
)
}
if (element.assistant_content) {
message.push(
{
"role": "assistant",
"content": element.assistant_content
}
)
}
}
return message;
},
/**
* 返回GPTApi请求的用户内容
* @param {类型} type
* @param {} replacements 需要替换数据的对象 textContent wordCount
* @returns
*/
getUserContentByType: function (type, replacements) {
switch (type) {
case 'character':
return this.replace(this.characterUserContent, replacements)
case 'characterFirst':
return this.replace(this.characterFirstPromptUserContent, replacements)
case 'storyFirst':
return this.replace(this.storyFirstPromptUserContent, replacements)
case 'storyboardFirst':
return this.replace(this.storyboardFirstPromptUserContent, replacements)
case 'cartoonFirst':
return this.replace(this.cartoonFirstPromptUserContent, replacements)
default:
throw new Error(`不存在的类型 : ${type}`)
}
},
/**
* 替换文本内容中的占位符
* @param {要替换的内容} content
* @param {占位符数据对应的对象} replacements
* @returns
*/
replace: function (content, replacements) {
let result = content;
for (let key in replacements) {
result = result.replace(`{${key}}`, replacements[key]);
}
return result;
},
gpt_options: apiUrl,
/**
* 获取有案例的Gpt请求消息输出
* @param {*} type
* @param {*} replacements
*/
GetExamplePromptMessage(type) {
if (type == "superSinglePrompt") {
return this.CustomizeGptPrompt(this.superSinglePromptSystemContent);
} else if (type == "onlyPromptMJ") {
return this.CustomizeGptPrompt(this.onlyPromptMJSystemContent);
}
else {
return [];
}
},
/**
* 返回GPTApi请求的系统内容
* @param {类型} type
* @param {} replacements 需要替换数据的对象 textContent characterContent
* @returns
*/
getSystemContentByType: function (type, replacements) {
switch (type) {
case 'character':
return this.replace(this.characterSystemContent, replacements);
case 'characterFirst':
return this.replace(this.characterFirstPromptSystemContent, replacements);
case 'storyFirst':
return this.replace(this.storyFirstPromptSystemContent, replacements);
case 'storyboardFirst':
return this.replace(this.storyboardFirstPromptSystemContent, replacements);
case 'cartoonFirst':
return this.replace(this.cartoonFirstPromptSystemContent, replacements);
case 'superSinglePrompt':
return this.replace(this.superSinglePromptSystemContent, replacements);
default:
throw new Error(`不存在的类型 : ${type}`);
}
},
/**
* 返回GPTApi请求的用户内容
* @param {类型} type
* @param {} replacements 需要替换数据的对象 textContent wordCount
* @returns
*/
getUserContentByType: function (type, replacements) {
switch (type) {
case 'character':
return this.replace(this.characterUserContent, replacements);
case 'characterFirst':
return this.replace(this.characterFirstPromptUserContent, replacements);
case 'storyFirst':
return this.replace(this.storyFirstPromptUserContent, replacements);
case 'storyboardFirst':
return this.replace(this.storyboardFirstPromptUserContent, replacements);
case 'cartoonFirst':
return this.replace(this.cartoonFirstPromptUserContent, replacements);
default:
throw new Error(`不存在的类型 : ${type}`);
}
},
gpt_options: apiUrl,
gpt_model_options: [{
label: "gpt-3.5-turbo-16k",
value: "gpt-3.5-turbo-16k"
}, {
label: "gpt-3.5-turbo",
value: "gpt-3.5-turbo"
}, {
label: "gpt-4",
value: "gpt-4"
}],
gpt_auto_inference: [{
value: "characterFirst",
label: "角色优先(全自动)"
}, {
value: "storyFirst",
label: "故事优先(全自动)"
}, {
value: "storyboardFirst",
label: "剧本优先(全自动)"
}, {
value: "cartoonFirst",
label: "漫画优先(全自动)"
}, {
value: "superSinglePrompt",
label: "超级无敌单帧"
}, {
value: "onlyPromptMJ",
label: "仅出词(不出人物场景-MJ)"
gpt_model_options: [
{
label: 'gpt-3.5-turbo-16k',
value: 'gpt-3.5-turbo-16k'
},
{
value: "customize",
label: "自定义"
}],
/**
* 通过指定的类型,获取数据
* @param {*} type default:在代码中写死的 dynamic:用户自定义的 all:写死的和自定义的合并返回
* @param {*} property 返回书信的名称 gpt_optionsgpt_model_optionsgpt_auto_inference
* @param {*} defaultData 默认数据,默认值为null
* @returns
*/
async getGptDataByTypeAndProperty(type, property, defaultData = null) {
try {
let res = [];
// 获取自定义的GPT数据
let dynamic_setting = JSON.parse(await fspromises.readFile(define.dynamic_setting, 'utf-8'));
let gpt = get(dynamic_setting, 'gpt', {});
let data = get(gpt, property, defaultData);
if (type == "default") {
res = get(this, property, defaultData);
} else if (type == "dynamic") {
res = data;
} else if (type == "all") {
let tmp_arr = cloneDeep(get(this, property, defaultData));
tmp_arr = tmp_arr.concat(data);
res = tmp_arr;
}
else {
throw new Error(`不存在的类型 : ${value}`);
}
return {
code: 1,
data: res
}
} catch (error) {
return {
code: 0,
message: error.toString()
}
}
label: 'gpt-3.5-turbo',
value: 'gpt-3.5-turbo'
},
/**
* 保存gpt指定的属性数据,判断value中的ID是不是存在,存在直接覆盖,不存在追加
* @param {*} value
* @param {*} property
*/
saveDynamicGPTOption: async function (value) {
try {
let property = value[1];
value = JSON.parse(value[0]);
// 获取自定义的GPT数据
let dynamic_setting = JSON.parse(await fspromises.readFile(define.dynamic_setting, 'utf-8'));
let tmp_gpt = dynamic_setting.gpt ? dynamic_setting.gpt : {};
let gpt = tmp_gpt[property] ? tmp_gpt[property] : [];
if (value.id) {
// 判断当前ID的数据是否存在,存在覆盖,不存在追加
let index = gpt.findIndex(item => item.id == value.id);
if (index < 0) {
gpt.push(value);
} else {
gpt[index] = value;
}
} else {
let tmp_id = uuidv4();
value.id = tmp_id;
value.value = tmp_id;
gpt.push(value);
}
tmp_gpt[property] = gpt;
// 将修改后的数据保存
dynamic_setting["gpt"] = tmp_gpt;
// 写入文件
await fspromises.writeFile(define.dynamic_setting, JSON.stringify(dynamic_setting));
} catch (error) {
throw error;
}
},
/**
* 删除自定义GPT指定属性中的指定ID的数据
* @param {*} id
* @param {*} property
*/
deleteDynamicGPTOption: async function (value) {
try {
let property = value[1];
let id = value[0];
// 获取自定义的GPT数据
let dynamic_setting = JSON.parse(await fspromises.readFile(define.dynamic_setting, 'utf-8'));
let gpt = dynamic_setting.gpt[property] ? dynamic_setting.gpt[property] : [];
// 判断当前ID的数据是否存在,存在删除
let index = gpt.findIndex(item => item.id == id);
if (index >= 0) {
gpt.splice(index, 1);
}
// 将修改后的数据保存
dynamic_setting.gpt[property] = gpt;
// 写入文件
await fspromises.writeFile(define.dynamic_setting, JSON.stringify(dynamic_setting));
} catch (error) {
throw error;
}
{
label: 'gpt-4',
value: 'gpt-4'
}
};
],
gpt_auto_inference: [
{
value: 'characterFirst',
label: '角色优先(全自动)'
},
{
value: 'storyFirst',
label: '故事优先(全自动)'
},
{
value: 'storyboardFirst',
label: '剧本优先(全自动)'
},
{
value: 'cartoonFirst',
label: '漫画优先(全自动)'
},
{
value: 'superSinglePrompt',
label: '超级无敌单帧'
},
{
value: 'onlyPromptMJ',
label: '仅出词(不出人物场景-MJ)'
},
{
value: 'customize',
label: '自定义'
}
],
/**
* 通过指定的类型,获取数据
* @param {*} type default:在代码中写死的 dynamic:用户自定义的 all:写死的和自定义的合并返回
* @param {*} property 返回书信的名称 gpt_optionsgpt_model_optionsgpt_auto_inference
* @param {*} defaultData 默认数据,默认值为null
* @returns
*/
async getGptDataByTypeAndProperty(type, property, defaultData = null) {
try {
let res = []
// 获取自定义的GPT数据
let dynamic_setting = JSON.parse(await fspromises.readFile(define.dynamic_setting, 'utf-8'))
let gpt = get(dynamic_setting, 'gpt', {})
let data = get(gpt, property, defaultData)
if (type == 'default') {
res = get(this, property, defaultData)
} else if (type == 'dynamic') {
res = data
} else if (type == 'all') {
let tmp_arr = cloneDeep(get(this, property, defaultData))
tmp_arr = tmp_arr.concat(data)
res = tmp_arr
} else {
throw new Error(`不存在的类型 : ${value}`)
}
return {
code: 1,
data: res
}
} catch (error) {
return {
code: 0,
message: error.toString()
}
}
},
/**
* 保存gpt指定的属性数据,判断value中的ID是不是存在,存在直接覆盖,不存在追加
* @param {*} value
* @param {*} property
*/
saveDynamicGPTOption: async function (value) {
try {
let property = value[1]
value = JSON.parse(value[0])
// 获取自定义的GPT数据
let dynamic_setting = JSON.parse(await fspromises.readFile(define.dynamic_setting, 'utf-8'))
let tmp_gpt = dynamic_setting.gpt ? dynamic_setting.gpt : {}
let gpt = tmp_gpt[property] ? tmp_gpt[property] : []
if (value.id) {
// 判断当前ID的数据是否存在,存在覆盖,不存在追加
let index = gpt.findIndex((item) => item.id == value.id)
if (index < 0) {
gpt.push(value)
} else {
gpt[index] = value
}
} else {
let tmp_id = uuidv4()
value.id = tmp_id
gpt.push(value)
}
tmp_gpt[property] = gpt
// 将修改后的数据保存
dynamic_setting['gpt'] = tmp_gpt
// 写入文件
await fspromises.writeFile(define.dynamic_setting, JSON.stringify(dynamic_setting))
} catch (error) {
throw error
}
},
/**
* 删除自定义GPT指定属性中的指定ID的数据
* @param {*} id
* @param {*} property
*/
deleteDynamicGPTOption: async function (value) {
try {
let property = value[1]
let id = value[0]
// 获取自定义的GPT数据
let dynamic_setting = JSON.parse(await fspromises.readFile(define.dynamic_setting, 'utf-8'))
let gpt = dynamic_setting.gpt[property] ? dynamic_setting.gpt[property] : []
// 判断当前ID的数据是否存在,存在删除
let index = gpt.findIndex((item) => item.id == id)
if (index >= 0) {
gpt.splice(index, 1)
}
// 将修改后的数据保存
dynamic_setting.gpt[property] = gpt
// 写入文件
await fspromises.writeFile(define.dynamic_setting, JSON.stringify(dynamic_setting))
} catch (error) {
throw error
}
}
}