@ls-stack/agent-eval 0.55.0 → 0.55.2

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.
@@ -1,7 +1,7 @@
1
- import { ft as createRunRequestSchema, mt as extractCacheEntries, pt as updateManualScoreRequestSchema } from "./runOrchestration-BWyE5lRX.mjs";
2
- import { o as stageManualInputFile } from "./cli-rvPrUj6S.mjs";
3
- import "./src-DEENkbkn.mjs";
4
- import { t as getRunnerInstance } from "./runner-CFQ8LZmY.mjs";
1
+ import { et as createRunRequestSchema, nt as extractCacheEntries, tt as updateManualScoreRequestSchema, ut as getEvalTitle } from "./runExecution-C31dpemR.mjs";
2
+ import { o as stageManualInputFile } from "./cli-Bu9347r1.mjs";
3
+ import "./src-FR60ZR_4.mjs";
4
+ import { t as getRunnerInstance } from "./runner-B4EfMn1d.mjs";
5
5
  import { z } from "zod/v4";
6
6
  import { readFile } from "node:fs/promises";
7
7
  import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
@@ -189,6 +189,77 @@ const openRunLocationRequestSchema = z.object({
189
189
  column: z.number().int().min(1)
190
190
  });
191
191
  const importQuerySeparatorRegex = /[?#]/;
192
+ function escapeRegex(value) {
193
+ return value.replace(/[|\\{}()[\]^$+?.]/g, "\\$&");
194
+ }
195
+ function globToRegex(pattern) {
196
+ const normalized = pattern.replaceAll("\\", "/");
197
+ let regex = "^";
198
+ for (let i = 0; i < normalized.length; i++) {
199
+ const char = normalized[i];
200
+ const next = normalized[i + 1];
201
+ if (char === "*" && next === "*") {
202
+ regex += ".*";
203
+ i++;
204
+ } else if (char === "*") regex += "[^/]*";
205
+ else if (char === "?") regex += "[^/]";
206
+ else regex += escapeRegex(char ?? "");
207
+ }
208
+ return new RegExp(`${regex}$`);
209
+ }
210
+ function fileMatches(pattern, filePath) {
211
+ const normalizedPattern = pattern.replaceAll("\\", "/");
212
+ if (normalizedPattern === filePath) return true;
213
+ return globToRegex(normalizedPattern).test(filePath);
214
+ }
215
+ function matchesRunTarget(ev, target) {
216
+ if (target.evalKeys !== void 0 && target.evalKeys.length > 0) {
217
+ if (!target.evalKeys.includes(ev.key)) return false;
218
+ }
219
+ if (target.evalIds !== void 0 && target.evalIds.length > 0) {
220
+ if (!target.evalIds.includes(ev.id)) return false;
221
+ }
222
+ if (target.files !== void 0 && target.files.length > 0) {
223
+ if (!target.files.some((file) => fileMatches(file, ev.filePath))) return false;
224
+ }
225
+ return true;
226
+ }
227
+ function getRunTargetEvalSummaries(evals, target) {
228
+ return evals.filter((ev) => matchesRunTarget(ev, target)).toSorted((left, right) => left.filePath.localeCompare(right.filePath) || left.id.localeCompare(right.id));
229
+ }
230
+ function logStartedAppRunEvals(params) {
231
+ const targetEvals = getRunTargetEvalSummaries(params.evals, params.target);
232
+ if (targetEvals.length === 0) return;
233
+ const label = targetEvals.length === 1 ? "eval" : "evals";
234
+ console.info(`[agent-evals] Starting app run ${params.shortId} (${params.runId}) with ${String(targetEvals.length)} ${label}:`);
235
+ for (const ev of targetEvals) console.info(` - ${getEvalTitle(ev)} (${ev.filePath}#${ev.id})`);
236
+ }
237
+ function formatDurationMs(durationMs) {
238
+ if (durationMs === null) return "";
239
+ if (durationMs < 1e3) return ` in ${String(durationMs)}ms`;
240
+ return ` in ${(durationMs / 1e3).toFixed(1)}s`;
241
+ }
242
+ function formatRunResultSummary(summary) {
243
+ const cancelled = summary.cancelledCases > 0 ? `, ${String(summary.cancelledCases)} cancelled` : "";
244
+ return `${summary.status}: ${String(summary.totalCases)} total, ${String(summary.passedCases)} passed, ${String(summary.failedCases)} failed, ${String(summary.errorCases)} errors${cancelled}${formatDurationMs(summary.totalDurationMs)}`;
245
+ }
246
+ function isTerminalRunEvent(eventType) {
247
+ return eventType === "run.finished" || eventType === "run.error" || eventType === "run.cancelled";
248
+ }
249
+ function subscribeToAppRunResultLog(params) {
250
+ let unsubscribe;
251
+ unsubscribe = params.runner.subscribe(params.runId, (event) => {
252
+ if (!isTerminalRunEvent(event.type)) return;
253
+ unsubscribe?.();
254
+ unsubscribe = void 0;
255
+ const run = params.runner.getRun(params.runId);
256
+ if (run === void 0) {
257
+ console.info(`[agent-evals] Run ${params.shortId} (${params.runId}) finished.`);
258
+ return;
259
+ }
260
+ console.info(`[agent-evals] Run ${params.shortId} (${params.runId}) ${formatRunResultSummary(run.summary)}`);
261
+ });
262
+ }
192
263
  function isInsideWorkspace(path, workspaceRoot) {
193
264
  return path === workspaceRoot || path.startsWith(workspaceRoot + sep);
194
265
  }
@@ -229,11 +300,23 @@ const runsRoutes = new Hono().get("/", (c) => {
229
300
  error: "Manual input validation failed",
230
301
  failures: validation.failures
231
302
  }, 400);
303
+ const evalsForTerminalLog = runner.getEvals();
232
304
  const runResult = await resultify(() => runner.startRun(body));
233
305
  if (runResult.error) return c.json({
234
306
  error: "Failed to start run",
235
307
  message: formatUnknownErrorDetails(runResult.error)
236
308
  }, 500);
309
+ logStartedAppRunEvals({
310
+ runId: runResult.value.manifest.id,
311
+ shortId: runResult.value.manifest.shortId,
312
+ evals: evalsForTerminalLog,
313
+ target: body.target
314
+ });
315
+ subscribeToAppRunResultLog({
316
+ runner,
317
+ runId: runResult.value.manifest.id,
318
+ shortId: runResult.value.manifest.shortId
319
+ });
237
320
  return c.json(runResult.value, 201);
238
321
  }).post("/actions/open-location", zValidator("json", openRunLocationRequestSchema), (c) => {
239
322
  const body = c.req.valid("json");