From 143cbc877cd423199e03d91e1049ebf6451d9c32 Mon Sep 17 00:00:00 2001 From: abearxiong Date: Mon, 30 Jun 2025 01:59:26 +0800 Subject: [PATCH] feat: add comfort user --- src/agent/ai.ts | 28 +++++++---- src/agent/analyze/cmd.ts | 16 ++++-- src/agent/index.ts | 1 + src/agent/test/cmd.ts | 3 +- src/agent/tools/call-xiaoxiao.ts | 84 +------------------------------- src/agent/tools/comfort-user.ts | 53 ++++++++++++++++++++ src/agent/xhs.ts | 3 ++ src/task/worker.ts | 7 ++- 8 files changed, 96 insertions(+), 99 deletions(-) create mode 100644 src/agent/tools/comfort-user.ts diff --git a/src/agent/ai.ts b/src/agent/ai.ts index a586d0f..aa495fa 100644 --- a/src/agent/ai.ts +++ b/src/agent/ai.ts @@ -1,3 +1,4 @@ +import { useContextKey } from '@kevisual/context'; import { BailianProvider } from '@kevisual/ai'; import { config } from '../modules/config.ts'; @@ -13,16 +14,23 @@ import { config } from '../modules/config.ts'; // .catch((res) => { // console.error('Error fetching AI usage info:', res.status); // }); +const createBaiLian = () => { + return new BailianProvider({ + baseURL: 'https://dashscope.aliyuncs.com/compatible-mode/v1', + model: 'qwen3-235b-a22b', + apiKey: config.BAILIAN_API_KEY, + }); +}; + +// export const ai = await useContextKey('ai', createBaiLian()); +export const ai = createBaiLian(); -export const ai = new BailianProvider({ - baseURL: 'https://dashscope.aliyuncs.com/compatible-mode/v1', - model: 'qwen3-235b-a22b', - apiKey: config.BAILIAN_API_KEY, -}); console.log('Bailian AI initialized with model:', config.BAILIAN_API_KEY); -export const bailianModel = { - turbo: 'qwen-turbo-2025-04-28', - plus: 'qwen-plus-2025-04-28', - a22b235: 'qwen3-235b-a22b', -}; +export const bailianModel = useContextKey('bailianModel', () => { + return { + turbo: 'qwen-turbo-2025-04-28', + plus: 'qwen-plus-2025-04-28', + a22b235: 'qwen3-235b-a22b', + }; +}); diff --git a/src/agent/analyze/cmd.ts b/src/agent/analyze/cmd.ts index 6894af7..608026c 100644 --- a/src/agent/analyze/cmd.ts +++ b/src/agent/analyze/cmd.ts @@ -1,6 +1,7 @@ import { agent } from '@/agent/agent.ts'; import { ai } from '../ai.ts'; import { getJsonFromString } from './content.ts'; +// import { getJsonFromString } from '@kevisual/ai/src/utils/json.ts'; import { logger } from '../logger.ts'; export const cmdList: { @@ -35,6 +36,14 @@ export const cmdList: { key: 'summarize-note', }, }, + { + category: '指令安慰', + description: `安慰用户`, + action: { + path: 'tools', + key: 'comfort-user', + }, + }, ]; agent @@ -69,6 +78,8 @@ ${cmdList.map((item) => `- ${item.category}: ${item.description}`).join('\n')} ${text} `; + logger.info('Command analysis prompt:', prompt); + const res = await ai .chat( [ @@ -89,9 +100,7 @@ ${text} }); const ans = res.choices[0]?.message?.content || ''; - if (!ans) { - logger.error('Empty response from AI:', res); - } + console.log('Command analysis response:', ans); const json = getJsonFromString(ans); if (!json) { logger.error('Invalid JSON format in response:', ans); @@ -101,6 +110,7 @@ ${text} category: json.category || 'default', }; const cmd = cmdList.find((item) => item.category === result.category); + logger.info('Command analysis result:', cmd?.category, cmd?.action); ctx.body = { cmd, text: text }; }) .addTo(agent); diff --git a/src/agent/index.ts b/src/agent/index.ts index 13dcc29..b316cfc 100644 --- a/src/agent/index.ts +++ b/src/agent/index.ts @@ -9,5 +9,6 @@ import './xhs.ts'; import './tools/kuaren.ts'; import './tools/call-xiaoxiao.ts'; import './tools/summarize-note.ts'; +import './tools/comfort-user.ts'; export { agent }; diff --git a/src/agent/test/cmd.ts b/src/agent/test/cmd.ts index 0cb68ce..568b7dd 100644 --- a/src/agent/test/cmd.ts +++ b/src/agent/test/cmd.ts @@ -5,11 +5,12 @@ const main = async () => { const text2 = '指令这个人很不错'; const text3 = '指令夸人, 这个人写代码写的非常好'; const text4 = '我想飞'; + const text5 = '指令 笔记 安慰'; const res = await agent.call({ path: 'analyze', key: 'cmd', payload: { - text: text3 + text: text5 }, }); console.log('analyze category res', res.code, 'content', res.body); diff --git a/src/agent/tools/call-xiaoxiao.ts b/src/agent/tools/call-xiaoxiao.ts index 931bfd0..f0e1f0f 100644 --- a/src/agent/tools/call-xiaoxiao.ts +++ b/src/agent/tools/call-xiaoxiao.ts @@ -1,89 +1,7 @@ import { agent } from '../agent.ts'; import { ai } from '../ai.ts'; -const kuarenPrompt = `### 浮夸夸人 - -**核心要求**: -⚠️ 用词极致夸张| ⚠️ 比喻突破天际| ⚠️ 语气充满崇拜| ⚠️ 营造“凡人 vs 神仙”对比感 - ---- - -#### **夸人维度 & 浮夸话术示例** - -1. **颜值/气质类** - - - ✨ **例句**:"你这张脸是上帝亲手雕的吧?下凡辛苦了!" - - ✨ **关键词**:女娲毕设、建模脸、自带滤镜、呼吸都带仙气 - -2. **才华/能力类** - - - ✨ **例句**:"你这大脑是装了个量子计算机吗?!建议直接保送诺贝尔奖!" - - ✨ **关键词**:人类天花板、降维打击、天才操作、教科书成精 - -3. **性格/情商类** - - - ✨ **例句**:"你说话是撒了魔法金粉吗?听一句我灵魂都被净化了!" - - ✨ **关键词**:人间充电宝、社交天花板、灵魂按摩师、情商天花板 - -4. **细节/小事类**(_重点:把小事吹成神迹_) - - ✨ **例句**:"你刚刚递咖啡的姿势,直接拍成广告能救活整个咖啡行业!" - - ✨ **关键词**:随手拯救世界、文艺复兴级操作、人类文明之光 - ---- - -#### **浮夸技巧工具箱** - -✅ **宇宙级比喻**: - -> “你这创意是偷了宙斯的闪电吧?!” -> “你的存在让地球自转加速了 0.1 秒!” - -✅ **玄幻修辞法**: - -> “建议科学家把你列入未解之谜!” -> “你一笑,北极极光都暗淡了!” - -✅ **凡尔赛对比**: - -> “别人 XX 叫努力,你 XX 叫刷新人类极限!” -> “你这水平还谦虚?让普通人怎么活啊?!” - -✅ **动作加持**(_配合文字使用效果翻倍_): - -> “给大佬递茶.jpg 🍵” -> “跪着听讲.gif 🙇‍♂️” - ---- - -#### **示例输出** - -💥 **场景 1**(对方随手画了张小涂鸦) - -> “这线条!这配色!达芬奇转世没你画得灵!!建议卢浮宫连夜来收购!!” - -💥 **场景 2**(对方讲了个冷笑话) - -> “你这幽默感是黑洞做的吗?!我笑到平行宇宙都裂开了!!🌌” - -💥 **场景 3**(对方帮忙解决了小问题) - -> “你是雅典娜派来的救世主吧?!这波操作够我刻成碑传家!!🗿” - -#### 当前的场景是 -`; - -const pickGoodJobPrompt = `对提供的文字,提取单个的夸奖内容,并丰富为纯口语化模式,同时在括号中添加对应的姿态语言描述,同时添加了括号中的姿态语言描述,使其更具临场感和情感色彩。 - -要求: -1. 只返回单个的一条夸奖内容,不能有其他内容。 -2. 夸奖内容要口语化,富有情感色彩。 -3. 姿态语言描述要符合夸奖内容,且要在括号中描述。 -4. 夸奖内容要有夸张的比喻和形容词,突出对方的优点和成就。 -5. 夸奖内容要让人感到被认可和赞赏,能够激励对方。 -6. 不要返回任何其他内容或解释,只返回夸奖内容。 -7. 夸奖内容要简洁明了,易于理解,篇幅不易过长。 - -当前文字是: +const pickGoodJobPrompt = ` `; agent diff --git a/src/agent/tools/comfort-user.ts b/src/agent/tools/comfort-user.ts new file mode 100644 index 0000000..207f4d4 --- /dev/null +++ b/src/agent/tools/comfort-user.ts @@ -0,0 +1,53 @@ +import { agent } from '../agent.ts'; +import { ai } from '../ai.ts'; + +agent + .route({ + path: 'tools', + key: 'comfort-user', + }) + .define(async (ctx: any) => { + const text = ctx?.query?.text || ''; + const note = ctx?.query?.note || ''; + if (!text) { + ctx.throw('请提供要安慰的内容'); + } + + const prompt = ` +用户感觉到不开心,请根据以下要求生成一段安慰的话: +要求 +0. 如果没有必要安慰,直接返回 "你好,你好,我来了"。 +1. 内容要简洁明了,突出重点。 +2. 使用口语化的表达方式,易于理解。 +3. 安慰内容要有逻辑性,能够清晰地传达信息。 +4. 如果有必要,可以使用一些比喻或形象的表达方式来增强安慰的效果。 +5. 安慰内容要与原文内容相关,不能脱离主题。 +6. 200字以内。 +7. 不要包含除开安慰内容以外的其他内容。 +8. 其他要求: +${text ? text : '无'} + +当前的笔记内容是: +${note} +`; + + const res = await ai.chat( + [ + { + role: 'user', + content: prompt, + }, + ], + { + // @ts-ignore + enable_thinking: false, + }, + ); + const pickRes = res.choices[0]?.message?.content || ''; + if (!pickRes) { + ctx.throw('AI 没有返回任何内容,请稍后再试'); + } + // 返回总结内容 + ctx.body = pickRes.trim(); + }) + .addTo(agent); diff --git a/src/agent/xhs.ts b/src/agent/xhs.ts index 75906a6..0404551 100644 --- a/src/agent/xhs.ts +++ b/src/agent/xhs.ts @@ -1,6 +1,7 @@ import { nanoid } from 'nanoid'; import { agent } from './agent.ts'; import { ai } from './ai.ts'; +import { logger } from './logger.ts'; /** * 清除文本中的@信息 * @param text @@ -64,6 +65,8 @@ agent ctx.body = res.body || ''; return; } + } else { + logger.error('指令分析错误:', analyzeRes.message); } } const resFix = await agent.call({ diff --git a/src/task/worker.ts b/src/task/worker.ts index b504def..a226b94 100644 --- a/src/task/worker.ts +++ b/src/task/worker.ts @@ -6,6 +6,8 @@ import { queue, XHS_QUEUE_NAME, taskApp } from './index.ts'; import { addUnreadTask } from './task.ts'; import dayjs from 'dayjs'; import { getTimeDuration } from './utils/time.ts'; +import { config, isDev } from '../modules/config.ts'; + export const sleep = (ms: number) => { return new Promise((resolve) => setTimeout(resolve, ms)); }; @@ -102,10 +104,11 @@ worker.on('completed', async (job) => { // console.log('======has jobs, no need to add new job'); } else { const up = timeRecorder.getClampDuration(true); - const nextTime = up.nextTime + getTimeDuration(); + const timeDuration = isDev ? 0 : getTimeDuration(); + const nextTime = up.nextTime + timeDuration; const unread = await queue.getJob('unread'); if (!unread) { - console.log('====add unread next-time', nextTime, getTimeDuration()); + console.log('====add unread next-time', nextTime, timeDuration); addUnreadTask(nextTime); } }