116 lines
3.8 KiB
TypeScript
116 lines
3.8 KiB
TypeScript
import { app } from './index.ts';
|
||
import { parse } from '@kevisual/router/src/commander.ts';
|
||
|
||
import { useIssueEnv, useCommentEnv, useRepoInfoEnv, IssueLabel } from '../src/index.ts'
|
||
import { pick } from 'es-toolkit';
|
||
import z from 'zod';
|
||
|
||
const writeToProcess = (message: string) => {
|
||
if (process.send) {
|
||
process.send(message);
|
||
} else {
|
||
console.log(message);
|
||
}
|
||
}
|
||
const getIssuesLabels = async () => {
|
||
const issueEnv = useIssueEnv();
|
||
const repoInfoEnv = useRepoInfoEnv();
|
||
const issueId = issueEnv.issueId;
|
||
const repoSlug = repoInfoEnv.repoSlug;
|
||
if (!issueId || !repoSlug) {
|
||
return [];
|
||
}
|
||
const res = await app.run({
|
||
path: 'cnb',
|
||
key: 'getIssue',
|
||
payload: {
|
||
repo: repoSlug,
|
||
issueNumber: issueId
|
||
}
|
||
});
|
||
if (res.code === 200) {
|
||
const issueData = res.data as any;
|
||
const labels = issueData.labels || [];
|
||
return labels as IssueLabel[];
|
||
}
|
||
console.error('获取 Issue 详情失败', res);
|
||
return []
|
||
|
||
}
|
||
|
||
const main = async ({ exit }: { exit: (code: number) => void }) => {
|
||
const repoInfoEnv = useRepoInfoEnv();
|
||
const commentEnv = useCommentEnv();
|
||
const issueEnv = useIssueEnv();
|
||
const pickCommentEnv = pick(commentEnv, ['commentId', 'commentIdLabel']);
|
||
const pickIssueEnv = pick(issueEnv, ['issueId', 'issueIdLabel', 'issueIid', 'issueIidLabel', 'issueTitle', 'issueTitleLabel', 'issueDescription', 'issueDescriptionLabel']);
|
||
const pickRepoInfoEnv = pick(repoInfoEnv, ['repoId', 'repoIdLabel', 'repoName', 'repoNameLabel', 'repoSlug', 'repoSlugLabel']);
|
||
// const issueLabels = issueEnv.issueLabels || [];
|
||
const isComment = !!commentEnv.commentId;
|
||
const envList = [
|
||
...Object.entries(pickRepoInfoEnv).map(([key, value]) => `${key}: ${value}`),
|
||
...Object.entries(issueEnv).map(([key, value]) => `${key}: ${value}`),
|
||
...Object.entries(pickCommentEnv).map(([key, value]) => `${key}: ${value}`),
|
||
]
|
||
writeToProcess('当前环境变量:');
|
||
const issueLabels = await getIssuesLabels();
|
||
const issueLabelsNames = issueLabels.map(label => label.name) || [];
|
||
envList.forEach(item => writeToProcess(item));
|
||
if (!isComment && !issueLabelsNames.includes('Run')) {
|
||
writeToProcess('当前 Issue 不包含 Run 标签,跳过执行');
|
||
return exit(0);
|
||
}
|
||
const messages = [
|
||
{
|
||
role: 'system',
|
||
content: `你是一个智能的代码助手, 根据用户提供的上下文信息,提供有用的建议和帮助, 如果用户的要求和执行工具不一致,请说出你不能这么做。并把最后的结果提交一个评论到对应的issue中,提交的内容必须不能包含 @ 提及。用户提供的上下文信息如下:`
|
||
},
|
||
{
|
||
role: 'system',
|
||
content: `相关变量:${JSON.stringify({ ...pickCommentEnv, ...pickIssueEnv, ...pickRepoInfoEnv })}`
|
||
}, {
|
||
role: 'user',
|
||
content: commentEnv.commentBody || pickIssueEnv.issueDescription || '无'
|
||
}
|
||
]
|
||
writeToProcess('输入消息:');
|
||
writeToProcess(JSON.stringify(messages, null, 2));
|
||
const result = await app.run({
|
||
path: 'cnb',
|
||
key: 'chat',
|
||
payload: {
|
||
messages
|
||
}
|
||
}, { appId: app.appId })
|
||
if (result.code === 200) {
|
||
let _message = result.data.message || []
|
||
writeToProcess('执行完成')
|
||
writeToProcess(JSON.stringify(_message, null, 2))
|
||
exit(0);
|
||
} else {
|
||
writeToProcess(result.message || '执行错误')
|
||
exit(1);
|
||
}
|
||
}
|
||
|
||
app.route({
|
||
path: 'cnb',
|
||
key: 'npc',
|
||
description: 'CNB智能助手,提供智能建议和帮助, 程序入口',
|
||
metadata: {
|
||
tags: ['notInNpcAgent'],
|
||
args: {
|
||
needExit: z.boolean().optional().describe('是否需要在执行完成后退出进程')
|
||
}
|
||
}
|
||
}).define(async (ctx) => {
|
||
const exit = (code: number) => {
|
||
if (ctx.args.needExit) {
|
||
process.exit(code);
|
||
}
|
||
}
|
||
await main({ exit });
|
||
}).addTo(app)
|
||
|
||
parse({ app: app, description: 'CNB控制台命令行工具', parse: true })
|