@axiom-lattice/gateway 2.1.112 → 2.1.113
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +11 -11
- package/CHANGELOG.md +9 -0
- package/dist/index.js +1954 -273
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1764 -83
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/controllers/export-import.ts +166 -0
- package/src/controllers/run.ts +30 -4
- package/src/export_registrations/a2a-api-key.registration.ts +89 -0
- package/src/export_registrations/agent.registration.ts +80 -0
- package/src/export_registrations/binding.registration.ts +106 -0
- package/src/export_registrations/channel-installation.registration.ts +88 -0
- package/src/export_registrations/collection.registration.ts +85 -0
- package/src/export_registrations/connection.registration.ts +97 -0
- package/src/export_registrations/database-config.registration.ts +94 -0
- package/src/export_registrations/eval.registration.ts +334 -0
- package/src/export_registrations/index.ts +31 -0
- package/src/export_registrations/mcp-config.registration.ts +97 -0
- package/src/export_registrations/menu.registration.ts +91 -0
- package/src/export_registrations/metrics-config.registration.ts +94 -0
- package/src/export_registrations/skill.registration.ts +88 -0
- package/src/export_registrations/task.registration.ts +99 -0
- package/src/index.ts +4 -0
- package/src/routes/index.ts +34 -0
- package/src/services/ExportImportService.ts +296 -0
- package/src/services/__tests__/ExportImportService.test.ts +130 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import type { ExportableEntityDefinition, ExportableEntity, ImportPreviewResult } from '@axiom-lattice/core';
|
|
2
|
+
import { getStoreLattice } from '@axiom-lattice/core';
|
|
3
|
+
import type { ConnectionEntry, ConnectionStore } from '@axiom-lattice/protocols';
|
|
4
|
+
|
|
5
|
+
function getStore(): ConnectionStore {
|
|
6
|
+
return getStoreLattice('default', 'connection').store as unknown as ConnectionStore;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
async function listAllConnections(tenantId: string): Promise<ConnectionEntry[]> {
|
|
10
|
+
const store = getStore();
|
|
11
|
+
if (typeof store.listByTenant !== 'function') {
|
|
12
|
+
throw new Error('ConnectionStore.listByTenant is not implemented. SQL bypass removed — upgrade your store adapter.');
|
|
13
|
+
}
|
|
14
|
+
return store.listByTenant(tenantId);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const connectionRegistration: ExportableEntityDefinition = {
|
|
18
|
+
entityType: 'connection',
|
|
19
|
+
label: 'Connection(连接)',
|
|
20
|
+
category: 'core',
|
|
21
|
+
dependsOn: [],
|
|
22
|
+
cascadeParents: [],
|
|
23
|
+
|
|
24
|
+
async listForExport(tenantId: string): Promise<ExportableEntity[]> {
|
|
25
|
+
const connections = await listAllConnections(tenantId);
|
|
26
|
+
return connections.map((c) => ({
|
|
27
|
+
_exportId: '',
|
|
28
|
+
data: {
|
|
29
|
+
id: c.id,
|
|
30
|
+
type: c.type,
|
|
31
|
+
key: c.key,
|
|
32
|
+
name: c.name,
|
|
33
|
+
description: c.description,
|
|
34
|
+
config: c.config,
|
|
35
|
+
},
|
|
36
|
+
}));
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
async previewImport(
|
|
40
|
+
tenantId: string,
|
|
41
|
+
entities: ExportableEntity[],
|
|
42
|
+
): Promise<ImportPreviewResult> {
|
|
43
|
+
const existing = await listAllConnections(tenantId);
|
|
44
|
+
const existingCompositeKeys = new Set(
|
|
45
|
+
existing.map((c) => `${c.type}:${c.key}`),
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
const conflicts: ImportPreviewResult['conflicts'] = [];
|
|
49
|
+
const insertions: ImportPreviewResult['insertions'] = [];
|
|
50
|
+
|
|
51
|
+
for (const entity of entities) {
|
|
52
|
+
const d = entity.data as Record<string, unknown>;
|
|
53
|
+
const compositeKey = `${d.type}:${d.key}`;
|
|
54
|
+
if (existingCompositeKeys.has(compositeKey)) {
|
|
55
|
+
conflicts.push({
|
|
56
|
+
_exportId: entity._exportId,
|
|
57
|
+
entityType: 'connection',
|
|
58
|
+
conflictType: 'unique_constraint',
|
|
59
|
+
existingName: `${d.type}:${d.key}`,
|
|
60
|
+
field: 'type+key',
|
|
61
|
+
});
|
|
62
|
+
} else {
|
|
63
|
+
insertions.push({
|
|
64
|
+
_exportId: entity._exportId,
|
|
65
|
+
entityType: 'connection',
|
|
66
|
+
name: `${d.type}:${d.key}`,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return { conflicts, insertions, errors: [] };
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
async applyImport(tenantId, entity, resolution) {
|
|
75
|
+
if (resolution.action === 'skip') return {};
|
|
76
|
+
|
|
77
|
+
const store = getStore();
|
|
78
|
+
const d = entity.data as Record<string, unknown>;
|
|
79
|
+
const type = d.type as string;
|
|
80
|
+
const key = d.key as string;
|
|
81
|
+
|
|
82
|
+
if (resolution.action === 'overwrite') {
|
|
83
|
+
try { await store.delete(tenantId, type, key); } catch { /* may not exist */ }
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
await store.create({
|
|
87
|
+
tenantId,
|
|
88
|
+
type,
|
|
89
|
+
key,
|
|
90
|
+
name: d.name as string,
|
|
91
|
+
description: d.description as string | undefined,
|
|
92
|
+
config: d.config as Record<string, unknown>,
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
return { newId: undefined };
|
|
96
|
+
},
|
|
97
|
+
};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { ExportableEntityDefinition, ExportableEntity, ImportPreviewResult } from '@axiom-lattice/core';
|
|
2
|
+
import { getStoreLattice } from '@axiom-lattice/core';
|
|
3
|
+
import type { DatabaseConfigStore } from '@axiom-lattice/protocols';
|
|
4
|
+
|
|
5
|
+
function getStore(): DatabaseConfigStore {
|
|
6
|
+
return getStoreLattice('default', 'database').store as unknown as DatabaseConfigStore;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const databaseConfigRegistration: ExportableEntityDefinition = {
|
|
10
|
+
entityType: 'database_config',
|
|
11
|
+
label: 'Database Config(数据库配置)',
|
|
12
|
+
category: 'core',
|
|
13
|
+
dependsOn: [],
|
|
14
|
+
cascadeParents: [],
|
|
15
|
+
|
|
16
|
+
async listForExport(tenantId: string): Promise<ExportableEntity[]> {
|
|
17
|
+
const store = getStore();
|
|
18
|
+
const configs = await store.getAllConfigs(tenantId);
|
|
19
|
+
return configs.map((c) => ({
|
|
20
|
+
_exportId: '',
|
|
21
|
+
data: {
|
|
22
|
+
id: c.id,
|
|
23
|
+
key: c.key,
|
|
24
|
+
name: c.name,
|
|
25
|
+
description: c.description,
|
|
26
|
+
config: c.config,
|
|
27
|
+
},
|
|
28
|
+
}));
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
async previewImport(
|
|
32
|
+
tenantId: string,
|
|
33
|
+
entities: ExportableEntity[],
|
|
34
|
+
): Promise<ImportPreviewResult> {
|
|
35
|
+
const store = getStore();
|
|
36
|
+
const existing = await store.getAllConfigs(tenantId);
|
|
37
|
+
const existingIds = new Set(existing.map((c) => c.id));
|
|
38
|
+
const existingKeys = new Set(existing.map((c) => c.key));
|
|
39
|
+
|
|
40
|
+
const conflicts: ImportPreviewResult['conflicts'] = [];
|
|
41
|
+
const insertions: ImportPreviewResult['insertions'] = [];
|
|
42
|
+
|
|
43
|
+
for (const entity of entities) {
|
|
44
|
+
const d = entity.data as Record<string, unknown>;
|
|
45
|
+
const id = d.id as string;
|
|
46
|
+
const key = d.key as string;
|
|
47
|
+
|
|
48
|
+
if (existingIds.has(id)) {
|
|
49
|
+
conflicts.push({
|
|
50
|
+
_exportId: entity._exportId,
|
|
51
|
+
entityType: 'database_config',
|
|
52
|
+
conflictType: 'id_exists',
|
|
53
|
+
existingId: id,
|
|
54
|
+
existingName: (d.name as string) || key,
|
|
55
|
+
});
|
|
56
|
+
} else if (key && existingKeys.has(key)) {
|
|
57
|
+
conflicts.push({
|
|
58
|
+
_exportId: entity._exportId,
|
|
59
|
+
entityType: 'database_config',
|
|
60
|
+
conflictType: 'unique_constraint',
|
|
61
|
+
existingName: (d.name as string) || key,
|
|
62
|
+
field: 'key',
|
|
63
|
+
});
|
|
64
|
+
} else {
|
|
65
|
+
insertions.push({
|
|
66
|
+
_exportId: entity._exportId,
|
|
67
|
+
entityType: 'database_config',
|
|
68
|
+
name: (d.name as string) || key,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return { conflicts, insertions, errors: [] };
|
|
74
|
+
},
|
|
75
|
+
|
|
76
|
+
async applyImport(tenantId, entity, resolution) {
|
|
77
|
+
const store = getStore();
|
|
78
|
+
const data = entity.data as Record<string, unknown>;
|
|
79
|
+
const id = resolution.action === 'rename' && resolution.newId ? resolution.newId : data.id as string;
|
|
80
|
+
|
|
81
|
+
if (resolution.action === 'overwrite') {
|
|
82
|
+
try { await store.deleteConfig(tenantId, id); } catch { /* may not exist */ }
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
await store.createConfig(tenantId, id, {
|
|
86
|
+
key: data.key as string,
|
|
87
|
+
name: data.name as string | undefined,
|
|
88
|
+
description: data.description as string | undefined,
|
|
89
|
+
config: data.config as any,
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
return { newId: id };
|
|
93
|
+
},
|
|
94
|
+
};
|
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
import type { ExportableEntityDefinition, ExportableEntity, ImportPreviewResult } from '@axiom-lattice/core';
|
|
2
|
+
import { getStoreLattice } from '@axiom-lattice/core';
|
|
3
|
+
import type { EvalStore } from '@axiom-lattice/protocols';
|
|
4
|
+
|
|
5
|
+
function getStore(): EvalStore {
|
|
6
|
+
return getStoreLattice('default', 'eval').store as unknown as EvalStore;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const evalRegistration: ExportableEntityDefinition = {
|
|
10
|
+
entityType: 'eval',
|
|
11
|
+
label: 'Eval(评估)',
|
|
12
|
+
category: 'core',
|
|
13
|
+
dependsOn: [],
|
|
14
|
+
cascadeParents: [],
|
|
15
|
+
referenceFields: { suiteId: 'eval_suite', projectId: 'eval_project', runId: 'eval_run', caseId: 'eval_case' },
|
|
16
|
+
|
|
17
|
+
async listForExport(tenantId: string): Promise<ExportableEntity[]> {
|
|
18
|
+
const store = getStore();
|
|
19
|
+
const projects = await store.getProjectsByTenant(tenantId);
|
|
20
|
+
const entities: ExportableEntity[] = [];
|
|
21
|
+
|
|
22
|
+
for (const project of projects) {
|
|
23
|
+
entities.push({
|
|
24
|
+
_exportId: '',
|
|
25
|
+
data: {
|
|
26
|
+
_subType: 'eval_project',
|
|
27
|
+
id: project.id,
|
|
28
|
+
name: project.name,
|
|
29
|
+
description: project.description,
|
|
30
|
+
version: project.version,
|
|
31
|
+
judgeModelConfig: project.judgeModelConfig,
|
|
32
|
+
targetServerConfig: project.targetServerConfig,
|
|
33
|
+
concurrency: project.concurrency,
|
|
34
|
+
reportConfig: project.reportConfig,
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const suites = await store.getSuitesByProject(tenantId, project.id);
|
|
39
|
+
for (const suite of suites) {
|
|
40
|
+
entities.push({
|
|
41
|
+
_exportId: '',
|
|
42
|
+
data: {
|
|
43
|
+
_subType: 'eval_suite',
|
|
44
|
+
id: suite.id,
|
|
45
|
+
projectId: suite.projectId,
|
|
46
|
+
name: suite.name,
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const cases = await store.getCasesBySuite(tenantId, suite.id);
|
|
51
|
+
for (const c of cases) {
|
|
52
|
+
entities.push({
|
|
53
|
+
_exportId: '',
|
|
54
|
+
data: {
|
|
55
|
+
_subType: 'eval_case',
|
|
56
|
+
id: c.id,
|
|
57
|
+
suiteId: c.suiteId,
|
|
58
|
+
inputMessage: c.inputMessage,
|
|
59
|
+
inputFiles: c.inputFiles,
|
|
60
|
+
steps: c.steps,
|
|
61
|
+
outputType: c.outputType,
|
|
62
|
+
contentAssertion: c.contentAssertion,
|
|
63
|
+
rubrics: c.rubrics,
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const runs = await store.getRunsByTenant(tenantId, { projectId: project.id });
|
|
70
|
+
for (const run of runs) {
|
|
71
|
+
entities.push({
|
|
72
|
+
_exportId: '',
|
|
73
|
+
data: {
|
|
74
|
+
_subType: 'eval_run',
|
|
75
|
+
id: run.id,
|
|
76
|
+
projectId: run.projectId,
|
|
77
|
+
status: run.status,
|
|
78
|
+
concurrency: run.concurrency,
|
|
79
|
+
totalCases: run.totalCases,
|
|
80
|
+
passedCases: run.passedCases,
|
|
81
|
+
failedCases: run.failedCases,
|
|
82
|
+
avgScore: run.avgScore,
|
|
83
|
+
error: run.error,
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
const results = await store.getResultsByRun(tenantId, run.id);
|
|
88
|
+
for (const result of results) {
|
|
89
|
+
entities.push({
|
|
90
|
+
_exportId: '',
|
|
91
|
+
data: {
|
|
92
|
+
_subType: 'eval_run_result',
|
|
93
|
+
id: result.id,
|
|
94
|
+
runId: result.runId,
|
|
95
|
+
suiteName: result.suiteName,
|
|
96
|
+
caseId: result.caseId,
|
|
97
|
+
pass: result.pass,
|
|
98
|
+
score: result.score,
|
|
99
|
+
summary: result.summary,
|
|
100
|
+
dimensionResults: result.dimensionResults,
|
|
101
|
+
durationMs: result.durationMs,
|
|
102
|
+
messages: result.messages,
|
|
103
|
+
logs: result.logs,
|
|
104
|
+
error: result.error,
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return entities;
|
|
112
|
+
},
|
|
113
|
+
|
|
114
|
+
async previewImport(
|
|
115
|
+
tenantId: string,
|
|
116
|
+
entities: ExportableEntity[],
|
|
117
|
+
): Promise<ImportPreviewResult> {
|
|
118
|
+
const store = getStore();
|
|
119
|
+
|
|
120
|
+
const existingProjects = await store.getProjectsByTenant(tenantId);
|
|
121
|
+
const existingProjectIds = new Set(existingProjects.map((p) => p.id));
|
|
122
|
+
const existingProjectNames = new Set(existingProjects.map((p) => p.name));
|
|
123
|
+
|
|
124
|
+
const existingSuites: Map<string, Set<string>> = new Map();
|
|
125
|
+
const existingSuiteIds = new Set<string>();
|
|
126
|
+
const existingCaseIds = new Set<string>();
|
|
127
|
+
const existingRunIds = new Set<string>();
|
|
128
|
+
const existingResultIds = new Set<string>();
|
|
129
|
+
|
|
130
|
+
for (const project of existingProjects) {
|
|
131
|
+
const suites = await store.getSuitesByProject(tenantId, project.id);
|
|
132
|
+
existingSuites.set(project.id, new Set(suites.map((s) => `${s.projectId}:${s.name}`)));
|
|
133
|
+
for (const s of suites) {
|
|
134
|
+
existingSuiteIds.add(s.id);
|
|
135
|
+
try {
|
|
136
|
+
const cases = await store.getCasesBySuite(tenantId, s.id);
|
|
137
|
+
for (const c of cases) existingCaseIds.add(c.id);
|
|
138
|
+
} catch { /* suite may not exist */ }
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
for (const project of existingProjects) {
|
|
143
|
+
const runs = await store.getRunsByTenant(tenantId, { projectId: project.id });
|
|
144
|
+
for (const run of runs) {
|
|
145
|
+
existingRunIds.add(run.id);
|
|
146
|
+
try {
|
|
147
|
+
const results = await store.getResultsByRun(tenantId, run.id);
|
|
148
|
+
for (const r of results) existingResultIds.add(r.id);
|
|
149
|
+
} catch { /* run may not exist */ }
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const conflicts: ImportPreviewResult['conflicts'] = [];
|
|
154
|
+
const insertions: ImportPreviewResult['insertions'] = [];
|
|
155
|
+
|
|
156
|
+
for (const entity of entities) {
|
|
157
|
+
const d = entity.data as Record<string, unknown>;
|
|
158
|
+
const subType = d._subType as string;
|
|
159
|
+
const id = d.id as string;
|
|
160
|
+
|
|
161
|
+
switch (subType) {
|
|
162
|
+
case 'eval_project': {
|
|
163
|
+
const name = d.name as string;
|
|
164
|
+
if (existingProjectIds.has(id)) {
|
|
165
|
+
conflicts.push({
|
|
166
|
+
_exportId: entity._exportId,
|
|
167
|
+
entityType: 'eval_project',
|
|
168
|
+
conflictType: 'id_exists',
|
|
169
|
+
existingId: id,
|
|
170
|
+
existingName: name,
|
|
171
|
+
});
|
|
172
|
+
} else if (name && existingProjectNames.has(name)) {
|
|
173
|
+
conflicts.push({
|
|
174
|
+
_exportId: entity._exportId,
|
|
175
|
+
entityType: 'eval_project',
|
|
176
|
+
conflictType: 'unique_constraint',
|
|
177
|
+
existingName: name,
|
|
178
|
+
field: 'name',
|
|
179
|
+
});
|
|
180
|
+
} else {
|
|
181
|
+
insertions.push({ _exportId: entity._exportId, entityType: 'eval_project', name });
|
|
182
|
+
}
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
case 'eval_suite': {
|
|
186
|
+
const projectId = d.projectId as string;
|
|
187
|
+
const name = d.name as string;
|
|
188
|
+
const suiteKey = `${projectId}:${name}`;
|
|
189
|
+
const projectSuites = existingSuites.get(projectId);
|
|
190
|
+
if (existingSuiteIds.has(id)) {
|
|
191
|
+
conflicts.push({
|
|
192
|
+
_exportId: entity._exportId,
|
|
193
|
+
entityType: 'eval_suite',
|
|
194
|
+
conflictType: 'id_exists',
|
|
195
|
+
existingId: id,
|
|
196
|
+
existingName: name,
|
|
197
|
+
});
|
|
198
|
+
} else if (projectSuites?.has(suiteKey)) {
|
|
199
|
+
conflicts.push({
|
|
200
|
+
_exportId: entity._exportId,
|
|
201
|
+
entityType: 'eval_suite',
|
|
202
|
+
conflictType: 'unique_constraint',
|
|
203
|
+
existingName: name,
|
|
204
|
+
field: 'projectId+name',
|
|
205
|
+
});
|
|
206
|
+
} else {
|
|
207
|
+
insertions.push({ _exportId: entity._exportId, entityType: 'eval_suite', name });
|
|
208
|
+
}
|
|
209
|
+
break;
|
|
210
|
+
}
|
|
211
|
+
case 'eval_case': {
|
|
212
|
+
if (existingCaseIds.has(id)) {
|
|
213
|
+
conflicts.push({
|
|
214
|
+
_exportId: entity._exportId,
|
|
215
|
+
entityType: 'eval_case',
|
|
216
|
+
conflictType: 'id_exists',
|
|
217
|
+
existingId: id,
|
|
218
|
+
});
|
|
219
|
+
} else {
|
|
220
|
+
insertions.push({ _exportId: entity._exportId, entityType: 'eval_case', name: id });
|
|
221
|
+
}
|
|
222
|
+
break;
|
|
223
|
+
}
|
|
224
|
+
case 'eval_run': {
|
|
225
|
+
if (existingRunIds.has(id)) {
|
|
226
|
+
conflicts.push({
|
|
227
|
+
_exportId: entity._exportId,
|
|
228
|
+
entityType: 'eval_run',
|
|
229
|
+
conflictType: 'id_exists',
|
|
230
|
+
existingId: id,
|
|
231
|
+
});
|
|
232
|
+
} else {
|
|
233
|
+
insertions.push({ _exportId: entity._exportId, entityType: 'eval_run', name: id });
|
|
234
|
+
}
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
237
|
+
case 'eval_run_result': {
|
|
238
|
+
if (existingResultIds.has(id)) {
|
|
239
|
+
conflicts.push({
|
|
240
|
+
_exportId: entity._exportId,
|
|
241
|
+
entityType: 'eval_run_result',
|
|
242
|
+
conflictType: 'id_exists',
|
|
243
|
+
existingId: id,
|
|
244
|
+
});
|
|
245
|
+
} else {
|
|
246
|
+
insertions.push({ _exportId: entity._exportId, entityType: 'eval_run_result', name: id });
|
|
247
|
+
}
|
|
248
|
+
break;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
return { conflicts, insertions, errors: [] };
|
|
254
|
+
},
|
|
255
|
+
|
|
256
|
+
async applyImport(tenantId, entity, resolution) {
|
|
257
|
+
if (resolution.action === 'skip') return {};
|
|
258
|
+
const store = getStore();
|
|
259
|
+
const d = entity.data as Record<string, unknown>;
|
|
260
|
+
const subType = d._subType as string;
|
|
261
|
+
const id = resolution.action === 'rename' && resolution.newId ? resolution.newId : d.id as string;
|
|
262
|
+
|
|
263
|
+
switch (subType) {
|
|
264
|
+
case 'eval_project': {
|
|
265
|
+
if (resolution.action === 'overwrite') {
|
|
266
|
+
try { await store.deleteProject(tenantId, id); } catch { /* may not exist */ }
|
|
267
|
+
}
|
|
268
|
+
await store.createProject(tenantId, id, {
|
|
269
|
+
name: d.name as string,
|
|
270
|
+
description: d.description as string | undefined,
|
|
271
|
+
version: d.version as string | undefined,
|
|
272
|
+
judgeModelConfig: d.judgeModelConfig as Record<string, unknown>,
|
|
273
|
+
targetServerConfig: d.targetServerConfig as Record<string, unknown>,
|
|
274
|
+
concurrency: d.concurrency as number | undefined,
|
|
275
|
+
reportConfig: d.reportConfig as Record<string, unknown> | undefined,
|
|
276
|
+
});
|
|
277
|
+
break;
|
|
278
|
+
}
|
|
279
|
+
case 'eval_suite': {
|
|
280
|
+
if (resolution.action === 'overwrite') {
|
|
281
|
+
try { await store.deleteSuite(tenantId, id); } catch { /* may not exist */ }
|
|
282
|
+
}
|
|
283
|
+
await store.createSuite(tenantId, d.projectId as string, id, {
|
|
284
|
+
name: d.name as string,
|
|
285
|
+
});
|
|
286
|
+
break;
|
|
287
|
+
}
|
|
288
|
+
case 'eval_case': {
|
|
289
|
+
if (resolution.action === 'overwrite') {
|
|
290
|
+
try { await store.deleteCase(tenantId, id); } catch { /* may not exist */ }
|
|
291
|
+
}
|
|
292
|
+
await store.createCase(tenantId, d.suiteId as string, id, {
|
|
293
|
+
inputMessage: d.inputMessage as string,
|
|
294
|
+
inputFiles: d.inputFiles as Record<string, string> | undefined,
|
|
295
|
+
steps: d.steps as Array<{ agent_id: string; override_message?: string }>,
|
|
296
|
+
outputType: d.outputType as 'file_content' | 'message_content',
|
|
297
|
+
contentAssertion: d.contentAssertion as string,
|
|
298
|
+
rubrics: d.rubrics as Array<{ name: string; weight: number; description: string }> | undefined,
|
|
299
|
+
});
|
|
300
|
+
break;
|
|
301
|
+
}
|
|
302
|
+
case 'eval_run': {
|
|
303
|
+
if (resolution.action === 'overwrite') {
|
|
304
|
+
try { await store.deleteRun(tenantId, id); } catch { /* may not exist */ }
|
|
305
|
+
}
|
|
306
|
+
await store.createRun(tenantId, d.projectId as string, id, {
|
|
307
|
+
totalCases: d.totalCases as number,
|
|
308
|
+
concurrency: d.concurrency as number,
|
|
309
|
+
});
|
|
310
|
+
break;
|
|
311
|
+
}
|
|
312
|
+
case 'eval_run_result': {
|
|
313
|
+
if (resolution.action === 'overwrite') {
|
|
314
|
+
try { await store.deleteRunResult(tenantId, entity.data.id as string); } catch { /* may not exist */ }
|
|
315
|
+
}
|
|
316
|
+
await store.createRunResult(tenantId, d.runId as string, id, {
|
|
317
|
+
suiteName: d.suiteName as string,
|
|
318
|
+
caseId: d.caseId as string | undefined,
|
|
319
|
+
pass: d.pass as boolean,
|
|
320
|
+
score: d.score as number,
|
|
321
|
+
summary: d.summary as string | undefined,
|
|
322
|
+
dimensionResults: d.dimensionResults as Array<{ name: string; score: number; reason: string }> | undefined,
|
|
323
|
+
durationMs: d.durationMs as number | undefined,
|
|
324
|
+
messages: d.messages as Array<{ role: string; content: string; id?: string }> | undefined,
|
|
325
|
+
logs: d.logs as Array<{ timestamp: string; level: string; message: string; data?: unknown }> | undefined,
|
|
326
|
+
error: d.error as string | undefined,
|
|
327
|
+
});
|
|
328
|
+
break;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
return { newId: id };
|
|
333
|
+
},
|
|
334
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { ExportableEntityRegistry } from '@axiom-lattice/core';
|
|
2
|
+
import { skillRegistration } from './skill.registration';
|
|
3
|
+
import { agentRegistration } from './agent.registration';
|
|
4
|
+
import { bindingRegistration } from './binding.registration';
|
|
5
|
+
import { databaseConfigRegistration } from './database-config.registration';
|
|
6
|
+
import { metricsConfigRegistration } from './metrics-config.registration';
|
|
7
|
+
import { mcpConfigRegistration } from './mcp-config.registration';
|
|
8
|
+
import { connectionRegistration } from './connection.registration';
|
|
9
|
+
import { collectionRegistration } from './collection.registration';
|
|
10
|
+
import { channelInstallationRegistration } from './channel-installation.registration';
|
|
11
|
+
import { menuRegistration } from './menu.registration';
|
|
12
|
+
import { taskRegistration } from './task.registration';
|
|
13
|
+
import { a2aApiKeyRegistration } from './a2a-api-key.registration';
|
|
14
|
+
import { evalRegistration } from './eval.registration';
|
|
15
|
+
|
|
16
|
+
export function registerAllBuiltinEntities(): void {
|
|
17
|
+
const registry = ExportableEntityRegistry.getInstance();
|
|
18
|
+
registry.register(skillRegistration);
|
|
19
|
+
registry.register(agentRegistration);
|
|
20
|
+
registry.register(bindingRegistration);
|
|
21
|
+
registry.register(databaseConfigRegistration);
|
|
22
|
+
registry.register(metricsConfigRegistration);
|
|
23
|
+
registry.register(mcpConfigRegistration);
|
|
24
|
+
registry.register(connectionRegistration);
|
|
25
|
+
registry.register(collectionRegistration);
|
|
26
|
+
registry.register(channelInstallationRegistration);
|
|
27
|
+
registry.register(menuRegistration);
|
|
28
|
+
registry.register(taskRegistration);
|
|
29
|
+
registry.register(a2aApiKeyRegistration);
|
|
30
|
+
registry.register(evalRegistration);
|
|
31
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import type { ExportableEntityDefinition, ExportableEntity, ImportPreviewResult } from '@axiom-lattice/core';
|
|
2
|
+
import { getStoreLattice } from '@axiom-lattice/core';
|
|
3
|
+
import type { McpServerConfigStore } from '@axiom-lattice/protocols';
|
|
4
|
+
|
|
5
|
+
function getStore(): McpServerConfigStore {
|
|
6
|
+
return getStoreLattice('default', 'mcp').store as unknown as McpServerConfigStore;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const mcpConfigRegistration: ExportableEntityDefinition = {
|
|
10
|
+
entityType: 'mcp_config',
|
|
11
|
+
label: 'MCP Config(MCP配置)',
|
|
12
|
+
category: 'core',
|
|
13
|
+
dependsOn: [],
|
|
14
|
+
cascadeParents: [],
|
|
15
|
+
|
|
16
|
+
async listForExport(tenantId: string): Promise<ExportableEntity[]> {
|
|
17
|
+
const store = getStore();
|
|
18
|
+
const configs = await store.getAllConfigs(tenantId);
|
|
19
|
+
return configs.map((c) => ({
|
|
20
|
+
_exportId: '',
|
|
21
|
+
data: {
|
|
22
|
+
id: c.id,
|
|
23
|
+
key: c.key,
|
|
24
|
+
name: c.name,
|
|
25
|
+
description: c.description,
|
|
26
|
+
config: c.config,
|
|
27
|
+
selectedTools: c.selectedTools,
|
|
28
|
+
status: c.status,
|
|
29
|
+
},
|
|
30
|
+
}));
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
async previewImport(
|
|
34
|
+
tenantId: string,
|
|
35
|
+
entities: ExportableEntity[],
|
|
36
|
+
): Promise<ImportPreviewResult> {
|
|
37
|
+
const store = getStore();
|
|
38
|
+
const existing = await store.getAllConfigs(tenantId);
|
|
39
|
+
const existingIds = new Set(existing.map((c) => c.id));
|
|
40
|
+
const existingKeys = new Set(existing.map((c) => c.key));
|
|
41
|
+
|
|
42
|
+
const conflicts: ImportPreviewResult['conflicts'] = [];
|
|
43
|
+
const insertions: ImportPreviewResult['insertions'] = [];
|
|
44
|
+
|
|
45
|
+
for (const entity of entities) {
|
|
46
|
+
const d = entity.data as Record<string, unknown>;
|
|
47
|
+
const id = d.id as string;
|
|
48
|
+
const key = d.key as string;
|
|
49
|
+
|
|
50
|
+
if (existingIds.has(id)) {
|
|
51
|
+
conflicts.push({
|
|
52
|
+
_exportId: entity._exportId,
|
|
53
|
+
entityType: 'mcp_config',
|
|
54
|
+
conflictType: 'id_exists',
|
|
55
|
+
existingId: id,
|
|
56
|
+
existingName: (d.name as string) || key,
|
|
57
|
+
});
|
|
58
|
+
} else if (key && existingKeys.has(key)) {
|
|
59
|
+
conflicts.push({
|
|
60
|
+
_exportId: entity._exportId,
|
|
61
|
+
entityType: 'mcp_config',
|
|
62
|
+
conflictType: 'unique_constraint',
|
|
63
|
+
existingName: (d.name as string) || key,
|
|
64
|
+
field: 'key',
|
|
65
|
+
});
|
|
66
|
+
} else {
|
|
67
|
+
insertions.push({
|
|
68
|
+
_exportId: entity._exportId,
|
|
69
|
+
entityType: 'mcp_config',
|
|
70
|
+
name: (d.name as string) || key,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return { conflicts, insertions, errors: [] };
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
async applyImport(tenantId, entity, resolution) {
|
|
79
|
+
const store = getStore();
|
|
80
|
+
const data = entity.data as Record<string, unknown>;
|
|
81
|
+
const id = resolution.action === 'rename' && resolution.newId ? resolution.newId : data.id as string;
|
|
82
|
+
|
|
83
|
+
if (resolution.action === 'overwrite') {
|
|
84
|
+
try { await store.deleteConfig(tenantId, id); } catch { /* may not exist */ }
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
await store.createConfig(tenantId, id, {
|
|
88
|
+
key: data.key as string,
|
|
89
|
+
name: data.name as string | undefined,
|
|
90
|
+
description: data.description as string | undefined,
|
|
91
|
+
config: data.config as any,
|
|
92
|
+
selectedTools: data.selectedTools as string[] | undefined,
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
return { newId: id };
|
|
96
|
+
},
|
|
97
|
+
};
|