diff --git a/packages/core/src/commands/preset.ts b/packages/core/src/commands/preset.ts index 5bf21086..d17dd630 100644 --- a/packages/core/src/commands/preset.ts +++ b/packages/core/src/commands/preset.ts @@ -25,6 +25,21 @@ export function apply(ctx: Context, config: Config, chain: ChatChain) { } ) + ctx.command( + 'chathub.preset.clone [newPresetName:string]', + '克隆预设', + { + authority: 3 + } + ).action(async ({ session }, preset, newPreset) => { + await chain.receiveCommand(session, 'clone_preset', { + clonePreset: { + name: preset, + newName: newPreset ?? preset + '(1)' + } + }) + }) + ctx.command('chathub.preset.delete ', '删除一个预设', { authority: 3 }).action(async ({ session }, preset) => { diff --git a/packages/core/src/llm-core/prompt/preset_prompt_parse.ts b/packages/core/src/llm-core/prompt/preset_prompt_parse.ts index 219f7d0e..b1d1c4f9 100644 --- a/packages/core/src/llm-core/prompt/preset_prompt_parse.ts +++ b/packages/core/src/llm-core/prompt/preset_prompt_parse.ts @@ -128,7 +128,7 @@ export function formatPresetTemplateString( }) } -interface RawPreset { +export interface RawPreset { keywords: string[] prompts: { role: 'user' | 'system' | 'assistant' diff --git a/packages/core/src/middlewares/clone_preset.ts b/packages/core/src/middlewares/clone_preset.ts new file mode 100644 index 00000000..d4857935 --- /dev/null +++ b/packages/core/src/middlewares/clone_preset.ts @@ -0,0 +1,74 @@ +import { Context } from 'koishi' +import { Config } from '../config' +import { ChainMiddlewareRunStatus, ChatChain } from '../chains/chain' +import fs from 'fs/promises' +import { dump, load } from 'js-yaml' +import { RawPreset } from '../llm-core/prompt' + +export function apply(ctx: Context, config: Config, chain: ChatChain) { + chain + .middleware('clone_preset', async (session, context) => { + const { command } = context + + if (command !== 'clone_preset') { + return ChainMiddlewareRunStatus.SKIPPED + } + + const { newName, name } = context.options.clonePreset + + const presetService = ctx.chathub.preset + + const oldPreset = await presetService.getPreset(name) + + try { + await presetService.getPreset(newName) + + await context.send( + '该预设关键词已经和其他预设关键词冲突,请更换其他关键词重试哦' + ) + + return ChainMiddlewareRunStatus.STOP + } catch (e) {} + + await context.send( + `你确定要克隆预设 ${name} 吗?如果你确定要克隆,请输入 Y 来确认。` + ) + + const result = await session.prompt(1000 * 30) + + if (result == null) { + context.message = '操作超时未确认,已自动取消。' + return ChainMiddlewareRunStatus.STOP + } else if (result !== 'Y') { + context.message = '已为你取消操作。' + return ChainMiddlewareRunStatus.STOP + } + + const loaded = load(oldPreset.rawText) as RawPreset + + loaded.keywords.push(newName) + + await fs.writeFile( + presetService.resolvePresetDir() + `/${newName}_clone.yml`, + dump(loaded) + ) + + context.message = `预设克隆成功,预设名称为: ${newName}。 请调用预设列表命令查看。` + + return ChainMiddlewareRunStatus.STOP + }) + .after('lifecycle-handle_command') +} + +declare module '../chains/chain' { + interface ChainMiddlewareName { + clone_preset: string + } + + interface ChainMiddlewareContextOptions { + clonePreset?: { + name: string + newName: string + } + } +} diff --git a/packages/core/src/middlewares/delete_preset.ts b/packages/core/src/middlewares/delete_preset.ts index 2dba9406..ce6acb29 100644 --- a/packages/core/src/middlewares/delete_preset.ts +++ b/packages/core/src/middlewares/delete_preset.ts @@ -32,6 +32,7 @@ export function apply(ctx: Context, config: Config, chain: ChatChain) { return ChainMiddlewareRunStatus.STOP } } catch (e) { + logger.error(e) await context.send( '找不到该预设!请检查你是否输入了正确的预设?' ) @@ -69,9 +70,10 @@ export function apply(ctx: Context, config: Config, chain: ChatChain) { for (const room of roomList) { room.preset = defaultPreset.triggerKeyword[0] - await ctx.database.upsert('chathub_room', [room]) } + await ctx.database.upsert('chathub_room', roomList) + context.message = `已删除预设: ${presetName},即将自动重启完成更改。` ctx.scope.update(config, true) diff --git a/packages/core/src/preset.ts b/packages/core/src/preset.ts index 7df259cc..f13b1870 100644 --- a/packages/core/src/preset.ts +++ b/packages/core/src/preset.ts @@ -85,15 +85,6 @@ export class Preset { await this.loadAllPreset() } - /* const cached = await this.cache.get('default-preset') - if (cached) { - try { - return this.getPreset(cached) - } catch { - logger.warn(`default preset ${cached} not found, reset default preset`) - } - } */ - const preset = this._presets.find((preset) => preset.triggerKeyword.includes('chatgpt') )