temp
This commit is contained in:
12
.cnb.yml
12
.cnb.yml
@@ -18,3 +18,15 @@ $:
|
|||||||
env: !reference [.common_env, env]
|
env: !reference [.common_env, env]
|
||||||
imports: !reference [.common_env, imports]
|
imports: !reference [.common_env, imports]
|
||||||
stages: !reference [.dev_template, stages]
|
stages: !reference [.dev_template, stages]
|
||||||
|
|
||||||
|
issue.comment@npc:
|
||||||
|
- docker:
|
||||||
|
image: docker.cnb.cool/kevisual/dev-env/bun:latest
|
||||||
|
services:
|
||||||
|
- docker
|
||||||
|
env: !reference [.common_env, env]
|
||||||
|
imports: !reference [.common_env, imports]
|
||||||
|
stages:
|
||||||
|
- name: "task"
|
||||||
|
script: |
|
||||||
|
bun run agent/npc.ts
|
||||||
@@ -35,9 +35,3 @@ export const notCNBCheck = (ctx: any) => {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const repo = useKey('CNB_REPO_SLUG_LOWERCASE') as string || 'kevision/kevision';
|
|
||||||
export const cnbAi = createOpenAICompatible({
|
|
||||||
baseURL: `https://api.cnb.cool/${repo}/-/ai/`,
|
|
||||||
name: 'custom-cnb',
|
|
||||||
apiKey: token,
|
|
||||||
});
|
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Result } from '@kevisual/query';
|
import { Result } from '@kevisual/query';
|
||||||
import { CNB } from '../../src/index.ts';
|
import { CNB } from '../../src/index.ts';
|
||||||
import { useKey } from '@kevisual/context';
|
import { useKey } from '@kevisual/context';
|
||||||
|
import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
|
||||||
export const getConfig = async (opts: { token?: string }) => {
|
export const getConfig = async (opts: { token?: string }) => {
|
||||||
const kevisualEnv = useKey('KEVISUAL_ENV')
|
const kevisualEnv = useKey('KEVISUAL_ENV')
|
||||||
const baseUrl = kevisualEnv === 'production' ? 'https://kevisual.cn/api/router' : 'https://kevisual.xiongxiao.me/api/router';
|
const baseUrl = kevisualEnv === 'production' ? 'https://kevisual.cn/api/router' : 'https://kevisual.xiongxiao.me/api/router';
|
||||||
@@ -32,7 +33,14 @@ type CNBItem = {
|
|||||||
runAt?: number
|
runAt?: number
|
||||||
owner?: boolean
|
owner?: boolean
|
||||||
cnb: CNB
|
cnb: CNB
|
||||||
|
cnbAi: ReturnType<typeof createOpenAICompatible>
|
||||||
}
|
}
|
||||||
|
// const repo = useKey('CNB_REPO_SLUG_LOWERCASE') as string || 'kevision/kevision';
|
||||||
|
// export const cnbAi = createOpenAICompatible({
|
||||||
|
// baseURL: `https://api.cnb.cool/${repo}/-/ai/`,
|
||||||
|
// name: 'custom-cnb',
|
||||||
|
// apiKey: token,
|
||||||
|
// });
|
||||||
export class CNBManager {
|
export class CNBManager {
|
||||||
cnbMap: Map<string, CNBItem> = new Map()
|
cnbMap: Map<string, CNBItem> = new Map()
|
||||||
constructor() {
|
constructor() {
|
||||||
@@ -71,20 +79,24 @@ export class CNBManager {
|
|||||||
* @returns CNB 实例
|
* @returns CNB 实例
|
||||||
*/
|
*/
|
||||||
async getContext(ctx: any) {
|
async getContext(ctx: any) {
|
||||||
|
const item = await this.getCNBItem(ctx)
|
||||||
|
return item.cnb
|
||||||
|
}
|
||||||
|
async getCNBItem(ctx: any) {
|
||||||
const tokenUser = ctx?.state?.tokenUser
|
const tokenUser = ctx?.state?.tokenUser
|
||||||
const username = tokenUser?.username
|
const username = tokenUser?.username
|
||||||
if (!username) {
|
if (!username) {
|
||||||
ctx.throw(403, 'Unauthorized')
|
ctx.throw(403, 'Unauthorized')
|
||||||
}
|
}
|
||||||
if (username === 'default') {
|
if (username === 'default') {
|
||||||
return this.getDefaultCNB().cnb
|
return this.getDefaultCNB()
|
||||||
}
|
}
|
||||||
const kevisualToken = ctx.query?.token;
|
const kevisualToken = ctx.query?.token;
|
||||||
const item = await this.getCNB({ username, kevisualToken });
|
const item = await this.getCNB({ username, kevisualToken });
|
||||||
if (!item) {
|
if (!item) {
|
||||||
ctx.throw(400, '不存在的 CNB 配置项,请检查 登录 Token 是否正确,或添加 CNB 配置')
|
ctx.throw(400, '不存在的 CNB 配置项,请检查 登录 Token 是否正确,或添加 CNB 配置')
|
||||||
}
|
}
|
||||||
return item.cnb
|
return item;
|
||||||
}
|
}
|
||||||
addCNB(opts: Partial<CNBItem>) {
|
addCNB(opts: Partial<CNBItem>) {
|
||||||
if (!opts.username || !opts.token) {
|
if (!opts.username || !opts.token) {
|
||||||
@@ -98,6 +110,12 @@ export class CNBManager {
|
|||||||
const cnb = opts?.cnb || new CNB({ token: opts.token, cookie: opts.cookie });
|
const cnb = opts?.cnb || new CNB({ token: opts.token, cookie: opts.cookie });
|
||||||
opts.cnb = cnb;
|
opts.cnb = cnb;
|
||||||
opts.runAt = Date.now()
|
opts.runAt = Date.now()
|
||||||
|
const repoSlug = useKey('CNB_REPO_SLUG_LOWERCASE') as string || 'kevision/kevision';
|
||||||
|
opts.cnbAi = createOpenAICompatible({
|
||||||
|
baseURL: `https://api.cnb.cool/${repoSlug}/-/ai/`,
|
||||||
|
name: `custom-cnb-${opts.username}`,
|
||||||
|
apiKey: opts.token,
|
||||||
|
})
|
||||||
this.cnbMap.set(opts.username, opts as CNBItem)
|
this.cnbMap.set(opts.username, opts as CNBItem)
|
||||||
return opts as CNBItem
|
return opts as CNBItem
|
||||||
}
|
}
|
||||||
|
|||||||
3
agent/npc.ts
Normal file
3
agent/npc.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import { app } from './index.ts';
|
||||||
|
|
||||||
|
import { getN } from '../src/index.ts'
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { runAgent } from '@kevisual/ai/agent'
|
import { runAgent } from '@kevisual/ai/agent'
|
||||||
import { app, notCNBCheck, cnbAi } from '../../app.ts';
|
import { app, notCNBCheck, cnbManager, cnb } from '../../app.ts';
|
||||||
import z from 'zod';
|
import z from 'zod';
|
||||||
|
|
||||||
app.route({
|
app.route({
|
||||||
@@ -13,7 +13,8 @@ app.route({
|
|||||||
messages: z.array(z.object({
|
messages: z.array(z.object({
|
||||||
role: z.enum(['user', 'assistant']).describe('消息角色,user表示用户输入,assistant表示助手回复'),
|
role: z.enum(['user', 'assistant']).describe('消息角色,user表示用户输入,assistant表示助手回复'),
|
||||||
content: z.string().describe('消息内容')
|
content: z.string().describe('消息内容')
|
||||||
})).describe('对话消息列表,按照时间顺序排列,包含用户和助手的历史消息')
|
})).describe('对话消息列表,按照时间顺序排列,包含用户和助手的历史消息'),
|
||||||
|
model: z.string().optional().describe('默认auto')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).define(async (ctx) => {
|
}).define(async (ctx) => {
|
||||||
@@ -22,6 +23,9 @@ app.route({
|
|||||||
ctx.throw(400, '缺少必要参数,必须提供question或messages');
|
ctx.throw(400, '缺少必要参数,必须提供question或messages');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const model = ctx.args?.model || 'auto'
|
||||||
|
const item = await cnbManager.getCNBItem(ctx);
|
||||||
|
const cnbAi = item.cnbAi;
|
||||||
const messages = ctx.args.messages || [{
|
const messages = ctx.args.messages || [{
|
||||||
role: 'user',
|
role: 'user',
|
||||||
content: ctx.args.question
|
content: ctx.args.question
|
||||||
@@ -29,8 +33,9 @@ app.route({
|
|||||||
const result = await runAgent({
|
const result = await runAgent({
|
||||||
app,
|
app,
|
||||||
messages: messages,
|
messages: messages,
|
||||||
languageModel: cnbAi('auto'),
|
languageModel: cnbAi(model),
|
||||||
token: ctx.query?.token as string,
|
token: '',
|
||||||
|
// token: ctx.query.token as string,
|
||||||
});
|
});
|
||||||
ctx.body = result;
|
ctx.body = result;
|
||||||
}).addTo(app);
|
}).addTo(app);
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "bun bun.config.ts",
|
"build": "bun bun.config.ts",
|
||||||
"flow": "ev npm patch && pnpm build && ev npm publish npm -p",
|
"flow": "ev npm patch && pnpm build && ev npm publish npm -p",
|
||||||
|
"compile": "bun build --compile --minify agent/commander.ts --outfile=./dist/cnb ",
|
||||||
"pub": "ev pack -u -m false -c -p"
|
"pub": "ev pack -u -m false -c -p"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
|
|||||||
Reference in New Issue
Block a user