feat(app): 移除内置agents并添加CORS支持和技能上传优化

移除了agents/registry.json中的所有内置agents配置,将agents数组清空。
为web应用添加了CORS中间件支持,允许指定的前端地址跨域访问。
重构了技能上传功能,增加了LLM重写机制,自动规范化上传的技能格式。
新增了工具名称提取逻辑,从技能正文中自动识别Required Tools段落。
更新了技能学习候选者和草稿的载荷结构,添加评估报告统计信息。
修改了意图路由技能的说明,改进任务状态管理逻辑。
This commit is contained in:
2026-06-12 13:25:20 +08:00
parent fc9fd93c36
commit 8aeb97a5fc
76 changed files with 3382 additions and 553 deletions

View File

@ -3,9 +3,23 @@ import { resolve } from 'node:path';
import { describe, expect, it } from 'vitest';
import { canMutateUserFilesPath } from './user-file-paths';
const root = resolve(__dirname, '..');
describe('user file system frontend wiring', () => {
it('only enables mutating file actions inside concrete user-file roots', () => {
expect(canMutateUserFilesPath('')).toBe(false);
expect(canMutateUserFilesPath('/')).toBe(false);
expect(canMutateUserFilesPath('qa-folder')).toBe(false);
expect(canMutateUserFilesPath('uploads')).toBe(true);
expect(canMutateUserFilesPath('uploads/qa-folder')).toBe(true);
expect(canMutateUserFilesPath('outputs/report.md')).toBe(true);
expect(canMutateUserFilesPath('shared')).toBe(true);
expect(canMutateUserFilesPath('tasks/task-1')).toBe(true);
});
it('routes API client helpers to user file endpoints', () => {
const apiSource = readFileSync(resolve(root, 'lib/api.ts'), 'utf8');
@ -17,6 +31,13 @@ describe('user file system frontend wiring', () => {
expect(apiSource).toContain('/api/user-files/mkdir');
});
it('notifies the app shell when API auth is cleared', () => {
const apiSource = readFileSync(resolve(root, 'lib/api.ts'), 'utf8');
expect(apiSource).toContain('AUTH_CLEARED_EVENT');
expect(apiSource).toContain("window.dispatchEvent(new CustomEvent(AUTH_CLEARED_EVENT))");
});
it('does not wire the Files page to workspace or MinIO management APIs', () => {
const pageSource = readFileSync(resolve(root, 'app/(app)/files/page.tsx'), 'utf8');
@ -29,4 +50,18 @@ describe('user file system frontend wiring', () => {
expect(pageSource).not.toContain('accessKey');
expect(pageSource).not.toContain('secretKey');
});
it('does not retry user-file loads after an auth failure', () => {
const pageSource = readFileSync(resolve(root, 'app/(app)/files/page.tsx'), 'utf8');
expect(pageSource).toContain('isAuthError');
expect(pageSource).toContain('if (isAuthError(err))');
});
it('shows backend upload error details instead of raw JSON payloads', () => {
const apiSource = readFileSync(resolve(root, 'lib/api.ts'), 'utf8');
expect(apiSource).toContain('function parseErrorDetail');
expect(apiSource).toContain('throw new Error(`接口错误 ${res.status}: ${parseErrorDetail(text)}`)');
});
});