Files
hack/tools/scripts/llm-key-hunter/results/_cache/content/angryparr0t_settime.json
T

1 line
22 KiB
JSON

{"repo": "angryparr0t/settime", "files": {".env": {"aa91fad8c883fe88f3ed93eb754079f852bfc4ab": {"t": 1785745086.7022781, "n": 62, "h": "68052659a375fb31", "c": "VUE_APP_DEEPSEEK_API_KEY='sk-f731ec2d53514cd1bdc21c0ba77006d8'"}, "48ac6bb63192ae9e575d94de9a4e768ebc58a6ef": {"t": 1785747706.914014, "n": 62, "h": "68052659a375fb31", "c": "VUE_APP_DEEPSEEK_API_KEY='sk-f731ec2d53514cd1bdc21c0ba77006d8'"}}, "src/api/ai.js": {"aa91fad8c883fe88f3ed93eb754079f852bfc4ab": {"t": 1785745553.462913, "n": 6977, "h": "92f1e4558fa0891f", "c": "import OpenAI from 'openai';\nimport {\n AI_CONFIG,\n getApiKeyStatus\n} from '../config/ai-config.js';\n\n// 检查API密钥状态\nconst apiKeyStatus = getApiKeyStatus();\nif (apiKeyStatus.status !== 'configured') {\n console.warn(`⚠️ ${apiKeyStatus.message}`);\n}\n\n// 创建OpenAI客户端实例,配置DeepSeek API\nconst openai = new OpenAI({\n apiKey: AI_CONFIG.DEEPSEEK_API_KEY,\n baseURL: AI_CONFIG.DEEPSEEK_BASE_URL,\n dangerouslyAllowBrowser: true, // 允许在浏览器中使用(仅用于开发)\n});\n\n// AI聊天服务类\nclass AIService {\n constructor() {\n this.conversationHistory = [];\n this.maxHistoryLength = AI_CONFIG.MAX_HISTORY_LENGTH;\n }\n\n // 添加消息到历史记录\n addMessage(role, content) {\n this.conversationHistory.push({\n role,\n content\n });\n\n // 保持历史记录在合理长度内\n if (this.conversationHistory.length > this.maxHistoryLength * 2) {\n this.conversationHistory = this.conversationHistory.slice(-this.maxHistoryLength * 2);\n }\n }\n\n // 清空对话历史\n clearHistory() {\n this.conversationHistory = [];\n }\n\n // 发送消息到DeepSeek AI(流式输出)\n async sendMessageStream(userMessage, onChunk) {\n try {\n // 添加用户消息到历史记录\n this.addMessage('user', userMessage);\n\n // 准备发送给API的消息\n const messages = [{\n role: 'system',\n content: AI_CONFIG.SYSTEM_PROMPT\n },\n ...this.conversationHistory\n ];\n\n // 调用DeepSeek API(流式)\n const response = await openai.chat.completions.create({\n model: AI_CONFIG.MODEL_NAME,\n messages: messages,\n max_tokens: AI_CONFIG.MAX_TOKENS,\n temperature: AI_CONFIG.TEMPERATURE,\n stream: true\n });\n\n let fullResponse = '';\n\n // 处理流式响应\n for await (const chunk of response) {\n const content = chunk.choices[0]?.delta?.content || '';\n const finishReason = chunk.choices[0]?.finish_reason;\n if (content) {\n fullResponse += content;\n // 调用回调函数传递当前内容\n onChunk(content, fullResponse);\n }\n // 新增:判断流式结束\n if (finishReason === 'stop') {\n break;\n }\n }\n\n // 尝试解析JSON响应\n let parsedResponse = this.parseScheduleResponse(fullResponse);\n\n // 添加完整的AI回复到历史记录\n this.addMessage('assistant', fullResponse);\n\n return {\n success: true,\n content: parsedResponse.content,\n type: parsedResponse.type,\n schedules: parsedResponse.schedules\n };\n\n } catch (error) {\n console.error('AI服务错误:', error);\n\n // 返回错误信息\n return {\n success: false,\n error: error.message || 'AI服务暂时不可用,请稍后重试',\n content: '抱歉,我现在无法回答您的问题。请检查网络连接或稍后重试。'\n };\n }\n }\n\n // 发送消息到DeepSeek AI(非流式,保持兼容性)\n async sendMessage(userMessage) {\n try {\n // 添加用户消息到历史记录\n this.addMessage('user', userMessage);\n\n // 准备发送给API的消息\n const messages = [{\n role: 'system',\n content: AI_CONFIG.SYSTEM_PROMPT\n },\n ...this.conversationHistory\n ];\n\n // 调用DeepSeek API\n const response = await openai.chat.completions.create({\n model: AI_CONFIG.MODEL_NAME,\n messages: messages,\n max_tokens: AI_CONFIG.MAX_TOKENS,\n temperature: AI_CONFIG.TEMPERATURE,\n stream: false\n });\n\n const aiResponse = response.choices[0].message.content;\n\n // 尝试解析JSON响应\n let parsedResponse = this.parseScheduleResponse(aiResponse);\n\n // 添加AI回复到历史记录\n this.addMessage('assistant', aiResponse);\n\n return {\n success: true,\n content: parsedResponse.content,\n type: parsedResponse.type,\n schedules: parsedResponse.schedules,\n usage: response.usage\n };\n\n } catch (error) {\n console.error('AI服务错误:', error);\n\n // 返回错误信息\n return {\n success: false,\n error: error.message || 'AI服务暂时不可用,请稍后重试',\n content: '抱歉,我现在无法回答您的问题。请检查网络连接或稍后重试。'\n };\n }\n }\n\n // 获取对话历史\n getHistory() {\n return [...this.conversationHistory];\n }\n\n // 解析日程响应\n parseScheduleResponse(response) {\n try {\n // 优先从 <Schedule> 标签中提取 JSON\n let jsonCandidate = null;\n const scheduleTagged = response.match(/<Schedule>[\\s\\S]*?<\\/Schedule>/i);\n if (scheduleTagged) {\n jsonCandidate = scheduleTagged[0].replace(/<\\/?Schedule>/gi, '').trim();\n }\n\n // 兜底:从全文中提取第一个大括号 JSON\n if (!jsonCandidate) {\n const jsonMatch = response.match(/\\{[\\s\\S]*\\}/);\n if (jsonMatch) {\n jsonCandidate = jsonMatch[0];\n }\n }\n\n if (jsonCandidate) {\n const parsed = JSON.parse(jsonCandidate);\n\n if (parsed.type === 'schedule' && Array.isArray(parsed.schedules)) {\n // 处理复杂日程格式(多天)\n if (parsed.schedules.length > 0 && parsed.schedules[0].plans) {\n // 将多天日程扁平化为单天日程\n const flattenedSchedules = [];\n parsed.schedules.forEach(daySchedule => {\n daySchedule.plans.forEach(plan => {\n flattenedSchedules.push({\n ...plan,\n day: daySchedule.day\n });\n });\n });\n\n return {\n content: '我为您生成了以下日程规划:',\n type: 'schedule',\n schedules: flattenedSchedules,\n originalData: parsed // 保留原始数据\n };\n } else {\n // 处理简单日程格式(单天)\n return {\n content: '我为您生成了以下日程规划:',\n type: 'schedule',\n schedules: parsed.schedules\n };\n }\n }\n }\n } catch (error) {\n console.log('解析日程响应失败,返回普通文本:', error);\n }\n\n // 如果不是日程规划或解析失败,返回普通文本\n return {\n content: response,\n type: 'text',\n schedules: null\n };\n }\n}\n\n// 创建单例实例\nconst aiService = new AIService();\n\nexport default aiService;"}, "48ac6bb63192ae9e575d94de9a4e768ebc58a6ef": {"t": 1785747708.1233892, "n": 6548, "h": "6f6d8c989cb3ebea", "c": "import OpenAI from 'openai';\nimport {\n AI_CONFIG,\n getApiKeyStatus\n} from '../config/ai-config.js';\n\n// 检查API密钥状态\nconst apiKeyStatus = getApiKeyStatus();\nif (apiKeyStatus.status !== 'configured') {\n console.warn(`⚠️ ${apiKeyStatus.message}`);\n}\n\n// 创建OpenAI客户端实例,配置DeepSeek API\nconst openai = new OpenAI({\n apiKey: AI_CONFIG.DEEPSEEK_API_KEY,\n baseURL: AI_CONFIG.DEEPSEEK_BASE_URL,\n dangerouslyAllowBrowser: true, // 允许在浏览器中使用(仅用于开发)\n});\n\n// AI聊天服务类\nclass AIService {\n constructor() {\n this.conversationHistory = [];\n this.maxHistoryLength = AI_CONFIG.MAX_HISTORY_LENGTH;\n }\n\n // 添加消息到历史记录\n addMessage(role, content) {\n this.conversationHistory.push({\n role,\n content\n });\n\n // 保持历史记录在合理长度内\n if (this.conversationHistory.length > this.maxHistoryLength * 2) {\n this.conversationHistory = this.conversationHistory.slice(-this.maxHistoryLength * 2);\n }\n }\n\n // 清空对话历史\n clearHistory() {\n this.conversationHistory = [];\n }\n\n // 发送消息到DeepSeek AI(流式输出)\n async sendMessageStream(userMessage, onChunk) {\n try {\n // 添加用户消息到历史记录\n this.addMessage('user', userMessage);\n\n // 准备发送给API的消息\n const messages = [{\n role: 'system',\n content: AI_CONFIG.SYSTEM_PROMPT\n },\n ...this.conversationHistory\n ];\n\n // 调用DeepSeek API(流式)\n const response = await openai.chat.completions.create({\n model: AI_CONFIG.MODEL_NAME,\n messages: messages,\n max_tokens: AI_CONFIG.MAX_TOKENS,\n temperature: AI_CONFIG.TEMPERATURE,\n stream: true\n });\n\n let fullResponse = '';\n\n // 处理流式响应\n for await (const chunk of response) {\n const content = chunk.choices[0]?.delta?.content || '';\n const finishReason = chunk.choices[0]?.finish_reason;\n if (content) {\n fullResponse += content;\n // 调用回调函数传递当前内容\n onChunk(content, fullResponse);\n }\n // 新增:判断流式结束\n if (finishReason === 'stop') {\n break;\n }\n }\n\n // 尝试解析JSON响应\n let parsedResponse = this.parseScheduleResponse(fullResponse);\n\n // 添加完整的AI回复到历史记录\n this.addMessage('assistant', fullResponse);\n\n return {\n success: true,\n content: parsedResponse.content,\n type: parsedResponse.type,\n schedules: parsedResponse.schedules\n };\n\n } catch (error) {\n console.error('AI服务错误:', error);\n\n // 返回错误信息\n return {\n success: false,\n error: error.message || 'AI服务暂时不可用,请稍后重试',\n content: '抱歉,我现在无法回答您的问题。请检查网络连接或稍后重试。'\n };\n }\n }\n\n // 发送消息到DeepSeek AI(非流式,保持兼容性)\n async sendMessage(userMessage) {\n try {\n // 添加用户消息到历史记录\n this.addMessage('user', userMessage);\n\n // 准备发送给API的消息\n const messages = [{\n role: 'system',\n content: AI_CONFIG.SYSTEM_PROMPT\n },\n ...this.conversationHistory\n ];\n\n // 调用DeepSeek API\n const response = await openai.chat.completions.create({\n model: AI_CONFIG.MODEL_NAME,\n messages: messages,\n max_tokens: AI_CONFIG.MAX_TOKENS,\n temperature: AI_CONFIG.TEMPERATURE,\n stream: false\n });\n\n const aiResponse = response.choices[0].message.content;\n\n // 尝试解析JSON响应\n let parsedResponse = this.parseScheduleResponse(aiResponse);\n\n // 添加AI回复到历史记录\n this.addMessage('assistant', aiResponse);\n\n return {\n success: true,\n content: parsedResponse.content,\n type: parsedResponse.type,\n schedules: parsedResponse.schedules,\n usage: response.usage\n };\n\n } catch (error) {\n console.error('AI服务错误:', error);\n\n // 返回错误信息\n return {\n success: false,\n error: error.message || 'AI服务暂时不可用,请稍后重试',\n content: '抱歉,我现在无法回答您的问题。请检查网络连接或稍后重试。'\n };\n }\n }\n\n // 获取对话历史\n getHistory() {\n return [...this.conversationHistory];\n }\n\n // 解析日程响应\n parseScheduleResponse(response) {\n try {\n // 尝试从响应中提取JSON\n const jsonMatch = response.match(/\\{[\\s\\S]*\\}/);\n if (jsonMatch) {\n const jsonStr = jsonMatch[0];\n const parsed = JSON.parse(jsonStr);\n\n if (parsed.type === 'schedule' && Array.isArray(parsed.schedules)) {\n // 处理复杂日程格式(多天)\n if (parsed.schedules.length > 0 && parsed.schedules[0].plans) {\n // 将多天日程扁平化为单天日程\n const flattenedSchedules = [];\n parsed.schedules.forEach(daySchedule => {\n daySchedule.plans.forEach(plan => {\n flattenedSchedules.push({\n ...plan,\n day: daySchedule.day\n });\n });\n });\n\n return {\n content: '我为您生成了以下日程规划:',\n type: 'schedule',\n schedules: flattenedSchedules,\n originalData: parsed // 保留原始数据\n };\n } else {\n // 处理简单日程格式(单天)\n return {\n content: '我为您生成了以下日程规划:',\n type: 'schedule',\n schedules: parsed.schedules\n };\n }\n }\n }\n } catch (error) {\n console.log('解析日程响应失败,返回普通文本:', error);\n }\n\n // 如果不是日程规划或解析失败,返回普通文本\n return {\n content: response,\n type: 'text',\n schedules: null\n };\n }\n}\n\n// 创建单例实例\nconst aiService = new AIService();\n\nexport default aiService;"}}, "src/config/ai-config.js": {"aa91fad8c883fe88f3ed93eb754079f852bfc4ab": {"t": 1785746700.5135255, "n": 2134, "h": "02ae1148e46ece0f", "c": "// AI配置文件\nexport const AI_CONFIG = {\n // DeepSeek API配置\n DEEPSEEK_API_KEY: process.env.VUE_APP_DEEPSEEK_API_KEY || 'sk-f731ec2d53514cd1bdc21c0ba77006d8',\n DEEPSEEK_BASE_URL: 'https://api.deepseek.com/v1',\n\n // 模型配置\n MODEL_NAME: 'deepseek-chat',\n MAX_TOKENS: 1000,\n TEMPERATURE: 0.7,\n\n // 对话配置\n MAX_HISTORY_LENGTH: 10,\n\n // 流式输出配置\n ENABLE_STREAMING: true,\n\n // 系统提示词\n SYSTEM_PROMPT: `你是一个智能助手,可以帮助用户处理日程管理相关的问题。请用中文回答,回答要简洁明了。\n\n**重要:你的回复支持Markdown格式,可以使用以下Markdown语法:**\n- **粗体文本** 用于强调重要信息\n- *斜体文本* 用于次要信息\n- \\`代码\\` 用于技术术语或代码\n- \\`\\`\\`代码块\\`\\`\\` 用于多行代码\n- > 引用块 用于重要提示\n- - 列表项 用于列举\n- 1. 有序列表 用于步骤说明\n- [链接文本](URL) 用于外部链接\n- | 表格 | 用于数据展示 |\n\n当用户请求日程规划时:\n1) 请将日程的 JSON 结构严格包裹在 <Schedule> 与 </Schedule> 标签中返回;\n2) 标签外请保留一段面向用户的自然语言说明(Markdown 可用),不要在聊天文本中直接展示 JSON;\n3) JSON 结构参考如下:\n\n简单日程格式(单天):\n<Schedule>\n{\n \"type\": \"schedule\",\n \"schedules\": [\n {\n \"time\": \"09:00-10:00\",\n \"title\": \"晨会\",\n \"description\": \"与团队讨论今日工作计划\"\n }\n ]\n}\n</Schedule>\n\n复杂日程格式(多天):\n<Schedule>\n{\n \"type\": \"schedule\",\n \"schedules\": [\n {\n \"day\": \"第1天\",\n \"plans\": [\n {\"time\": \"09:00-11:30\", \"title\": \"学习内容\", \"description\": \"详细描述\"}\n ]\n }\n ]\n}\n</Schedule>\n\n如果用户没有明确请求日程规划,请正常回复文本内容,可以使用Markdown格式来增强可读性。`\n};\n\n// 检查API密钥是否已配置\nexport function isApiKeyConfigured() {\n return (\n AI_CONFIG.DEEPSEEK_API_KEY &&\n AI_CONFIG.DEEPSEEK_API_KEY !== 'your-deepseek-api-key-here' &&\n AI_CONFIG.DEEPSEEK_API_KEY.startsWith('sk-')\n );\n}\n\n// 获取配置信息\nexport function getConfigInfo() {\n return {\n isConfigured: isApiKeyConfigured(),\n modelName: AI_CONFIG.MODEL_NAME,\n maxTokens: AI_CONFIG.MAX_TOKENS,\n temperature: AI_CONFIG.TEMPERATURE,\n };\n}\n\n// 获取API密钥状态信息\nexport function getApiKeyStatus() {\n const key = AI_CONFIG.DEEPSEEK_API_KEY;\n\n if (!key || key === 'your-deepseek-api-key-here') {\n return {\n status: 'not-configured',\n message: 'API密钥未配置,请在src/config/ai-config.js中设置正确的API密钥',\n };\n }\n\n if (!key.startsWith('sk-')) {\n return {\n status: 'invalid-format',\n message: 'API密钥格式不正确,应该以sk-开头',\n };\n }\n\n return {\n status: 'configured',\n message: 'API密钥已配置',\n };\n}"}, "48ac6bb63192ae9e575d94de9a4e768ebc58a6ef": {"t": 1785747706.5749931, "n": 1967, "h": "443a85bef871848d", "c": "// AI配置文件\nexport const AI_CONFIG = {\n // DeepSeek API配置\n DEEPSEEK_API_KEY: process.env.VUE_APP_DEEPSEEK_API_KEY || 'sk-f731ec2d53514cd1bdc21c0ba77006d8',\n DEEPSEEK_BASE_URL: 'https://api.deepseek.com/v1',\n\n // 模型配置\n MODEL_NAME: 'deepseek-chat',\n MAX_TOKENS: 1000,\n TEMPERATURE: 0.7,\n\n // 对话配置\n MAX_HISTORY_LENGTH: 10,\n\n // 流式输出配置\n ENABLE_STREAMING: true,\n\n // 系统提示词\n SYSTEM_PROMPT: `你是一个智能助手,可以帮助用户处理日程管理相关的问题。请用中文回答,回答要简洁明了。\n\n**重要:你的回复支持Markdown格式,可以使用以下Markdown语法:**\n- **粗体文本** 用于强调重要信息\n- *斜体文本* 用于次要信息\n- \\`代码\\` 用于技术术语或代码\n- \\`\\`\\`代码块\\`\\`\\` 用于多行代码\n- > 引用块 用于重要提示\n- - 列表项 用于列举\n- 1. 有序列表 用于步骤说明\n- [链接文本](URL) 用于外部链接\n- | 表格 | 用于数据展示 |\n\n当用户请求日程规划时,请按照以下JSON格式返回日程数据:\n\n简单日程格式(单天):\n{\n \"type\": \"schedule\",\n \"schedules\": [\n {\n \"time\": \"09:00-10:00\",\n \"title\": \"晨会\",\n \"description\": \"与团队讨论今日工作计划\"\n }\n ]\n}\n\n复杂日程格式(多天):\n{\n \"type\": \"schedule\",\n \"schedules\": [\n {\n \"day\": \"第1天\",\n \"plans\": [\n {\"time\": \"09:00-11:30\", \"title\": \"学习内容\", \"description\": \"详细描述\"}\n ]\n }\n ]\n}\n\n如果用户没有明确请求日程规划,请正常回复文本内容,可以使用Markdown格式来增强可读性。`\n};\n\n// 检查API密钥是否已配置\nexport function isApiKeyConfigured() {\n return AI_CONFIG.DEEPSEEK_API_KEY &&\n AI_CONFIG.DEEPSEEK_API_KEY !== 'your-deepseek-api-key-here' &&\n AI_CONFIG.DEEPSEEK_API_KEY.startsWith('sk-');\n}\n\n// 获取配置信息\nexport function getConfigInfo() {\n return {\n isConfigured: isApiKeyConfigured(),\n modelName: AI_CONFIG.MODEL_NAME,\n maxTokens: AI_CONFIG.MAX_TOKENS,\n temperature: AI_CONFIG.TEMPERATURE\n };\n}\n\n// 获取API密钥状态信息\nexport function getApiKeyStatus() {\n const key = AI_CONFIG.DEEPSEEK_API_KEY;\n\n if (!key || key === 'your-deepseek-api-key-here') {\n return {\n status: 'not-configured',\n message: 'API密钥未配置,请在src/config/ai-config.js中设置正确的API密钥'\n };\n }\n\n if (!key.startsWith('sk-')) {\n return {\n status: 'invalid-format',\n message: 'API密钥格式不正确,应该以sk-开头'\n };\n }\n\n return {\n status: 'configured',\n message: 'API密钥已配置'\n };\n}"}}}}