@gleanwork/mcp-server-tester 1.0.1-beta.0 → 1.1.0
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/cli/index.js +1 -1
- package/dist/fixtures/mcp.js +1 -1
- package/dist/fixtures/mcp.js.map +1 -1
- package/dist/index-BcUWzQCx.d.cts +4282 -0
- package/dist/index-BcUWzQCx.d.ts +4282 -0
- package/dist/index.cjs +677 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +551 -4365
- package/dist/index.d.ts +551 -4365
- package/dist/index.js +667 -29
- package/dist/index.js.map +1 -1
- package/dist/reporters/mcpReporter.cjs +294 -1
- package/dist/reporters/mcpReporter.cjs.map +1 -1
- package/dist/reporters/mcpReporter.d.cts +426 -3
- package/dist/reporters/mcpReporter.d.ts +426 -3
- package/dist/reporters/mcpReporter.js +294 -1
- package/dist/reporters/mcpReporter.js.map +1 -1
- package/dist/reporters/ui-dist/app.js +1 -1
- package/dist/types/index.cjs +19 -0
- package/dist/types/index.cjs.map +1 -0
- package/dist/types/index.d.cts +9 -0
- package/dist/types/index.d.ts +9 -0
- package/dist/types/index.js +17 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +8 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as fs from 'fs/promises';
|
|
2
|
-
import { readFile, mkdir, writeFile } from 'fs/promises';
|
|
2
|
+
import { readFile, mkdir, writeFile, readdir } from 'fs/promises';
|
|
3
3
|
import * as path2 from 'path';
|
|
4
|
-
import { dirname } from 'path';
|
|
4
|
+
import { dirname, join } from 'path';
|
|
5
5
|
import * as z4 from 'zod/v4';
|
|
6
6
|
import { ZodFirstPartyTypeKind } from 'zod/v3';
|
|
7
7
|
import { z } from 'zod';
|
|
@@ -3099,6 +3099,20 @@ var init_dist3 = __esm({
|
|
|
3099
3099
|
};
|
|
3100
3100
|
}
|
|
3101
3101
|
});
|
|
3102
|
+
|
|
3103
|
+
// src/assertions/validators/types.ts
|
|
3104
|
+
var SnapshotSanitizers = {
|
|
3105
|
+
/** Replaces Unix timestamps (seconds and milliseconds) with a stable placeholder */
|
|
3106
|
+
TIMESTAMP: "timestamp",
|
|
3107
|
+
/** Replaces UUID v1-v5 strings with a stable placeholder */
|
|
3108
|
+
UUID: "uuid",
|
|
3109
|
+
/** Replaces ISO 8601 date/datetime strings with a stable placeholder */
|
|
3110
|
+
ISO_DATE: "iso-date",
|
|
3111
|
+
/** Replaces MongoDB ObjectId strings with a stable placeholder */
|
|
3112
|
+
OBJECT_ID: "objectId",
|
|
3113
|
+
/** Replaces JWT tokens with a stable placeholder */
|
|
3114
|
+
JWT: "jwt"
|
|
3115
|
+
};
|
|
3102
3116
|
var MCPHostCapabilitiesSchema = z.object({
|
|
3103
3117
|
sampling: z.record(z.string(), z.unknown()).optional(),
|
|
3104
3118
|
roots: z.object({
|
|
@@ -4384,7 +4398,7 @@ function escapeHtml(text) {
|
|
|
4384
4398
|
|
|
4385
4399
|
// package.json
|
|
4386
4400
|
var package_default = {
|
|
4387
|
-
version: "1.
|
|
4401
|
+
version: "1.1.0"};
|
|
4388
4402
|
|
|
4389
4403
|
// src/mcp/clientFactory.ts
|
|
4390
4404
|
function getRetryAfterDelayMs(err) {
|
|
@@ -5908,20 +5922,6 @@ async function validateJudge(response, config) {
|
|
|
5908
5922
|
}
|
|
5909
5923
|
}
|
|
5910
5924
|
|
|
5911
|
-
// src/assertions/validators/types.ts
|
|
5912
|
-
var SnapshotSanitizers = {
|
|
5913
|
-
/** Replaces Unix timestamps (seconds and milliseconds) with a stable placeholder */
|
|
5914
|
-
TIMESTAMP: "timestamp",
|
|
5915
|
-
/** Replaces UUID v1-v5 strings with a stable placeholder */
|
|
5916
|
-
UUID: "uuid",
|
|
5917
|
-
/** Replaces ISO 8601 date/datetime strings with a stable placeholder */
|
|
5918
|
-
ISO_DATE: "iso-date",
|
|
5919
|
-
/** Replaces MongoDB ObjectId strings with a stable placeholder */
|
|
5920
|
-
OBJECT_ID: "objectId",
|
|
5921
|
-
/** Replaces JWT tokens with a stable placeholder */
|
|
5922
|
-
JWT: "jwt"
|
|
5923
|
-
};
|
|
5924
|
-
|
|
5925
5925
|
// src/mcp/fixtures/mcpFixture.ts
|
|
5926
5926
|
var DEFAULT_CALL_TIMEOUT_MS = 3e4;
|
|
5927
5927
|
function withCallTimeout(promise, ms, opName) {
|
|
@@ -7280,6 +7280,216 @@ function buildBaselinePassMap(baseline) {
|
|
|
7280
7280
|
}
|
|
7281
7281
|
return map;
|
|
7282
7282
|
}
|
|
7283
|
+
var KIND_DIRS = {
|
|
7284
|
+
"eval-runner-result": "eval-runs",
|
|
7285
|
+
"reporter-run": "reporter-runs",
|
|
7286
|
+
"eval-run-comparison": "comparisons/eval-runs",
|
|
7287
|
+
"server-comparison": "comparisons/servers"
|
|
7288
|
+
};
|
|
7289
|
+
function createEvalResultStore(config) {
|
|
7290
|
+
if (config.provider === "file") {
|
|
7291
|
+
return new FileEvalResultStore(config);
|
|
7292
|
+
}
|
|
7293
|
+
return new GCSEvalResultStore(config);
|
|
7294
|
+
}
|
|
7295
|
+
function resolveEvalResultStore(store) {
|
|
7296
|
+
return isEvalResultStore(store) ? store : createEvalResultStore(store);
|
|
7297
|
+
}
|
|
7298
|
+
function isEvalResultStore(value) {
|
|
7299
|
+
return typeof value === "object" && value !== null && "saveArtifact" in value && "loadArtifact" in value && "loadLatestArtifact" in value && "listArtifacts" in value;
|
|
7300
|
+
}
|
|
7301
|
+
function createStoredEvalArtifact(options) {
|
|
7302
|
+
const createdAt = options.createdAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
7303
|
+
return {
|
|
7304
|
+
schemaVersion: 1,
|
|
7305
|
+
kind: options.kind,
|
|
7306
|
+
id: options.id ?? createDefaultArtifactId(createdAt),
|
|
7307
|
+
createdAt,
|
|
7308
|
+
metadata: {
|
|
7309
|
+
...defaultEnvironmentMetadata(),
|
|
7310
|
+
...options.metadata ?? {}
|
|
7311
|
+
},
|
|
7312
|
+
data: options.data
|
|
7313
|
+
};
|
|
7314
|
+
}
|
|
7315
|
+
function createDefaultArtifactId(timestamp = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
7316
|
+
const safeTimestamp = timestamp.replace(/[:.]/g, "-");
|
|
7317
|
+
const runNumber = process.env.GITHUB_RUN_NUMBER;
|
|
7318
|
+
const sha = process.env.GITHUB_SHA?.slice(0, 12);
|
|
7319
|
+
const suffix = runNumber ?? sha;
|
|
7320
|
+
return suffix ? `${safeTimestamp}-${suffix}` : safeTimestamp;
|
|
7321
|
+
}
|
|
7322
|
+
function defaultEnvironmentMetadata() {
|
|
7323
|
+
return {
|
|
7324
|
+
...process.env.GITHUB_SHA !== void 0 && {
|
|
7325
|
+
gitHash: process.env.GITHUB_SHA
|
|
7326
|
+
},
|
|
7327
|
+
...process.env.GITHUB_REF_NAME !== void 0 && {
|
|
7328
|
+
branch: process.env.GITHUB_REF_NAME
|
|
7329
|
+
},
|
|
7330
|
+
...process.env.GITHUB_RUN_NUMBER !== void 0 && {
|
|
7331
|
+
runNumber: process.env.GITHUB_RUN_NUMBER
|
|
7332
|
+
},
|
|
7333
|
+
...process.env.GITHUB_EVENT_NAME !== void 0 && {
|
|
7334
|
+
trigger: process.env.GITHUB_EVENT_NAME
|
|
7335
|
+
}
|
|
7336
|
+
};
|
|
7337
|
+
}
|
|
7338
|
+
var FileEvalResultStore = class {
|
|
7339
|
+
dir;
|
|
7340
|
+
constructor(config) {
|
|
7341
|
+
this.dir = config.dir;
|
|
7342
|
+
}
|
|
7343
|
+
async saveArtifact(artifact) {
|
|
7344
|
+
const artifactDir = join(this.dir, KIND_DIRS[artifact.kind]);
|
|
7345
|
+
await mkdir(artifactDir, { recursive: true });
|
|
7346
|
+
const serialized = JSON.stringify(artifact, null, 2);
|
|
7347
|
+
await writeFile(
|
|
7348
|
+
join(artifactDir, `${artifact.id}.json`),
|
|
7349
|
+
serialized,
|
|
7350
|
+
"utf8"
|
|
7351
|
+
);
|
|
7352
|
+
await writeFile(join(artifactDir, "latest.json"), serialized, "utf8");
|
|
7353
|
+
}
|
|
7354
|
+
async loadArtifact(kind, id) {
|
|
7355
|
+
const raw = await readFile(
|
|
7356
|
+
join(this.dir, KIND_DIRS[kind], `${id}.json`),
|
|
7357
|
+
"utf8"
|
|
7358
|
+
);
|
|
7359
|
+
return JSON.parse(raw);
|
|
7360
|
+
}
|
|
7361
|
+
async loadLatestArtifact(kind) {
|
|
7362
|
+
try {
|
|
7363
|
+
const raw = await readFile(
|
|
7364
|
+
join(this.dir, KIND_DIRS[kind], "latest.json"),
|
|
7365
|
+
"utf8"
|
|
7366
|
+
);
|
|
7367
|
+
return JSON.parse(raw);
|
|
7368
|
+
} catch (error) {
|
|
7369
|
+
if (isMissingFileError(error)) {
|
|
7370
|
+
return null;
|
|
7371
|
+
}
|
|
7372
|
+
throw error;
|
|
7373
|
+
}
|
|
7374
|
+
}
|
|
7375
|
+
async listArtifacts(kind, options = {}) {
|
|
7376
|
+
let files;
|
|
7377
|
+
try {
|
|
7378
|
+
files = await readdir(join(this.dir, KIND_DIRS[kind]));
|
|
7379
|
+
} catch (error) {
|
|
7380
|
+
if (isMissingFileError(error)) {
|
|
7381
|
+
return [];
|
|
7382
|
+
}
|
|
7383
|
+
throw error;
|
|
7384
|
+
}
|
|
7385
|
+
const summaries = await Promise.all(
|
|
7386
|
+
files.filter((f) => f.endsWith(".json") && f !== "latest.json").map(async (file) => {
|
|
7387
|
+
const raw = await readFile(
|
|
7388
|
+
join(this.dir, KIND_DIRS[kind], file),
|
|
7389
|
+
"utf8"
|
|
7390
|
+
);
|
|
7391
|
+
return toSummary(JSON.parse(raw));
|
|
7392
|
+
})
|
|
7393
|
+
);
|
|
7394
|
+
return summaries.sort((a, b) => b.createdAt.localeCompare(a.createdAt)).slice(0, options.limit);
|
|
7395
|
+
}
|
|
7396
|
+
};
|
|
7397
|
+
var GCSEvalResultStore = class {
|
|
7398
|
+
bucketName;
|
|
7399
|
+
prefix;
|
|
7400
|
+
storage;
|
|
7401
|
+
constructor(config) {
|
|
7402
|
+
this.bucketName = config.bucket;
|
|
7403
|
+
this.prefix = trimSlashes(config.prefix ?? "");
|
|
7404
|
+
}
|
|
7405
|
+
async saveArtifact(artifact) {
|
|
7406
|
+
const bucket = await this.getBucket();
|
|
7407
|
+
const serialized = JSON.stringify(artifact, null, 2);
|
|
7408
|
+
await bucket.file(
|
|
7409
|
+
this.objectPath(
|
|
7410
|
+
artifact.kind,
|
|
7411
|
+
`${encodeURIComponent(artifact.id)}.json`
|
|
7412
|
+
)
|
|
7413
|
+
).save(serialized, {
|
|
7414
|
+
contentType: "application/json",
|
|
7415
|
+
resumable: false,
|
|
7416
|
+
validation: false
|
|
7417
|
+
});
|
|
7418
|
+
await bucket.file(this.objectPath(artifact.kind, "latest.json")).save(serialized, {
|
|
7419
|
+
contentType: "application/json",
|
|
7420
|
+
resumable: false,
|
|
7421
|
+
validation: false
|
|
7422
|
+
});
|
|
7423
|
+
}
|
|
7424
|
+
async loadArtifact(kind, id) {
|
|
7425
|
+
const bucket = await this.getBucket();
|
|
7426
|
+
const file = bucket.file(
|
|
7427
|
+
this.objectPath(kind, `${encodeURIComponent(id)}.json`)
|
|
7428
|
+
);
|
|
7429
|
+
const [buffer] = await file.download();
|
|
7430
|
+
return JSON.parse(buffer.toString("utf8"));
|
|
7431
|
+
}
|
|
7432
|
+
async loadLatestArtifact(kind) {
|
|
7433
|
+
const bucket = await this.getBucket();
|
|
7434
|
+
const file = bucket.file(this.objectPath(kind, "latest.json"));
|
|
7435
|
+
const [exists] = await file.exists();
|
|
7436
|
+
if (!exists) return null;
|
|
7437
|
+
const [buffer] = await file.download();
|
|
7438
|
+
return JSON.parse(buffer.toString("utf8"));
|
|
7439
|
+
}
|
|
7440
|
+
async listArtifacts(kind, options = {}) {
|
|
7441
|
+
const bucket = await this.getBucket();
|
|
7442
|
+
const [files] = await bucket.getFiles({
|
|
7443
|
+
prefix: this.objectPath(kind, "")
|
|
7444
|
+
});
|
|
7445
|
+
const summaries = await Promise.all(
|
|
7446
|
+
files.filter(
|
|
7447
|
+
(f) => f.name.endsWith(".json") && !f.name.endsWith("/latest.json")
|
|
7448
|
+
).map(async (file) => {
|
|
7449
|
+
const [buffer] = await file.download();
|
|
7450
|
+
return toSummary(
|
|
7451
|
+
JSON.parse(buffer.toString("utf8"))
|
|
7452
|
+
);
|
|
7453
|
+
})
|
|
7454
|
+
);
|
|
7455
|
+
return summaries.sort((a, b) => b.createdAt.localeCompare(a.createdAt)).slice(0, options.limit);
|
|
7456
|
+
}
|
|
7457
|
+
async getBucket() {
|
|
7458
|
+
if (!this.storage) {
|
|
7459
|
+
const moduleName = "@google-cloud/storage";
|
|
7460
|
+
let Storage;
|
|
7461
|
+
try {
|
|
7462
|
+
const mod = await import(moduleName);
|
|
7463
|
+
Storage = mod.Storage;
|
|
7464
|
+
} catch (error) {
|
|
7465
|
+
throw new Error(
|
|
7466
|
+
`GCS result storage requires the optional \`@google-cloud/storage\` package. Install it and authenticate with Application Default Credentials via GOOGLE_APPLICATION_CREDENTIALS.
|
|
7467
|
+
Original error: ${error instanceof Error ? error.message : String(error)}`
|
|
7468
|
+
);
|
|
7469
|
+
}
|
|
7470
|
+
this.storage = new Storage();
|
|
7471
|
+
}
|
|
7472
|
+
return this.storage.bucket(this.bucketName);
|
|
7473
|
+
}
|
|
7474
|
+
objectPath(kind, filename) {
|
|
7475
|
+
const parts = [this.prefix, KIND_DIRS[kind], filename].filter(Boolean);
|
|
7476
|
+
return parts.join("/");
|
|
7477
|
+
}
|
|
7478
|
+
};
|
|
7479
|
+
function toSummary(artifact) {
|
|
7480
|
+
return {
|
|
7481
|
+
kind: artifact.kind,
|
|
7482
|
+
id: artifact.id,
|
|
7483
|
+
createdAt: artifact.createdAt,
|
|
7484
|
+
metadata: artifact.metadata
|
|
7485
|
+
};
|
|
7486
|
+
}
|
|
7487
|
+
function trimSlashes(value) {
|
|
7488
|
+
return value.replace(/^\/+|\/+$/g, "");
|
|
7489
|
+
}
|
|
7490
|
+
function isMissingFileError(error) {
|
|
7491
|
+
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
7492
|
+
}
|
|
7283
7493
|
var execFileAsync = promisify(execFile);
|
|
7284
7494
|
async function execFileNoThrow(file, args) {
|
|
7285
7495
|
try {
|
|
@@ -7326,6 +7536,41 @@ function sumUsage(a, b) {
|
|
|
7326
7536
|
}
|
|
7327
7537
|
|
|
7328
7538
|
// src/evals/evalRunner.ts
|
|
7539
|
+
function createToolOverrideMCP(mcp, variant) {
|
|
7540
|
+
return {
|
|
7541
|
+
...mcp,
|
|
7542
|
+
async listTools() {
|
|
7543
|
+
const tools = await mcp.listTools();
|
|
7544
|
+
const knownToolNames = new Set(tools.map((tool2) => tool2.name));
|
|
7545
|
+
const unknownToolNames = Object.keys(variant.tools).filter(
|
|
7546
|
+
(name15) => !knownToolNames.has(name15)
|
|
7547
|
+
);
|
|
7548
|
+
if (unknownToolNames.length > 0) {
|
|
7549
|
+
throw new Error(
|
|
7550
|
+
`[mcp-server-tester] toolOverrides variant "${variant.id}" references unknown tool(s): ` + unknownToolNames.join(", ")
|
|
7551
|
+
);
|
|
7552
|
+
}
|
|
7553
|
+
return tools.map((tool2) => {
|
|
7554
|
+
const override = variant.tools[tool2.name];
|
|
7555
|
+
if (!override) {
|
|
7556
|
+
return tool2;
|
|
7557
|
+
}
|
|
7558
|
+
return {
|
|
7559
|
+
...tool2,
|
|
7560
|
+
...override.description !== void 0 && {
|
|
7561
|
+
description: override.description
|
|
7562
|
+
},
|
|
7563
|
+
...override.inputSchema !== void 0 && {
|
|
7564
|
+
inputSchema: override.inputSchema
|
|
7565
|
+
}
|
|
7566
|
+
};
|
|
7567
|
+
});
|
|
7568
|
+
},
|
|
7569
|
+
async callTool(name15, args) {
|
|
7570
|
+
return mcp.callTool(name15, args);
|
|
7571
|
+
}
|
|
7572
|
+
};
|
|
7573
|
+
}
|
|
7329
7574
|
async function executeToolCall(evalCase, mcp) {
|
|
7330
7575
|
const mode = evalCase.mode || "direct";
|
|
7331
7576
|
try {
|
|
@@ -7510,9 +7755,12 @@ async function runExpectBlockValidations(expectBlock, response, config) {
|
|
|
7510
7755
|
}
|
|
7511
7756
|
return { expectations: results, toolPrecision, toolRecall };
|
|
7512
7757
|
}
|
|
7513
|
-
function buildRequest(evalCase) {
|
|
7758
|
+
function buildRequest(evalCase, toolOverrideVariantId) {
|
|
7514
7759
|
const request = {};
|
|
7515
7760
|
if (evalCase.description) request.description = evalCase.description;
|
|
7761
|
+
if (toolOverrideVariantId !== void 0) {
|
|
7762
|
+
request.toolOverrideVariantId = toolOverrideVariantId;
|
|
7763
|
+
}
|
|
7516
7764
|
if (evalCase.mode === "mcp_host") {
|
|
7517
7765
|
if (evalCase.scenario) request.scenario = evalCase.scenario;
|
|
7518
7766
|
if (evalCase.mcpHostConfig) {
|
|
@@ -7577,7 +7825,7 @@ async function runSingleIteration(evalCase, context, options) {
|
|
|
7577
7825
|
toolName: evalCase.scenario != null ? "mcp_host" : evalCase.toolName ?? "unknown",
|
|
7578
7826
|
source: "eval",
|
|
7579
7827
|
pass: didCasePass(error, expectationResults),
|
|
7580
|
-
request: buildRequest(evalCase),
|
|
7828
|
+
request: buildRequest(evalCase, options.toolOverrideVariantId),
|
|
7581
7829
|
response,
|
|
7582
7830
|
error,
|
|
7583
7831
|
expectations: expectationResults,
|
|
@@ -7656,7 +7904,8 @@ async function runEvalCase(evalCase, context, options = {}) {
|
|
|
7656
7904
|
authType: context.mcp.authType,
|
|
7657
7905
|
project: context.mcp.project,
|
|
7658
7906
|
durationMs: 0,
|
|
7659
|
-
tags: evalCase.tags
|
|
7907
|
+
tags: evalCase.tags,
|
|
7908
|
+
request: buildRequest(evalCase, options.toolOverrideVariantId)
|
|
7660
7909
|
};
|
|
7661
7910
|
const totalHostUsage = iterationResults.reduce(
|
|
7662
7911
|
(acc, r) => sumUsage(acc, r.hostUsage),
|
|
@@ -7715,11 +7964,15 @@ async function runEvalDataset(options, context) {
|
|
|
7715
7964
|
filterTags,
|
|
7716
7965
|
saveResultsTo,
|
|
7717
7966
|
omitResponsesFromBaseline = true,
|
|
7967
|
+
redactStoredResponses,
|
|
7968
|
+
resultStore,
|
|
7718
7969
|
baselineResultsFrom,
|
|
7970
|
+
toolOverrides,
|
|
7719
7971
|
mcpHostModel,
|
|
7720
7972
|
judgeModel
|
|
7721
7973
|
} = options;
|
|
7722
7974
|
const startTime = Date.now();
|
|
7975
|
+
const effectiveContext = toolOverrides ? { ...context, mcp: createToolOverrideMCP(context.mcp, toolOverrides) } : context;
|
|
7723
7976
|
const allSchemas = {
|
|
7724
7977
|
...dataset.schemas,
|
|
7725
7978
|
...schemas
|
|
@@ -7751,9 +8004,10 @@ async function runEvalDataset(options, context) {
|
|
|
7751
8004
|
}
|
|
7752
8005
|
}
|
|
7753
8006
|
const effectiveCase = withIterations.judgeReps === void 0 && defaultJudgeReps !== void 0 ? { ...withIterations, judgeReps: defaultJudgeReps } : withIterations;
|
|
7754
|
-
const result2 = await runEvalCase(effectiveCase,
|
|
8007
|
+
const result2 = await runEvalCase(effectiveCase, effectiveContext, {
|
|
7755
8008
|
datasetName: dataset.name,
|
|
7756
|
-
schemas: allSchemas
|
|
8009
|
+
schemas: allSchemas,
|
|
8010
|
+
toolOverrideVariantId: toolOverrides?.id
|
|
7757
8011
|
});
|
|
7758
8012
|
if (onCaseComplete) {
|
|
7759
8013
|
await onCaseComplete(result2);
|
|
@@ -7778,6 +8032,9 @@ async function runEvalDataset(options, context) {
|
|
|
7778
8032
|
gitHash,
|
|
7779
8033
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7780
8034
|
packageVersion: package_default.version,
|
|
8035
|
+
...toolOverrides !== void 0 && {
|
|
8036
|
+
toolOverrideVariantId: toolOverrides.id
|
|
8037
|
+
},
|
|
7781
8038
|
...mcpHostModel !== void 0 && { mcpHostModel },
|
|
7782
8039
|
...judgeModel !== void 0 && { judgeModel }
|
|
7783
8040
|
};
|
|
@@ -7796,7 +8053,7 @@ async function runEvalDataset(options, context) {
|
|
|
7796
8053
|
};
|
|
7797
8054
|
if (baselineResultsFrom) {
|
|
7798
8055
|
try {
|
|
7799
|
-
const baseline = await loadBaseline(baselineResultsFrom);
|
|
8056
|
+
const baseline = typeof baselineResultsFrom === "string" ? await loadBaseline(baselineResultsFrom) : await loadStoredBaseline(baselineResultsFrom, resultStore);
|
|
7800
8057
|
const baselinePassRate = baseline.total > 0 ? baseline.passed / baseline.total : 0;
|
|
7801
8058
|
const baselineMap = buildBaselinePassMap(baseline);
|
|
7802
8059
|
const currentCaseIds = result.caseResults.map((cr) => cr.id);
|
|
@@ -7824,7 +8081,7 @@ async function runEvalDataset(options, context) {
|
|
|
7824
8081
|
result.deltaPassRate = result.total > 0 ? result.passed / result.total - baselinePassRate : 0;
|
|
7825
8082
|
} catch (err) {
|
|
7826
8083
|
console.warn(
|
|
7827
|
-
`[mcp-server-tester] Could not load baseline from ${baselineResultsFrom}: ${err instanceof Error ? err.message : String(err)}`
|
|
8084
|
+
`[mcp-server-tester] Could not load baseline from ${formatBaselineRef(baselineResultsFrom)}: ${err instanceof Error ? err.message : String(err)}`
|
|
7828
8085
|
);
|
|
7829
8086
|
}
|
|
7830
8087
|
}
|
|
@@ -7839,9 +8096,26 @@ async function runEvalDataset(options, context) {
|
|
|
7839
8096
|
result.datasetToolF1 = avgPrec + avgRecall > 0 ? 2 * avgPrec * avgRecall / (avgPrec + avgRecall) : 0;
|
|
7840
8097
|
}
|
|
7841
8098
|
if (saveResultsTo) {
|
|
7842
|
-
|
|
7843
|
-
|
|
7844
|
-
|
|
8099
|
+
if (typeof saveResultsTo === "string") {
|
|
8100
|
+
await saveBaseline(result, saveResultsTo, {
|
|
8101
|
+
omitResponses: omitResponsesFromBaseline
|
|
8102
|
+
});
|
|
8103
|
+
} else {
|
|
8104
|
+
await saveStoredEvalResult(result, saveResultsTo, {
|
|
8105
|
+
resultStore,
|
|
8106
|
+
omitResponses: redactStoredResponses ?? true,
|
|
8107
|
+
metadata: {
|
|
8108
|
+
datasetName: dataset.name,
|
|
8109
|
+
...toolOverrides?.id !== void 0 && {
|
|
8110
|
+
toolOverrideVariantId: toolOverrides.id
|
|
8111
|
+
},
|
|
8112
|
+
...mcpHostModel !== void 0 && { mcpHostModel },
|
|
8113
|
+
...judgeModel !== void 0 && { judgeModel },
|
|
8114
|
+
...gitHash !== void 0 && { gitHash },
|
|
8115
|
+
packageVersion: package_default.version
|
|
8116
|
+
}
|
|
8117
|
+
});
|
|
8118
|
+
}
|
|
7845
8119
|
}
|
|
7846
8120
|
if (context.testInfo) {
|
|
7847
8121
|
await context.testInfo.attach("mcp-test-results", {
|
|
@@ -7855,6 +8129,50 @@ async function runEvalDataset(options, context) {
|
|
|
7855
8129
|
}
|
|
7856
8130
|
return result;
|
|
7857
8131
|
}
|
|
8132
|
+
async function loadStoredBaseline(baselineResultsFrom, resultStore) {
|
|
8133
|
+
if (!resultStore) {
|
|
8134
|
+
throw new Error("resultStore is required for store-backed baselines");
|
|
8135
|
+
}
|
|
8136
|
+
const store = resolveEvalResultStore(resultStore);
|
|
8137
|
+
const artifact = baselineResultsFrom.ref === "latest" ? await store.loadLatestArtifact("eval-runner-result") : await store.loadArtifact(
|
|
8138
|
+
"eval-runner-result",
|
|
8139
|
+
baselineResultsFrom.ref.id
|
|
8140
|
+
);
|
|
8141
|
+
if (!artifact) {
|
|
8142
|
+
throw new Error("No latest eval run artifact found");
|
|
8143
|
+
}
|
|
8144
|
+
return artifact.data;
|
|
8145
|
+
}
|
|
8146
|
+
async function saveStoredEvalResult(result, saveResultsTo, options) {
|
|
8147
|
+
if (!options.resultStore) {
|
|
8148
|
+
throw new Error("resultStore is required for store-backed saves");
|
|
8149
|
+
}
|
|
8150
|
+
const store = resolveEvalResultStore(options.resultStore);
|
|
8151
|
+
const data = options.omitResponses ? omitResponsesFromResult(result) : result;
|
|
8152
|
+
const id = saveResultsTo.ref && saveResultsTo.ref !== "latest" ? saveResultsTo.ref.id : void 0;
|
|
8153
|
+
await store.saveArtifact(
|
|
8154
|
+
createStoredEvalArtifact({
|
|
8155
|
+
kind: "eval-runner-result",
|
|
8156
|
+
id,
|
|
8157
|
+
data,
|
|
8158
|
+
metadata: options.metadata
|
|
8159
|
+
})
|
|
8160
|
+
);
|
|
8161
|
+
}
|
|
8162
|
+
function omitResponsesFromResult(result) {
|
|
8163
|
+
return {
|
|
8164
|
+
...result,
|
|
8165
|
+
caseResults: result.caseResults.map(
|
|
8166
|
+
({ response: _response, ...rest }) => rest
|
|
8167
|
+
)
|
|
8168
|
+
};
|
|
8169
|
+
}
|
|
8170
|
+
function formatBaselineRef(baselineResultsFrom) {
|
|
8171
|
+
if (typeof baselineResultsFrom === "string") {
|
|
8172
|
+
return baselineResultsFrom;
|
|
8173
|
+
}
|
|
8174
|
+
return baselineResultsFrom.ref === "latest" ? "resultStore latest" : `resultStore ${baselineResultsFrom.ref.id}`;
|
|
8175
|
+
}
|
|
7858
8176
|
|
|
7859
8177
|
// src/evals/serverComparison.ts
|
|
7860
8178
|
async function runServerComparison(options, contextA, contextB) {
|
|
@@ -7896,7 +8214,7 @@ async function runServerComparison(options, contextA, contextB) {
|
|
|
7896
8214
|
}
|
|
7897
8215
|
const total = cases.length;
|
|
7898
8216
|
const decidedCases = aWins + bWins + ties;
|
|
7899
|
-
|
|
8217
|
+
const comparison = {
|
|
7900
8218
|
dataset: options.dataset.name,
|
|
7901
8219
|
total,
|
|
7902
8220
|
aWins,
|
|
@@ -7913,6 +8231,326 @@ async function runServerComparison(options, contextA, contextB) {
|
|
|
7913
8231
|
serverBResult: resultB,
|
|
7914
8232
|
durationMs: Date.now() - startTime
|
|
7915
8233
|
};
|
|
8234
|
+
if (options.comparisonStore) {
|
|
8235
|
+
await saveServerComparison({
|
|
8236
|
+
store: options.comparisonStore,
|
|
8237
|
+
comparison,
|
|
8238
|
+
id: options.comparisonId,
|
|
8239
|
+
metadata: {
|
|
8240
|
+
datasetName: options.dataset.name,
|
|
8241
|
+
...options.comparisonMetadata ?? {}
|
|
8242
|
+
},
|
|
8243
|
+
redactStoredResponses: options.redactStoredResponses
|
|
8244
|
+
});
|
|
8245
|
+
}
|
|
8246
|
+
return comparison;
|
|
8247
|
+
}
|
|
8248
|
+
async function saveServerComparison(options) {
|
|
8249
|
+
const store = resolveEvalResultStore(options.store);
|
|
8250
|
+
const data = options.redactStoredResponses ? redactResponses(options.comparison) : options.comparison;
|
|
8251
|
+
const artifact = createStoredEvalArtifact({
|
|
8252
|
+
kind: "server-comparison",
|
|
8253
|
+
id: options.id,
|
|
8254
|
+
data,
|
|
8255
|
+
metadata: {
|
|
8256
|
+
datasetName: options.comparison.dataset,
|
|
8257
|
+
...options.metadata ?? {}
|
|
8258
|
+
}
|
|
8259
|
+
});
|
|
8260
|
+
await store.saveArtifact(artifact);
|
|
8261
|
+
return artifact;
|
|
8262
|
+
}
|
|
8263
|
+
function redactResponses(value) {
|
|
8264
|
+
return JSON.parse(
|
|
8265
|
+
JSON.stringify(
|
|
8266
|
+
value,
|
|
8267
|
+
(key, currentValue) => key === "response" ? void 0 : currentValue
|
|
8268
|
+
)
|
|
8269
|
+
);
|
|
8270
|
+
}
|
|
8271
|
+
|
|
8272
|
+
// src/evals/evalRunComparison.ts
|
|
8273
|
+
function compareEvalRuns(options) {
|
|
8274
|
+
const { baseline, candidate, labels } = options;
|
|
8275
|
+
const candidateMap = new Map(
|
|
8276
|
+
candidate.caseResults.map((result) => [result.id, result])
|
|
8277
|
+
);
|
|
8278
|
+
const cases = [];
|
|
8279
|
+
const seenIds = /* @__PURE__ */ new Set();
|
|
8280
|
+
for (const baselineCase of baseline.caseResults) {
|
|
8281
|
+
seenIds.add(baselineCase.id);
|
|
8282
|
+
const candidateCase = candidateMap.get(baselineCase.id);
|
|
8283
|
+
if (!candidateCase) {
|
|
8284
|
+
cases.push({
|
|
8285
|
+
id: baselineCase.id,
|
|
8286
|
+
outcome: "MISSING_FROM_CANDIDATE",
|
|
8287
|
+
baseline: baselineCase
|
|
8288
|
+
});
|
|
8289
|
+
continue;
|
|
8290
|
+
}
|
|
8291
|
+
cases.push({
|
|
8292
|
+
id: baselineCase.id,
|
|
8293
|
+
outcome: compareCaseOutcome(baselineCase.pass, candidateCase.pass),
|
|
8294
|
+
baseline: baselineCase,
|
|
8295
|
+
candidate: candidateCase
|
|
8296
|
+
});
|
|
8297
|
+
}
|
|
8298
|
+
for (const candidateCase of candidate.caseResults) {
|
|
8299
|
+
if (seenIds.has(candidateCase.id)) {
|
|
8300
|
+
continue;
|
|
8301
|
+
}
|
|
8302
|
+
cases.push({
|
|
8303
|
+
id: candidateCase.id,
|
|
8304
|
+
outcome: "MISSING_FROM_BASELINE",
|
|
8305
|
+
candidate: candidateCase
|
|
8306
|
+
});
|
|
8307
|
+
}
|
|
8308
|
+
const baselinePassRate = passRate(baseline);
|
|
8309
|
+
const candidatePassRate = passRate(candidate);
|
|
8310
|
+
return {
|
|
8311
|
+
baselineLabel: labels?.baseline ?? "baseline",
|
|
8312
|
+
candidateLabel: labels?.candidate ?? candidate.metadata?.toolOverrideVariantId ?? "candidate",
|
|
8313
|
+
baselinePassRate,
|
|
8314
|
+
candidatePassRate,
|
|
8315
|
+
deltaPassRate: candidatePassRate - baselinePassRate,
|
|
8316
|
+
...metricDelta(
|
|
8317
|
+
"ToolPrecision",
|
|
8318
|
+
baseline.datasetToolPrecision,
|
|
8319
|
+
candidate.datasetToolPrecision
|
|
8320
|
+
),
|
|
8321
|
+
...metricDelta(
|
|
8322
|
+
"ToolRecall",
|
|
8323
|
+
baseline.datasetToolRecall,
|
|
8324
|
+
candidate.datasetToolRecall
|
|
8325
|
+
),
|
|
8326
|
+
...metricDelta("ToolF1", baseline.datasetToolF1, candidate.datasetToolF1),
|
|
8327
|
+
cases,
|
|
8328
|
+
improvedCases: cases.filter((c) => c.outcome === "IMPROVED"),
|
|
8329
|
+
regressedCases: cases.filter((c) => c.outcome === "REGRESSED"),
|
|
8330
|
+
unchangedPasses: cases.filter((c) => c.outcome === "UNCHANGED_PASS"),
|
|
8331
|
+
unchangedFailures: cases.filter((c) => c.outcome === "UNCHANGED_FAIL"),
|
|
8332
|
+
missingFromBaseline: cases.filter(
|
|
8333
|
+
(c) => c.outcome === "MISSING_FROM_BASELINE"
|
|
8334
|
+
),
|
|
8335
|
+
missingFromCandidate: cases.filter(
|
|
8336
|
+
(c) => c.outcome === "MISSING_FROM_CANDIDATE"
|
|
8337
|
+
)
|
|
8338
|
+
};
|
|
8339
|
+
}
|
|
8340
|
+
async function loadStoredEvalRunnerResult(storeLike, ref) {
|
|
8341
|
+
const store = resolveEvalResultStore(storeLike);
|
|
8342
|
+
const artifact = ref === "latest" ? await store.loadLatestArtifact("eval-runner-result") : await store.loadArtifact(
|
|
8343
|
+
"eval-runner-result",
|
|
8344
|
+
ref.id
|
|
8345
|
+
);
|
|
8346
|
+
if (!artifact) {
|
|
8347
|
+
throw new Error("No latest eval run artifact found");
|
|
8348
|
+
}
|
|
8349
|
+
return artifact;
|
|
8350
|
+
}
|
|
8351
|
+
async function saveEvalRunComparison(options) {
|
|
8352
|
+
const store = resolveEvalResultStore(options.store);
|
|
8353
|
+
const data = options.redactStoredResponses ? redactResponses2(options.comparison) : options.comparison;
|
|
8354
|
+
const artifact = createStoredEvalArtifact({
|
|
8355
|
+
kind: "eval-run-comparison",
|
|
8356
|
+
id: options.id,
|
|
8357
|
+
data,
|
|
8358
|
+
metadata: {
|
|
8359
|
+
labels: {
|
|
8360
|
+
baseline: options.comparison.baselineLabel,
|
|
8361
|
+
candidate: options.comparison.candidateLabel
|
|
8362
|
+
},
|
|
8363
|
+
...options.metadata ?? {}
|
|
8364
|
+
}
|
|
8365
|
+
});
|
|
8366
|
+
await store.saveArtifact(artifact);
|
|
8367
|
+
return artifact;
|
|
8368
|
+
}
|
|
8369
|
+
function compareCaseOutcome(baselinePass, candidatePass) {
|
|
8370
|
+
if (!baselinePass && candidatePass) return "IMPROVED";
|
|
8371
|
+
if (baselinePass && !candidatePass) return "REGRESSED";
|
|
8372
|
+
return baselinePass ? "UNCHANGED_PASS" : "UNCHANGED_FAIL";
|
|
8373
|
+
}
|
|
8374
|
+
function passRate(result) {
|
|
8375
|
+
return result.total > 0 ? result.passed / result.total : 0;
|
|
8376
|
+
}
|
|
8377
|
+
function metricDelta(name15, baselineValue, candidateValue) {
|
|
8378
|
+
const result = {};
|
|
8379
|
+
if (baselineValue !== void 0) {
|
|
8380
|
+
result[`baseline${name15}`] = baselineValue;
|
|
8381
|
+
}
|
|
8382
|
+
if (candidateValue !== void 0) {
|
|
8383
|
+
result[`candidate${name15}`] = candidateValue;
|
|
8384
|
+
}
|
|
8385
|
+
if (baselineValue !== void 0 && candidateValue !== void 0) {
|
|
8386
|
+
result[`delta${name15}`] = candidateValue - baselineValue;
|
|
8387
|
+
}
|
|
8388
|
+
return result;
|
|
8389
|
+
}
|
|
8390
|
+
function redactResponses2(value) {
|
|
8391
|
+
return JSON.parse(
|
|
8392
|
+
JSON.stringify(
|
|
8393
|
+
value,
|
|
8394
|
+
(key, currentValue) => key === "response" ? void 0 : currentValue
|
|
8395
|
+
)
|
|
8396
|
+
);
|
|
8397
|
+
}
|
|
8398
|
+
|
|
8399
|
+
// src/evals/variantExperiment.ts
|
|
8400
|
+
async function runVariantExperiment(options, context) {
|
|
8401
|
+
const metric = options.metric ?? "passRate";
|
|
8402
|
+
const maxRounds = options.maxRounds ?? 1;
|
|
8403
|
+
const minImprovement = options.minImprovement ?? 0;
|
|
8404
|
+
const allowRegressions = options.allowRegressions ?? false;
|
|
8405
|
+
const baseline = await runEvalDataset(
|
|
8406
|
+
buildRunOptions(options, void 0),
|
|
8407
|
+
context
|
|
8408
|
+
);
|
|
8409
|
+
const baselineValue = readMetric(baseline, metric);
|
|
8410
|
+
if (baselineValue === void 0) {
|
|
8411
|
+
throw new Error(
|
|
8412
|
+
`Metric '${metric}' is unavailable: the dataset produced no tool precision/recall data. Add mcp_host cases with toolsTriggered expectations, or use metric 'passRate'.`
|
|
8413
|
+
);
|
|
8414
|
+
}
|
|
8415
|
+
const rounds = [];
|
|
8416
|
+
let bestSoFar;
|
|
8417
|
+
let bestAttempted;
|
|
8418
|
+
let reason = "max-rounds";
|
|
8419
|
+
for (let round = 0; round < maxRounds; round++) {
|
|
8420
|
+
const variants = await gatherVariants(options, {
|
|
8421
|
+
round,
|
|
8422
|
+
baseline,
|
|
8423
|
+
metric,
|
|
8424
|
+
history: rounds,
|
|
8425
|
+
bestSoFar
|
|
8426
|
+
});
|
|
8427
|
+
if (variants.length === 0) {
|
|
8428
|
+
reason = round === 0 ? "no-variants" : "no-improvement";
|
|
8429
|
+
break;
|
|
8430
|
+
}
|
|
8431
|
+
const candidates = [];
|
|
8432
|
+
for (const variant of variants) {
|
|
8433
|
+
const candidate = await scoreVariant(
|
|
8434
|
+
options,
|
|
8435
|
+
context,
|
|
8436
|
+
baseline,
|
|
8437
|
+
baselineValue,
|
|
8438
|
+
metric,
|
|
8439
|
+
allowRegressions,
|
|
8440
|
+
variant
|
|
8441
|
+
);
|
|
8442
|
+
candidates.push(candidate);
|
|
8443
|
+
bestAttempted = pickBetter(bestAttempted, candidate, true);
|
|
8444
|
+
}
|
|
8445
|
+
const roundBest = candidates.reduce(
|
|
8446
|
+
(best, candidate) => pickBetter(best, candidate, false),
|
|
8447
|
+
void 0
|
|
8448
|
+
);
|
|
8449
|
+
rounds.push({ round, candidates, best: roundBest });
|
|
8450
|
+
if (roundBest) {
|
|
8451
|
+
const improvement = roundBest.metricValue - (bestSoFar?.metricValue ?? baselineValue);
|
|
8452
|
+
bestSoFar = pickBetter(bestSoFar, roundBest, false);
|
|
8453
|
+
if (improvement < minImprovement) {
|
|
8454
|
+
reason = "no-improvement";
|
|
8455
|
+
break;
|
|
8456
|
+
}
|
|
8457
|
+
}
|
|
8458
|
+
}
|
|
8459
|
+
const winner = bestSoFar;
|
|
8460
|
+
const proposalSource = winner ?? bestAttempted;
|
|
8461
|
+
const proposal = proposalSource ? buildProposal(metric, baselineValue, proposalSource, winner !== void 0) : void 0;
|
|
8462
|
+
return {
|
|
8463
|
+
metric,
|
|
8464
|
+
baseline,
|
|
8465
|
+
rounds,
|
|
8466
|
+
winner,
|
|
8467
|
+
proposal,
|
|
8468
|
+
converged: true,
|
|
8469
|
+
reason
|
|
8470
|
+
};
|
|
8471
|
+
}
|
|
8472
|
+
async function gatherVariants(options, context) {
|
|
8473
|
+
if (context.round === 0 && options.variants && options.variants.length > 0) {
|
|
8474
|
+
return options.variants;
|
|
8475
|
+
}
|
|
8476
|
+
if (options.proposeVariants) {
|
|
8477
|
+
return options.proposeVariants(context);
|
|
8478
|
+
}
|
|
8479
|
+
return [];
|
|
8480
|
+
}
|
|
8481
|
+
async function scoreVariant(options, context, baseline, baselineValue, metric, allowRegressions, variant) {
|
|
8482
|
+
const result = await runEvalDataset(
|
|
8483
|
+
buildRunOptions(options, variant),
|
|
8484
|
+
context
|
|
8485
|
+
);
|
|
8486
|
+
const comparison = compareEvalRuns({
|
|
8487
|
+
baseline,
|
|
8488
|
+
candidate: result,
|
|
8489
|
+
labels: { candidate: variant.id }
|
|
8490
|
+
});
|
|
8491
|
+
const metricValue = readMetric(result, metric) ?? baselineValue;
|
|
8492
|
+
const disqualified = !allowRegressions && comparison.regressedCases.length > 0;
|
|
8493
|
+
return {
|
|
8494
|
+
variant,
|
|
8495
|
+
result,
|
|
8496
|
+
comparison,
|
|
8497
|
+
metricValue,
|
|
8498
|
+
metricDelta: metricValue - baselineValue,
|
|
8499
|
+
disqualified
|
|
8500
|
+
};
|
|
8501
|
+
}
|
|
8502
|
+
function pickBetter(incumbent, challenger, includeDisqualified) {
|
|
8503
|
+
if (!includeDisqualified && challenger.disqualified) {
|
|
8504
|
+
return incumbent;
|
|
8505
|
+
}
|
|
8506
|
+
if (!incumbent) {
|
|
8507
|
+
return challenger;
|
|
8508
|
+
}
|
|
8509
|
+
return challenger.metricValue > incumbent.metricValue ? challenger : incumbent;
|
|
8510
|
+
}
|
|
8511
|
+
function buildProposal(metric, baselineValue, source, isWinner) {
|
|
8512
|
+
let recommendation;
|
|
8513
|
+
if (isWinner) {
|
|
8514
|
+
recommendation = source.metricDelta > 0 ? "apply" : "inconclusive";
|
|
8515
|
+
} else {
|
|
8516
|
+
recommendation = source.disqualified ? "reject" : "inconclusive";
|
|
8517
|
+
}
|
|
8518
|
+
return {
|
|
8519
|
+
variantId: source.variant.id,
|
|
8520
|
+
metric,
|
|
8521
|
+
baselineValue,
|
|
8522
|
+
candidateValue: source.metricValue,
|
|
8523
|
+
delta: source.metricDelta,
|
|
8524
|
+
toolChanges: source.variant.tools,
|
|
8525
|
+
improvedCaseIds: source.comparison.improvedCases.map((c) => c.id),
|
|
8526
|
+
regressedCaseIds: source.comparison.regressedCases.map((c) => c.id),
|
|
8527
|
+
recommendation
|
|
8528
|
+
};
|
|
8529
|
+
}
|
|
8530
|
+
function readMetric(result, metric) {
|
|
8531
|
+
switch (metric) {
|
|
8532
|
+
case "passRate":
|
|
8533
|
+
return result.total > 0 ? result.passed / result.total : 0;
|
|
8534
|
+
case "toolF1":
|
|
8535
|
+
return result.datasetToolF1;
|
|
8536
|
+
case "toolPrecision":
|
|
8537
|
+
return result.datasetToolPrecision;
|
|
8538
|
+
case "toolRecall":
|
|
8539
|
+
return result.datasetToolRecall;
|
|
8540
|
+
}
|
|
8541
|
+
}
|
|
8542
|
+
function buildRunOptions(options, toolOverrides) {
|
|
8543
|
+
return {
|
|
8544
|
+
dataset: options.dataset,
|
|
8545
|
+
toolOverrides,
|
|
8546
|
+
defaultLlmIterations: options.defaultLlmIterations,
|
|
8547
|
+
defaultJudgeReps: options.defaultJudgeReps,
|
|
8548
|
+
concurrency: options.concurrency,
|
|
8549
|
+
filterTags: options.filterTags,
|
|
8550
|
+
schemas: options.schemas,
|
|
8551
|
+
mcpHostModel: options.mcpHostModel,
|
|
8552
|
+
judgeModel: options.judgeModel
|
|
8553
|
+
};
|
|
7916
8554
|
}
|
|
7917
8555
|
|
|
7918
8556
|
// src/spec/conformanceChecks.ts
|
|
@@ -8086,6 +8724,6 @@ function formatCapabilities(capabilities) {
|
|
|
8086
8724
|
return parts.length > 0 ? parts.join(", ") : "none declared";
|
|
8087
8725
|
}
|
|
8088
8726
|
|
|
8089
|
-
export { BUILT_IN_RUBRICS, CLIOAuthClient, DiscoveryError, ENV_VAR_NAMES, EvalCaseSchema, EvalDatasetSchema, MCPConfigSchema, MCP_PROTOCOL_VERSION, PlaywrightOAuthClientProvider, SnapshotSanitizers, clearJudgeRegistry, closeMCPClient, createJudge, createMCPClientForConfig, createMCPFixture, createTokenAuthHeaders, discoverAuthorizationServer, discoverProtectedResource, expect, extractText, getMissingDependencyMessage, getRegisteredJudge, getResponseSizeBytes, hasValidTokens, injectTokens, isBuiltInRubric, isHttpConfig, isProviderAvailable, isStdioConfig, isTokenExpired, isTokenExpiringSoon, loadBaseline, loadEvalDataset, loadEvalDatasetFromObject, loadTokens, loadTokensFromEnv, test2 as mcpAuthTest, normalizeToolResponse, normalizeWhitespace, performClientCredentialsFlow, performOAuthSetup, performOAuthSetupIfNeeded, refreshAccessToken, registerJudge, resolveRubric, runConformanceChecks, runEvalCase, runEvalDataset, runServerComparison, saveBaseline, simulateMCPHost, test, validateAccessToken, validateError, validateEvalCase, validateEvalDataset, validateJudge, validateMCPConfig, validatePattern, validateResponse, validateSchema, validateSize, validateText, validateToolCallCount, validateToolCalls };
|
|
8727
|
+
export { BUILT_IN_RUBRICS, CLIOAuthClient, DiscoveryError, ENV_VAR_NAMES, EvalCaseSchema, EvalDatasetSchema, FileEvalResultStore, GCSEvalResultStore, MCPConfigSchema, MCP_PROTOCOL_VERSION, PlaywrightOAuthClientProvider, SnapshotSanitizers, clearJudgeRegistry, closeMCPClient, compareEvalRuns, createDefaultArtifactId, createEvalResultStore, createJudge, createMCPClientForConfig, createMCPFixture, createStoredEvalArtifact, createTokenAuthHeaders, defaultEnvironmentMetadata, discoverAuthorizationServer, discoverProtectedResource, expect, extractText, getMissingDependencyMessage, getRegisteredJudge, getResponseSizeBytes, hasValidTokens, injectTokens, isBuiltInRubric, isEvalResultStore, isHttpConfig, isProviderAvailable, isStdioConfig, isTokenExpired, isTokenExpiringSoon, loadBaseline, loadEvalDataset, loadEvalDatasetFromObject, loadStoredEvalRunnerResult, loadTokens, loadTokensFromEnv, test2 as mcpAuthTest, normalizeToolResponse, normalizeWhitespace, performClientCredentialsFlow, performOAuthSetup, performOAuthSetupIfNeeded, refreshAccessToken, registerJudge, resolveEvalResultStore, resolveRubric, runConformanceChecks, runEvalCase, runEvalDataset, runServerComparison, runVariantExperiment, saveBaseline, saveEvalRunComparison, saveServerComparison, simulateMCPHost, test, validateAccessToken, validateError, validateEvalCase, validateEvalDataset, validateJudge, validateMCPConfig, validatePattern, validateResponse, validateSchema, validateSize, validateText, validateToolCallCount, validateToolCalls };
|
|
8090
8728
|
//# sourceMappingURL=index.js.map
|
|
8091
8729
|
//# sourceMappingURL=index.js.map
|