generated from tailored/router-template
temp
This commit is contained in:
parent
a412c09da0
commit
8891b196ba
@ -46,9 +46,10 @@
|
||||
"devDependencies": {
|
||||
"@kevisual/ai-center": "^0.0.3",
|
||||
"@kevisual/app-assistant": "workspace:*",
|
||||
"@kevisual/xhs": "workspace:*",
|
||||
"@kevisual/social-prompts": "workspace:*",
|
||||
"@kevisual/types": "^0.0.9",
|
||||
"@kevisual/use-config": "^1.0.12",
|
||||
"@kevisual/xhs": "workspace:*",
|
||||
"@types/bun": "^1.2.11",
|
||||
"@types/crypto-js": "^4.2.2",
|
||||
"@types/formidable": "^3.4.5",
|
||||
@ -58,6 +59,7 @@
|
||||
"commander": "^13.1.0",
|
||||
"concurrently": "^9.1.2",
|
||||
"cross-env": "^7.0.3",
|
||||
"dotenv": "^16.5.0",
|
||||
"inquire": "^0.4.8",
|
||||
"ioredis": "^5.6.1",
|
||||
"nodemon": "^3.1.10",
|
||||
|
14
packages/social-prompts/kevisual.json
Normal file
14
packages/social-prompts/kevisual.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"$vars": {
|
||||
"root": "https://kevisual.cn/root/ai"
|
||||
},
|
||||
"registry": {
|
||||
"root": "https://kevisual.cn/root/ai"
|
||||
},
|
||||
"match": {
|
||||
"./xhs/answer.ts": {
|
||||
"url": "${root}/xhs/answer.ts"
|
||||
},
|
||||
"./kevisual.json": {}
|
||||
}
|
||||
}
|
14
packages/social-prompts/package.json
Normal file
14
packages/social-prompts/package.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "@kevisual/social-prompts",
|
||||
"version": "0.0.1",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "abearxiong <xiongxiao@xiongxiao.me> (https://www.xiongxiao.me)",
|
||||
"license": "MIT",
|
||||
"packageManager": "pnpm@10.10.0",
|
||||
"type": "module"
|
||||
}
|
15
packages/social-prompts/tsconfig.json
Normal file
15
packages/social-prompts/tsconfig.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"extends": "@kevisual/types/json/backend.json",
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./",
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"src/*"
|
||||
]
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
"xhs/**/*.ts",
|
||||
],
|
||||
"exclude": [],
|
||||
}
|
34
packages/social-prompts/xhs/answer.ts
Normal file
34
packages/social-prompts/xhs/answer.ts
Normal file
@ -0,0 +1,34 @@
|
||||
export const answer = [
|
||||
{
|
||||
role: 'system',
|
||||
content: `你是一个小红书的内容回答问题的助手,用户提供一条笔记的信息,属于内容的上下文,和用户提供的问题,你需要给出一个简短的回答,回答要简洁明了,符合小红书的风格。
|
||||
要求:
|
||||
1. 不能包函链接,如果包函链接,把对应的链接的字符 "." 替换为魔法字符 "点",比如 https://www.baidu.com 替换为 https://www点baidu点com
|
||||
2. 言语中不能包函文档类型,比如md格式,只需要对应的文本的内容
|
||||
3. 只返回给我最后的结果,不需要思考过程
|
||||
|
||||
例子:
|
||||
笔记内容是:我有一个问题,我有一个网页的html的内容,不知道怎么打开
|
||||
用户:介绍一下怎么用vscode打开html网页
|
||||
|
||||
回答:
|
||||
首先打开vscode,然后把html文件拖到vscode中,就可以打开了,或者直接在vscode中打开html文件,点击右上角的预览按钮,就可以预览网页了。
|
||||
|
||||
现在可以开始了。
|
||||
`,
|
||||
},
|
||||
];
|
||||
|
||||
export const createQuestion = (question: string, note: string, answers: any[] = []) => {
|
||||
return [
|
||||
...answers,
|
||||
{
|
||||
role: 'assistant',
|
||||
content: `上下文的内参考的内容是: ${note}`,
|
||||
},
|
||||
{
|
||||
role: 'user',
|
||||
content: `用户: ${question}`,
|
||||
},
|
||||
];
|
||||
};
|
@ -344,7 +344,7 @@ class XhsClient {
|
||||
const state = stateMatch[1].replace(/undefined/g, '""');
|
||||
if (state !== '{}') {
|
||||
const noteDict = transformJsonKeys(JSON.parse(state));
|
||||
return noteDict.note.note_detail_map[noteId].note;
|
||||
return { code: 0, data: noteDict.note.note_detail_map[noteId].note };
|
||||
}
|
||||
}
|
||||
|
||||
@ -355,8 +355,12 @@ class XhsClient {
|
||||
throw new DataFetchError(html);
|
||||
} catch (error) {
|
||||
console.error('Error fetching note:', error);
|
||||
fs.writeFileSync('a.html', html);
|
||||
throw error;
|
||||
return {
|
||||
code: 500,
|
||||
msg: '请求失败',
|
||||
error: error.message,
|
||||
data: null,
|
||||
};
|
||||
}
|
||||
}
|
||||
/**
|
||||
|
68
packages/xhs/src/libs/modules/get-note.ts
Normal file
68
packages/xhs/src/libs/modules/get-note.ts
Normal file
@ -0,0 +1,68 @@
|
||||
import { XhsClient, Result } from '../xhs.ts';
|
||||
interface ImageInfo {
|
||||
image_scene: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
interface ImageItem {
|
||||
file_id: string;
|
||||
height: number;
|
||||
width: number;
|
||||
url: string;
|
||||
trace_id: string;
|
||||
url_pre: string;
|
||||
stream: Record<string, never>; // 空对象类型
|
||||
info_list: ImageInfo[];
|
||||
url_default: string;
|
||||
live_photo: boolean;
|
||||
}
|
||||
|
||||
interface AtUser {
|
||||
xsec_token: string;
|
||||
user_id: string;
|
||||
nickname: string;
|
||||
}
|
||||
|
||||
interface User {
|
||||
user_id: string;
|
||||
nickname: string;
|
||||
avatar: string;
|
||||
xsec_token: string;
|
||||
}
|
||||
|
||||
interface InteractInfo {
|
||||
collected_count: string;
|
||||
comment_count: string;
|
||||
share_count: string;
|
||||
followed: boolean;
|
||||
relation: string;
|
||||
liked: boolean;
|
||||
liked_count: string;
|
||||
collected: boolean;
|
||||
}
|
||||
|
||||
interface ShareInfo {
|
||||
un_share: boolean;
|
||||
}
|
||||
|
||||
interface NoteData {
|
||||
xsec_token: string;
|
||||
desc: string;
|
||||
user: User;
|
||||
interact_info: InteractInfo;
|
||||
tag_list: never[]; // 空数组类型
|
||||
at_user_list: AtUser[];
|
||||
ip_location: string;
|
||||
share_info: ShareInfo;
|
||||
note_id: string;
|
||||
type: string;
|
||||
title: string;
|
||||
image_list: ImageItem[];
|
||||
time: number;
|
||||
last_update_time: number;
|
||||
}
|
||||
export const getNote = async function (id: string, x: string) {
|
||||
const that = this as XhsClient;
|
||||
const res = await that.getNoteByIdFromHtml(id, x);
|
||||
return res as Result<NoteData>;
|
||||
};
|
@ -2,6 +2,7 @@ import { getApiInfo } from './xhs-api/api.ts';
|
||||
import { XhsClient as XhsClientBase } from '@kevisual/xhs-core';
|
||||
import { Mention, CommonentInfo, ResponseMession } from './xhs-type/mention.ts';
|
||||
import { pick } from 'lodash-es';
|
||||
import { getNote } from './modules/get-note.ts';
|
||||
export type Result<T> = {
|
||||
code: number; // 0: success
|
||||
msg?: string;
|
||||
@ -211,7 +212,8 @@ export class XhsClient extends XhsClientBase {
|
||||
|
||||
try {
|
||||
const response = await this.post(uri, data, { sign: this.sign.bind(this) });
|
||||
return response['items'][0]['node_card'];
|
||||
// return response['items'][0]['node_card'];
|
||||
return response;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
@ -221,7 +223,7 @@ export class XhsClient extends XhsClientBase {
|
||||
* @param comment
|
||||
* @returns
|
||||
*/
|
||||
async postComment(comment: { note_id: string; comment_id?: string; content: string; images_info?: any, images?: string[] }) {
|
||||
async postComment(comment: { note_id: string; comment_id?: string; content: string; images_info?: any; images?: string[] }) {
|
||||
const uri = '/api/sns/web/v1/comment/post';
|
||||
try {
|
||||
const data = {
|
||||
@ -249,6 +251,7 @@ export class XhsClient extends XhsClientBase {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
getNote = getNote;
|
||||
}
|
||||
|
||||
type UnreadCount = {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { xhsServices, program } from '../common.ts';
|
||||
|
||||
import util from 'node:util';
|
||||
|
||||
// client.getNoteComments()
|
||||
|
||||
@ -8,7 +8,7 @@ import { xhsServices, program } from '../common.ts';
|
||||
// });
|
||||
const getNoteById = async () => {
|
||||
const client = xhsServices.getClient();
|
||||
client.getNoteById('67dcc34e000000000602a8eb', 'ABuYS8Xb1o08DlRmMLIabdqnW0OKnLR9nMpDGq5bVRdvk').then((res) => {
|
||||
client.getNoteById('68136dab0000000007034c46', 'LByEmonX8WfJ9ebpAowVbOZX9Xh8T0Qkjil5KRFqDD6LM').then((res) => {
|
||||
console.log(res);
|
||||
});
|
||||
};
|
||||
@ -16,8 +16,8 @@ const getNote = async () => {
|
||||
const id = '68136dab0000000007034c46';
|
||||
const x = 'LByEmonX8WfJ9ebpAowVbOZX9Xh8T0Qkjil5KRFqDD6LM=';
|
||||
const client = xhsServices.getClient();
|
||||
client.getNoteByIdFromHtml(id, x).then((res) => {
|
||||
console.log(res);
|
||||
client.getNote(id, x).then((res) => {
|
||||
console.log(util.inspect(res, { depth: null }));
|
||||
});
|
||||
};
|
||||
program
|
||||
|
26
pnpm-lock.yaml
generated
26
pnpm-lock.yaml
generated
@ -10,13 +10,13 @@ importers:
|
||||
dependencies:
|
||||
'@kevisual/code-center-module':
|
||||
specifier: 0.0.18
|
||||
version: 0.0.18(@kevisual/auth@1.0.5)(@kevisual/router@0.0.13)(@kevisual/use-config@1.0.12(dotenv@16.5.0))(ioredis@5.6.1)(pg@8.15.6)(sequelize@6.37.7(pg@8.15.6))
|
||||
version: 0.0.18(@kevisual/auth@1.0.5)(@kevisual/router@0.0.13)(@kevisual/use-config@1.0.14(dotenv@16.5.0))(ioredis@5.6.1)(pg@8.15.6)(sequelize@6.37.7(pg@8.15.6))
|
||||
'@kevisual/router':
|
||||
specifier: 0.0.13
|
||||
version: 0.0.13
|
||||
'@kevisual/use-config':
|
||||
specifier: ^1.0.12
|
||||
version: 1.0.12(dotenv@16.5.0)
|
||||
version: 1.0.14(dotenv@16.5.0)
|
||||
cookie:
|
||||
specifier: ^1.0.2
|
||||
version: 1.0.2
|
||||
@ -39,6 +39,9 @@ importers:
|
||||
'@kevisual/app-assistant':
|
||||
specifier: workspace:*
|
||||
version: link:packages/app-assistant
|
||||
'@kevisual/social-prompts':
|
||||
specifier: workspace:*
|
||||
version: link:packages/social-prompts
|
||||
'@kevisual/types':
|
||||
specifier: ^0.0.9
|
||||
version: 0.0.9
|
||||
@ -72,6 +75,9 @@ importers:
|
||||
cross-env:
|
||||
specifier: ^7.0.3
|
||||
version: 7.0.3
|
||||
dotenv:
|
||||
specifier: ^16.5.0
|
||||
version: 16.5.0
|
||||
inquire:
|
||||
specifier: ^0.4.8
|
||||
version: 0.4.8
|
||||
@ -110,6 +116,8 @@ importers:
|
||||
specifier: ^5.51.1
|
||||
version: 5.51.1
|
||||
|
||||
packages/social-prompts: {}
|
||||
|
||||
packages/xhs:
|
||||
dependencies:
|
||||
'@kevisual/db':
|
||||
@ -236,11 +244,6 @@ packages:
|
||||
'@kevisual/types@0.0.9':
|
||||
resolution: {integrity: sha512-SDJ7GMbOx7Ghz2kreHqym56ccAJS3t93y+NS0+afTLxcq2+cKcoEy2F8WXEv0mnJ6EsDp5AbA7Jv5TZA1Jbc3A==}
|
||||
|
||||
'@kevisual/use-config@1.0.12':
|
||||
resolution: {integrity: sha512-PNoZqj6vdhv6DvjRMNwoGH9HJupm7QvjkvtCEYW2ryK7J8sI73r2ThCl4OEbXdRYVgl1EeK/e2IJh0Rf51bVwA==}
|
||||
peerDependencies:
|
||||
dotenv: ^16.4.7
|
||||
|
||||
'@kevisual/use-config@1.0.14':
|
||||
resolution: {integrity: sha512-U4fmPFJre+Ph+hdg+EKVaRGxdpD4T4ZoOz5QLEyC6o3ekg8NC4n1i7Myo1ektqATyoG9Y0q/bJdOhiJwnLEt4g==}
|
||||
peerDependencies:
|
||||
@ -2100,11 +2103,11 @@ snapshots:
|
||||
|
||||
'@kevisual/auth@1.0.5': {}
|
||||
|
||||
'@kevisual/code-center-module@0.0.18(@kevisual/auth@1.0.5)(@kevisual/router@0.0.13)(@kevisual/use-config@1.0.12(dotenv@16.5.0))(ioredis@5.6.1)(pg@8.15.6)(sequelize@6.37.7(pg@8.15.6))':
|
||||
'@kevisual/code-center-module@0.0.18(@kevisual/auth@1.0.5)(@kevisual/router@0.0.13)(@kevisual/use-config@1.0.14(dotenv@16.5.0))(ioredis@5.6.1)(pg@8.15.6)(sequelize@6.37.7(pg@8.15.6))':
|
||||
dependencies:
|
||||
'@kevisual/auth': 1.0.5
|
||||
'@kevisual/router': 0.0.13
|
||||
'@kevisual/use-config': 1.0.12(dotenv@16.5.0)
|
||||
'@kevisual/use-config': 1.0.14(dotenv@16.5.0)
|
||||
ioredis: 5.6.1
|
||||
nanoid: 5.1.5
|
||||
pg: 8.15.6
|
||||
@ -2136,11 +2139,6 @@ snapshots:
|
||||
|
||||
'@kevisual/types@0.0.9': {}
|
||||
|
||||
'@kevisual/use-config@1.0.12(dotenv@16.5.0)':
|
||||
dependencies:
|
||||
'@kevisual/load': 0.0.6
|
||||
dotenv: 16.5.0
|
||||
|
||||
'@kevisual/use-config@1.0.14(dotenv@16.5.0)':
|
||||
dependencies:
|
||||
'@kevisual/load': 0.0.6
|
||||
|
@ -19,7 +19,6 @@ taskApp
|
||||
if (res.code === 200) {
|
||||
const data = res.body;
|
||||
const unread_count = data.unread_count;
|
||||
console.log('unread_count====', data);
|
||||
if (unread_count > 0) {
|
||||
queue.add(
|
||||
'mention',
|
||||
@ -69,21 +68,26 @@ taskApp
|
||||
console.log('queryMention', util.inspect(data, { depth: 10 }));
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
const item = data[i];
|
||||
const note_id = item.note_id;
|
||||
const xsec_token = item.xsec_token;
|
||||
const comment_id = item.comment.comment_id;
|
||||
const content = item.comment?.content || 'test';
|
||||
const postData = {
|
||||
note_id,
|
||||
content,
|
||||
comment_id,
|
||||
};
|
||||
const res = await xhsApp.call({
|
||||
path: 'mention',
|
||||
key: 'addComment',
|
||||
payload: postData,
|
||||
});
|
||||
console.log('addComment', postData, 'res', res.body);
|
||||
queue.add(
|
||||
'mention-ai',
|
||||
{
|
||||
path: 'task',
|
||||
key: 'ai',
|
||||
payload: {
|
||||
data: item,
|
||||
},
|
||||
},
|
||||
{
|
||||
attempts: 3,
|
||||
delay: 0,
|
||||
removeOnComplete: true,
|
||||
removeOnFail: {
|
||||
age: 24 * 3600, // keep up to 24 hours
|
||||
},
|
||||
},
|
||||
);
|
||||
console.log('add mention task', item);
|
||||
await sleep(200);
|
||||
}
|
||||
}
|
||||
const postRead = await xhsApp.call({
|
||||
@ -98,3 +102,28 @@ taskApp
|
||||
};
|
||||
})
|
||||
.addTo(taskApp);
|
||||
|
||||
taskApp
|
||||
.route({
|
||||
path: 'task',
|
||||
key: 'ai',
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
const data = ctx.query.data;
|
||||
const note_id = data.note_id;
|
||||
const xsec_token = data.xsec_token;
|
||||
const comment_id = data.comment.comment_id;
|
||||
const content = data.comment?.content || 'test';
|
||||
const postData = {
|
||||
note_id,
|
||||
content,
|
||||
comment_id,
|
||||
};
|
||||
const res = await xhsApp.call({
|
||||
path: 'mention',
|
||||
key: 'addComment',
|
||||
payload: postData,
|
||||
});
|
||||
console.log('addComment', postData, 'res', res.body);
|
||||
})
|
||||
.addTo(taskApp);
|
||||
|
27
src/test/ai.ts
Normal file
27
src/test/ai.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import { ProviderManager, SiliconFlowProvider } from '@kevisual/ai-center';
|
||||
import dotenv from 'dotenv';
|
||||
import util from 'node:util';
|
||||
dotenv.config();
|
||||
import { createQuestion, answer } from '@kevisual/social-prompts/xhs/answer.ts';
|
||||
const pm = new SiliconFlowProvider({
|
||||
model: 'Qwen/Qwen3-32B',
|
||||
apiKey: process.env.SILICONFLOW_API_KEY,
|
||||
});
|
||||
|
||||
const main = async () => {
|
||||
const usage = await pm.getUsageInfo();
|
||||
console.log('usage', usage);
|
||||
};
|
||||
|
||||
// main();
|
||||
const ques = async () => {
|
||||
// const msg = createQuestion('介绍一下如何安装node,在mac当中', '前端的node如何安装环境', answer);
|
||||
const msg = createQuestion('介绍一下如何安装node,在mac当中', '前端的node如何安装环境', answer);
|
||||
console.log('msg', msg);
|
||||
const res = await pm.chat(msg);
|
||||
console.log(util.inspect(res.choices, { depth: null }));
|
||||
const ans = res.choices[0].message.content;
|
||||
console.log('ans', ans, ans.length);
|
||||
};
|
||||
|
||||
ques();
|
Loading…
x
Reference in New Issue
Block a user