@velum-labs/routekit-eval-service 1.0.11 → 1.0.12
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/dist/layer-options.d.ts
CHANGED
|
@@ -7,4 +7,12 @@ export type RouteKitEvalServiceOptions = Omit<NodeTestExecutionOptions, "bridgeO
|
|
|
7
7
|
* execution fails before starting a child when it is absent.
|
|
8
8
|
*/
|
|
9
9
|
readonly bearerCredential?: string;
|
|
10
|
+
/**
|
|
11
|
+
* Host-owned per-test deadline.
|
|
12
|
+
*
|
|
13
|
+
* When set, the production execution adapter applies this value at the
|
|
14
|
+
* node:test boundary even if an intermediate comparison request carries a
|
|
15
|
+
* stale or missing timeout.
|
|
16
|
+
*/
|
|
17
|
+
readonly timeoutMs?: number;
|
|
10
18
|
};
|
|
@@ -20,13 +20,24 @@ const makeProductionExecutionPort = (options) => Effect.map(HttpClient.HttpClien
|
|
|
20
20
|
}))
|
|
21
21
|
};
|
|
22
22
|
}
|
|
23
|
-
|
|
23
|
+
const execution = makeRouteKitEvalExecutionPortService({
|
|
24
24
|
bearerCredential,
|
|
25
25
|
...(options.childEnvironment === undefined
|
|
26
26
|
? {}
|
|
27
27
|
: { childEnvironment: options.childEnvironment }),
|
|
28
28
|
...(options.execPath === undefined ? {} : { execPath: options.execPath })
|
|
29
29
|
}, httpClient);
|
|
30
|
+
if (options.timeoutMs === undefined)
|
|
31
|
+
return execution;
|
|
32
|
+
return {
|
|
33
|
+
execute: (input) => execution.execute({
|
|
34
|
+
...input,
|
|
35
|
+
request: {
|
|
36
|
+
...input.request,
|
|
37
|
+
timeoutMs: options.timeoutMs
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
};
|
|
30
41
|
});
|
|
31
42
|
const makeProductionEvalEngineLayer = (options) => makeEvalEngineLayer().pipe(Layer.provide(Layer.effect(EvalExecutionPort, makeProductionExecutionPort(options))));
|
|
32
43
|
/**
|
|
@@ -216,3 +216,50 @@ test("production runner executes candidate and judge traffic through the live en
|
|
|
216
216
|
await new Promise((resolve, reject) => gateway.close((error) => (error === undefined ? resolve() : reject(error))));
|
|
217
217
|
}
|
|
218
218
|
});
|
|
219
|
+
test("production runner applies the host timeout at node:test instead of a stale request deadline", async () => {
|
|
220
|
+
const root = await mkdtemp(path.join(os.tmpdir(), "routekit-eval-runner-timeout-"));
|
|
221
|
+
roots.push(root);
|
|
222
|
+
const suite = path.join(root, "support.eval.ts");
|
|
223
|
+
await writeFile(suite, [
|
|
224
|
+
'import { test } from "node:test";',
|
|
225
|
+
'import { setupAgent, setupJudge } from "routekit/eval";',
|
|
226
|
+
'const judge = setupJudge({ agent: setupAgent({ model: "openai/judge" }), minScore: 0.8 });',
|
|
227
|
+
'test("support case", async () => {',
|
|
228
|
+
' const run = await setupAgent({ model: "openai/cheap" }).run({ prompt: "Help", caseId: "support-case" });',
|
|
229
|
+
" run.toComplete();",
|
|
230
|
+
' await judge.autoEvals({ criteria: "Helpful", prompt: "Help", run });',
|
|
231
|
+
"});"
|
|
232
|
+
].join("\n"));
|
|
233
|
+
await writeManifest(root, ["openai/cheap"], "openai/judge", ["support-case"]);
|
|
234
|
+
const gateway = createServer((incoming, outgoing) => {
|
|
235
|
+
void (async () => {
|
|
236
|
+
const body = JSON.parse(await readBody(incoming));
|
|
237
|
+
await new Promise((resolve) => setTimeout(resolve, 25));
|
|
238
|
+
const content = body.model === "openai/judge"
|
|
239
|
+
? JSON.stringify({ pass: true, reason: "helpful", score: 0.9 })
|
|
240
|
+
: "Helpful answer";
|
|
241
|
+
outgoing.writeHead(200, { "content-type": "application/json" });
|
|
242
|
+
outgoing.end(JSON.stringify({
|
|
243
|
+
model: body.model,
|
|
244
|
+
choices: [{ message: { role: "assistant", content } }]
|
|
245
|
+
}));
|
|
246
|
+
})();
|
|
247
|
+
});
|
|
248
|
+
await new Promise((resolve) => gateway.listen(0, "127.0.0.1", resolve));
|
|
249
|
+
const address = gateway.address();
|
|
250
|
+
assert.ok(address !== null && typeof address !== "string");
|
|
251
|
+
try {
|
|
252
|
+
const result = await Effect.runPromise(withEvalService({
|
|
253
|
+
bearerCredential: "parent-only-token",
|
|
254
|
+
timeoutMs: 15_000
|
|
255
|
+
}, (service) => service.runComparison({
|
|
256
|
+
...requestFor(suite, `http://127.0.0.1:${String(address.port)}`),
|
|
257
|
+
candidateModels: ["openai/cheap"],
|
|
258
|
+
timeoutMs: 5
|
|
259
|
+
}, "full")).pipe(Effect.provide(NodeHttpClient.layerUndici)));
|
|
260
|
+
assert.equal(result.models[0]?.cases[0]?.outcome, "passed");
|
|
261
|
+
}
|
|
262
|
+
finally {
|
|
263
|
+
await new Promise((resolve, reject) => gateway.close((error) => (error === undefined ? resolve() : reject(error))));
|
|
264
|
+
}
|
|
265
|
+
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@velum-labs/routekit-eval-service",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.12",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/velum-labs/routekit.git",
|
|
@@ -32,10 +32,10 @@
|
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@effect/platform-node": "4.0.0-rc.108",
|
|
34
34
|
"effect": "4.0.0-rc.108",
|
|
35
|
-
"@velum-labs/routekit-eval-contracts": "1.0.
|
|
36
|
-
"@velum-labs/routekit-eval-engine": "1.0.
|
|
37
|
-
"@velum-labs/routekit-eval-store": "1.0.
|
|
38
|
-
"@velum-labs/routekit-registry": "1.0.
|
|
35
|
+
"@velum-labs/routekit-eval-contracts": "1.0.12",
|
|
36
|
+
"@velum-labs/routekit-eval-engine": "1.0.12",
|
|
37
|
+
"@velum-labs/routekit-eval-store": "1.0.12",
|
|
38
|
+
"@velum-labs/routekit-registry": "1.0.12"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"typescript": "7.0.2"
|