feat: add neo4j
This commit is contained in:
parent
4cbc72def7
commit
25c055b490
14
package.json
14
package.json
@ -31,11 +31,12 @@
|
||||
],
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@abearxiong/router": "0.0.1-alpha.33",
|
||||
"@abearxiong/router": "0.0.1-alpha.34",
|
||||
"@abearxiong/use-config": "^0.0.2",
|
||||
"@babel/core": "^7.25.2",
|
||||
"@babel/preset-env": "^7.25.4",
|
||||
"@babel/preset-typescript": "^7.24.7",
|
||||
"@kevisual/ai-graph": "workspace:^",
|
||||
"@types/semver": "^7.5.8",
|
||||
"dayjs": "^1.11.13",
|
||||
"dts-bundle-generator": "^9.5.1",
|
||||
@ -45,6 +46,9 @@
|
||||
"lodash-es": "^4.17.21",
|
||||
"minio": "^8.0.1",
|
||||
"nanoid": "^5.0.7",
|
||||
"neo4j-driver": "^5.24.1",
|
||||
"neode": "^0.4.9",
|
||||
"ollama": "^0.5.9",
|
||||
"pg": "^8.13.0",
|
||||
"semver": "^7.6.3",
|
||||
"sequelize": "^6.37.3",
|
||||
@ -58,9 +62,10 @@
|
||||
"@types/jest": "^29.5.13",
|
||||
"@types/jsonwebtoken": "^9.0.7",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/node": "^22.5.5",
|
||||
"@types/node": "^22.6.1",
|
||||
"@types/superagent": "^8.1.9",
|
||||
"@types/supertest": "^6.0.2",
|
||||
"@types/uuid": "^10.0.0",
|
||||
"@types/webpack-env": "^1.18.5",
|
||||
"concurrently": "^9.0.1",
|
||||
"copy-webpack-plugin": "^12.0.2",
|
||||
@ -79,5 +84,10 @@
|
||||
"webpack-cli": "^5.1.4",
|
||||
"webpack-node-externals": "^3.0.0"
|
||||
},
|
||||
"resolutions": {
|
||||
"glob": "latest",
|
||||
"inflight": "latest",
|
||||
"rimraf": "latest"
|
||||
},
|
||||
"pnpm": {}
|
||||
}
|
@ -1 +1 @@
|
||||
Subproject commit 492d1b0e7ccfce266caa5ea38d6cc8162e4ef11f
|
||||
Subproject commit d1e2306233fde79b510dec614a95f867d686243d
|
455
pnpm-lock.yaml
generated
455
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
2
pnpm-workspace.yaml
Normal file
2
pnpm-workspace.yaml
Normal file
@ -0,0 +1,2 @@
|
||||
packages:
|
||||
- 'packages/*'
|
@ -64,7 +64,11 @@ export const loadOne = async (item: RouterCodeModel) => {
|
||||
}
|
||||
};
|
||||
export const load = async function () {
|
||||
const codes = await RouterCodeModel.findAll();
|
||||
const codes = await RouterCodeModel.findAll({
|
||||
logging: (sql, timing) => {
|
||||
console.log('manager load database router codeModel');
|
||||
},
|
||||
});
|
||||
const codeManager: CodeManager[] = codes.map((item) => {
|
||||
const { path, key, id, code, exec, project, active, middleware } = item.toJSON();
|
||||
if (!active) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
// admin router manger
|
||||
|
||||
import { Route } from '@abearxiong/router';
|
||||
import { CustomError, Route } from '@abearxiong/router';
|
||||
import { router } from '../modules/router.ts';
|
||||
import { manager, updateNewCode, removeCode, stopCode, startCode } from './dashboard/manager.ts';
|
||||
import { loadOne } from './dashboard/load.ts';
|
||||
@ -143,9 +143,8 @@ updateRouter.run = async (ctx) => {
|
||||
await newCodeRouter.save();
|
||||
codeRouter = newCodeRouter;
|
||||
} catch (e) {
|
||||
ctx.body = e.message.toString();
|
||||
ctx.code = 500;
|
||||
return ctx;
|
||||
console.error('updateRouter', e);
|
||||
throw new CustomError(e.message.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,15 @@
|
||||
import { App } from '@abearxiong/router';
|
||||
import { useConfig } from '@abearxiong/use-config';
|
||||
import { dynamicImport } from './lib/dynamic-import.ts';
|
||||
import { redisPublisher, redisSubscriber } from './modules/redis.ts';
|
||||
|
||||
import { redisPublisher, redisSubscriber, redis } from './modules/redis.ts';
|
||||
import { neode } from './modules/neo4j.ts';
|
||||
import { minioClient } from './modules/minio.ts';
|
||||
import { sequelize } from './modules/sequelize.ts';
|
||||
useConfig();
|
||||
export const emit = (channel: string, message?: any) => {
|
||||
redisPublisher.publish(channel, JSON.stringify(message));
|
||||
};
|
||||
export { neode, redis, minioClient, sequelize };
|
||||
|
||||
export const app = new App<{ import: any; emit: typeof emit }>({
|
||||
serverOptions: {
|
||||
|
@ -41,7 +41,7 @@ RouterCodeModel.init(
|
||||
type: DataTypes.UUID,
|
||||
primaryKey: true,
|
||||
defaultValue: DataTypes.UUIDV4,
|
||||
comment: '用户id',
|
||||
comment: '用户code id',
|
||||
},
|
||||
path: {
|
||||
type: DataTypes.STRING,
|
||||
@ -60,11 +60,11 @@ RouterCodeModel.init(
|
||||
defaultValue: 'default',
|
||||
},
|
||||
code: {
|
||||
type: DataTypes.STRING,
|
||||
type: DataTypes.TEXT,
|
||||
defaultValue: '',
|
||||
},
|
||||
exec: {
|
||||
type: DataTypes.STRING, // 对代码进行编译后的代码
|
||||
type: DataTypes.TEXT, // 对代码进行编译后的代码
|
||||
defaultValue: '',
|
||||
},
|
||||
type: {
|
||||
@ -93,5 +93,7 @@ RouterCodeModel.init(
|
||||
tableName: 'cf_router_code',
|
||||
},
|
||||
);
|
||||
// RouterCodeModel.sync({ alter: true });
|
||||
RouterCodeModel.sync({ alter: true, logging: false }).catch((e) => {
|
||||
console.error('RouterCodeModel sync', e);
|
||||
});
|
||||
// RouterCodeModel.sync({force: true});
|
||||
|
18
src/models/prompt.ts
Normal file
18
src/models/prompt.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { neode } from '@/app.ts';
|
||||
|
||||
export const PromptNeo = neode.model('Prompt', {
|
||||
id: {
|
||||
type: 'uuid',
|
||||
primary: true,
|
||||
},
|
||||
title: {
|
||||
type: 'string',
|
||||
},
|
||||
description: 'string',
|
||||
// profile: { type: 'object', optional: true }, // 用于存储 JSON 对象
|
||||
prompt: 'string',
|
||||
// inputVariables: { type: 'array', item },
|
||||
// tags: { type: 'array', items: 'string', optional: true } // 定义字符串数组
|
||||
inputVariables: { type: 'string', default: JSON.stringify([]) },
|
||||
localVariables: { type: 'string', default: JSON.stringify([]) },
|
||||
});
|
29
src/modules/neo4j.ts
Normal file
29
src/modules/neo4j.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import Neode from 'neode';
|
||||
import { useConfig } from '@abearxiong/use-config';
|
||||
|
||||
type NeodeConfig = {
|
||||
uri: string;
|
||||
username: string;
|
||||
password: string;
|
||||
};
|
||||
const { neo4j } = useConfig<{ neo4j: NeodeConfig }>('neo4j');
|
||||
|
||||
const { uri, username, password } = neo4j;
|
||||
// 设置连接配置
|
||||
// const neode = new Neode('bolt://localhost:7687', 'neo4j', 'your_password');
|
||||
export const neode = new Neode(uri, username, password);
|
||||
|
||||
const testConnect = async () => {
|
||||
// 连接成功
|
||||
// 尝试执行简单的 Cypher 查询以测试连接
|
||||
neode
|
||||
.cypher('RETURN 1', {})
|
||||
.then(() => {
|
||||
console.log('connect neo4j success');
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('Failed to connect:', err);
|
||||
});
|
||||
};
|
||||
|
||||
testConnect();
|
30
src/modules/ollama.ts
Normal file
30
src/modules/ollama.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import { useConfig } from '@abearxiong/use-config';
|
||||
import { Ollama, Message, ChatRequest } from 'ollama';
|
||||
|
||||
const config = useConfig<{ ollama: Ollama['config'] & { model: string } }>();
|
||||
|
||||
const { host } = config.ollama;
|
||||
|
||||
export const ollama = new Ollama({ host });
|
||||
|
||||
export type ChatMessage = {
|
||||
content: string;
|
||||
} & Message;
|
||||
|
||||
type ChatOpts = {
|
||||
model?: string;
|
||||
messages?: ChatMessage[];
|
||||
options?: ChatRequest['options'];
|
||||
} & ChatRequest;
|
||||
export const chat = (messages: ChatMessage[], chatOpts?: ChatOpts) => {
|
||||
const { options, stream, ...rest } = chatOpts || {};
|
||||
return ollama.chat({
|
||||
messages,
|
||||
model: config.model,
|
||||
options: {
|
||||
temperature: 0,
|
||||
...chatOpts?.options,
|
||||
},
|
||||
...rest,
|
||||
});
|
||||
};
|
@ -5,7 +5,7 @@ const config = useConfig<{
|
||||
redis: ConstructorParameters<typeof Redis>;
|
||||
}>();
|
||||
// 配置 Redis 连接
|
||||
const redis = new Redis({
|
||||
export const redis = new Redis({
|
||||
host: 'localhost', // Redis 服务器的主机名或 IP 地址
|
||||
port: 6379, // Redis 服务器的端口号
|
||||
// password: 'your_password', // Redis 的密码 (如果有)
|
||||
|
@ -26,10 +26,6 @@ export class ContainerModel extends Model {
|
||||
declare data: ContainerData;
|
||||
declare publish: ContainerPublish;
|
||||
declare uid: string;
|
||||
|
||||
// timestamps
|
||||
public readonly createdAt!: Date;
|
||||
public readonly updatedAt!: Date;
|
||||
}
|
||||
ContainerModel.init(
|
||||
{
|
||||
|
@ -3,3 +3,5 @@ import './container/index.ts';
|
||||
import './page/index.ts';
|
||||
|
||||
import './resource/index.ts';
|
||||
|
||||
import './prompt-graph/index.ts';
|
1
src/routes/prompt-graph/index.ts
Normal file
1
src/routes/prompt-graph/index.ts
Normal file
@ -0,0 +1 @@
|
||||
import './list.ts'
|
76
src/routes/prompt-graph/list.ts
Normal file
76
src/routes/prompt-graph/list.ts
Normal file
@ -0,0 +1,76 @@
|
||||
import { PromptNeo } from '@/models/prompt.ts';
|
||||
import { app } from '@/app.ts';
|
||||
import { v4 } from 'uuid';
|
||||
app
|
||||
.route('prompt', 'list')
|
||||
.define(async (ctx) => {
|
||||
const prompts = await PromptNeo.all();
|
||||
const json = await prompts.toJson();
|
||||
console.log('json', json);
|
||||
ctx.body = json;
|
||||
})
|
||||
.addTo(app);
|
||||
|
||||
app
|
||||
.route('prompt', 'update')
|
||||
.define(async (ctx) => {
|
||||
const { id, title, description, prompt, inputVariables, localVariables } = ctx.query;
|
||||
const promptNode = await PromptNeo.first('id', id);
|
||||
|
||||
if (!promptNode) {
|
||||
const promptData = {
|
||||
id: v4(),
|
||||
title,
|
||||
description,
|
||||
prompt,
|
||||
inputVariables: JSON.stringify(inputVariables),
|
||||
localVariables: JSON.stringify(localVariables),
|
||||
};
|
||||
const _prompt = await PromptNeo.create(promptData);
|
||||
ctx.body = await _prompt.toJson();
|
||||
return;
|
||||
}
|
||||
|
||||
await promptNode.update({ title, description, prompt, inputVariables, localVariables });
|
||||
ctx.body = await promptNode.toJson();
|
||||
})
|
||||
.addTo(app);
|
||||
|
||||
app
|
||||
.route('prompt', 'delete')
|
||||
.define(async (ctx) => {
|
||||
const { id, title } = ctx.query;
|
||||
const promptNode = await PromptNeo.first('id', id);
|
||||
if (!promptNode) {
|
||||
ctx.body = 'prompt not found';
|
||||
return;
|
||||
}
|
||||
await promptNode.delete();
|
||||
ctx.body = 'delete success';
|
||||
})
|
||||
.addTo(app);
|
||||
app
|
||||
.route('prompt', 'deleteAll')
|
||||
.define(async (ctx) => {
|
||||
const prompts = await PromptNeo.all();
|
||||
for (const prompt of prompts) {
|
||||
await prompt.delete();
|
||||
}
|
||||
ctx.body = 'delete all success';
|
||||
})
|
||||
.addTo(app);
|
||||
app
|
||||
.route('prompt', 'createDemo')
|
||||
.define(async (ctx) => {
|
||||
const promptData = {
|
||||
id: v4(),
|
||||
title: 'test',
|
||||
description: '这是测试保存prompt的数据',
|
||||
prompt: '这是测试保存prompt的数据',
|
||||
inputVariables: JSON.stringify([{ key: 'test', value: 'test' }]),
|
||||
localVariables: JSON.stringify([{ key: 'test', value: 'test' }]),
|
||||
};
|
||||
const prompt = await PromptNeo.create(promptData);
|
||||
ctx.body = await prompt.toJson();
|
||||
})
|
||||
.addTo(app);
|
Loading…
x
Reference in New Issue
Block a user