123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- /**
- * AI服务类
- * 处理与AI模型的通信和响应
- */
- class AIService {
- constructor() {
- this.apiEndpoint = CONFIG.AI_API.ENDPOINT;
- this.messageContainer = document.getElementById("chat-messages");
- this.model = CONFIG.AI_API.MODEL;
-
- this.context = [];
- this.currentExcelData = null; // 保存当前Excel数据
- this.response = ''
- // 使用默认API密钥
- this.apiKey = CONFIG.AI_API.DEFAULT_API_KEY;
- this.controller = null; // 用于中断请求的 AbortController
- this.currentPageInfo = null; // 保存当前页面信息
- this.openai = new OpenAI(
- {
- // 若没有配置环境变量,请用百炼API Key将下行替换为:apiKey: "sk-xxx",
- apiKey: 'sk-e9855234f47346049809ce23ed3ebe3f',
- baseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1",
- dangerouslyAllowBrowser: true,
- }
- );
- }
- /**
- * 初始化AI服务
- */
- async init() {
- try {
- // 尝试从storage中获取用户设置的API密钥
- const result = await Utils.getStorageData("apiKey");
- if (result?.apiKey) {
- this.apiKey = result.apiKey;
- }
- console.log("AI Service initialized");
- } catch (error) {
- console.error("Failed to initialize AI service:", error);
- }
- }
- /**
- * 设置API密钥
- * @param {string} apiKey
- */
- async setApiKey(apiKey) {
- this.apiKey = apiKey;
- await Utils.setStorageData("apiKey", { apiKey });
- }
- /**
- * 发送消息到DeepSeek API
- * @param {string} message 用户消息
- * @returns {Promise<string>} AI响应
- */
- async sendMessage(message) {
- try {
- // 创建新的 AbortController
- this.controller = new AbortController();
- const a = +new Date()
- const response = await this.openai.chat.completions.create({
- model: "qwen-plus", //模型列表:https://help.aliyun.com/zh/model-studio/getting-started/models
- messages: this.formatMessages(message),
- stream:true
- });
- // console.log(completion);
- const signal = response.controller.signal;
- let text = '匹配到的关系为:'
- const paragraph = window.chatUI.addMessage(text, "assistant");
- try {
- const iterator = response.iterator();
- for await (const chunk of iterator) {
- if (chunk) {
- console.log(chunk);
-
- const decodedChunk = chunk.choices[0].delta.content;
- if (decodedChunk) {
- text += decodedChunk;
- paragraph.innerHTML = text
- }
-
- }
- }
- console.log(document.getElementById("fill-button"));
-
- document.getElementById("fill-button").onclick = () => {
- window.parent.postMessage({
- type: "HANDLE_FILL_INPUT", data: {
- formData: JSON.parse(this.response.split('json')[1].split('```')[0]) //根据不同返回修改res
- }
- }, "*");
- }
- this.response = text
- console.log(text);
-
- } catch (error) {
- if (signal.aborted) {
- console.log("Stream reading aborted");
- } else {
- console.error("Error reading stream:", error);
- }
- }
- console.log((+new Date() - a) / 1000)
- // console.log(completion.choices[0].message.content);
- // const response = await fetch(this.apiEndpoint, {
- // method: "POST",
- // headers: {
- // "Content-Type": "application/json",
- // Authorization: `Bearer ${this.apiKey}`,
- // },
- // body: JSON.stringify({
- // model: this.model,
- // messages: this.formatMessages(message),
- // }),
- // signal: this.controller.signal,
- // });
- // if (!response.ok) {
- // throw new Error(`API request failed: ${response.status}`);
- // }
- // const data = await response.json();
- // const aiResponse = data.choices[0]?.message?.content;
- // const aiResponse = completion.choices[0].message.content
- // if (!aiResponse) {
- // throw new Error("无效的API响应");
- // }
- // return aiResponse;
- } catch (error) {
- if (error.name === "AbortError") {
- throw new Error("REQUEST_ABORTED");
- }
- console.error("API call failed:", error);
- throw error;
- } finally {
- this.controller = null;
- }
- }
- /**
- * 格式化消息历史
- * @param {string} currentMessage 当前消息
- * @returns {Array} 格式化后的消息数组
- */
- formatMessages(currentMessage) {
- const messages = this.context.map((msg) => ({
- role: msg.role,
- content: msg.content,
- }));
- // 如果存在页面信息,添加到当前消息的上下文
- if (this.currentPageInfo) {
- currentMessage = `基于之前总结的页面内容(标题:${this.currentPageInfo.title}),${currentMessage}`;
- }
- messages.push({
- role: "user",
- content: currentMessage,
- });
- return messages;
- }
- /**
- * 更新对话上下文
- * @param {string} message 新消息
- * @param {string} role 消息角色(user/assistant)
- */
- updateContext(message, role) {
- this.context.push({
- role,
- content: message,
- timestamp: new Date().toISOString(),
- });
- // 保持上下文长度在合理范围内
- if (this.context.length > 10) {
- this.context = this.context.slice(-10);
- }
- }
- /**
- * 清除对话上下文
- */
- clearContext() {
- this.context = [];
- }
- /**
- * 获取当前对话上下文
- * @returns {Array} 对话上下文数组
- */
- getContext() {
- return this.context;
- }
- // 添加中断方法
- abortRequest() {
- if (this.controller) {
- this.controller.abort();
- this.controller = null;
- }
- }
- /**
- * 获取页面总结提示词
- * @param {Object} pageInfo 页面信息
- * @returns {string} 提示词
- */
- // 4. 按重要性排序
- // 5. 如果内容是新闻,需要包含时间、地点、人物等关键信息
- // 6. 如果内容是教程,需要突出操作步骤和关键提示
- // 7. 如果内容是产品介绍,需要包含主要特点和优势
- getSummaryPrompt(pageInfo) {
- return `请帮我总结以下网页内容的要点:
- 页面标题:${pageInfo.title}
- 网站:${pageInfo.siteName}
- URL:${pageInfo.url}
- 主要内容:
- ${pageInfo.mainContent}
- 要求:
- 1. 帮助我分析表单项与上传excel文件中每一列的关系
- 2- 将excel文件中每一列的内容与表单项进行匹配,并生成对应的数组,在一个字段内返回
- `;
- }
- /**
- * 设置当前Excel数据
- * @param {Object} data Excel数据和元信息
- */
- setExcelData(data) {
- this.currentExcelData = data;
- }
- /**
- * 设置当前页面信息
- * @param {Object} pageInfo 页面信息
- */
- setPageInfo(pageInfo) {
- this.currentPageInfo = pageInfo;
- }
- }
- // 确保在DOM加载完成后再创建实例
- document.addEventListener("DOMContentLoaded", () => {
- // 只有在实例不存在时才创建
- if (!window.aiService) {
- window.aiService = new AIService();
- }
- });
|