123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280 |
- import OpenAI from 'openai'
- import hljs from 'highlight.js'
- import 'highlight.js/styles/atom-one-dark.css' // 导入一个暗色主题样式
- import { getActivePinia } from 'pinia'
- import { useMsgStore } from '@/store/modules/msg.ts'
- export async function sendMessage(message) {
- const pinia = getActivePinia()
- if (!pinia) {
- throw new Error('No active Pinia instance found')
- }
- const store = useMsgStore(pinia)
- const { openai, AIModel } = store
- try {
- // 创建新的 AbortController
- const controller = new AbortController()
- const a = +new Date()
- return await openai.chat.completions.create({
- //模型列表:https://help.aliyun.com/zh/model-studio/getting-started/models
- model: AIModel.value,
- messages: message,
- stream: true
- })
- } catch (error) {
- return { error: error }
- } finally {
- }
- }
- export async function getFileContent(data) {
- try {
- const res = await fetch('http://180.76.147.97:18899/upload_file', {
- method: 'post',
- body: data
- }).then((res) => res.json())
- return res
- } catch (error) {
- }
- }
- export async function getFormKey(data) {
- try {
- const res = await fetch('http://180.76.147.97:18899/uie', {
- method: 'post',
- body: JSON.stringify(data)
- }).then((res) => res.json())
- return res
- } catch (error) {
- }
- }
- export async function hepl(data) {
- try {
- const res = await fetch(' http://180.76.147.97:18899/test', {
- method: 'post',
- body: JSON.stringify(data)
- }).then((res) => res.json())
- return res
- } catch (error) {
- }
- }
- function formatMessages(currentMessage, Summary, html) {
- const messages = [
- {
- role: 'user',
- content: currentMessage
- }
- ]
- // const messages = this.context.filter(msg => msg.role === 'user').map((msg) => ({
- // role: msg.role,
- // content: msg.content,
- // }));
- // console.log(currentMessage, this.currentPageInfo, input);
- // // 如果存在页面信息,添加到当前消息的上下文
- // if (this.currentPageInfo && !input) {
- // currentMessage = `基于之前总结的页面内容(标题:${JSON.stringify(this.currentPageInfo)}),${currentMessage}`;
- // }
- // messages.push()
- if (Summary) return messages
- if (html)
- messages.unshift({
- role: 'user',
- content: `页面主要内容${html}`
- })
- return messages
- }
- export function getSummaryPrompt(pageInfo) {
- // return `请根据所有网页总结以下网页内容的要点:
- //
- // 页面标题:${pageInfo.title}
- // 网站:${pageInfo.siteName}
- // URL:${pageInfo.url}
- //
- // 主要内容:
- // ${pageInfo.mainContent}
- //
- // 要求:
- // 1. 用简洁清晰的语言提取3-5个核心要点
- // 2. 保持客观中立的语气
- // 3. 按重要性排序
- // 4. 如果内容是新闻,需要包含时间、地点、人物等关键信息
- // 5. 如果内容是教程,需要突出操作步骤和关键提示
- // 6. 如果内容是产品介绍,需要包含主要特点和优势
- // 7. 返回内容做好换行,以及展示样式
- //
- // 请以"以下是对该页面内容的总结:"开头,然后用要点的形式列出主要内容。`
- return `页面标题:${pageInfo.title};
- 网站:${pageInfo.siteName};
- 网站地址:${pageInfo.url};
- 主要内容:${pageInfo.mainContent}`
- }
- export function getFileSummaryPrompt(file, name) {
- return `请帮我总结以下文件内容的要点:
- 文件名称:${name}
- 主要内容:
- ${file}
- 要求:
- 1. 用简洁清晰的语言提取3-5个核心要点
- 2. 保持客观中立的语气
- 3. 按重要性排序
- 4. 返回内容做好换行,以及展示样式
- 请以"以下是对该文件内容的总结:"开头,然后用要点的形式列出主要内容。`
- }
- export function formatMessage(text) {
- if (!text) return ''
- // 用于转义代码块中的 HTML 字符
- const escapeHtml = (str) => {
- return str
- .replace(/&/g, '&')
- .replace(/</g, '<')
- .replace(/>/g, '>')
- .replace(/"/g, '"')
- .replace(/'/g, ''')
- }
- // 处理代码高亮
- const highlightCode = (code, language) => {
- if (language && language.trim() !== '') {
- try {
- return hljs.highlight(code, { language: language.trim() }).value
- } catch (e) {
- // 如果指定的语言不支持,回退到自动检测
- return hljs.highlightAuto(code).value
- }
- }
- return hljs.highlightAuto(code).value
- }
- return (
- text
- // 处理带有语言标识的代码块
- .replace(/```(\w+)?\n([\s\S]*?)```/g, (match, lang, code) => {
- const highlightedCode = highlightCode(code, lang || '')
- return `<pre style="background-color: #282c34; padding: 10px; border-radius: 5px; overflow-x: auto;"><code class="hljs ${lang || ''}">${highlightedCode}</code></pre>`
- })
- // 处理不带语言标识的代码块
- .replace(/```([\s\S]*?)```/g, (match, code) => {
- const highlightedCode = highlightCode(code, '')
- return `<pre style="background-color: #282c34; padding: 10px; border-radius: 5px; overflow-x: auto;"><code class="hljs">${highlightedCode}</code></pre>`
- })
- // 处理行内代码
- .replace(
- /`([^`]+)`/g,
- (match, code) =>
- `<code style="background-color: #f0f0f0; padding: 2px 4px; border-radius: 3px;">${escapeHtml(code)}</code>`
- )
- // 处理标题 (h1 ~ h6)
- .replace(/^#{1,6}\s+(.+)$/gm, (match, content) => {
- const level = match.trim().split('#').length - 1
- return `<h${level}>${content.trim()}</h${level}>`
- })
- // 处理换行
- .replace(/\n/g, '<br>')
- // 处理连续空格
- .replace(/ {2,}/g, (match) => ' '.repeat(match.length))
- // 处理粗体
- .replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
- // 处理斜体
- .replace(/\*(.*?)\*/g, '<em>$1</em>')
- // 处理链接
- .replace(
- /\[([^\]]+)\]\(([^)]+)\)/g,
- '<a href="$2" target="_blank">$1</a>'
- )
- // 处理无序列表:先将每行列表项转换为 <li> 标签
- .replace(/^[*-]\s+(.+)$/gm, '<li>$1</li>')
- // 然后将连续的 <li> 包裹在 <ul> 中
- .replace(/(<li>.*<\/li>)/gs, '<ul>$1</ul>')
- // 处理有序列表:先将每行列表项转换为 <li> 标签
- .replace(/^\d+\.\s+(.+)$/gm, '<li>$1</li>')
- // 然后将连续的 <li> 包裹在 <ol> 中
- .replace(/(<li>.*<\/li>)/gs, '<ol>$1</ol>')
- // 处理分隔线
- .replace(/^---+$/gm, '<hr>')
- // 处理引用
- .replace(/^>\s+(.+)$/gm, '<blockquote>$1</blockquote>')
- )
- }
- export function buildExcelUnderstandingPrompt(data, fileName, pageInfo) {
- // if (!data || data.length < 2) {
- // return "这是一个空的Excel文件,请检查文件内容。";
- // }
- // const headers = data[0];
- // const rows = data.slice(1);
- // data[0].forEach((header, i) => {
- // if (!this.excelData[header]) this.excelData[header] = []
- // this.excelData[header].push(data[1][i])
- // })
- return `我将向你展示一个通过SheetJS库读取的Excel文件内容和一个form表单。请帮我理解这些数据:
- 文件名:${fileName}
- 列标题:${data.join(', ')}
- 表单内容:
- ${pageInfo}
-
- 要求:
- 1. 请根据表单中的表单项和列标题进行匹配,一定以表单为准,列标题只能匹配一次,没有和列标题匹配到的表单项不返回!
- 2. 生成表单项与列标题对应的数组,并使用findBy告诉我通过表单项的什么字段信息匹配到的,使用findByValue告诉我匹配到的表单项字段值,使用excelColumn字段告诉我excel文件中列标题的值。
- 3. 表单项有id根据id匹配,findBy是id,并通过findByValue告诉我id的值,没有id根据label匹配,findBy是label,并通过findByValue给我label元素的值,没有label根据placeholder匹配,findBy是placeholder,并通过findByValue告诉我placeholder的值,没有placeholder,再根据其他内容匹配
- 3. 并去除没有匹配到的表单项和excel文件中没有匹配到的列,
- 4. 通过type字段告诉我输入项的类型,表单项有label,通过label字段返回label的值。
- 5. 返回json格式数组,不要返回其他任何内容`
- }
- // 5. 如果表单项有label标签,同时返回label, 通过label字段告诉我label元素的文本
- export function buildObjPrompt(obj, pageInfo) {
- return `我将向你展示一个对象和一个form表单。请帮我理解这些数据:
- 对象:${JSON.stringify(obj)}
- 表单内容:
- ${pageInfo}
-
- 要求:
- 1. 请根据表单中的表单项和对象进行匹配,一定以表单为准,key同时在对象和表单中出现,才能返回!
- 2. 表单项有label,根据label匹配,没有label根据placeholder匹配,没有placeholder,根据id匹配,再根据其他内容匹配
- 3. 并根据实际可操作的表单项的所有信息与上传的对象的key进行匹配,生成表单项与key的数组,并使用findBy告诉我通过表单项的什么字段信息匹配到的,使用findByValue告诉我匹配到的表单项字段值,使用excelColumn字段告诉我对应的key值。在一个字段内返回
- 4. 并去除没有匹配到的表单项和对象中没有匹配到的key,
- 5. 通过type字段告诉我输入项的类型,如果对象中key对应的是日期,type统一返回date。
- 6. 表单项有label,通过label字段返回label的值。
- 7. 返回json格式返回数组,不要返回其他任何内容`
- }
- function escapeHtml(html) {
- const div = document.createElement('div')
- div.textContent = html
- return div.innerHTML
- }
- export async function modelFileUpload(file) {
- const pinia = getActivePinia()
- if (!pinia) {
- throw new Error('No active Pinia instance found')
- }
- const store = useMsgStore(pinia)
- const { openai, AIModel } = store
- const fileObject = await openai.files.create({
- file,
- purpose: 'file-extract'
- }, {
- headers: {
- 'Content-Type': 'multipart/form-data'
- }
- })
- return fileObject.id
- }
|