feat: add neo4j
This commit is contained in:
parent
4cbc72def7
commit
25c055b490
14
package.json
14
package.json
@ -31,11 +31,12 @@
|
|||||||
],
|
],
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@abearxiong/router": "0.0.1-alpha.33",
|
"@abearxiong/router": "0.0.1-alpha.34",
|
||||||
"@abearxiong/use-config": "^0.0.2",
|
"@abearxiong/use-config": "^0.0.2",
|
||||||
"@babel/core": "^7.25.2",
|
"@babel/core": "^7.25.2",
|
||||||
"@babel/preset-env": "^7.25.4",
|
"@babel/preset-env": "^7.25.4",
|
||||||
"@babel/preset-typescript": "^7.24.7",
|
"@babel/preset-typescript": "^7.24.7",
|
||||||
|
"@kevisual/ai-graph": "workspace:^",
|
||||||
"@types/semver": "^7.5.8",
|
"@types/semver": "^7.5.8",
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.13",
|
||||||
"dts-bundle-generator": "^9.5.1",
|
"dts-bundle-generator": "^9.5.1",
|
||||||
@ -45,6 +46,9 @@
|
|||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"minio": "^8.0.1",
|
"minio": "^8.0.1",
|
||||||
"nanoid": "^5.0.7",
|
"nanoid": "^5.0.7",
|
||||||
|
"neo4j-driver": "^5.24.1",
|
||||||
|
"neode": "^0.4.9",
|
||||||
|
"ollama": "^0.5.9",
|
||||||
"pg": "^8.13.0",
|
"pg": "^8.13.0",
|
||||||
"semver": "^7.6.3",
|
"semver": "^7.6.3",
|
||||||
"sequelize": "^6.37.3",
|
"sequelize": "^6.37.3",
|
||||||
@ -58,9 +62,10 @@
|
|||||||
"@types/jest": "^29.5.13",
|
"@types/jest": "^29.5.13",
|
||||||
"@types/jsonwebtoken": "^9.0.7",
|
"@types/jsonwebtoken": "^9.0.7",
|
||||||
"@types/lodash-es": "^4.17.12",
|
"@types/lodash-es": "^4.17.12",
|
||||||
"@types/node": "^22.5.5",
|
"@types/node": "^22.6.1",
|
||||||
"@types/superagent": "^8.1.9",
|
"@types/superagent": "^8.1.9",
|
||||||
"@types/supertest": "^6.0.2",
|
"@types/supertest": "^6.0.2",
|
||||||
|
"@types/uuid": "^10.0.0",
|
||||||
"@types/webpack-env": "^1.18.5",
|
"@types/webpack-env": "^1.18.5",
|
||||||
"concurrently": "^9.0.1",
|
"concurrently": "^9.0.1",
|
||||||
"copy-webpack-plugin": "^12.0.2",
|
"copy-webpack-plugin": "^12.0.2",
|
||||||
@ -79,5 +84,10 @@
|
|||||||
"webpack-cli": "^5.1.4",
|
"webpack-cli": "^5.1.4",
|
||||||
"webpack-node-externals": "^3.0.0"
|
"webpack-node-externals": "^3.0.0"
|
||||||
},
|
},
|
||||||
|
"resolutions": {
|
||||||
|
"glob": "latest",
|
||||||
|
"inflight": "latest",
|
||||||
|
"rimraf": "latest"
|
||||||
|
},
|
||||||
"pnpm": {}
|
"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 () {
|
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 codeManager: CodeManager[] = codes.map((item) => {
|
||||||
const { path, key, id, code, exec, project, active, middleware } = item.toJSON();
|
const { path, key, id, code, exec, project, active, middleware } = item.toJSON();
|
||||||
if (!active) {
|
if (!active) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// admin router manger
|
// admin router manger
|
||||||
|
|
||||||
import { Route } from '@abearxiong/router';
|
import { CustomError, Route } from '@abearxiong/router';
|
||||||
import { router } from '../modules/router.ts';
|
import { router } from '../modules/router.ts';
|
||||||
import { manager, updateNewCode, removeCode, stopCode, startCode } from './dashboard/manager.ts';
|
import { manager, updateNewCode, removeCode, stopCode, startCode } from './dashboard/manager.ts';
|
||||||
import { loadOne } from './dashboard/load.ts';
|
import { loadOne } from './dashboard/load.ts';
|
||||||
@ -143,9 +143,8 @@ updateRouter.run = async (ctx) => {
|
|||||||
await newCodeRouter.save();
|
await newCodeRouter.save();
|
||||||
codeRouter = newCodeRouter;
|
codeRouter = newCodeRouter;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
ctx.body = e.message.toString();
|
console.error('updateRouter', e);
|
||||||
ctx.code = 500;
|
throw new CustomError(e.message.toString());
|
||||||
return ctx;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
import { App } from '@abearxiong/router';
|
import { App } from '@abearxiong/router';
|
||||||
import { useConfig } from '@abearxiong/use-config';
|
import { useConfig } from '@abearxiong/use-config';
|
||||||
import { dynamicImport } from './lib/dynamic-import.ts';
|
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();
|
useConfig();
|
||||||
export const emit = (channel: string, message?: any) => {
|
export const emit = (channel: string, message?: any) => {
|
||||||
redisPublisher.publish(channel, JSON.stringify(message));
|
redisPublisher.publish(channel, JSON.stringify(message));
|
||||||
};
|
};
|
||||||
|
export { neode, redis, minioClient, sequelize };
|
||||||
|
|
||||||
export const app = new App<{ import: any; emit: typeof emit }>({
|
export const app = new App<{ import: any; emit: typeof emit }>({
|
||||||
serverOptions: {
|
serverOptions: {
|
||||||
|
@ -41,7 +41,7 @@ RouterCodeModel.init(
|
|||||||
type: DataTypes.UUID,
|
type: DataTypes.UUID,
|
||||||
primaryKey: true,
|
primaryKey: true,
|
||||||
defaultValue: DataTypes.UUIDV4,
|
defaultValue: DataTypes.UUIDV4,
|
||||||
comment: '用户id',
|
comment: '用户code id',
|
||||||
},
|
},
|
||||||
path: {
|
path: {
|
||||||
type: DataTypes.STRING,
|
type: DataTypes.STRING,
|
||||||
@ -60,11 +60,11 @@ RouterCodeModel.init(
|
|||||||
defaultValue: 'default',
|
defaultValue: 'default',
|
||||||
},
|
},
|
||||||
code: {
|
code: {
|
||||||
type: DataTypes.STRING,
|
type: DataTypes.TEXT,
|
||||||
defaultValue: '',
|
defaultValue: '',
|
||||||
},
|
},
|
||||||
exec: {
|
exec: {
|
||||||
type: DataTypes.STRING, // 对代码进行编译后的代码
|
type: DataTypes.TEXT, // 对代码进行编译后的代码
|
||||||
defaultValue: '',
|
defaultValue: '',
|
||||||
},
|
},
|
||||||
type: {
|
type: {
|
||||||
@ -93,5 +93,7 @@ RouterCodeModel.init(
|
|||||||
tableName: 'cf_router_code',
|
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});
|
// 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: ConstructorParameters<typeof Redis>;
|
||||||
}>();
|
}>();
|
||||||
// 配置 Redis 连接
|
// 配置 Redis 连接
|
||||||
const redis = new Redis({
|
export const redis = new Redis({
|
||||||
host: 'localhost', // Redis 服务器的主机名或 IP 地址
|
host: 'localhost', // Redis 服务器的主机名或 IP 地址
|
||||||
port: 6379, // Redis 服务器的端口号
|
port: 6379, // Redis 服务器的端口号
|
||||||
// password: 'your_password', // Redis 的密码 (如果有)
|
// password: 'your_password', // Redis 的密码 (如果有)
|
||||||
|
@ -26,10 +26,6 @@ export class ContainerModel extends Model {
|
|||||||
declare data: ContainerData;
|
declare data: ContainerData;
|
||||||
declare publish: ContainerPublish;
|
declare publish: ContainerPublish;
|
||||||
declare uid: string;
|
declare uid: string;
|
||||||
|
|
||||||
// timestamps
|
|
||||||
public readonly createdAt!: Date;
|
|
||||||
public readonly updatedAt!: Date;
|
|
||||||
}
|
}
|
||||||
ContainerModel.init(
|
ContainerModel.init(
|
||||||
{
|
{
|
||||||
|
@ -3,3 +3,5 @@ import './container/index.ts';
|
|||||||
import './page/index.ts';
|
import './page/index.ts';
|
||||||
|
|
||||||
import './resource/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