@axiom-lattice/gateway 2.1.110 → 2.1.112
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 +13 -13
- package/CHANGELOG.md +21 -0
- package/dist/index.js +182 -63
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +188 -66
- package/dist/index.mjs.map +1 -1
- package/dist/{resources-5POCLGXV.mjs → resources-VA7LSDKN.mjs} +2 -1
- package/dist/{resources-5POCLGXV.mjs.map → resources-VA7LSDKN.mjs.map} +1 -1
- package/package.json +5 -6
- package/src/controllers/__tests__/resources.test.ts +23 -0
- package/src/controllers/__tests__/workflow-tracking.test.ts +113 -0
- package/src/controllers/connections.ts +7 -0
- package/src/controllers/eval.ts +44 -4
- package/src/controllers/resources.ts +1 -2
- package/src/controllers/workflow-tracking.ts +105 -11
- package/src/index.ts +14 -8
- package/src/routes/index.ts +8 -1
- package/src/services/eval-runner.ts +63 -55
package/src/routes/index.ts
CHANGED
|
@@ -510,7 +510,9 @@ export const registerLatticeRoutes = (app: FastifyInstance, channelDeps?: { rout
|
|
|
510
510
|
workflowTrackingController.getAllWorkflowRuns
|
|
511
511
|
);
|
|
512
512
|
|
|
513
|
-
app.get
|
|
513
|
+
app.get<{
|
|
514
|
+
Querystring: { page?: string; pageSize?: string };
|
|
515
|
+
}>(
|
|
514
516
|
"/api/workflows/inbox",
|
|
515
517
|
workflowTrackingController.getInboxItems
|
|
516
518
|
);
|
|
@@ -546,6 +548,11 @@ export const registerLatticeRoutes = (app: FastifyInstance, channelDeps?: { rout
|
|
|
546
548
|
Params: { runId: string };
|
|
547
549
|
}>("/api/workflows/runs/:runId/tasks", workflowTrackingController.getRunTasks);
|
|
548
550
|
|
|
551
|
+
// Abort a running workflow — stops graph + all sub-agents
|
|
552
|
+
app.post<{
|
|
553
|
+
Params: { runId: string };
|
|
554
|
+
}>("/api/workflows/runs/:runId/abort", workflowTrackingController.abortWorkflowRun);
|
|
555
|
+
|
|
549
556
|
// 简化的 Inbox 任务回复接口(后台 streaming 执行,立即返回)
|
|
550
557
|
app.post<{
|
|
551
558
|
Body: { runId: string; answers: Array<{ questionIndex: number; selectedOptions: string[] }> };
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { EventEmitter } from "events";
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import {
|
|
3
|
+
getStoreLattice,
|
|
4
|
+
modelLatticeManager,
|
|
5
|
+
LatticeEvalProject,
|
|
6
|
+
} from "@axiom-lattice/core";
|
|
4
7
|
import type { EvalStore } from "@axiom-lattice/protocols";
|
|
5
8
|
import type {
|
|
6
9
|
CaseRunResult,
|
|
@@ -8,8 +11,7 @@ import type {
|
|
|
8
11
|
LatticeEvalProjectType,
|
|
9
12
|
LatticeEvalSuiteType,
|
|
10
13
|
LatticeEvalLogEvent,
|
|
11
|
-
|
|
12
|
-
} from "@axiom-lattice/agent-eval";
|
|
14
|
+
} from "@axiom-lattice/core";
|
|
13
15
|
import { v4 as uuidv4 } from "uuid";
|
|
14
16
|
|
|
15
17
|
export interface EvalStreamEvent {
|
|
@@ -48,6 +50,12 @@ class EvalRunner {
|
|
|
48
50
|
const project = await store.getProjectById(tenantId, projectId);
|
|
49
51
|
if (!project) throw new Error("Project not found");
|
|
50
52
|
|
|
53
|
+
for (const ctx of this.runs.values()) {
|
|
54
|
+
if (ctx.projectId === projectId) {
|
|
55
|
+
throw new Error("A run is already in progress for this project");
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
51
59
|
const existingRuns = await store.getRunsByTenant(tenantId, { projectId, status: "running" });
|
|
52
60
|
if (existingRuns.length > 0) {
|
|
53
61
|
throw new Error("A run is already in progress for this project");
|
|
@@ -65,8 +73,8 @@ class EvalRunner {
|
|
|
65
73
|
cases: cases.map((c) => ({
|
|
66
74
|
caseId: c.id,
|
|
67
75
|
input: { message: c.inputMessage, files: c.inputFiles },
|
|
68
|
-
steps: c.steps
|
|
69
|
-
output: { type:
|
|
76
|
+
steps: c.steps,
|
|
77
|
+
output: { type: "message_content" },
|
|
70
78
|
eval: {
|
|
71
79
|
content_assertion: c.contentAssertion,
|
|
72
80
|
eval_rubrics: c.rubrics?.map((r) => ({
|
|
@@ -79,39 +87,35 @@ class EvalRunner {
|
|
|
79
87
|
});
|
|
80
88
|
}
|
|
81
89
|
|
|
82
|
-
const
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
const judgeCfg = project.judgeModelConfig as Record<string, unknown>;
|
|
87
|
-
const hasModelKey = Boolean(judgeCfg.modelKey);
|
|
88
|
-
const hasApiKey = Boolean(judgeCfg.apiKeyEnvName || judgeCfg.apiKey);
|
|
89
|
-
const hasCredentials = hasApiKey;
|
|
90
|
-
|
|
91
|
-
let judgeModelConfig: { modelKey?: string; model?: any } = {};
|
|
90
|
+
const judgeCfg = (project.judgeModelConfig ?? {}) as Record<string, unknown>;
|
|
91
|
+
const judgeModelKey = (judgeCfg.modelKey as string) || "";
|
|
92
|
+
let resolvedJudgeModelKey: string;
|
|
92
93
|
|
|
93
|
-
if (
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
const firstModel = modelLatticeManager.getAllLattices()[0];
|
|
97
|
-
if (firstModel) {
|
|
98
|
-
judgeModelConfig = { modelKey: firstModel.key };
|
|
99
|
-
} else {
|
|
100
|
-
judgeModelConfig = { model: judgeCfg as any };
|
|
94
|
+
if (judgeModelKey) {
|
|
95
|
+
if (!modelLatticeManager.hasLattice(judgeModelKey)) {
|
|
96
|
+
throw new Error(`Judge model "${judgeModelKey}" is not registered`);
|
|
101
97
|
}
|
|
98
|
+
resolvedJudgeModelKey = judgeModelKey;
|
|
102
99
|
} else {
|
|
103
|
-
|
|
100
|
+
const firstModel = modelLatticeManager.getAllLattices()[0];
|
|
101
|
+
if (!firstModel) {
|
|
102
|
+
throw new Error("No model registered — cannot run eval without a judge model");
|
|
103
|
+
}
|
|
104
|
+
resolvedJudgeModelKey = firstModel.key;
|
|
105
|
+
console.warn(`[eval-runner] Project "${project.name}" has no judge modelKey — falling back to first registered model "${firstModel.key}"`);
|
|
104
106
|
}
|
|
105
107
|
|
|
108
|
+
const runId = uuidv4();
|
|
109
|
+
const concurrency = Math.max(1, Math.floor((project as unknown as Record<string, unknown>).concurrency as number) || 3);
|
|
110
|
+
await store.createRun(tenantId, projectId, runId, { totalCases, concurrency });
|
|
111
|
+
|
|
106
112
|
const projectConfig: LatticeEvalProjectType = {
|
|
107
113
|
projectName: project.name,
|
|
108
114
|
version: project.version,
|
|
109
115
|
description: project.description,
|
|
110
116
|
suites: evalSuites,
|
|
111
|
-
judge_agent_config:
|
|
117
|
+
judge_agent_config: { modelKey: resolvedJudgeModelKey },
|
|
112
118
|
lattice_server_config: {
|
|
113
|
-
base_url: (project.targetServerConfig as Record<string, string>).base_url || "",
|
|
114
|
-
api_key: (project.targetServerConfig as Record<string, string>).api_key || "",
|
|
115
119
|
tenant_id: tenantId,
|
|
116
120
|
},
|
|
117
121
|
concurrency,
|
|
@@ -163,37 +167,41 @@ class EvalRunner {
|
|
|
163
167
|
const runPromise = (async () => {
|
|
164
168
|
try {
|
|
165
169
|
const evalProject = new LatticeEvalProject(projectConfig, onCaseComplete);
|
|
166
|
-
const { report } = await evalProject.runAllSuitesBatch(concurrency);
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
170
|
+
const { report } = await evalProject.runAllSuitesBatch(concurrency, abortController.signal);
|
|
171
|
+
|
|
172
|
+
if (!abortController.signal.aborted) {
|
|
173
|
+
const completedCount = stats.passed + stats.failed;
|
|
174
|
+
await store.updateRunStatus(tenantId, runId, {
|
|
175
|
+
status: "completed",
|
|
176
|
+
completedAt: new Date(),
|
|
177
|
+
passedCases: stats.passed,
|
|
178
|
+
failedCases: stats.failed,
|
|
179
|
+
avgScore: completedCount > 0 ? stats.totalScore / completedCount : 0,
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
this.eventEmitter.emit(`run:${runId}`, {
|
|
183
|
+
type: "completed",
|
|
184
|
+
runId,
|
|
185
|
+
data: { passed: stats.passed, failed: stats.failed, avgScore: completedCount > 0 ? stats.totalScore / completedCount : 0 },
|
|
186
|
+
} satisfies EvalStreamEvent);
|
|
187
|
+
}
|
|
182
188
|
|
|
183
189
|
return { report };
|
|
184
190
|
} catch (err) {
|
|
185
191
|
const errorMsg = (err as Error).message;
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
192
|
+
if (!abortController.signal.aborted) {
|
|
193
|
+
await store.updateRunStatus(tenantId, runId, {
|
|
194
|
+
status: "failed",
|
|
195
|
+
error: errorMsg,
|
|
196
|
+
completedAt: new Date(),
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
this.eventEmitter.emit(`run:${runId}`, {
|
|
200
|
+
type: "error",
|
|
201
|
+
runId,
|
|
202
|
+
data: { message: errorMsg },
|
|
203
|
+
} satisfies EvalStreamEvent);
|
|
204
|
+
}
|
|
197
205
|
|
|
198
206
|
throw err;
|
|
199
207
|
} finally {
|