mirror of
https://github.com/jeffusion/gitea-ai-assistant.git
synced 2026-03-27 10:05:50 +00:00
feat: 添加Agent审查相关配置项和依赖
新增REVIEW_ENGINE、向量记忆、Reflection/Debate等环境变量;添加@qdrant/js-client-rest和zod-to-json-schema依赖;添加test脚本 Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
32
.env.example
32
.env.example
@@ -19,3 +19,35 @@ PORT=3000
|
||||
# 在Linux/Mac终端: openssl rand -hex 32
|
||||
# 或者在Node.js中: require('crypto').randomBytes(32).toString('hex')
|
||||
WEBHOOK_SECRET=your_webhook_secret
|
||||
|
||||
# Agent审查配置(默认关闭,开启请设置为agent)
|
||||
REVIEW_ENGINE=legacy
|
||||
REVIEW_WORKDIR=/tmp/gitea-assistant
|
||||
REVIEW_MODEL_PLANNER=gpt-4o-mini
|
||||
REVIEW_MODEL_SPECIALIST=gpt-4o-mini
|
||||
REVIEW_MODEL_JUDGE=gpt-4o-mini
|
||||
REVIEW_MAX_PARALLEL_RUNS=2
|
||||
REVIEW_MAX_FILES_PER_RUN=200
|
||||
REVIEW_MAX_FILE_CONTENT_CHARS=40000
|
||||
REVIEW_AUTO_PUBLISH_MIN_CONFIDENCE=0.8
|
||||
REVIEW_ENABLE_HUMAN_GATE=true
|
||||
REVIEW_ALLOWED_COMMANDS=git,rg,cat,sed,wc
|
||||
REVIEW_COMMAND_TIMEOUT_MS=10000
|
||||
|
||||
# 向量记忆和学习系统配置(可选,第二阶段功能)
|
||||
# Qdrant向量数据库URL(如果不配置则禁用记忆系统)
|
||||
QDRANT_URL=http://localhost:6333
|
||||
# 是否启用记忆系统(需要先配置QDRANT_URL)
|
||||
ENABLE_MEMORY=false
|
||||
# Few-shot学习示例数量(0-20)
|
||||
FEW_SHOT_EXAMPLES_COUNT=10
|
||||
|
||||
# Reflection和Debate配置(可选,第三阶段功能)
|
||||
# 是否启用Reflection自我批评机制(提升审查质量)
|
||||
ENABLE_REFLECTION=false
|
||||
# Reflection最大轮次(1-5)
|
||||
MAX_REFLECTION_ROUNDS=2
|
||||
# 是否启用Debate多代理辩论机制(提升高严重性问题准确性)
|
||||
ENABLE_DEBATE=false
|
||||
# Debate触发阈值(high=仅高严重性, medium=高和中等严重性)
|
||||
DEBATE_THRESHOLD=high
|
||||
|
||||
23
bun.lock
23
bun.lock
@@ -1,16 +1,19 @@
|
||||
{
|
||||
"lockfileVersion": 1,
|
||||
"configVersion": 0,
|
||||
"workspaces": {
|
||||
"": {
|
||||
"name": "ai-review",
|
||||
"dependencies": {
|
||||
"@hono/zod-validator": "^0.4.3",
|
||||
"@qdrant/js-client-rest": "^1.16.2",
|
||||
"axios": "^1.8.3",
|
||||
"dotenv": "^16.4.7",
|
||||
"hono": "^4.7.4",
|
||||
"hono": "^4.11.9",
|
||||
"lodash-es": "^4.17.21",
|
||||
"openai": "^4.87.3",
|
||||
"zod": "^3.24.2",
|
||||
"zod": "^3.25.1",
|
||||
"zod-to-json-schema": "^3.25.1",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
@@ -27,7 +30,11 @@
|
||||
|
||||
"@hono/zod-validator": ["@hono/zod-validator@0.4.3", "", { "peerDependencies": { "hono": ">=3.9.0", "zod": "^3.19.1" } }, "sha512-xIgMYXDyJ4Hj6ekm9T9Y27s080Nl9NXHcJkOvkXPhubOLj8hZkOL8pDnnXfvCf5xEE8Q4oMFenQUZZREUY2gqQ=="],
|
||||
|
||||
"@types/lodash": ["@types/lodash@4.17.16", "", {}, "sha512-HX7Em5NYQAXKW+1T+FiuG27NGwzJfCX3s1GjOa7ujxZa52kjJLOr4FUxT+giF6Tgxv1e+/czV/iTtBw27WTU9g=="],
|
||||
"@qdrant/js-client-rest": ["@qdrant/js-client-rest@1.16.2", "", { "dependencies": { "@qdrant/openapi-typescript-fetch": "1.2.6", "undici": "^6.0.0" }, "peerDependencies": { "typescript": ">=4.7" } }, "sha512-Zm4wEZURrZ24a+Hmm4l1QQYjiz975Ep3vF0yzWR7ICGcxittNz47YK2iBOk8kb8qseCu8pg7WmO1HOIsO8alvw=="],
|
||||
|
||||
"@qdrant/openapi-typescript-fetch": ["@qdrant/openapi-typescript-fetch@1.2.6", "", {}, "sha512-oQG/FejNpItrxRHoyctYvT3rwGZOnK4jr3JdppO/c78ktDvkWiPXPHNsrDf33K9sZdRb6PR7gi4noIapu5q4HA=="],
|
||||
|
||||
"@types/lodash": ["@types/lodash@4.17.23", "", {}, "sha512-RDvF6wTulMPjrNdCoYRC8gNR880JNGT8uB+REUpC2Ns4pRqQJhGz90wh7rgdXDPpCczF3VGktDuFGVnz8zP7HA=="],
|
||||
|
||||
"@types/lodash-es": ["@types/lodash-es@4.17.12", "", { "dependencies": { "@types/lodash": "*" } }, "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ=="],
|
||||
|
||||
@@ -117,7 +124,7 @@
|
||||
|
||||
"hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
|
||||
|
||||
"hono": ["hono@4.7.4", "", {}, "sha512-Pst8FuGqz3L7tFF+u9Pu70eI0xa5S3LPUmrNd5Jm8nTHze9FxLTK9Kaj5g/k4UcwuJSXTP65SyHOPLrffpcAJg=="],
|
||||
"hono": ["hono@4.11.9", "", {}, "sha512-Eaw2YTGM6WOxA6CXbckaEvslr2Ne4NFsKrvc0v97JD5awbmeBLO5w9Ho9L9kmKonrwF9RJlW6BxT1PVv/agBHQ=="],
|
||||
|
||||
"humanize-ms": ["humanize-ms@1.2.1", "", { "dependencies": { "ms": "^2.0.0" } }, "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ=="],
|
||||
|
||||
@@ -131,7 +138,7 @@
|
||||
|
||||
"js-yaml": ["js-yaml@3.14.1", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g=="],
|
||||
|
||||
"lodash-es": ["lodash-es@4.17.21", "", {}, "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="],
|
||||
"lodash-es": ["lodash-es@4.17.23", "", {}, "sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg=="],
|
||||
|
||||
"math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
|
||||
|
||||
@@ -183,6 +190,8 @@
|
||||
|
||||
"typescript": ["typescript@5.8.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ=="],
|
||||
|
||||
"undici": ["undici@6.23.0", "", {}, "sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g=="],
|
||||
|
||||
"undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="],
|
||||
|
||||
"web-streams-polyfill": ["web-streams-polyfill@4.0.0-beta.3", "", {}, "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug=="],
|
||||
@@ -193,7 +202,9 @@
|
||||
|
||||
"wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="],
|
||||
|
||||
"zod": ["zod@3.24.2", "", {}, "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ=="],
|
||||
"zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
|
||||
|
||||
"zod-to-json-schema": ["zod-to-json-schema@3.25.1", "", { "peerDependencies": { "zod": "^3.25 || ^4" } }, "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA=="],
|
||||
|
||||
"@types/node-fetch/@types/node": ["@types/node@18.19.80", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-kEWeMwMeIvxYkeg1gTc01awpwLbfMRZXdIhwRcakd/KlK53jmRC26LqcbIt7fnAQTu5GzlnWmzA3H6+l1u6xxQ=="],
|
||||
|
||||
|
||||
5
check-engine.js
Normal file
5
check-engine.js
Normal file
@@ -0,0 +1,5 @@
|
||||
const a = require('./dist/review/engine');
|
||||
const b = require('@/review/engine');
|
||||
console.log('same?', a.reviewEngine === b.reviewEngine);
|
||||
console.log('a file', require.resolve('./dist/review/engine'));
|
||||
console.log('b file', require.resolve('@/review/engine'));
|
||||
@@ -7,12 +7,14 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@hono/zod-validator": "^0.4.3",
|
||||
"@qdrant/js-client-rest": "^1.16.2",
|
||||
"axios": "^1.8.3",
|
||||
"dotenv": "^16.4.7",
|
||||
"hono": "^4.7.4",
|
||||
"hono": "^4.11.9",
|
||||
"lodash-es": "^4.17.21",
|
||||
"openai": "^4.87.3",
|
||||
"zod": "^3.24.2"
|
||||
"zod": "^3.25.1",
|
||||
"zod-to-json-schema": "^3.25.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
@@ -30,7 +32,8 @@
|
||||
"build": "rm -rf dist && tsc",
|
||||
"start": "bun run src/index.ts",
|
||||
"start:prod": "bun run dist/index.js",
|
||||
"lint": "tslint -c tslint.json src/**/*.ts"
|
||||
"lint": "tslint -c tslint.json src/**/*.ts",
|
||||
"test": "bun test"
|
||||
},
|
||||
"keywords": [
|
||||
"code-review",
|
||||
|
||||
@@ -6,6 +6,7 @@ config();
|
||||
|
||||
// 判断是否为开发环境
|
||||
const isDev = process.env.NODE_ENV === 'development' || !process.env.NODE_ENV;
|
||||
const defaultAllowedReviewCommands = ['git', 'rg', 'cat', 'sed', 'wc'];
|
||||
|
||||
// 环境变量验证模式
|
||||
const envSchema = z.object({
|
||||
@@ -32,6 +33,46 @@ const envSchema = z.object({
|
||||
// 管理后台配置
|
||||
ADMIN_PASSWORD: z.string().default('password'),
|
||||
JWT_SECRET: z.string().default('a-secure-secret-for-jwt'),
|
||||
|
||||
// Agent审查配置
|
||||
REVIEW_ENGINE: z.enum(['legacy', 'agent']).default('legacy'),
|
||||
REVIEW_WORKDIR: z.string().default('/tmp/gitea-assistant'),
|
||||
REVIEW_MODEL_PLANNER: z.string().default('gpt-4o-mini'),
|
||||
REVIEW_MODEL_SPECIALIST: z.string().default('gpt-4o-mini'),
|
||||
REVIEW_MODEL_JUDGE: z.string().default('gpt-4o-mini'),
|
||||
REVIEW_MAX_PARALLEL_RUNS: z.coerce.number().int().min(1).max(8).default(2),
|
||||
REVIEW_MAX_FILES_PER_RUN: z.coerce.number().int().min(1).max(1000).default(200),
|
||||
REVIEW_MAX_FILE_CONTENT_CHARS: z.coerce.number().int().min(1000).max(1_000_000).default(40_000),
|
||||
REVIEW_AUTO_PUBLISH_MIN_CONFIDENCE: z.coerce.number().min(0).max(1).default(0.8),
|
||||
REVIEW_ENABLE_HUMAN_GATE: z
|
||||
.enum(['true', 'false'])
|
||||
.default('true')
|
||||
.transform((value) => value === 'true'),
|
||||
REVIEW_ALLOWED_COMMANDS: z.string().default(defaultAllowedReviewCommands.join(',')),
|
||||
REVIEW_COMMAND_TIMEOUT_MS: z.coerce.number().int().min(1000).max(300000).default(10000),
|
||||
|
||||
// 向量记忆和学习系统配置
|
||||
QDRANT_URL: z.preprocess(
|
||||
(val) => (typeof val === 'string' && val.trim() === '' ? undefined : val),
|
||||
z.string().url().optional()
|
||||
),
|
||||
ENABLE_MEMORY: z
|
||||
.enum(['true', 'false'])
|
||||
.default('false')
|
||||
.transform((value) => value === 'true'),
|
||||
FEW_SHOT_EXAMPLES_COUNT: z.coerce.number().int().min(0).max(20).default(10),
|
||||
|
||||
// Reflection和Debate配置(第三阶段)
|
||||
ENABLE_REFLECTION: z
|
||||
.enum(['true', 'false'])
|
||||
.default('false')
|
||||
.transform((value) => value === 'true'),
|
||||
MAX_REFLECTION_ROUNDS: z.coerce.number().int().min(1).max(5).default(2),
|
||||
ENABLE_DEBATE: z
|
||||
.enum(['true', 'false'])
|
||||
.default('false')
|
||||
.transform((value) => value === 'true'),
|
||||
DEBATE_THRESHOLD: z.enum(['high', 'medium']).default('high'),
|
||||
});
|
||||
|
||||
// 处理验证结果
|
||||
@@ -74,4 +115,31 @@ export default {
|
||||
jwtSecret: envParseResult.success ? envParseResult.data.JWT_SECRET : 'a-secure-secret-for-jwt',
|
||||
giteaAdminToken: envParseResult.success ? envParseResult.data.GITEA_ADMIN_TOKEN : undefined,
|
||||
},
|
||||
review: {
|
||||
engine: envParseResult.success ? envParseResult.data.REVIEW_ENGINE : 'legacy',
|
||||
workdir: envParseResult.success ? envParseResult.data.REVIEW_WORKDIR : '/tmp/gitea-assistant',
|
||||
modelPlanner: envParseResult.success ? envParseResult.data.REVIEW_MODEL_PLANNER : 'gpt-4o-mini',
|
||||
modelSpecialist: envParseResult.success ? envParseResult.data.REVIEW_MODEL_SPECIALIST : 'gpt-4o-mini',
|
||||
modelJudge: envParseResult.success ? envParseResult.data.REVIEW_MODEL_JUDGE : 'gpt-4o-mini',
|
||||
maxParallelRuns: envParseResult.success ? envParseResult.data.REVIEW_MAX_PARALLEL_RUNS : 2,
|
||||
maxFilesPerRun: envParseResult.success ? envParseResult.data.REVIEW_MAX_FILES_PER_RUN : 200,
|
||||
maxFileContentChars: envParseResult.success ? envParseResult.data.REVIEW_MAX_FILE_CONTENT_CHARS : 40_000,
|
||||
autoPublishMinConfidence: envParseResult.success
|
||||
? envParseResult.data.REVIEW_AUTO_PUBLISH_MIN_CONFIDENCE
|
||||
: 0.8,
|
||||
enableHumanGate: envParseResult.success ? envParseResult.data.REVIEW_ENABLE_HUMAN_GATE : true,
|
||||
allowedCommands: envParseResult.success
|
||||
? envParseResult.data.REVIEW_ALLOWED_COMMANDS.split(',')
|
||||
.map((item) => item.trim())
|
||||
.filter(Boolean)
|
||||
: defaultAllowedReviewCommands,
|
||||
commandTimeoutMs: envParseResult.success ? envParseResult.data.REVIEW_COMMAND_TIMEOUT_MS : 10000,
|
||||
qdrantUrl: envParseResult.success ? envParseResult.data.QDRANT_URL : undefined,
|
||||
enableMemory: envParseResult.success ? envParseResult.data.ENABLE_MEMORY : false,
|
||||
fewShotExamplesCount: envParseResult.success ? envParseResult.data.FEW_SHOT_EXAMPLES_COUNT : 10,
|
||||
enableReflection: envParseResult.success ? envParseResult.data.ENABLE_REFLECTION : false,
|
||||
maxReflectionRounds: envParseResult.success ? envParseResult.data.MAX_REFLECTION_ROUNDS : 2,
|
||||
enableDebate: envParseResult.success ? envParseResult.data.ENABLE_DEBATE : false,
|
||||
debateThreshold: envParseResult.success ? envParseResult.data.DEBATE_THRESHOLD : 'high',
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user