diff --git a/packages/xhs/src/libs/xhs.ts b/packages/xhs/src/libs/xhs.ts index 5ea7687..50be948 100644 --- a/packages/xhs/src/libs/xhs.ts +++ b/packages/xhs/src/libs/xhs.ts @@ -38,6 +38,7 @@ export const getSign = async (signInfo: SignInfo, options?: SignOptions): Promis // signUrl = 'http://localhost:5005/sign'; // const urlA1 = ''http://light.xiongxiao.me:5006/a1'; // const urlA1 = 'http://localhost:5005/a1'; + // console.log('sign', signUrl); const signs = await fetch(signUrl, { method: 'POST', headers: { @@ -215,6 +216,7 @@ export class XhsClient extends XhsClientBase { try { const response = await this.post(uri, data, { sign: this.sign.bind(this) }); + console.log('getNoteById response', response, typeof response); // return response['items'][0]['node_card']; return response; } catch (error) { diff --git a/packages/xhs/src/routes/index.ts b/packages/xhs/src/routes/index.ts index 1a477c4..283e90f 100644 --- a/packages/xhs/src/routes/index.ts +++ b/packages/xhs/src/routes/index.ts @@ -1 +1,2 @@ -import './mentions/index.ts' \ No newline at end of file +import './mentions/index.ts' +import './notes/index.ts' \ No newline at end of file diff --git a/packages/xhs/src/routes/notes/create-note.ts b/packages/xhs/src/routes/notes/create-note.ts index 2c484ae..3ef16e0 100644 --- a/packages/xhs/src/routes/notes/create-note.ts +++ b/packages/xhs/src/routes/notes/create-note.ts @@ -7,8 +7,8 @@ app }) .define(async (ctx) => { const client = xhsServices.getClient(); - const res = await client.c - if (res.code === 0) { - } + // const res = await client.getNote({}); + // if (res.code === 0) { + // } }) .addTo(app); diff --git a/packages/xhs/src/routes/notes/get-note.ts b/packages/xhs/src/routes/notes/get-note.ts new file mode 100644 index 0000000..8ef365c --- /dev/null +++ b/packages/xhs/src/routes/notes/get-note.ts @@ -0,0 +1,18 @@ +import { app, xhsServices } from '@kevisual/xhs/app.ts'; +app + .route({ + path: 'note', + key: 'getNote', + description: '获取笔记详情', + }) + .define(async (ctx) => { + const { node_id, xsec_token } = ctx.query; + const client = xhsServices.getClient(); + const res = await client.getNote(node_id, xsec_token); + if (res.code === 200) { + ctx.body = res.data || {}; + } else { + ctx.throw(`获取笔记失败: ${node_id}`); + } + }) + .addTo(app); diff --git a/packages/xhs/src/routes/notes/index.ts b/packages/xhs/src/routes/notes/index.ts index 3137afe..623a4bc 100644 --- a/packages/xhs/src/routes/notes/index.ts +++ b/packages/xhs/src/routes/notes/index.ts @@ -1 +1,2 @@ -import './create-note.ts' \ No newline at end of file +import './create-note.ts' +import './get-note.ts' \ No newline at end of file diff --git a/packages/xhs/src/services/xhs-services.ts b/packages/xhs/src/services/xhs-services.ts index c7e0afb..e2bc170 100644 --- a/packages/xhs/src/services/xhs-services.ts +++ b/packages/xhs/src/services/xhs-services.ts @@ -104,6 +104,16 @@ export class XhsServices { } return user.userid === xhsUserInfo.userid; } + isReplayAi(data: any, key?: string) { + const mention = data?.mention || {}; + const user_info = mention?.comment_info?.target_comment?.user_info || {}; + if (user_info?.userid) { + const xhsUserInfo = this.getXhsUserInfo(key); + // 处理用户信息 + return user_info.userid === xhsUserInfo.userid; + } + return false; + } setCookie(cookie: string, key?: string) { const xhsClient = this.map.get(this.getKey(key)); if (xhsClient) { @@ -123,4 +133,17 @@ export class XhsServices { xhsClient.options.username = user.username; } } + + setSignConfig(signConfig: { signUrl: string }, key?: string) { + const xhsClient = this.map.get(this.getKey(key)); + if (xhsClient) { + xhsClient.options.signConfig = signConfig; + xhsClient.client.signConfig = signConfig; + } + console.log('setSignConfig', xhsClient?.options?.signConfig); + } + getSignConfig(key?: string) { + const xhsClient = this.map.get(this.getKey(key)); + return xhsClient?.options?.signConfig || {}; + } } diff --git a/packages/xhs/src/test/query/get-note.ts b/packages/xhs/src/test/query/get-note.ts index bf47446..80b230a 100644 --- a/packages/xhs/src/test/query/get-note.ts +++ b/packages/xhs/src/test/query/get-note.ts @@ -8,17 +8,27 @@ import util from 'node:util'; // }); const getNoteById = async () => { const client = xhsServices.getClient(); - client.getNoteById('68136dab0000000007034c46', 'LByEmonX8WfJ9ebpAowVbOZX9Xh8T0Qkjil5KRFqDD6LM').then((res) => { - console.log(res); - }); + // client.getNoteById('68136dab0000000007034c46', 'LByEmonX8WfJ9ebpAowVbOZX9Xh8T0Qkjil5KRFqDD6LM').then((res) => { + // console.log(res); + // }); + + const res = await client.getNoteById('68136dab0000000007034c46', 'LB6fmNfsd0keAQNjh3zOejDC2TVQLGY3zlTZjeRazBZdI='); + // console.log(res); }; const getNote = async () => { + // const id = '68136dab0000000007034c46'; + // const x = 'LByEmonX8WfJ9ebpAowVbOZX9Xh8T0Qkjil5KRFqDD6LM='; const id = '68136dab0000000007034c46'; - const x = 'LByEmonX8WfJ9ebpAowVbOZX9Xh8T0Qkjil5KRFqDD6LM='; + const x = 'LB6fmNfsd0keAQNjh3zOejDC2TVQLGY3zlTZjeRazBZdI='; const client = xhsServices.getClient(); - client.getNote(id, x).then((res) => { + const res = await client.getNote(id, x).then((res) => { console.log(util.inspect(res, { depth: null })); + return res; }); + console.log('type res', typeof res); + if (res.code === 0) { + console.log('desc', res.data.desc); + } }; program .command('get-note') diff --git a/src/agent/analyze/cmd.ts b/src/agent/analyze/cmd.ts index f4edb7f..6894af7 100644 --- a/src/agent/analyze/cmd.ts +++ b/src/agent/analyze/cmd.ts @@ -27,6 +27,14 @@ export const cmdList: { key: 'call-xiaoxiao', }, }, + { + category: '指令总结', + description: `总结当前的笔记,缩写当前笔记的内容`, + action: { + path: 'tools', + key: 'summarize-note', + }, + }, ]; agent @@ -96,4 +104,3 @@ ${text} ctx.body = { cmd, text: text }; }) .addTo(agent); - diff --git a/src/agent/fix/prompt.ts b/src/agent/fix/prompt.ts index 946bdf2..58b38f6 100644 --- a/src/agent/fix/prompt.ts +++ b/src/agent/fix/prompt.ts @@ -22,7 +22,7 @@ agent { role: 'user', content: ` -你是一个提示词优化的专家,请根据用户提供的提示词进行修正和优化,其中用户的提示词返回的要求如果没有或者不明确,请你都修正为要求返回的文本在500字以内,如果有,则要求在500字内。同时要求内容是纯文本格式,不能是markdown模式,也不包含任何HTML标签或其他格式化内容。 +你是一个提示词优化的专家,请根据用户提供的提示词进行修正和优化,其中用户的提示词返回的要求如果没有或者不明确,请你修正为要求返回的文本在500字以内,如果有,保持原本的要求数字的文本。与此同时,要求内容是纯文本格式,不能是markdown模式,也不包含任何HTML标签或其他格式化内容。 只对提示词进行优化,并且不需要对内容进行分析或总结。并返回修改后的总的提示词内容。 @@ -64,6 +64,6 @@ ${text} if (!ans) { logger.error('Empty response from AI:', res); } - ctx.body = getTagContent(ans) + ctx.body = getTagContent(ans); }) .addTo(agent); diff --git a/src/agent/index.ts b/src/agent/index.ts index d76f576..13dcc29 100644 --- a/src/agent/index.ts +++ b/src/agent/index.ts @@ -8,5 +8,6 @@ import './fix/prompt.ts'; import './xhs.ts'; import './tools/kuaren.ts'; import './tools/call-xiaoxiao.ts'; +import './tools/summarize-note.ts'; export { agent }; diff --git a/src/agent/tools/summarize-note.ts b/src/agent/tools/summarize-note.ts new file mode 100644 index 0000000..a6c6ff5 --- /dev/null +++ b/src/agent/tools/summarize-note.ts @@ -0,0 +1,53 @@ +import { agent } from '../agent.ts'; +import { ai } from '../ai.ts'; + +agent + .route({ + path: 'tools', + key: 'summarize-note', + }) + .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. 250字以内。 +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/modules/config.ts b/src/modules/config.ts index 33055d4..ae4afbd 100644 --- a/src/modules/config.ts +++ b/src/modules/config.ts @@ -1,3 +1,5 @@ import { useConfig } from '@kevisual/use-config/env'; export const config = useConfig(); + +export const isDev = config.ENV === 'development'; diff --git a/src/task/routes/mention.ts b/src/task/routes/mention.ts index f9fa7c6..7734d9b 100644 --- a/src/task/routes/mention.ts +++ b/src/task/routes/mention.ts @@ -116,7 +116,9 @@ taskApp // 检测是这个用户的username的笔记,如果是的话,需要有at的用户信息才继续。 const isOwner = xhsServices.isOwner({ username: note_username, userid: note_userid }); + const isReplayAi = xhsServices.isReplayAi(data); const xsec_token = data.xsec_token; + console.log(data); const comment_id = data.comment.comment_id; let content: string = data.comment?.content || 'test'; const postData = { @@ -132,12 +134,29 @@ taskApp return; } } - content = content.replace('@' + note_username, ''); + content = content.replace('@' + note_username, ''); + const sliceContentCmd = content.slice(0, 20); + let note = ''; + let hasNote = false; + if (sliceContentCmd.includes('笔记') || sliceContentCmd.includes('总结')) { + const res = await xhsApp.call({ path: 'note', key: 'getNote', payload: { node_id: note_id, xsec_token } }); + if (res.code === 200) { + note = res.body?.desc || ''; + hasNote = note ? true : false; + } + } + if (isReplayAi) { + // 如果是对AI回复的评论,则不需要再回复 + console.log('不需要AI回复AI的评论', note_username, note_id, content); + return; + } const resAgent = await agent.call({ path: 'xhs', payload: { text: content, + note, + hasNote, }, }); let responseText = ''; diff --git a/src/task/task.ts b/src/task/task.ts index d4307d8..f8a1c07 100644 --- a/src/task/task.ts +++ b/src/task/task.ts @@ -7,7 +7,7 @@ import { app as xhsApp, xhsServices as xhs, xhsRootClient, XhsServices } from '@ import { nanoid } from 'nanoid'; export const XHS_GET_UNREAD = 'unread_count'; export const XHS_QUEUE_NAME = 'XHS_QUEUE'; -import { config } from '../modules/config.ts'; +import { config, isDev } from '../modules/config.ts'; const server: XhsServices = xhs; server.setCookie(config.XHS_ROOT_COOKIE || ''); @@ -15,7 +15,13 @@ server.setUserInfo({ userid: config.XHS_USER_ID || '', username: config.XHS_USER_NAME || '', }); +if (isDev) { + server.setSignConfig({ + signUrl: 'http://localhost:5006/sign', + }); +} console.log('XHS_USER_INFO', config.XHS_USER_ID, config.XHS_USER_NAME, 'XHS_ROOT_COOKIE', config.XHS_ROOT_COOKIE); +console.log('XHS_SIGN_URL', server.getSignConfig().signUrl); export const taskApp = new QueryRouterServer(); export { xhsApp }; export const xhsServices = server;