feat: update package dependencies and add new routes for CNB environment management
- Updated package.json and pnpm-lock.yaml with new dependencies and versions. - Removed outdated readme files from requirements. - Enhanced CNB environment configuration in cnb-env.ts with new VS Code remote SSH settings. - Modified KnowledgeBase class to return structured results. - Updated Workspace class to return structured results. - Implemented new routes for managing CNB cookies and VS Code proxy URIs. - Added AI chat functionality for querying knowledge base. - Created skills for cleaning up closed workspaces.
This commit is contained in:
142
agent/routes/knowledge/ai.ts
Normal file
142
agent/routes/knowledge/ai.ts
Normal file
@@ -0,0 +1,142 @@
|
||||
import { createSkill, tool } from '@kevisual/router';
|
||||
import { app, cnb } from '../../app.ts';
|
||||
import { CNBChat } from '@kevisual/ai/browser'
|
||||
|
||||
/**
|
||||
|
||||
调用cnb-ai-chat技能, repo为kevisual/starred-auto.
|
||||
问题是:用户提供的问题是OpenListTeam/OpenList是什么,有多少star
|
||||
|
||||
*/
|
||||
app.route({
|
||||
path: 'cnb',
|
||||
key: 'cnb-ai-chat',
|
||||
description: '调用cnb的知识库ai对话功能进行聊天',
|
||||
middleware: ['auth'],
|
||||
metadata: {
|
||||
tags: ['opencode'],
|
||||
...createSkill({
|
||||
skill: 'cnb-ai-chat',
|
||||
title: '调用cnb的知识库ai对话功能进行聊天',
|
||||
summary: '调用cnb的知识库ai对话功能进行聊天,基于cnb提供的ai能力',
|
||||
args: {
|
||||
question: tool.schema.string().describe('用户输入的消息内容'),
|
||||
repo: tool.schema.string().optional().describe('知识库仓库ID,默认为空表示使用默认知识库'),
|
||||
}
|
||||
})
|
||||
}
|
||||
}).define(async (ctx) => {
|
||||
const question = ctx.query?.question;
|
||||
if (!question) {
|
||||
ctx.body = { content: '请提供有效的消息内容' };
|
||||
return;
|
||||
}
|
||||
let repo = ctx.query?.repo;
|
||||
if (!repo) {
|
||||
// 如果未指定知识库仓库ID,则使用默认知识库
|
||||
const res = await cnb.repo.getRepoList({ flags: 'KnowledgeBase' });
|
||||
if (res.code === 200 && res.data.length > 0) {
|
||||
repo = res.data[0].path;
|
||||
}
|
||||
}
|
||||
console.log("Using knowledge base repo:", repo);
|
||||
const ragRes = await cnb.knowledgeBase.queryKnowledgeBase(repo || '', {
|
||||
query: question,
|
||||
score_threshold: 0.62,
|
||||
top_k: 10,
|
||||
});
|
||||
if (ragRes.code !== 200) {
|
||||
ctx.body = { content: `查询知识库失败,错误信息:${ragRes.message}` };
|
||||
return;
|
||||
}
|
||||
const list = ragRes.data || [];
|
||||
// 构建RAG上下文,包含文件来源和相似度信息
|
||||
const ragContext = list.map((item, index) => {
|
||||
const source = item.metadata?.path || item.metadata?.name || '未知来源';
|
||||
const type = item.metadata?.type === 'code' ? '〔代码〕' : '〔文档〕';
|
||||
const scorePercent = Math.round((item.score || 0) * 100);
|
||||
const url = item.metadata?.url || '无';
|
||||
return `〔来源${index + 1}〕${type} ${source} (相似度: ${scorePercent}%)\n${item.chunk}\n访问地址: ${url}`;
|
||||
}).join('\n\n---\n\n');
|
||||
// hunyuan-a13b
|
||||
// enable_thinking
|
||||
const chat = new CNBChat({
|
||||
repo,
|
||||
token: cnb.token,
|
||||
model: 'hunyuan-a13b'
|
||||
});
|
||||
const messages = [
|
||||
{
|
||||
role: 'system',
|
||||
content: `[角色定义]='''\n你是一个专业的技术助手,擅长基于提供的知识库内容进行准确、有条理的分析和回答。你的特点是:\n1. 严格基于RAG检索到的上下文内容进行回答,不添加未经验证的信息\n2. 回答时清晰标注信息来源,便于用户追溯查证\n3. 面对不确定的信息,明确标注「根据提供的内容无法确定」\n4. 代码相关问题注重可执行性和最佳实践\n'''[要求]='''\n1. 严格遵循用户的提问要求,优先解决用户的核心问题\n2. 避免侵犯版权的内容,不复制原文超过100字(技术术语和函数名除外)\n3. 使用中文进行响应,语言专业且易于理解\n4. 如果上下文存在多个来源,优先使用相似度更高的内容\n5. 对于代码片段,确保完整且可直接使用\n6. 当上下文中没有相关信息时,直接说明「知识库中未找到相关内容」\n7. 在思考过程中分析:用户的真实意图是什么?提供的上下文是否足够回答?\n'''[回答格式]='''\n- 先简要说明回答的核心结论\n- 如有必要,分点阐述详细分析过程\n- 标注关键信息来源(标注【来源X】即可)\n- 提供可操作的建议或代码示例\n'''`
|
||||
},
|
||||
{
|
||||
role: 'user',
|
||||
content: `[上下文]='''\n${ragContext}\n'''\n\n[用户问题]='''\n${question}\n'''\n\n请基于以上上下文知识库内容回答用户问题。`
|
||||
}
|
||||
] as Array<{ role: 'system' | 'user' | 'assistant', content: string }>;
|
||||
const response = await chat.chat({
|
||||
messages
|
||||
});
|
||||
const txt = chat.responseText;
|
||||
ctx.body = { content: txt, response };
|
||||
}).addTo(app);
|
||||
|
||||
|
||||
// RAG知识库查询技能: 查询openlist有多少star
|
||||
app.route({
|
||||
path: 'cnb',
|
||||
key: 'cnb-rag-query',
|
||||
description: '调用cnb的知识库RAG查询功能进行问答',
|
||||
middleware: ['auth'],
|
||||
metadata: {
|
||||
tags: ['opencode'],
|
||||
...createSkill({
|
||||
skill: 'cnb-rag-query',
|
||||
title: '调用cnb的知识库RAG查询功能进行问答',
|
||||
summary: '调用cnb的知识库RAG查询功能进行问答,基于cnb提供的知识库能力',
|
||||
args: {
|
||||
question: tool.schema.string().describe('用户输入的消息内容'),
|
||||
repo: tool.schema.string().optional().describe('知识库仓库ID,默认为空表示使用默认知识库'),
|
||||
}
|
||||
})
|
||||
}
|
||||
}).define(async (ctx) => {
|
||||
const question = ctx.query?.question;
|
||||
if (!question) {
|
||||
ctx.body = { content: '请提供有效的消息内容' };
|
||||
return;
|
||||
}
|
||||
let repo = ctx.query?.repo;
|
||||
if (!repo) {
|
||||
// 如果未指定知识库仓库ID,则使用默认知识库
|
||||
const res = await cnb.repo.getRepoList({ flags: 'KnowledgeBase' });
|
||||
if (res.code === 200 && res.data.length > 0) {
|
||||
repo = res.data[0].path;
|
||||
}
|
||||
}
|
||||
console.log("Using knowledge base repo:", repo);
|
||||
const ragRes = await cnb.knowledgeBase.queryKnowledgeBase(repo || '', {
|
||||
query: question,
|
||||
score_threshold: 0.62,
|
||||
top_k: 10,
|
||||
});
|
||||
if (ragRes.code !== 200) {
|
||||
ctx.body = { content: `查询知识库失败,错误信息:${ragRes.message}` };
|
||||
return;
|
||||
}
|
||||
const list = ragRes.data || [];
|
||||
let answer = `基于知识库「${repo}」的查询结果:\n\n`;
|
||||
if (list.length === 0) {
|
||||
answer += '知识库中未找到相关内容。';
|
||||
} else {
|
||||
list.forEach((item, index) => {
|
||||
const source = item.metadata?.path || item.metadata?.name || '未知来源';
|
||||
const type = item.metadata?.type === 'code' ? '〔代码〕' : '〔文档〕';
|
||||
const scorePercent = Math.round((item.score || 0) * 100);
|
||||
const url = item.metadata?.url || '无';
|
||||
answer += `【来源${index + 1}】${type} ${source} (相似度: ${scorePercent}%)\n${item.chunk}\n访问地址: ${url}\n\n`;
|
||||
});
|
||||
}
|
||||
ctx.body = { content: answer };
|
||||
}).addTo(app);
|
||||
Reference in New Issue
Block a user