Files
k3GPT/main/ui/agent.html

719 lines
39 KiB
HTML
Raw Normal View History

2025-11-19 19:43:08 +08:00
<div x-data="agent" class="mx-auto relative w-full">
<!-- 左右两块配置-->
<div class="flex w-full my-2 content border rounded-lg shadow-sm">
<div class="w-1/2 relative my-2 mx-4">
<!-- 智能体配置 -->
<div class=" bg-card text-neutral-900">
<div class="p-6 pt-0 space-y-2">
<div class="space-y-1"><label class="text-neutral-500 text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
<span class="text-red-700">*</span>名称(如企业文化、规则制度等,一般不超过10个字)</label>
<input type="text" x-model="kagent.title" class="flex w-full h-10 px-3 py-2 text-sm bg-white border rounded-md peer border-neutral-300 ring-offset-background placeholder:text-neutral-400 focus:border-neutral-300 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-400 disabled:cursor-not-allowed disabled:opacity-50" />
</div>
<div class="space-y-1"><label class="text-neutral-500 text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
<span class="text-red-700">*</span>介绍(功能性介绍,一般不超过30字)</label>
<input type="text" x-model="kagent.demo" class="flex w-full h-10 px-3 py-2 text-sm bg-white border rounded-md peer border-neutral-300 ring-offset-background placeholder:text-neutral-400 focus:border-neutral-300 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-400 disabled:cursor-not-allowed disabled:opacity-50" />
</div>
<div class="space-y-1"><label class="text-neutral-500 text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
<span class="text-red-700">*</span>引导语(一般不超过100字,支持MarkDown格式,两个空格加回车==换行)</label>
<textarea type="text" x-model="kagent.guide" rows="3" class="flex w-full h-30 px-3 py-2 text-sm bg-white border rounded-md peer border-neutral-300 ring-offset-background placeholder:text-neutral-400 focus:border-neutral-300 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-400 disabled:cursor-not-allowed disabled:opacity-50"></textarea>
</div>
<div class="space-y-1"><label class="text-neutral-500 text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
<span class="text-red-700">*</span>类型</label>
<div class="flex gap-2">
<div class="flex w-fit min-w-52 items-center justify-start gap-2 rounded-md border border-outline bg-surface-alt px-4 py-2 font-medium text-on-surface">
<input x-model="kagent.atype" type="radio" class="before:content[''] relative h-4 w-4 rounded-full" name="radioDefault" value="0">
<span class="text-sm">文件检索</span>
</div>
<div class="flex w-fit min-w-52 items-center justify-start gap-2 rounded-md border border-outline bg-surface-alt px-4 py-2 font-medium text-on-surface">
<input x-model="kagent.atype" type="radio" class="before:content[''] relative h-4 w-4 rounded-full" name="radioDefault" value="1" >
<span class="text-sm">目录检索</span>
</div>
<div class="flex w-fit min-w-52 items-center justify-start gap-2 rounded-md border border-outline bg-surface-alt px-4 py-2 font-medium text-on-surface">
<input x-model="kagent.atype" @click="set_files" type="radio" class="before:content[''] relative h-4 w-4 rounded-full" name="radioDefault" value="2">
<span class="text-sm">AI生成</span>
</div>
<div class="flex w-fit min-w-52 items-center justify-start gap-2 rounded-md border border-outline bg-surface-alt px-4 py-2 font-medium text-on-surface">
<input x-model="kagent.atype" type="radio" class="before:content[''] relative h-4 w-4 rounded-full" name="radioDefault" value="3">
<span class="text-sm">融合智能</span>
</div>
</div>
</div>
<div x-show="kagent.atype==0" class="space-y-1">
<button type="button" @click="open_file_selector" class="mx-auto cursor-pointer whitespace-nowrap rounded bg-sky-700 mx-2 px-2 py-1.5 text-sm font-medium tracking-wide text-white transition hover:opacity-75 text-center focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-sky-700 active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:bg-sky-600 dark:text-white dark:focus-visible:outline-sky-600">选择文件</button>
<button type="button" @click="clear_select_files" class="mx-auto cursor-pointer whitespace-nowrap rounded bg-green-700 mx-2 px-2 py-1.5 text-sm font-medium tracking-wide text-white transition hover:opacity-75 text-center focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-sky-700 active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:bg-sky-600 dark:text-white dark:focus-visible:outline-sky-600">清空选择</button>
<sapn x-text="select_count_info" class="text-neutral-500 text-sm font-medium"></sapn>
<textarea type="text" x-model="kagent.files" rows="2" class="flex w-full h-30 px-3 py-2 text-sm bg-white border rounded-md peer border-neutral-300 ring-offset-background placeholder:text-neutral-400 focus:border-neutral-300 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-400 disabled:cursor-not-allowed disabled:opacity-50"></textarea>
</div>
<div x-show="kagent.atype==1" class="space-y-1">
<sapn class="text-neutral-500 text-sm font-medium">文件路径中包含如下关键字的都会被检索,支持多个关键字,号隔开</sapn>
<input type="text" x-model="kagent.files" class="flex w-full h-30 px-3 py-2 text-sm bg-white border rounded-md peer border-neutral-300 ring-offset-background placeholder:text-neutral-400 focus:border-neutral-300 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-400 disabled:cursor-not-allowed disabled:opacity-50"></input>
</div>
<div x-show="kagent.atype==3" class="space-y-1">
<select x-model="kagent.files" class="w-full appearance-none rounded border border-zinc-300 bg-zinc-100 px-4 py-2 text-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-sky-700 disabled:cursor-not-allowed disabled:opacity-75 dark:border-zinc-700 dark:bg-zinc-800/50 dark:focus-visible:outline-sky-600">
<option value="0" selected>基本型(单一功能提示词)</option>
<option value="A" selected>反思型(路由+反思+工具)</option>
<option value="B" selected>反思型+联网搜索</option>
<option value="C" selected>增强型(反思型+评估)</option>
<option value="D" selected>增强型+联网搜索</option>
</select>
</div>
<div class="space-y-1">
<label class="text-neutral-500 text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
<span class="text-red-700">*</span>标签(标签名称+空格+颜色代码,可以添加新标签,颜色代码点击颜色盘选择)</label>
<div id="agent_catalog" alp-unit="agent_catalog.aps"></div>
</div>
</div>
</div>
<!-- End Tab Content 2 -->
</div>
<div class="w-1/2 relative my-2 mx-4">
<!-- 提示词模板 -->
<div class="rounded-lg bg-card text-neutral-900">
<div class="flex flex-col p-6">
<h3 class="text-lg font-semibold leading-none tracking-tight">提示词模板(支持MarkDown格式)</h3>
<p class="text-sm text-neutral-500"><span class="text-red-700">*</span>如果需要是使用json格式来描述数据时一定要使用双符号{{}}。<br>启用历史对话{{history}}, 其它json输出[{{"id":"任务1","task":104}}]</p>
</div>
<div class="p-6 pt-0 space-y-2">
<div class="space-y-1">
<button type="button" onclick="toggleFullscreen();" class="mx-auto cursor-pointer whitespace-nowrap rounded bg-green-700 mx-2 px-2 py-1.5 text-sm font-medium tracking-wide text-white transition hover:opacity-75 text-center focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-sky-700 active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:bg-sky-600 dark:text-white dark:focus-visible:outline-sky-600">全屏编辑</button>
<button type="button" @click="open_baike_selector" class="mx-auto cursor-pointer whitespace-nowrap rounded bg-blue-700 mx-2 px-2 py-1.5 text-sm font-medium tracking-wide text-white transition hover:opacity-75 text-center focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-sky-700 active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:bg-sky-600 dark:text-white dark:focus-visible:outline-sky-600">导入提示词</button>
<button type="button" @click="AIEditorOpen=true" class="mx-auto cursor-pointer whitespace-nowrap rounded bg-sky-700 mx-2 px-2 py-1.5 text-sm font-medium tracking-wide text-white transition hover:opacity-75 text-center focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-sky-700 active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:bg-sky-600 dark:text-white dark:focus-visible:outline-sky-600">备份提示词</button>
<button type="button" onclick="gen_agent_prompt();" class="mx-auto cursor-pointer whitespace-nowrap rounded bg-sky-700 mx-2 px-2 py-1.5 text-sm font-medium tracking-wide text-white transition hover:opacity-75 text-center focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-sky-700 active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:bg-sky-600 dark:text-white dark:focus-visible:outline-sky-600">多智能体提示词</button>
<textarea id="myTextarea" type="text" x-model="kagent.prompt" rows="13" class="flex w-full h-30 px-3 py-2 text-sm bg-white border rounded-md peer border-neutral-300 ring-offset-background placeholder:text-neutral-400 focus:border-neutral-300 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-400 disabled:cursor-not-allowed disabled:opacity-50"></textarea></div>
</div>
</div>
<!-- End Tab Content 2 -->
</div>
</div>
<!-- 保存按钮-->
<div class="flex items-center">
<button id="save_agent_cfg" type="button" @click="save" class="mx-auto cursor-pointer whitespace-nowrap rounded bg-sky-700 px-4 py-2 text-sm font-medium tracking-wide text-white transition hover:opacity-75 text-center focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-sky-700 active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:bg-sky-600 dark:text-white dark:focus-visible:outline-sky-600">保存配置</button>
<button id="agent_chat" x-show="Agent_Kasn!=''" type="button" @click="chat_modalIsOpen=true" class="mx-auto cursor-pointer whitespace-nowrap rounded bg-sky-700 px-4 py-2 text-sm font-medium tracking-wide text-white transition hover:opacity-75 text-center focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-sky-700 active:opacity-100 active:outline-offset-0 disabled:opacity-75 disabled:cursor-not-allowed dark:bg-sky-600 dark:text-white dark:focus-visible:outline-sky-600">测试对话</button>
</div>
<!-- 通知窗口-->
<div x-show="save_fin" id="draggable" class="fixed moved bottom-10 left-0 right-0 z-30 mx-auto max-w-2xl w-full overflow-hidden rounded border border-green-700 bg-zinc-50 text-neutral-600 dark:bg-zinc-900 dark:text-zinc-200" role="alert">
<div class="flex w-full items-center gap-2 bg-green-700/10 p-4">
<div class="bg-green-700/15 text-green-700 rounded-full p-1" aria-hidden="true">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="size-6" aria-hidden="true">
<path fill-rule="evenodd" d="M10 18a8 8 0 1 0 0-16 8 8 0 0 0 0 16Zm3.857-9.809a.75.75 0 0 0-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 1 0-1.06 1.061l2.5 2.5a.75.75 0 0 0 1.137-.089l4-5.5Z" clip-rule="evenodd" />
</svg>
</div>
<div class="ml-2">
<h3 class="text-sm font-semibold text-green-700">保存成功</h3>
<p class="text-xs font-medium sm:text-sm">知识体配置保存成功,3秒后自动消失</p>
</div>
<button @click="save_fin=false" class="ml-auto" aria-label="dismiss alert">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" stroke="currentColor" fill="none" stroke-width="2.5" class="w-4 h-4 shrink-0">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/>
</svg>
</button>
</div>
</div>
<!-- 选择文件窗口-->
<div x-show="FileSelecterOpen" id="file_selector" class="fixed top-10 left-0 right-0 z-30 mx-auto max-w-3xl w-full overflow-hidden rounded border border-sky-700 bg-zinc-50 text-neutral-600 dark:bg-zinc-900 dark:text-zinc-200" role="alert">
<div id="file_selector_m" class="flex moved w-full items-center gap-2 bg-sky-700/90 p-2">
<div class="ml-2">
<h3 class="text-sm font-semibold text-white">文件筛选</h3>
</div>
<button @click="FileSelecterOpen=false" class="ml-auto" aria-label="dismiss alert">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" stroke="currentColor" fill="none" stroke-width="2.5" class="w-4 h-4 shrink-0">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/>
</svg>
</button>
</div>
<!-- body-->
<div class="flex w-full items-center gap-2 bg-sky-700/10 p-2">
<template x-if="FileSelecterOpen">
<div id="file_list" alp-unit="kg_select.aps" class="w-full overflow-hidden"></div>
</template>
</div>
</div>
<!-- 选择百科提示词窗口-->
<div x-show="BaikeSelectOpen" id="baike_selector" class="fixed top-10 left-0 right-0 z-30 mx-auto max-w-4xl w-full overflow-hidden rounded border border-sky-700 bg-zinc-50 text-neutral-600 dark:bg-zinc-900 dark:text-zinc-200" role="alert">
<div id="baike_selector_m" class="flex moved w-full items-center gap-2 bg-sky-700/90 p-2">
<div class="ml-2">
<h3 class="text-sm font-semibold text-white">提示词模板</h3>
</div>
<button @click="BaikeSelectOpen=false" class="ml-auto" aria-label="dismiss alert">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" stroke="currentColor" fill="none" stroke-width="2.5" class="w-4 h-4 shrink-0">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/>
</svg>
</button>
</div>
<!-- body-->
<div class="flex w-full items-center gap-2 bg-sky-700/10 p-2">
<template x-if="BaikeSelectOpen">
<div id="baike_list" alp-unit="baike_select.html" class="w-full overflow-hidden"></div>
</template>
</div>
</div>
<!-- AI 编辑器 导出提示词到百科 -->
<div>
<div x-cloak x-show="AIEditorOpen" x-transition.opacity.duration.200ms x-trap.inert.noscroll="AIEditorOpen" @keydown.esc.window="close_aieditor" class="fixed inset-0 z-30 flex items-end justify-center bg-black/20 px-4 py-2 backdrop-blur-md sm:items-center lg:p-8" role="dialog" aria-modal="true" aria-labelledby="infoModalTitle">
<!-- Modal Dialog -->
<div x-show="AIEditorOpen" x-transition:enter="transition ease-out duration-200 delay-100 motion-reduce:transition-opacity" x-transition:enter-start="opacity-0 scale-50" x-transition:enter-end="opacity-100 scale-100" class="w-full max-w-2xl flex flex-col gap-1 overflow-hidden rounded border border-zinc-300 bg-zinc-50 text-neutral-600 dark:border-zinc-700 dark:bg-zinc-800 dark:text-zinc-200">
<!-- Dialog Header -->
<div class="flex items-center justify-between border-b border-zinc-300 bg-zinc-100/60 px-4 py-2 dark:border-zinc-700 dark:bg-zinc-900/20">
<div class="flex items-center justify-center rounded-full bg-sky-700/20 text-sky-700 p-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="size-6" aria-hidden="true">
<path fill-rule="evenodd" d="M18 10a8 8 0 1 1-16 0 8 8 0 0 1 16 0Zm-7-4a1 1 0 1 1-2 0 1 1 0 0 1 2 0ZM9 9a.75.75 0 0 0 0 1.5h.253a.25.25 0 0 1 .244.304l-.459 2.066A1.75 1.75 0 0 0 10.747 15H11a.75.75 0 0 0 0-1.5h-.253a.25.25 0 0 1-.244-.304l.459-2.066A1.75 1.75 0 0 0 9.253 9H9Z" clip-rule="evenodd" />
</svg>
导出提示词模板到百科
</div>
<button @click="close_aieditor" aria-label="close modal">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" stroke="currentColor" fill="none" stroke-width="1.4" class="w-5 h-5">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/>
</svg>
</button>
</div>
<!-- Dialog Body -->
<div class="p-6 space-y-2 h-full">
<div class="space-y-1"><label class="text-sm font-bold font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">百科标题</label>
<input type="text" x-model="new_title" class="flex w-full h-10 px-3 py-2 text-sm bg-white border rounded-md peer border-neutral-300 ring-offset-background placeholder:text-neutral-400 focus:border-neutral-300 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-400 disabled:cursor-not-allowed disabled:opacity-50" /></div>
</div>
<!-- Dialog Footer -->
<div class="flex items-center border-t border-zinc-300 bg-zinc-100/60 p-4 dark:border-zinc-700 dark:bg-zinc-900/20 sm:flex-row sm:items-center md:justify-end">
<button @click="save_bake" type="button" class="mx-auto cursor-pointer whitespace-nowrap rounded bg-sky-700 px-4 py-2 text-center text-sm font-medium tracking-wide text-white transition hover:opacity-75 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-sky-700 active:opacity-100 active:outline-offset-0 dark:bg-sky-600 dark:text-white dark:focus-visible:outline-sky-600">保存</button>
</div>
</div>
</div>
</div>
<!-- 对话测试窗口 -->
<div x-cloak x-show="chat_modalIsOpen" x-transition.opacity.duration.200ms x-trap.inert.noscroll="chat_modalIsOpen" x-on:keydown.esc.window="chat_modalIsOpen = ppt_modalIsOpen = poster_modalIsOpen = false" x-on:click.self="chat_modalIsOpen = ppt_modalIsOpen = poster_modalIsOpen = false" class="fixed inset-0 z-50 flex w-full h-100vh items-start justify-end bg-black/20 backdrop-blur-md" role="dialog" aria-modal="true" aria-labelledby="defaultModalTitle">
<!-- Modal Dialog -->
<div x-show="chat_modalIsOpen" x-transition:enter="transition ease-out duration-200 delay-100 motion-reduce:transition-opacity" x-transition:enter-start="opacity-0 scale-50" x-transition:enter-end="opacity-100 scale-100" class="flex w-100 flex-col gap-4 overflow-hidden rounded border border-zinc-300 bg-zinc-50 text-neutral-600 dark:border-zinc-700 dark:bg-zinc-800 dark:text-zinc-200">
<!-- Dialog Header -->
<div class="flex items-center justify-between border-b border-zinc-300 bg-zinc-100/60 p-4 dark:border-zinc-700 dark:bg-zinc-900/20">
<h3 id="defaultModalTitle" class="font-semibold tracking-wide text-neutral-900 dark:text-zinc-50">知识体对话助手</h3>
<button x-on:click="chat_modalIsOpen = ppt_modalIsOpen = poster_modalIsOpen = false" aria-label="close modal">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" stroke="currentColor" fill="none" stroke-width="1.4" class="w-5 h-5">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/>
</svg>
</button>
</div>
<div id="chat_ai_dialog" alp-unit="chat_agent.html"></div>
</div>
</div>
</div>
</div>
<!-- 全屏编辑器-->
<div class="container" id="md_edior">
<div class="toolbar">
<button onclick="insertText('**', '**')">加粗</button>
<button onclick="insertText('*', '*')">斜体</button>
<button onclick="insertText('- ', '', true)">无序列表</button>
<button onclick="insertText('1. ', '', true)">有序列表</button>
<button onclick="insertText('# ', '')">一级标题</button>
<button onclick="insertText('## ', '')">二级标题</button>
<button onclick="insertText('### ', '')">三级标题</button>
<button onclick="insertText('```\n', '\n```')">代码块</button>
<button onclick="do_save()">保存</button>
<button onclick="do_chat()">对话测试</button>
<button onclick="do_exit()" style="background-color:#0000ff;color: white;">退出编辑</button>
</div>
<div class="editor-container">
<textarea id="editor" placeholder="输入Markdown内容..."></textarea>
<div id="preview"></div>
</div>
</div>
<style>
/* 基础样式 */
h1, h2, h3, h4, h5 {
font-weight: bold;
line-height: 1.2;
margin-bottom: 0.5em;
}
h1 {
font-size: 1.5em;
color: #000;
}
h2 {
font-size: 1.25em;
color: #000;
}
h3 {
font-size: 1em;
color: #000;
}
#preview ul {
list-style-type: disc; /* 默认样式为实心圆 */
margin: 0;
padding-left: 20px; /* 根据需要调整缩进 */
}
#preview ul li {
margin-left: 1em; /* 可选:增加项目之间的间距 */
}
#preview ol {
list-style-type: decimal; /* 默认样式为数字1, 2, 3... */
margin: 0;
padding-left: 20px; /* 根据需要调整缩进 */
}
#preview ol li {
margin-left: 1em; /* 可选:增加项目之间的间距 */
}
.container {
display: none;
}
/* 全屏/顶层样式 */
.fullscreen {
position: fixed;
top: 10px;
left: 10px;
width: 98%;
background-color: white;
z-index: 31; /* 确保它位于其他内容之上 在保存提示之下*/
resize: none; /* 禁止用户调整大小 */
border: none; /* 移除边框 */
padding: 20px; /* 可选:增加一些内边距 */
box-sizing: border-box; /* 确保padding不会影响宽度和高度 */
flex-direction: column;
height: 95vh;
}
/* 关闭按钮样式 */
.close-fullscreen-btn {
position: absolute;
top: 10px;
right: 10px;
background-color: blue;
color: white;
border: none;
padding: 5px 10px;
cursor: pointer;
z-index: 35; /* 确保关闭按钮始终在最上层 */
}
.toolbar {
margin-bottom: 10px;
}
.toolbar button {
padding: 5px 10px;
margin-right: 5px;
cursor: pointer;
background-color: #ccc;
border: 1px solid #4d5569;
border-radius: 5px;
}
.editor-container {
display: flex;
gap: 20px;
flex-grow: 1;
}
#editor {
width: 50%;
padding: 10px;
border: 1px solid #ccc;
border-radius: 4px;
resize: none;
font-family: 'Courier New', monospace;
height: 80vh;
}
#preview {
width: 50%;
padding: 10px;
border: 1px solid #ccc;
border-radius: 4px;
overflow-y: auto;
height: 80vh;
}
</style>
<script>
//kagent的配置
function agent(){
return {
save_fin: false,
FileSelecterOpen: false,
BaikeSelectOpen: false,
AIEditorOpen: false,
chat_modalIsOpen:false,
kagent:{},
select_count_info:'',
new_title: '',
file_count:0,
show_list:false, //不显示对话列表
init(){
//动态加载,AI对话框
this.$watch('chat_modalIsOpen',value => {
if (value){
this.$nextTick(() => {
var dom = document.getElementById('chat_ai_dialog')
scan_alp_units(dom);
});
}
});
if (this.kagent_id !=0) {
axios.get('/api/kagent/'+this.kagent_id).then(response => {
this.kagent = response.data;
this.new_title = this.kagent.title;
this.gen_count();
}).catch(error => {
console.error('Error fetching data:', error);
throw error; // 重新抛出错误以便调用者可以处理
});
}else{
this.kagent.id=0;
this.kagent.prompt=`
# 你是一个xxxx方面的知识助手或专家
## 核心技能
1. 你可以根据提供的上下文信息回答用户的问题。
2. 你可以根据用户的要求来生成一个完整的方案
3. 其它相关问题
## 多轮对话
如果有历史对话信息的话,可以用来参考
`;
this.kagent.atype=0;
this.Agent_Kasn = "";
}
},
open_file_selector(){
this.FileSelecterOpen = true;
set_draggable_by_id('file_selector');
//dom 更新后加载==动态加载
this.$nextTick(() => {
var dom = document.getElementById('file_list')
scan_alp_units(dom);
});
},
open_baike_selector(){
this.BaikeSelectOpen = true;
set_draggable_by_id('baike_selector');
//dom 更新后加载==动态加载
this.$nextTick(() => {
var dom = document.getElementById('baike_list')
scan_alp_units(dom);
});
},
gen_count(){ //计算文件数量
if (this.kagent.atype==0 && this.kagent.files !=''){
var files_list = this.kagent.files.match(/[^,\s]+(?:\s+[^,\s]+)*/g);
this.file_count = files_list.length;
this.select_count_info =`已选中${this.file_count}个文件`;
}
},
clear_select_files(){
this.kagent.files = '';
this.select_count_info ='';
},
set_files(){
if (this.kagent.files==''){
this.kagent.files=this.kagent.title;
}
},
save(){
this.kagent.prompt = document.getElementById('myTextarea').value;
this.kagent.catalog = document.getElementById('phoneNumber').value;
// 使用 axios 发送 POST 请求
axios.post('/api/kagent', this.kagent)
.then(response =>{
this.save_fin = true;
//只返回了id和kasn
this.kagent.id = response.data.id
this.Agent_Kasn = response.data.kasn;
setTimeout(() => {
this.save_fin = false;
}, 3000); // 3000 毫秒 = 3 秒
})
.catch(error => {
alert(error);
console.error('Error post data:', error);
throw error; // 重新抛出错误以便调用者可以处理
});
//同时建立相关的百科
const newItem = {
catalog: '智能体数据/'+this.kagent.title,
demo: '和 智能体:'+this.kagent.title+' 相关的数据',
};
// 使用 axios 发送 POST 请求
axios.post('/api/catalog', newItem)
.then(response =>{
console.info(response.data.code);
})
.catch(error => {
alert(error);
throw error; // 重新抛出错误以便调用者可以处理
});
},
save_bake(){
// 数据对象,代表要发送的数据
const newItem = {
id: 0,
title: this.new_title,
catalog: '大模型/提示词模板',
html: this.kagent.prompt,
};
// 使用 axios 发送 POST 请求
axios.post('/api/baike', newItem)
.then(response =>{
this.AIEditorOpen = false;
})
.catch(error => {
alert(error);
console.error('Error post data:', error);
throw error; // 重新抛出错误以便调用者可以处理
});
}
}
}
//全局变量
var isDragging = false;
var offsetX, offsetY;
//设置某个层可以鼠标拖动(position: absolute; /* 必须是absolute或fixed才能拖动 */)
function set_draggable_by_id(id){
//本体
var draggable = document.getElementById(id);
//拖拽的标题
var draggable_m = document.getElementById(id+"_m");
draggable_m.onmousedown = function(e) {
isDragging = true;
// 计算鼠标相对于元素左上角的位置
offsetX = e.clientX - draggable.offsetLeft;
offsetY = e.clientY - draggable.offsetTop;
console.info("开始拖动");
// 在移动过程中持续更新位置
document.onmousemove = function(e) {
if (isDragging) {
draggable.style.left = (e.clientX - offsetX) + 'px';
draggable.style.top = (e.clientY - offsetY) + 'px';
}
};
};
//console.info("设置可拖动完成");
// 监听全局的mouseup事件来停止拖拽
document.onmouseup = function() {
isDragging = false;
document.onmousemove = null;
};
}
// 实时预览
var editor = document.getElementById('editor');
var preview = document.getElementById('preview');
editor.addEventListener('input', updatePreview);
function toggleFullscreen() {
var md_edior = document.getElementById("md_edior");
//var closeButton = document.querySelector('.close-fullscreen-btn');
var mytextarea = document.getElementById("myTextarea");
editor = document.getElementById('editor');
preview = document.getElementById('preview');
editor.addEventListener('input', updatePreview);
if (md_edior.classList.contains('fullscreen')) {
mytextarea.value=editor.value;
// 如果已经是全屏状态,则恢复原状并移除关闭按钮
md_edior.classList.remove('fullscreen');
md_edior.classList.add('container');
//closeButton.parentNode.removeChild(closeButton);
} else {
// 否则,进入全屏状态,并添加关闭按钮
editor.value = mytextarea.value;
md_edior.classList.remove('container');
md_edior.classList.add('fullscreen');
updatePreview();
}
}
//保存
function do_save(){
var mytextarea = document.getElementById("myTextarea");
mytextarea.value=editor.value;
const save_button = document.getElementById('save_agent_cfg');
save_button.click();
}
//启动测试对话
function do_chat(){
//事件传递
const agent_chat = document.getElementById('agent_chat');
agent_chat.click();
}
//退出全屏编辑
function do_exit(){
toggleFullscreen();
}
// 更新预览
function updatePreview() {
preview.innerHTML = marked.parse(editor.value);
}
// 工具按钮功能
function insertText(before, after, lineStart = false) {
const textarea = editor;
const start = textarea.selectionStart;
const end = textarea.selectionEnd;
const text = textarea.value;
const selection = text.substring(start, end);
if (lineStart) {
const currentLineStart = text.lastIndexOf('\n', start - 1) + 1;
const currentLineEnd = text.indexOf('\n', end);
const currentLine = text.substring(currentLineStart, currentLineEnd);
if (currentLine.startsWith(before)) {
// 移除格式
const newText = text.substring(0, currentLineStart) +
currentLine.replace(before, '') +
text.substring(currentLineEnd);
textarea.value = newText;
textarea.selectionStart = start - before.length;
textarea.selectionEnd = end - before.length;
} else {
// 添加格式
const newText = text.substring(0, currentLineStart) +
before +
text.substring(currentLineStart);
textarea.value = newText;
textarea.selectionStart = start + before.length;
textarea.selectionEnd = end + before.length;
}
} else {
// 普通插入
const newText = text.substring(0, start) +
before +
selection +
after +
text.substring(end);
textarea.value = newText;
textarea.selectionStart = start + before.length;
textarea.selectionEnd = start + before.length + selection.length;
}
updatePreview();
textarea.focus();
}
// 智能编辑功能
editor.addEventListener('keydown', function(e) {
if (e.key === 'Enter') {
const text = this.value;
const start = this.selectionStart;
const lineStart = text.lastIndexOf('\n', start - 1) + 1;
const currentLine = text.substring(lineStart, start);
// 自动延续列表
const listMatch = currentLine.match(/^(\s*)(\d+\.|-|\*)\s/);
if (listMatch) {
e.preventDefault();
const indent = listMatch[1];
let bullet = listMatch[2];
if (bullet.includes('.')) {
bullet = parseInt(bullet) + 1 + '.';
}
const newText = text.substring(0, start) +
'\n' + indent + bullet + ' ';
//新的加上原先老的
this.value = newText+ text.substring(start);
this.selectionStart = start + indent.length + bullet.length + 2;
this.selectionEnd = start + indent.length + bullet.length + 2;
updatePreview();
}
}
});
// Synchronize scrolling between editor and preview
editor.addEventListener('scroll', function() {
const scrollPercentage = editor.scrollTop / (editor.scrollHeight - editor.clientHeight);
preview.scrollTop = (preview.scrollHeight - preview.clientHeight) * scrollPercentage;
});
preview.addEventListener('scroll', function() {
const scrollPercentage = preview.scrollTop / (preview.scrollHeight - preview.clientHeight);
editor.scrollTop = (editor.scrollHeight - editor.clientHeight) * scrollPercentage;
});
function gen_agent_prompt(){
// 显示确认框
if (confirm("在执行此操作前最好先备份当前提示词,确定要生成多智能体提示词吗?")) {
var prompt=`
## 调用智能体技能
### 智能体描述
其中第一列是智能体的标识SN,第二列是智能体的名称和描述.
可以根据需要自行添加发布好的智能体
<agents>[
["TpSVXH1WiBg","PPT生成智能体"],
["JX2ErpFVfQg","海报助手"],
]</agents>
`;
var mytextarea = document.getElementById("myTextarea");
mytextarea.value = prompt;
}
}
</script>