Files
k3GPT/main/ui/chat_agent.html
2025-11-19 19:43:03 +08:00

951 lines
64 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<div x-data="chat_agent" class="flex w-full my-2 rounded border">
<!-- 左边的 div -->
<div class="w-1/5 bg-zinc-50 h-[90vh] flex flex-col border-r">
<h3 x-text="kagent.title" class="text-lg text-blue-700 font-bold text-center p-2"></h3>
<div class="text-center my-2">
<button x-on:click="new0" type="button" class="text-white bg-gradient-to-br from-indigo-600 to-blue-600 focus-visible:outline-indigo-600 dark:focus-visible:outline-indigo-600 rounded inline-flex cursor-pointer items-center justify-center gap-2 whitespace-nowrap px-4 py-2 text-xs tracking-wide transition hover:opacity-75 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 active:opacity-100 active:outline-offset-0 disabled:cursor-not-allowed disabled:opacity-75">新建对话</button>
<button x-show="qItems.length >0" x-on:click="gen_chat_baike" type="button" class="text-white bg-gradient-to-br from-indigo-600 to-blue-600 focus-visible:outline-indigo-600 dark:focus-visible:outline-indigo-600 rounded inline-flex cursor-pointer items-center justify-center gap-2 whitespace-nowrap px-4 py-2 text-xs tracking-wide transition hover:opacity-75 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 active:opacity-100 active:outline-offset-0 disabled:cursor-not-allowed disabled:opacity-75">生成词条</button>
<button x-show="show_list" x-on:click="$store.nav.is_ground=true" type="button" class="text-white bg-gradient-to-br from-indigo-600 to-blue-600 focus-visible:outline-indigo-600 dark:focus-visible:outline-indigo-600 rounded inline-flex cursor-pointer items-center justify-center gap-2 whitespace-nowrap px-4 py-2 text-xs tracking-wide transition hover:opacity-75 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 active:opacity-100 active:outline-offset-0 disabled:cursor-not-allowed disabled:opacity-75">返回</button>
</div>
<div class="overflow-hidden overflow-y-auto ">
<!-- <div class="font-bold text-sm">当前对话列表:</div> -->
<ul>
<template x-for="(qitem, index) in qItems" :key="index">
<li class="ml-4 text-sm text-blue-700 my-2">
<span x-text="index+1"></span>.&nbsp;&nbsp;<a x-text="qitem.req" :href="'#QA'+index" @click="copy_query(qitem.req)"></a>
<button @click="del_chat(index)" class="rounded-full text-neutral-600/75 hover:bg-zinc-900/10 hover:text-neutral-600 focus:outline-none focus-visible:text-neutral-600 focus-visible:zinc-300 focus-visible:outline-offset-0 focus-visible:outline-sky-700 active:bg-zinc-900/5 active:-outline-offset-2 dark:text-zinc-200/75 dark:hover:bg-zinc-50/10 dark:hover:text-zinc-200 dark:focus-visible:text-zinc-200 dark:focus-visible:outline-sky-600 dark:active:bg-zinc-50/5" title="删除此对话" aria-label="删除此对话" >
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" aria-hidden="true" fill="currentColor" class="pointer-events-none w-4 h-4">
<path d="M5.28 4.22a.75.75 0 0 0-1.06 1.06L6.94 8l-2.72 2.72a.75.75 0 1 0 1.06 1.06L8 9.06l2.72 2.72a.75.75 0 1 0 1.06-1.06L9.06 8l2.72-2.72a.75.75 0 0 0-1.06-1.06L8 6.94 5.28 4.22Z"/>
</svg>
</button>
</li>
</template>
</ul>
</div>
<div class="flex flex-col">
<div class="font-bold text-sm">历史对话列表:</div>
<ul>
<template x-for="(req, index) in hItems" :key="index">
<li class="ml-4 text-sm text-blue-700 my-2">
<span x-text="index+1"></span>.&nbsp;&nbsp;<a href="#" x-text="req.slice(0,30)" @click="copy_query(req)"></a>
</li>
</template>
</ul>
</div>
</div>
<!-- 右边的 div -->
<div class="w-4/5 bg-zinc-50">
<div class="mx-4 flex flex-col h-[90vh]">
<!-- 对话的展示-->
<div id="chat_display_2" class="flex-grow overflow-hidden overflow-y-auto">
<!-- 对话列表-->
<div class="mx-10">
<div class="flex flex-col gap-2 mx-4">
<!-- AI's Response -->
<div class="w-full mt-2 max-w-2xl border-zinc-300 bg-zinc-100 p-2 text-left dark:border-zinc-700 dark:bg-zinc-800 rounded border" >
<div class="flex items-center gap-2 text-neutral-900 dark:text-zinc-50">
<span class="flex size-8 items-center justify-center rounded-full bg-sky-700 text-white dark:bg-sky-600 dark:text-white">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" class="size-5">
<path d="M6 12.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5M3 8.062C3 6.76 4.235 5.765 5.53 5.886a26.6 26.6 0 0 0 4.94 0C11.765 5.765 13 6.76 13 8.062v1.157a.93.93 0 0 1-.765.935c-.845.147-2.34.346-4.235.346s-3.39-.2-4.235-.346A.93.93 0 0 1 3 9.219zm4.542-.827a.25.25 0 0 0-.217.068l-.92.9a25 25 0 0 1-1.871-.183.25.25 0 0 0-.068.495c.55.076 1.232.149 2.02.193a.25.25 0 0 0 .189-.071l.754-.736.847 1.71a.25.25 0 0 0 .404.062l.932-.97a25 25 0 0 0 1.922-.188.25.25 0 0 0-.068-.495c-.538.074-1.207.145-1.98.189a.25.25 0 0 0-.166.076l-.754.785-.842-1.7a.25.25 0 0 0-.182-.135" />
<path d="M8.5 1.866a1 1 0 1 0-1 0V3h-2A4.5 4.5 0 0 0 1 7.5V8a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1v1a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-1a1 1 0 0 0 1-1V9a1 1 0 0 0-1-1v-.5A4.5 4.5 0 0 0 10.5 3h-2zM14 7.5V13a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V7.5A3.5 3.5 0 0 1 5.5 4h5A3.5 3.5 0 0 1 14 7.5" />
</svg>
</span>
<span class="text-sm font-bold">Yi.AI</span>
</div>
<p x-html="kagent.guide" class="text-pretty sm:pl-10 mt-4 sm:mt-0 text-sm text-neutral-600 dark:text-zinc-200">
你好,我是一个知识机器人,我可以帮你检索知识库并回答你的问题。
请问我有什么可以帮助你的?
</p>
<!-- Actions -->
<div class="mt-2 flex items-center gap-2 sm:pl-10">
<button class="rounded-full p-1 text-neutral-600/75 hover:bg-zinc-900/10 hover:text-neutral-600 focus:outline-none focus-visible:text-neutral-600 focus-visible:zinc-300 focus-visible:outline-offset-0 focus-visible:outline-sky-700 active:bg-zinc-900/5 active:-outline-offset-2 dark:text-zinc-200/75 dark:hover:bg-zinc-50/10 dark:hover:text-zinc-200 dark:focus-visible:text-zinc-200 dark:focus-visible:outline-sky-600 dark:active:bg-zinc-50/5" title="Read Aloud" aria-label="Read Aloud" >
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="size-4" aria-hidden="true">
<path d="M10.5 3.75a.75.75 0 0 0-1.264-.546L5.203 7H2.667a.75.75 0 0 0-.7.48A6.985 6.985 0 0 0 1.5 10c0 .887.165 1.737.468 2.52.111.29.39.48.7.48h2.535l4.033 3.796a.75.75 0 0 0 1.264-.546V3.75ZM16.45 5.05a.75.75 0 0 0-1.06 1.061 5.5 5.5 0 0 1 0 7.778.75.75 0 0 0 1.06 1.06 7 7 0 0 0 0-9.899Z"/>
<path d="M14.329 7.172a.75.75 0 0 0-1.061 1.06 2.5 2.5 0 0 1 0 3.536.75.75 0 0 0 1.06 1.06 4 4 0 0 0 0-5.656Z"/>
</svg>
</button>
<button @click="FileSelecterOpen=true" class="rounded-full p-1 text-neutral-600/75 hover:bg-zinc-900/10 hover:text-neutral-600 focus:outline-none focus-visible:text-neutral-600 focus-visible:zinc-300 focus-visible:outline-offset-0 focus-visible:outline-sky-700 active:bg-zinc-900/5 active:-outline-offset-2 dark:text-zinc-200/75 dark:hover:bg-zinc-50/10 dark:hover:text-zinc-200 dark:focus-visible:text-zinc-200 dark:focus-visible:outline-sky-600 dark:active:bg-zinc-50/5" title="个人文件夹" aria-label="个人文件夹" >
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="size-4 shrink-0" aria-hidden="true">
<path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/>
<path d="M12 11v6"/>
<path d="M8 11v6"/>
<path d="M16 11v6"/>
</svg>
</button>
<button class="rounded-full p-1 text-neutral-600/75 hover:bg-zinc-900/10 hover:text-neutral-600 focus:outline-none focus-visible:text-neutral-600 focus-visible:zinc-300 focus-visible:outline-offset-0 focus-visible:outline-sky-700 active:bg-zinc-900/5 active:-outline-offset-2 dark:text-zinc-200/75 dark:hover:bg-zinc-50/10 dark:hover:text-zinc-200 dark:focus-visible:text-zinc-200 dark:focus-visible:outline-sky-600 dark:active:bg-zinc-50/5" title="More settings" aria-label="More settings" >
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="size-4" aria-hidden="true">
<path d="M9.5 13a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0m0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0m0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0"/>
</svg>
</button>
</div>
</div>
<template x-for="(item, index) in Items" :key="index">
<div>
<!-- User's Chat -->
<div :id="'QA'+index" class="w-full ml-auto max-w-xl border-zinc-300 bg-blue-700/50 p-2 text-left dark:border-zinc-700 dark:bg-zinc-800 rounded border" >
<div class="flex items-center gap-2 text-white dark:text-zinc-50">
<!--
<span class="flex size-8 items-center justify-center rounded-full bg-blue-700 text-white dark:bg-sky-600 dark:text-white">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" class="size-5">
<path d="M6 12.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5M3 8.062C3 6.76 4.235 5.765 5.53 5.886a26.6 26.6 0 0 0 4.94 0C11.765 5.765 13 6.76 13 8.062v1.157a.93.93 0 0 1-.765.935c-.845.147-2.34.346-4.235.346s-3.39-.2-4.235-.346A.93.93 0 0 1 3 9.219zm4.542-.827a.25.25 0 0 0-.217.068l-.92.9a25 25 0 0 1-1.871-.183.25.25 0 0 0-.068.495c.55.076 1.232.149 2.02.193a.25.25 0 0 0 .189-.071l.754-.736.847 1.71a.25.25 0 0 0 .404.062l.932-.97a25 25 0 0 0 1.922-.188.25.25 0 0 0-.068-.495c-.538.074-1.207.145-1.98.189a.25.25 0 0 0-.166.076l-.754.785-.842-1.7a.25.25 0 0 0-.182-.135" />
<path d="M8.5 1.866a1 1 0 1 0-1 0V3h-2A4.5 4.5 0 0 0 1 7.5V8a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1v1a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-1a1 1 0 0 0 1-1V9a1 1 0 0 0-1-1v-.5A4.5 4.5 0 0 0 10.5 3h-2zM14 7.5V13a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V7.5A3.5 3.5 0 0 1 5.5 4h5A3.5 3.5 0 0 1 14 7.5" />
</svg>
</span>
-->
<span x-text="item.req" class="text-sm">Alice Brown</span>
</div>
<p class="text-pretty mt-2 text-sm text-white dark:text-zinc-200">
<button class="rounded-full p-1 text-white hover:bg-zinc-900/10 hover:text-neutral-600 focus:outline-none focus-visible:text-neutral-600 focus-visible:zinc-300 focus-visible:outline-offset-0 focus-visible:outline-sky-700 active:bg-zinc-900/5 active:-outline-offset-2 dark:text-zinc-200/75 dark:hover:bg-zinc-50/10 dark:hover:text-zinc-200 dark:focus-visible:text-zinc-200 dark:focus-visible:outline-sky-600 dark:active:bg-zinc-50/5" title="Read Aloud" aria-label="Read Aloud" >
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="size-4" aria-hidden="true">
<path d="M10.5 3.75a.75.75 0 0 0-1.264-.546L5.203 7H2.667a.75.75 0 0 0-.7.48A6.985 6.985 0 0 0 1.5 10c0 .887.165 1.737.468 2.52.111.29.39.48.7.48h2.535l4.033 3.796a.75.75 0 0 0 1.264-.546V3.75ZM16.45 5.05a.75.75 0 0 0-1.06 1.061 5.5 5.5 0 0 1 0 7.778.75.75 0 0 0 1.06 1.06 7 7 0 0 0 0-9.899Z"/>
<path d="M14.329 7.172a.75.75 0 0 0-1.061 1.06 2.5 2.5 0 0 1 0 3.536.75.75 0 0 0 1.06 1.06 4 4 0 0 0 0-5.656Z"/>
</svg>
</button>
<button x-on:click="copy_query(item.req)" class="rounded-full p-1 text-white hover:bg-zinc-900/10 hover:text-neutral-600 focus:outline-none focus-visible:text-neutral-600 focus-visible:zinc-300 focus-visible:outline-offset-0 focus-visible:outline-sky-700 active:bg-zinc-900/5 active:-outline-offset-2 dark:text-zinc-200/75 dark:hover:bg-zinc-50/10 dark:hover:text-zinc-200 dark:focus-visible:text-zinc-200 dark:focus-visible:outline-sky-600 dark:active:bg-zinc-50/5" title="Copy" aria-label="Copy" >
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="size-4" aria-hidden="true">
<path fill-rule="evenodd" d="M13.887 3.182c.396.037.79.08 1.183.128C16.194 3.45 17 4.414 17 5.517V16.75A2.25 2.25 0 0 1 14.75 19h-9.5A2.25 2.25 0 0 1 3 16.75V5.517c0-1.103.806-2.068 1.93-2.207.393-.048.787-.09 1.183-.128A3.001 3.001 0 0 1 9 1h2c1.373 0 2.531.923 2.887 2.182ZM7.5 4A1.5 1.5 0 0 1 9 2.5h2A1.5 1.5 0 0 1 12.5 4v.5h-5V4Z" clip-rule="evenodd"/>
</svg>
</button>
<button class="rounded-full p-1 text-neutral-600/75 hover:bg-zinc-900/10 text-white focus:outline-none focus-visible:text-neutral-600 focus-visible:zinc-300 focus-visible:outline-offset-0 focus-visible:outline-sky-700 active:bg-zinc-900/5 active:-outline-offset-2 dark:text-zinc-200/75 dark:hover:bg-zinc-50/10 dark:hover:text-zinc-200 dark:focus-visible:text-zinc-200 dark:focus-visible:outline-sky-600 dark:active:bg-zinc-50/5" title="More settings" aria-label="More settings" >
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="size-4" aria-hidden="true">
<path d="M9.5 13a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0m0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0m0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0"/>
</svg>
</button>
</p>
</div>
<!-- AI's Response -->
<div x-show="item.rsp_show" class="mt-2 w-full border-zinc-300 bg-zinc-100 p-2 text-left dark:border-zinc-700 dark:bg-zinc-800 rounded border" >
<div class="flex items-center gap-2 text-neutral-900 dark:text-zinc-50">
<span class="flex size-8 items-center justify-center rounded-full bg-sky-700 text-white dark:bg-sky-600 dark:text-white">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" class="size-5">
<path d="M6 12.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5M3 8.062C3 6.76 4.235 5.765 5.53 5.886a26.6 26.6 0 0 0 4.94 0C11.765 5.765 13 6.76 13 8.062v1.157a.93.93 0 0 1-.765.935c-.845.147-2.34.346-4.235.346s-3.39-.2-4.235-.346A.93.93 0 0 1 3 9.219zm4.542-.827a.25.25 0 0 0-.217.068l-.92.9a25 25 0 0 1-1.871-.183.25.25 0 0 0-.068.495c.55.076 1.232.149 2.02.193a.25.25 0 0 0 .189-.071l.754-.736.847 1.71a.25.25 0 0 0 .404.062l.932-.97a25 25 0 0 0 1.922-.188.25.25 0 0 0-.068-.495c-.538.074-1.207.145-1.98.189a.25.25 0 0 0-.166.076l-.754.785-.842-1.7a.25.25 0 0 0-.182-.135" />
<path d="M8.5 1.866a1 1 0 1 0-1 0V3h-2A4.5 4.5 0 0 0 1 7.5V8a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1v1a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-1a1 1 0 0 0 1-1V9a1 1 0 0 0-1-1v-.5A4.5 4.5 0 0 0 10.5 3h-2zM14 7.5V13a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V7.5A3.5 3.5 0 0 1 5.5 4h5A3.5 3.5 0 0 1 14 7.5" />
</svg>
</span>
<span x-text="item.rsp" style="overflow-wrap: break-word;" class="text-sm font-bold">Pengu AI</span>
<button @click="show_info(index)" class="rounded-full p-1 text-neutral-600/75 hover:bg-zinc-900/10 hover:text-neutral-600 focus:outline-none focus-visible:text-neutral-600 focus-visible:zinc-300 focus-visible:outline-offset-0 focus-visible:outline-sky-700 active:bg-zinc-900/5 active:-outline-offset-2 dark:text-zinc-200/75 dark:hover:bg-zinc-50/10 dark:hover:text-zinc-200 dark:focus-visible:text-zinc-200 dark:focus-visible:outline-sky-600 dark:active:bg-zinc-50/5" title="上下文信息" aria-label="上下文信息" >
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="size-4" aria-hidden="true">
<path d="M9.5 13a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0m0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0m0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0"/>
</svg>
</button>
</div>
<p x-bind:id="item.chat_id" :x-ref="item.chat_id" class="text-pretty sm:pl-10 mt-4 sm:mt-0 text-sm text-neutral-600 dark:text-zinc-200"></p>
<!-- 不需要参考文件了
<ul x-show="is_gen && item.ctx.length >0" class="text-pretty sm:pl-10 mt-4 sm:mt-0 text-sm">
<p class="text-sm text-sky-700"><br>以下为参考文件,单击可以选中文件,进行单个文件的对话:</p>
<template x-for="(doc,doc_index) in Array.from(new Map(item.ctx.map(doc => [doc.name, doc])).values());" :key="doc_index">
<li @click="add_one_doc(doc)" class="inline-flex bg-white text-black rounded-full p-2 m-2 hover:text-sky-700"><span x-text="doc_index+1"></span>.<span x-text="doc.name"></span></li>
</template>
</ul>
-->
<!-- Actions -->
<div class="mt-2 flex items-center gap-2 sm:pl-10">
<button class="rounded-full p-1 text-neutral-600/75 hover:bg-zinc-900/10 hover:text-neutral-600 focus:outline-none focus-visible:text-neutral-600 focus-visible:zinc-300 focus-visible:outline-offset-0 focus-visible:outline-sky-700 active:bg-zinc-900/5 active:-outline-offset-2 dark:text-zinc-200/75 dark:hover:bg-zinc-50/10 dark:hover:text-zinc-200 dark:focus-visible:text-zinc-200 dark:focus-visible:outline-sky-600 dark:active:bg-zinc-50/5" title="Read Aloud" aria-label="Read Aloud" >
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="size-4" aria-hidden="true">
<path d="M10.5 3.75a.75.75 0 0 0-1.264-.546L5.203 7H2.667a.75.75 0 0 0-.7.48A6.985 6.985 0 0 0 1.5 10c0 .887.165 1.737.468 2.52.111.29.39.48.7.48h2.535l4.033 3.796a.75.75 0 0 0 1.264-.546V3.75ZM16.45 5.05a.75.75 0 0 0-1.06 1.061 5.5 5.5 0 0 1 0 7.778.75.75 0 0 0 1.06 1.06 7 7 0 0 0 0-9.899Z"/>
<path d="M14.329 7.172a.75.75 0 0 0-1.061 1.06 2.5 2.5 0 0 1 0 3.536.75.75 0 0 0 1.06 1.06 4 4 0 0 0 0-5.656Z"/>
</svg>
</button>
<button x-on:click="copy_that(item.chat_id)" class="rounded-full p-1 text-neutral-600/75 hover:bg-zinc-900/10 hover:text-neutral-600 focus:outline-none focus-visible:text-neutral-600 focus-visible:zinc-300 focus-visible:outline-offset-0 focus-visible:outline-sky-700 active:bg-zinc-900/5 active:-outline-offset-2 dark:text-zinc-200/75 dark:hover:bg-zinc-50/10 dark:hover:text-zinc-200 dark:focus-visible:text-zinc-200 dark:focus-visible:outline-sky-600 dark:active:bg-zinc-50/5" title="Copy" aria-label="Copy" >
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="size-4" aria-hidden="true">
<path fill-rule="evenodd" d="M13.887 3.182c.396.037.79.08 1.183.128C16.194 3.45 17 4.414 17 5.517V16.75A2.25 2.25 0 0 1 14.75 19h-9.5A2.25 2.25 0 0 1 3 16.75V5.517c0-1.103.806-2.068 1.93-2.207.393-.048.787-.09 1.183-.128A3.001 3.001 0 0 1 9 1h2c1.373 0 2.531.923 2.887 2.182ZM7.5 4A1.5 1.5 0 0 1 9 2.5h2A1.5 1.5 0 0 1 12.5 4v.5h-5V4Z" clip-rule="evenodd"/>
</svg>
</button>
<button @click="new_baike(item.chat_id,index)" class="rounded-full p-1 text-neutral-600/75 hover:bg-zinc-900/10 hover:text-neutral-600 focus:outline-none focus-visible:text-neutral-600 focus-visible:zinc-300 focus-visible:outline-offset-0 focus-visible:outline-sky-700 active:bg-zinc-900/5 active:-outline-offset-2 dark:text-zinc-200/75 dark:hover:bg-zinc-50/10 dark:hover:text-zinc-200 dark:focus-visible:text-zinc-200 dark:focus-visible:outline-sky-600 dark:active:bg-zinc-50/5" title="创建词条" aria-label="创建词条" >
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" class="size-4">
<path d="M9.5 2.672a.5.5 0 1 0 1 0V.843a.5.5 0 0 0-1 0zm4.5.035A.5.5 0 0 0 13.293 2L12 3.293a.5.5 0 1 0 .707.707zM7.293 4A.5.5 0 1 0 8 3.293L6.707 2A.5.5 0 0 0 6 2.707zm-.621 2.5a.5.5 0 1 0 0-1H4.843a.5.5 0 1 0 0 1zm8.485 0a.5.5 0 1 0 0-1h-1.829a.5.5 0 0 0 0 1zM13.293 10A.5.5 0 1 0 14 9.293L12.707 8a.5.5 0 1 0-.707.707zM9.5 11.157a.5.5 0 0 0 1 0V9.328a.5.5 0 0 0-1 0zm1.854-5.097a.5.5 0 0 0 0-.706l-.708-.708a.5.5 0 0 0-.707 0L8.646 5.94a.5.5 0 0 0 0 .707l.708.708a.5.5 0 0 0 .707 0l1.293-1.293Zm-3 3a.5.5 0 0 0 0-.706l-.708-.708a.5.5 0 0 0-.707 0L.646 13.94a.5.5 0 0 0 0 .707l.708.708a.5.5 0 0 0 .707 0z"/>
</svg>
</button>
<!-- 点赞 -->
<button @click="like_it(item.chat_id)" class="rounded-full p-1 text-neutral-600/75 hover:bg-zinc-900/10 hover:text-neutral-600 focus:outline-none focus-visible:text-neutral-600 focus-visible:zinc-300 focus-visible:outline-offset-0 focus-visible:outline-sky-700 active:bg-zinc-900/5 active:-outline-offset-2 dark:text-zinc-200/75 dark:hover:bg-zinc-50/10 dark:hover:text-zinc-200 dark:focus-visible:text-zinc-200 dark:focus-visible:outline-sky-600 dark:active:bg-zinc-50/5" title="点赞" aria-label="Like" >
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="size-4" aria-hidden="true">
<path d="M1 8.25a1.25 1.25 0 1 1 2.5 0v7.5a1.25 1.25 0 1 1-2.5 0v-7.5ZM11 3V1.7c0-.268.14-.526.395-.607A2 2 0 0 1 14 3c0 .995-.182 1.948-.514 2.826-.204.54.166 1.174.744 1.174h2.52c1.243 0 2.261 1.01 2.146 2.247a23.864 23.864 0 0 1-1.341 5.974C17.153 16.323 16.072 17 14.9 17h-3.192a3 3 0 0 1-1.341-.317l-2.734-1.366A3 3 0 0 0 6.292 15H5V8h.963c.685 0 1.258-.483 1.612-1.068a4.011 4.011 0 0 1 2.166-1.73c.432-.143.853-.386 1.011-.814.16-.432.248-.9.248-1.388Z"/>
</svg>
</button>
<!-- 点踩 -->
<button @click="dislike_it(item.chat_id)" class="rounded-full p-1 text-neutral-600/75 hover:bg-zinc-900/10 hover:text-neutral-600 focus:outline-none focus-visible:text-neutral-600 focus-visible:zinc-300 focus-visible:outline-offset-0 focus-visible:outline-sky-700 active:bg-zinc-900/5 active:-outline-offset-2 dark:text-zinc-200/75 dark:hover:bg-zinc-50/10 dark:hover:text-zinc-200 dark:focus-visible:text-zinc-200 dark:focus-visible:outline-sky-600 dark:active:bg-zinc-50/5" title="点踩" aria-label="Like" >
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="size-4" aria-hidden="true">
<!--<path d="M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3zm7-13h2.67A2.31 2.31 0 0 1 22 4v7a2.31 2.31 0 0 1-2.33 2H17"/>-->
<path d="M19 11.75a1.25 1.25 0 1 1-2.5 0v-7.5a1.25 1.25 0 1 1 2.5 0v7.5ZM9 17v1.3c0 .268-.14.526-.395.607A2 2 0 0 0 6 17c0-.995.182-1.948.514-2.826.204-.54-.166-1.174-.744-1.174h-2.52c-1.24 0-2.261-1.01-2.146-2.247a23.864 23.864 0 0 0 1.341-5.974C2.847 3.677 3.928 3 5.1 3h3.192a3 3 0 0 0 1.341.317l2.734 1.366A3 3 0 0 1 13.708 5H15v7h-.963c-.685 0-1.258.483-1.612 1.068a4.011 4.011 0 0 0-2.166 1.73c-.432.143-.853.386-1.011.814-.16.432-.248.9-.248 1.388Z"/>
</svg>
</button>
<button class="rounded-full p-1 text-neutral-600/75 hover:bg-zinc-900/10 hover:text-neutral-600 focus:outline-none focus-visible:text-neutral-600 focus-visible:zinc-300 focus-visible:outline-offset-0 focus-visible:outline-sky-700 active:bg-zinc-900/5 active:-outline-offset-2 dark:text-zinc-200/75 dark:hover:bg-zinc-50/10 dark:hover:text-zinc-200 dark:focus-visible:text-zinc-200 dark:focus-visible:outline-sky-600 dark:active:bg-zinc-50/5" title="More settings" aria-label="More settings" >
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="size-4" aria-hidden="true">
<path d="M9.5 13a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0m0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0m0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0"/>
</svg>
</button>
</div>
</div>
</div>
</template>
</ul>
</div>
</div>
</div>
<!-- 输入框 -->
<div class="flex w-full flex-col gap-2 mb-4 mt-2">
<div class="relative w-full">
<label for="aiPromt" for="aiPromt" class="sr-only">ai prompt</label>
<!--
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" aria-hidden="true" class="absolute left-3 top-1/2 size-4 -translate-y-1/2 fill-sky-700 dark:fill-sky-600">
<path fill-rule="evenodd" d="M5 4a.75.75 0 0 1 .738.616l.252 1.388A1.25 1.25 0 0 0 6.996 7.01l1.388.252a.75.75 0 0 1 0 1.476l-1.388.252A1.25 1.25 0 0 0 5.99 9.996l-.252 1.388a.75.75 0 0 1-1.476 0L4.01 9.996A1.25 1.25 0 0 0 3.004 8.99l-1.388-.252a.75.75 0 0 1 0-1.476l1.388-.252A1.25 1.25 0 0 0 4.01 6.004l.252-1.388A.75.75 0 0 1 5 4ZM12 1a.75.75 0 0 1 .721.544l.195.682c.118.415.443.74.858.858l.682.195a.75.75 0 0 1 0 1.442l-.682.195a1.25 1.25 0 0 0-.858.858l-.195.682a.75.75 0 0 1-1.442 0l-.195-.682a1.25 1.25 0 0 0-.858-.858l-.682-.195a.75.75 0 0 1 0-1.442l.682-.195a1.25 1.25 0 0 0 .858-.858l.195-.682A.75.75 0 0 1 12 1ZM10 11a.75.75 0 0 1 .728.568.968.968 0 0 0 .704.704.75.75 0 0 1 0 1.456.968.968 0 0 0-.704.704.75.75 0 0 1-1.456 0 .968.968 0 0 0-.704-.704.75.75 0 0 1 0-1.456.968.968 0 0 0 .704-.704A.75.75 0 0 1 10 11Z" clip-rule="evenodd" />
</svg>
-->
<!-- 文件上传-->
<input x-ref="fileInput" @input="upload_file" type="file" multiple hidden class="w-full overflow-clip rounded border border-red-700 bg-zinc-100/50 text-sm text-red-700 file:mr-4 file:cursor-pointer file:border-none file:bg-zinc-100 file:px-4 file:py-2 file:font-medium file:text-neutral-900 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:bg-zinc-800/50 dark:file:bg-zinc-800 dark:file:text-zinc-50 dark:focus-visible:outline-sky-600" />
<svg @click="$refs.fileInput.click()" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" class="absolute left-3 top-1/2 size-6 cursor-pointer -translate-y-1/2 fill-blue-700 dark:fill-sky-600">
<path fill-rule="evenodd" d="M10.5 3.75a6 6 0 0 0-5.98 6.496A5.25 5.25 0 0 0 6.75 20.25H18a4.5 4.5 0 0 0 2.206-8.423 3.75 3.75 0 0 0-4.133-4.303A6.001 6.001 0 0 0 10.5 3.75Zm2.03 5.47a.75.75 0 0 0-1.06 0l-3 3a.75.75 0 1 0 1.06 1.06l1.72-1.72v4.94a.75.75 0 0 0 1.5 0v-4.94l1.72 1.72a.75.75 0 1 0 1.06-1.06l-3-3Z" clip-rule="evenodd"/>
</svg>
<!--
<input x-show="one" x-model="query" x-on:input.debounce.100ms="query_len" x-on:keydown.enter="gen" type="text" class="w-full bg-zinc-100 border border-sky-700 rounded px-2 py-2 pl-10 pr-24 text-sm text-neutral-600 focus-visible:outline focus-visible:outline-sky-700 disabled:cursor-not-allowed disabled:opacity-75 dark:border-zinc-700 dark:bg-zinc-800/50 dark:text-zinc-200 dark:focus-visible:outline-sky-600" value="" name="prompt" placeholder="Ask AI ..." />
-->
<textarea id="aiPromt" :rows="one" x-model="query" x-on:input.debounce.100ms="query_len" x-on:keydown.enter="gen" type="text" class="w-full bg-zinc-100 border border-sky-700 rounded px-2 py-2 pl-10 pr-24 text-sm text-neutral-600 focus-visible:outline focus-visible:outline-sky-700 disabled:cursor-not-allowed disabled:opacity-75 dark:border-zinc-700 dark:bg-zinc-800/50 dark:text-zinc-200 dark:focus-visible:outline-sky-600" value="" name="prompt" placeholder="Ask AI ..." ></textarea>
<button type="button" x-show="is_gen" x-on:click="gen" class="absolute right-3 top-1/2 -translate-y-1/2 cursor-pointer bg-sky-700 rounded-full p-1 text-xs 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" title="开始">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" fill="currentColor" class="size-6 shrink-0" aria-hidden="true">
<path d="M837.888 173.7728c14.4384 14.08 18.0736 30.5664 10.8544 49.4592L621.056 818.176c-6.912 18.0736-20.0704 26.9824-39.424 26.6752-19.4048-0.256-32.256-9.5744-38.656-27.8528a541.4912 541.4912 0 0 0-127.1808-204.3904 541.4912 541.4912 0 0 0-202.496-130.2016l-4.3008-1.536c-17.92-6.5536-27.0336-19.3536-27.4432-38.4-0.3584-19.0464 8.192-32.256 25.856-39.424l580.7616-238.8992c18.688-7.68 35.2768-4.5056 49.7152 9.6256zM778.6496 234.496L275.5584 441.344a601.1392 601.1392 0 0 1 184.0128 128.0512 601.2416 601.2416 0 0 1 122.368 179.0976l196.7104-514.048z m-129.8944 102.1952a30.72 30.72 0 0 1 21.76 52.3776l-68.5568 68.864a30.72 30.72 0 0 1-43.52-43.3664l68.5568-68.8128a30.72 30.72 0 0 1 21.76-9.0624z"></path>
</svg>
</button>
<button type="button" x-show="!is_gen" x-on:click="stop" class="absolute right-3 top-1/2 -translate-y-1/2 cursor-pointer bg-white border border-neutral-300 rounded-full p-1 text-xs tracking-wide text-blue-700 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" title="停止">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" fill="currentColor" class="size-6 shrink-0" style="animation: fadeInOut 5s ease-in-out infinite;" aria-hidden="true">
<path d="M236.8 723.2V300.8c0-35.3472 28.6528-64 64-64h422.4c35.3472 0 64 28.6528 64 64v422.4c0 35.3472-28.6528 64-64 64H300.8c-35.3472 0-64-28.6528-64-64z"></path>
</svg>
</button>
</div>
</div>
</div>
</div>
<!-- Info 上下文的信息提示-->
<div x-show="Info" class="fixed top-10 left-0 right-0 z-30 w-full mx-auto max-w-2xl flex items-center justify-center rounded border border-sky-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-sky-700/10 p-4">
<div class="bg-sky-700/15 text-sky-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="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>
<div class="ml-2 max-h-[80vh] overflow-y-auto">
<h3 class="text-sm font-semibold text-sky-700">上下文信息如下:</h3>
<p class="text-xs font-medium sm:text-sm"></p>
<ul class="mt-2 list-inside list-disc pl-2 text-xs font-medium sm:text-sm">
<template x-for="(item,index) in fItems" :key="index">
<li><strong x-text="item.name">文件名</strong> 长度: [<span x-text="item.size" class="text-blue-700">长度</span>]
<p class="text-sky-700">来源: <span x-text="item.base"></span> &nbsp;&nbsp;路径: <span x-text="item.path"></span></p>
<p x-html="marked.parse(item.ctx)">内容</p></li>
</template>
</ul>
</div>
<button @click="Info=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>
<!--百科编辑器 -->
<template x-if="AIEditorOpen">
<div x-ref="his" x-cloak 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="flex w-full h-full 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>
百科词条AI编辑器
</div>
<button @click="AIEditorOpen=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>
<!-- Dialog Body -->
<div class="px-4 py-2 text-center h-full">
<iframe :src="aieditor_id" class="w-full h-full overflow-hidden"></iframe>
</div>
</div>
</div>
</template>
<!-- 选择文件窗口-->
<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="kg_select" alp-unit="kg_select.aps" class="w-full overflow-hidden"></div>
</template>
</div>
</div>
<!--点赞或点踩-->
<template x-if="like_fin">
<div class="fixed 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="ml-2">
<h3 class="text-sm font-semibold text-green-700" x-html="like_text"></h3>
</div>
</div>
</div>
</template>
</div>
<style>
.content-layer {
position: relative; /* 必须设置,否则 absolute 不生效 */
border: 1px solid #ddd;
color: white;
background-color: rgb(3 105 161 / 0.7);
border-radius: 5px;
margin-bottom: 5px;
padding:5px;
word-break: break-all; /* 中文自动换行关键 */
}
/* 表格基础样式 */
.content-layer table {
width: 100%; /* 让表格占据其容器的全宽 */
border-collapse: collapse; /* 合并边框 */
margin: 20px 0;
background-color: white; /* 灰*/
}
.floating-info-btn {
position: absolute;
bottom: 5px;
right: 5px;
width: 20px;
height: 20px;
border-radius: 50%;
background-color: #0000ff;
color: white;
border: none;
font-size: 18px;
cursor: pointer;
box-shadow: 0 2px 6px rgba(0,0,0,0.3);
opacity: 0.9;
transition: all 0.3s ease;
z-index: 25;
}
.floating-info-btn:hover {
transform: scale(1.1);
background-color: #0056b3;
}
@keyframes fadeInOut {
0% {
opacity: 1; /* 明 */
}
50% {
opacity: 0.2; /* 暗 */
}
100% {
opacity: 1; /* 回到明 */
}
}
</style>
<script>
function chat_agent(){
return {
query:"",
HisOpen: false, //历史对话框
AIEditorOpen: false, // 百科创作对话框
aieditor_id:"", //百科id
eventSource: "", //对话流
is_gen: true, //生成模式
Info: false, // 显示上下文
fItems:[], //上下文信息
qItems:[],// 问题列表
hItems:[],// 历史最后问题列表
Items:[], //对话全部内容
like_fin:false,
like_text:"感谢小主的鼓励,我会加倍努力的!",
one:1, //一行文本输入
baike_id:0, //新增词条
ai_file:{base:"",name:"",path:""}, // 默认的上传文件
kagent:{}, // 具体配置
FileSelecterOpen:false, //显示个人文件夹
people_files:"",
init(){
axios.get('/api/kagent_cfg/'+this.Agent_Kasn).then(response => {
this.kagent = response.data;
this.people_files="个人文件夹/"+this.kagent.username;
this.update_last_chat();
}).catch(error => {
console.error('Error fetching data:', error);
throw error; // 重新抛出错误以便调用者可以处理
});
if (this.cache_ai_file){
this.ai_file = this.cache_ai_file;
this.push_item({chat_id:"",req:"你之前上传了文件: "+this.ai_file.name+", 可以继续对话",rsp:"",rsp_show:false});
}
//动态加载,AI对话框
this.$watch('FileSelecterOpen',value => {
if (value){
this.$nextTick(() => {
var dom = document.getElementById("kg_select")
scan_alp_units(dom);
});
}
});
// 超级个人助理的调用
if (this.super_query){
this.query=this.super_query;
this.gen();
//this.super_query="";
}
},
update_last_chat(){
axios.get('/api/chat_history/my?title='+this.kagent.title).then(response => {
this.hItems = response.data.data;
}).catch(error => {
console.error('Error fetching data:', error);
throw error; // 重新抛出错误以便调用者可以处理
});
},
//点赞
like_it(chat_id){
this.like_fin=true;
this.like_text="&#x1F60A;感谢小主的鼓励,我会加倍努力的!";
axios.put('/api/superman/like/'+chat_id).then(response => {
setTimeout(() => {
this.like_fin = false;
}, 3000); // 3000 毫秒 = 3 秒
}).catch(error => {
console.error('Error fetching data:', error);
throw error; // 重新抛出错误以便调用者可以处理
});
},
dislike_it(chat_id){
this.like_fin=true;
this.like_text="&#x1F62D;不好意思主人!这次干咋了,下次我会努力的!";
axios.put('/api/superman/dislike/'+chat_id).then(response => {
setTimeout(() => {
this.like_fin = false;
}, 3000); // 3000 毫秒 = 3 秒
}).catch(error => {
console.error('Error fetching data:', error);
throw error; // 重新抛出错误以便调用者可以处理
});
},
remove_files(){
this.ai_file={base:"",name:"",path:""};
localStorage.removeItem(this.Agent_Kasn);
},
put_file(base_path){
console.info(this.Items);
},
push_item(item){
this.Items.push(item);
},
push_qitem(item){
this.qItems.push(item);
},
update_last_item(chat_id,title,ctx){
var last = this.Items[this.Items.length-1];
last.chat_id=chat_id;
last.rsp=title;
last.rsp_show=true;
last.ctx=ctx;
},
query_len(){
if (this.query.length >45){
this.one=5;
if (this.query.length >250){
this.one=10;
}
if (this.query.length >500){
this.one=15;
}
}
},
new0(){ //新建对话
this.qItems=[];
this.Items=[];
this.ai_file={base:"",name:"",path:""};
this.is_gen = true;
this.one = 1;
},
copy_query(query){ //复制查询
this.query = query;
this.query_len()
},
gen_chat_baike(){//生成对话列表的百科
var content="";
if(this.ai_file.path!=""){
var file_name = this.ai_file.path.split("/").at(-1);
content=`<h1>${file_name}</h1><h3>对话分析过程</h3>`;
}else{
content=`<h1>对话列表</h1>`;
}
for(var i=0;i<this.qItems.length;i++){
let chat_id = this.qItems[i].chat_id;
const messagesDiv = document.getElementById(chat_id);
let rsp = messagesDiv.innerHTML;
let begin = rsp.lastIndexOf('class="content-layer">');
let end = rsp.lastIndexOf('<button class="floating-info-btn"');
rsp = rsp.slice(begin+'class="content-layer">'.length,end);
content +='<h2>'+this.qItems[i].req+"</h2>"+rsp;
}
// 数据对象,代表要发送的数据
const newItem = {
id: this.baike_id,
title: "对话列表-"+this.qItems[0].req,
catalog: "个人空间",
html: content
};
// 使用 axios 发送 POST 请求
axios.post('/api/baike', newItem)
.then(response =>{
this.baike_id = response.data.id;
this.AIEditorOpen=true;
this.aieditor_id="create.html?id="+this.baike_id;
})
.catch(error => {
alert(error);
console.error('Error post data:', error);
throw error; // 重新抛出错误以便调用者可以处理
});
},
show_info(index){ //显示上下文
this.Info=true;
this.fItems = this.Items[index].ctx;
},
copy_that(chat_id){
const messagesDiv = document.getElementById(chat_id);
let rsp = messagesDiv.innerHTML;
rsp = rsp.replace("<think>","<p>").replace("</think>","</p>");
copyToClipboard(rsp);
},
new_baike(chat_id,index){ //新建百科词条
const messagesDiv = document.getElementById(chat_id);
let rsp = messagesDiv.innerHTML;
let begin = rsp.lastIndexOf('class="content-layer">');
let end = rsp.lastIndexOf('<button class="floating-info-btn"');
rsp = rsp.slice(begin+'class="content-layer">'.length,end);
// 数据对象,代表要发送的数据
const newItem = {
id: 0,
title: this.Items[index].req.slice(0,20),
catalog: "个人空间",
html: rsp
};
// 使用 axios 发送 POST 请求
axios.post('/api/baike', newItem)
.then(response =>{
let baike_id = response.data.id;
this.AIEditorOpen=true;
this.aieditor_id="create.html?id="+baike_id;
})
.catch(error => {
alert(error);
console.error('Error post data:', error);
throw error; // 重新抛出错误以便调用者可以处理
});
},
stop(){
this.eventSource.close();
this.is_gen = true;
this.one=1;
update_create_button();
},
gen(){
if (this.query=="")return false;
this.is_gen = false;
this.push_item({chat_id:"",req:this.query,rsp:"",rsp_show:false});
var query=this.query;
if (this.query.length >100){
query = this.query.slice(0,100)+"...";
}
//ai模式处理
var ai_mode="Detailed";
try {
// data_active:true, //数据分析
// netsearch_active:true, //联网搜索
// ds_active:true, //深度思考
if (this.data_active) ai_mode +=",da";
if (this.netsearch_active) ai_mode +=",ns";
if (this.ds_active) ai_mode +=",ds";
} catch (error) {
console.log(ai_mode);
}
//对话都带有文件
var newItem = {
question: this.query,
kagent_sn: this.Agent_Kasn,
file: this.ai_file.file,
base: this.ai_file.base,
path: this.ai_file.path,
history: this.qItems.map(item => ({'问题':item.req.slice(0,100),'回答':item.rsp.slice(0,50)})),
ai_mode: ai_mode,
};
// 使用 axios 发送 POST 请求
axios.post('/api/chat_kagent', newItem)
.then(response =>{
this.query="";
this.one=1;
rsp = response.data;
if (this.kagent.atype==3 || this.kagent.atype==100)
{
this.update_last_item(rsp.chat_id,`正在思考中...`,rsp.ctx);
}else{
this.update_last_item(rsp.chat_id,`搜索到${rsp.count}个相关信息,正在整理中...`,rsp.ctx);
}
this.push_qitem({chat_id:rsp.chat_id,req:query,rsp:""});
// 创建一个EventSource实例连接到服务器发送的事件流
this.eventSource = new EventSource('/api/chat_kagent/'+rsp.chat_id);
update_chat2(this.eventSource,rsp.chat_id,this);
})
.catch(error => {
console.error('Error post data:', error);
throw error; // 重新抛出错误以便调用者可以处理
});
},
del_chat(index){//删除对话列表中的对话
this.qItems.splice(index,1);
},
upload_file(){
const file = this.$refs.fileInput.files[0];
//if (!file) return;
const formData = new FormData();
formData.append('file', file);
formData.append("curpath",this.kagent.files);
try {
axios.post('/api/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
}).then( response =>{
var doc = response.data;
if (doc.errno === 1) {
alert(doc.message);
}else{
this.ai_file=doc.file;
this.push_item({chat_id:"",req:"你上传了文件: "+doc.file.name,rsp:"",rsp_show:false});
// 保存本地缓存
localStorage.setItem(this.Agent_Kasn, JSON.stringify(this.ai_file))
}
})
} catch (error) {
console.error('Error:', error);
alert('An error occurred while uploading the file.');
}
}// upload_file 上传文件
}
}
var chart_index=0;
var chart_datas={};//存储对话的图表,表格等数据
var chart_ids={}; //存储对话的不表的div的id
//流式更新对话
function update_chat2(eventSource,chat_id,fun){
fun.is_gen = false;
//分块更新
var ResponseDiv = null;
var messagesDiv = document.createElement('div');
chart_datas[chat_id] ={}; //图表数据
chart_ids[chat_id]={}; //图表div 的id
var do_files=[];
var event_cnt=-1;
var last_data=""; //不是<new>的有效数据
var last_event=""; //所有事件数据
// 监听消息事件
eventSource.onmessage = function(event) {
//首次创建,并添加子消息层
if (ResponseDiv==null){
ResponseDiv = document.getElementById(chat_id);
ResponseDiv.appendChild(messagesDiv);
}
event_cnt++;
//正式开始
const message = JSON.parse(event.data);
if (message.rsp.indexOf("<new>")!=0){
last_data = message;
}
last_event=message;
if ("type" in message){ //数据分析的工具消息
if (["do_group_count","do_group_agg","do_fields_agg"].includes(message.type)){
try {
let rsp = JSON.parse(message.rsp);
if ("excel" in rsp){
do_files.push({"name":rsp["excel"].split(/[\\/]/).pop(),"path":rsp["excel"],"base":"文件中心"});
}
var think_mk=`<div style="position: relative; height:300px; width:700px; margin-bottom:60px;">
<canvas id="myChart_${chart_index}"></canvas>
</div>`;
messagesDiv.innerHTML = think_mk;
const r = draw_chart("myChart_"+chart_index,rsp,message.type);
chart_datas[chat_id][r["title"]] = r["data"];
chart_ids[chat_id][r["title"]] = "myChart_"+chart_index;
chart_index ++;
} catch (error) {
console.error(error);
think_mk = "图表出错:"+error+"<br>"+message.rsp;
messagesDiv.innerHTML = think_mk;
}
}else if (["do_filter","do_ext_tags"].includes(message.type)){
try {
let rsp = JSON.parse(message.rsp);
if ("excel" in rsp){
do_files.push({"name":rsp["excel"].split(/[\\/]/).pop(),"path":rsp["excel"],"base":"文件中心"});
}
var think_mk=`<div id="myChart_${chart_index}"
style="position: relative; height:300px; width:700px; background-color: white;
border-radius: 5px; overflow: auto; margin:5px;">
</div>`;
messagesDiv.innerHTML = think_mk;
//console.info(message)
const r = draw_table("myChart_"+chart_index,rsp,message.type);
chart_datas[chat_id]["Table_"+chart_index] = r;
chart_index ++;
} catch (error) {
think_mk = "表格出错:"+error+"<br>"+message.rsp;
messagesDiv.innerHTML = think_mk;
}
}else{
think_mk = marked.parse(message.rsp);
messagesDiv.innerHTML = think_mk;
}
//带type的后面是新的一个消息,新的一个层
messagesDiv = document.createElement('div');
ResponseDiv.appendChild(messagesDiv);
}else if (message.rsp.indexOf("<think>")==0){
//块更新
if (event_cnt%15!=0) return 0;
var end = message.rsp.indexOf("</think>");
if (end==-1){ //思考还未结束
//var think_mk = marked.parse(message.rsp.slice(7));
var think_mk = message.rsp.slice(7);
messagesDiv.innerHTML = think_mk;
}else{
//var think_mk = marked.parse(message.rsp.slice(7,end));
var think_mk = message.rsp.slice(7,end);
var think_all=think_mk;
var result= marked.parse(message.rsp.slice(end+8));
if (result!=""){
think_all +=`<div class="content-layer">${result}</div>`;
}
messagesDiv.innerHTML = think_all;
fun.update_last_qitem(message.rsp.slice(end+8));
}
}else if(message.rsp.indexOf("<new>")==0){
//最后内容的更新
const message = last_data;
var end = message.rsp.indexOf("</think>");
if (end==-1){
let result =marked.parse(message.rsp);
var think_all=`<div class="content-layer">${result}</div>`;
messagesDiv.innerHTML = think_all;
}else{
var think_mk = message.rsp.slice(7,end);
var think_all=think_mk;
var result= marked.parse(message.rsp.slice(end+8));
if (result!=""){
think_all +=`<div class="content-layer">${result}</div>`;
}
messagesDiv.innerHTML = think_all;
}
//新的一个消息,新的一个层
messagesDiv = document.createElement('div');
ResponseDiv.appendChild(messagesDiv);
}else{
//块更新
if (event_cnt%15!=0) return 0;
//正式内容都用蓝色背景
let result =marked.parse(message.rsp);
//var think_all=`<div style="color: white; background-color: rgb(3 105 161 / 0.7); border-radius: 5px; margin-bottom: 5px; padding:5px;">${result}</div>`;
var think_all=`<div class="content-layer">${result}</div>`;
messagesDiv.innerHTML = think_all;
fun.update_last_qitem(message.rsp);
}
//自动滚动
const div = document.getElementById("chat_display_2");
div.scrollTop = div.scrollHeight;
};
// 监听错误事件
eventSource.onerror = function(error) {
fun.is_gen = true;
if(last_event.rsp.indexOf("<new>")!=0){
//最后内容的更新
const message = last_data;
var end = message.rsp.indexOf("</think>");
if (end==-1){
let result =marked.parse(message.rsp);
var think_all=`<div class="content-layer">${result}</div>`;
}else{
var think_mk = message.rsp.slice(7,end);
var think_all=think_mk;
var result= marked.parse(message.rsp.slice(end+8));
if (result!=""){
think_all +=`<div class="content-layer">${result}</div>`;
}
}
//内容不一样再更新
if (messagesDiv.innerHTML!=think_all){
messagesDiv.innerHTML = think_all;
}
}
fun.update_last_item(rsp.chat_id,`回答结束`,rsp.ctx);
console.info(chat_id+" 回答结束");
update_create_button();
//结束后滚动
const div = document.getElementById("chat_display_2");
div.scrollTop = div.scrollHeight;
if (eventSource.readyState != EventSource.CLOSED){
eventSource.close(); // 关闭连接
}
};
}
// 更新百科内容创建按扭
function update_create_button(){
// 获取所有具有相同 class 的 div
const layers = document.querySelectorAll('.content-layer');
layers.forEach(layer => {
// 创建悬浮按钮
const btn = document.createElement('button');
btn.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" class="size-4">
<path d="M9.5 2.672a.5.5 0 1 0 1 0V.843a.5.5 0 0 0-1 0zm4.5.035A.5.5 0 0 0 13.293 2L12 3.293a.5.5 0 1 0 .707.707zM7.293 4A.5.5 0 1 0 8 3.293L6.707 2A.5.5 0 0 0 6 2.707zm-.621 2.5a.5.5 0 1 0 0-1H4.843a.5.5 0 1 0 0 1zm8.485 0a.5.5 0 1 0 0-1h-1.829a.5.5 0 0 0 0 1zM13.293 10A.5.5 0 1 0 14 9.293L12.707 8a.5.5 0 1 0-.707.707zM9.5 11.157a.5.5 0 0 0 1 0V9.328a.5.5 0 0 0-1 0zm1.854-5.097a.5.5 0 0 0 0-.706l-.708-.708a.5.5 0 0 0-.707 0L8.646 5.94a.5.5 0 0 0 0 .707l.708.708a.5.5 0 0 0 .707 0l1.293-1.293Zm-3 3a.5.5 0 0 0 0-.706l-.708-.708a.5.5 0 0 0-.707 0L.646 13.94a.5.5 0 0 0 0 .707l.708.708a.5.5 0 0 0 .707 0z"/>
</svg>`; // 可以是图标或文字
btn.classList.add('floating-info-btn'); // 添加类名便于样式控制
// 鼠标悬停效果
btn.onmouseover = () => btn.style.transform = 'scale(1.1)';
btn.onmouseout = () => btn.style.transform = 'scale(1.0)';
// // 关键:设置父容器为 relative使绝对定位生效
// layer.style.position = 'relative';
// 将按钮添加到当前 div 中
layer.appendChild(btn);
// 绑定点击事件:获取当前层内的 DOM 信息
btn.addEventListener('click', function (e) {
e.stopPropagation(); //
var rsp = layer.innerHTML;
let end = rsp.indexOf('<button class="floating-info-btn"');
rsp = rsp.slice(0,end);
// 数据对象,代表要发送的数据
const newItem = {
id: 0,
title: layer.innerText.slice(0,30),
catalog: "个人空间",
html: rsp
};
// 使用 axios 发送 POST 请求
axios.post('/api/baike', newItem)
.then(response =>{
let baike_id = response.data.id;
window.open("/ui/create.html?id="+baike_id, '_blank');
})
.catch(error => {
alert(error);
console.error('Error post data:', error);
throw error; // 重新抛出错误以便调用者可以处理
});
});
});
}
</script>