@verdict-ai/mcp 0.0.0-stage → 0.2.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/LICENSE +9 -0
- package/README.md +24 -2
- package/dist/agreement.d.ts +67 -0
- package/dist/agreement.js +45 -0
- package/dist/agreement.js.map +1 -0
- package/dist/bin.d.ts +2 -0
- package/dist/bin.js +10 -0
- package/dist/bin.js.map +1 -0
- package/dist/hub.d.ts +16 -0
- package/dist/hub.js +62 -0
- package/dist/hub.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +149 -0
- package/dist/index.js.map +1 -0
- package/dist/operations.d.ts +52 -0
- package/dist/operations.js +39 -0
- package/dist/operations.js.map +1 -0
- package/dist/result.d.ts +18 -0
- package/dist/result.js +15 -0
- package/dist/result.js.map +1 -0
- package/dist/summary.d.ts +45 -0
- package/dist/summary.js +16 -0
- package/dist/summary.js.map +1 -0
- package/package.json +57 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Verdict contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
+
|
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,25 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @verdict-ai/mcp
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Stdio MCP server exposing evaluation tools to agents.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm install @verdict-ai/mcp
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Add this to `claude_desktop_config.json`:
|
|
10
|
+
|
|
11
|
+
```json
|
|
12
|
+
{
|
|
13
|
+
"mcpServers": {
|
|
14
|
+
"verdict": {
|
|
15
|
+
"command": "npx",
|
|
16
|
+
"args": ["-y", "@verdict-ai/mcp"],
|
|
17
|
+
"env": {
|
|
18
|
+
"VERDICT_API_URL": "http://localhost:8787"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Requires Node 20 or newer. [Documentation](https://verdict-docs.developerolim.workers.dev/reference/mcp). MIT licensed.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exposes check_against_humans: run a rubric file over a human-labelled gold file and report agreement.
|
|
3
|
+
* Agents edit the rubric between calls, so the file is re-read every time; the reply lists every disagreement with a
|
|
4
|
+
* preview so the caller can see what to change without opening the gold file.
|
|
5
|
+
*/
|
|
6
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
7
|
+
import { type AgreementReport, type Engine } from "@verdict-ai/core";
|
|
8
|
+
/** File access stays injectable so the tool can be exercised in memory. */
|
|
9
|
+
export interface AgreementDependencies {
|
|
10
|
+
engine?: Engine;
|
|
11
|
+
read: (path: string) => Promise<string>;
|
|
12
|
+
resolve: (path: string) => string;
|
|
13
|
+
dirname: (path: string) => string;
|
|
14
|
+
}
|
|
15
|
+
/** Shapes a report for an agent: totals first, then only the subjects and criteria that disagree. */
|
|
16
|
+
export declare function agreementSummary(report: AgreementReport): {
|
|
17
|
+
rubric: string;
|
|
18
|
+
items: number;
|
|
19
|
+
agreement: string;
|
|
20
|
+
decided: number;
|
|
21
|
+
agreed: number;
|
|
22
|
+
askedHuman: number;
|
|
23
|
+
failed: number;
|
|
24
|
+
criteria: {
|
|
25
|
+
[k: string]: {
|
|
26
|
+
agreed: number;
|
|
27
|
+
n: number;
|
|
28
|
+
agreement: string | null;
|
|
29
|
+
askedHuman: number;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
splits: {
|
|
33
|
+
[k: string]: {
|
|
34
|
+
agreed: number;
|
|
35
|
+
decided: number;
|
|
36
|
+
items: number;
|
|
37
|
+
agreement: string | null;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
labelSources: Record<string, number>;
|
|
41
|
+
disagreements: {
|
|
42
|
+
id: string;
|
|
43
|
+
name: string;
|
|
44
|
+
human: {
|
|
45
|
+
passed?: boolean | undefined;
|
|
46
|
+
criteria?: Record<string, string | number | boolean> | undefined;
|
|
47
|
+
};
|
|
48
|
+
preview: string | undefined;
|
|
49
|
+
verdict: {
|
|
50
|
+
passed: boolean | null;
|
|
51
|
+
criteria: {
|
|
52
|
+
[k: string]: {
|
|
53
|
+
value: string | number | null;
|
|
54
|
+
confidence: number | null;
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
}[];
|
|
59
|
+
askedHumanFor: string[];
|
|
60
|
+
invalidInput: {
|
|
61
|
+
id: string;
|
|
62
|
+
name: string;
|
|
63
|
+
errors: import("@verdict-ai/core").InputError[] | undefined;
|
|
64
|
+
}[];
|
|
65
|
+
};
|
|
66
|
+
/** Registers the tool; failures reach the caller as MCP error content. */
|
|
67
|
+
export declare function registerAgreement(server: McpServer, deps: AgreementDependencies): void;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { checkAgainstHumans, loadRubricText, parseGoldSet, parseRubric, ValidationError } from "@verdict-ai/core";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { text, toolResult } from "./result.js";
|
|
4
|
+
const percent = (x) => (x === null ? null : `${Math.round(x * 100)}%`);
|
|
5
|
+
/** Shapes a report for an agent: totals first, then only the subjects and criteria that disagree. */
|
|
6
|
+
export function agreementSummary(report) {
|
|
7
|
+
const disagreeing = report.results.filter((x) => x.agrees === false || Object.values(x.criteria).some((c) => c.agrees === false));
|
|
8
|
+
return {
|
|
9
|
+
rubric: report.rubric, items: report.items,
|
|
10
|
+
agreement: `${report.agreed}/${report.decided} decided by Verdict agree with the humans (${percent(report.agreement)})`,
|
|
11
|
+
decided: report.decided, agreed: report.agreed, askedHuman: report.askedHuman, failed: report.failed,
|
|
12
|
+
criteria: Object.fromEntries(Object.entries(report.criteria).map(([id, c]) => [id, { agreed: c.agreed, n: c.n, agreement: percent(c.agreement), askedHuman: c.askedHuman }])),
|
|
13
|
+
splits: Object.fromEntries(Object.entries(report.splits).map(([name, t]) => [name, { agreed: t.agreed, decided: t.decided, items: t.items, agreement: percent(t.agreement) }])),
|
|
14
|
+
labelSources: report.labelSources,
|
|
15
|
+
disagreements: disagreeing.map((x) => ({
|
|
16
|
+
id: x.id, name: x.name, human: x.human, preview: x.preview,
|
|
17
|
+
verdict: { passed: x.passed, criteria: Object.fromEntries(Object.entries(x.criteria).map(([id, c]) => [id, { value: c.verdict, confidence: c.confidence === null ? null : Math.round(c.confidence * 100) / 100 }])) },
|
|
18
|
+
})),
|
|
19
|
+
askedHumanFor: report.results.filter((x) => x.askedHuman).map((x) => x.name),
|
|
20
|
+
invalidInput: report.results.filter((x) => x.inputErrors).map((x) => ({ id: x.id, name: x.name, errors: x.inputErrors })),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/** Registers the tool; failures reach the caller as MCP error content. */
|
|
24
|
+
export function registerAgreement(server, deps) {
|
|
25
|
+
server.registerTool("check_against_humans", {
|
|
26
|
+
title: "Check a rubric against human labels",
|
|
27
|
+
description: "Run a rubric over a gold set (subjects people already judged) and report how often Verdict reached the same verdict: overall pass/fail agreement, per-criterion agreement, how many subjects the judge handed to a human (low-confidence escalation), and every disagreement with a preview. `rubricPath` is a local YAML/JSON rubric file, re-read on every call; `gold` is a local JSON array or JSON-lines file of {id?, name, inputs, expected?: {criterion: label}, human?: {passed?, criteria?}, labelSource?, split?}; choice criteria are labelled with an option id, and unreadable labels are rejected before any judge runs. Local mode only.",
|
|
28
|
+
inputSchema: {
|
|
29
|
+
rubricPath: z.string().optional().describe("Local rubric file (YAML or JSON)"),
|
|
30
|
+
rubric: z.union([z.string(), z.record(z.string(), z.unknown())]).optional().describe("Stored rubric id or inline rubric, instead of rubricPath"),
|
|
31
|
+
gold: z.string().describe("Local gold-set file: JSON array or JSON lines"),
|
|
32
|
+
},
|
|
33
|
+
}, async ({ rubricPath, rubric, gold }) => toolResult(async () => {
|
|
34
|
+
// Gold files and rubric paths are local; a remote API has no access to them.
|
|
35
|
+
if (!deps.engine)
|
|
36
|
+
throw new ValidationError("check_against_humans needs the local engine (unset VERDICT_API_URL)");
|
|
37
|
+
const ref = rubricPath ? loadRubricText(await deps.read(deps.resolve(rubricPath))) : typeof rubric === "string" ? rubric : rubric ? parseRubric(rubric) : undefined;
|
|
38
|
+
if (!ref)
|
|
39
|
+
throw new ValidationError("pass rubricPath or rubric");
|
|
40
|
+
const goldPath = deps.resolve(gold);
|
|
41
|
+
const items = parseGoldSet(await deps.read(goldPath), deps.dirname(goldPath));
|
|
42
|
+
return text(agreementSummary(await checkAgainstHumans(deps.engine, ref, items)));
|
|
43
|
+
}));
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=agreement.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agreement.js","sourceRoot":"","sources":["../src/agreement.ts"],"names":[],"mappings":"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"}
|
package/dist/bin.d.ts
ADDED
package/dist/bin.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Starts the executable transport at the process boundary.
|
|
4
|
+
* Library imports remain side-effect free; startup failures must be visible to the invoking process.
|
|
5
|
+
*/
|
|
6
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
7
|
+
import { createMcpServer } from "./index.js";
|
|
8
|
+
const server = createMcpServer();
|
|
9
|
+
await server.connect(new StdioServerTransport());
|
|
10
|
+
//# sourceMappingURL=bin.js.map
|
package/dist/bin.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA;;;GAGG;AACH,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC;AACjC,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,oBAAoB,EAAE,CAAC,CAAC"}
|
package/dist/hub.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hub tools for agents (docs/design/hub.md P3-4): search published cards, read one, and fork one into the rubrics this
|
|
3
|
+
* server keeps so `evaluate` can use it. Public reads only — no hub key is sent. A card is used only after its rubric
|
|
4
|
+
* freezes here to the version the hub names.
|
|
5
|
+
*/
|
|
6
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
7
|
+
import { type Engine } from "@verdict-ai/core";
|
|
8
|
+
import { Verdict } from "@verdict-ai/sdk";
|
|
9
|
+
export interface HubToolOptions {
|
|
10
|
+
/** Default hub (VERDICT_HUB_URL); each call may name another. */
|
|
11
|
+
hubUrl?: string;
|
|
12
|
+
fetch?: typeof fetch;
|
|
13
|
+
engine?: Engine;
|
|
14
|
+
client?: Verdict;
|
|
15
|
+
}
|
|
16
|
+
export declare function registerHub(server: McpServer, opts: HubToolOptions): void;
|
package/dist/hub.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { forkDraft, parseHubRef, questionAgreement, ValidationError, verifyPublishedVersion } from "@verdict-ai/core";
|
|
2
|
+
import { Verdict } from "@verdict-ai/sdk";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { text, toolResult } from "./result.js";
|
|
5
|
+
const CASES_SHOWN = 20;
|
|
6
|
+
export function registerHub(server, opts) {
|
|
7
|
+
const hubFor = (hub) => {
|
|
8
|
+
const url = (hub ?? opts.hubUrl)?.replace(/\/$/, "");
|
|
9
|
+
if (!url)
|
|
10
|
+
throw new ValidationError("no hub configured: pass `hub` or set VERDICT_HUB_URL");
|
|
11
|
+
// An empty key: never fall back to VERDICT_API_KEY, which belongs to another server.
|
|
12
|
+
return { url, client: new Verdict({ baseUrl: url, apiKey: "", fetch: opts.fetch }) };
|
|
13
|
+
};
|
|
14
|
+
const load = async (ref, hub) => {
|
|
15
|
+
const r = parseHubRef(ref), h = hubFor(hub);
|
|
16
|
+
const { publication, versions } = await h.client.hub.card(r.owner, r.slug, r.versionId ? { version: r.versionId } : {});
|
|
17
|
+
return { hub: h.url, publication, versions, version: await verifyPublishedVersion(publication, r.versionId, h.url) };
|
|
18
|
+
};
|
|
19
|
+
server.registerTool("hub_search", {
|
|
20
|
+
title: "Search the hub",
|
|
21
|
+
description: "Search published single-question judgment cards (rubrics with public test cases). Returns one result per card at its newest version, with a `hub:owner/slug@rv_…` ref for hub_get or fork_rubric.",
|
|
22
|
+
inputSchema: {
|
|
23
|
+
q: z.string().optional().describe("matches title, author, slug and domain"), domain: z.string().optional(), locale: z.string().optional(),
|
|
24
|
+
type: z.enum(["score", "noul", "choice"]).optional().describe("noul = yes/no"), owner: z.string().optional(), limit: z.number().int().min(1).max(50).optional(),
|
|
25
|
+
hub: z.string().url().optional(),
|
|
26
|
+
},
|
|
27
|
+
}, async ({ hub, ...q }) => toolResult(async () => {
|
|
28
|
+
const { data } = await hubFor(hub).client.hub.search(q);
|
|
29
|
+
return text(data.map((d) => ({ ref: `hub:${d.ref}@${d.latest.versionId}`, title: d.title, description: d.description, judgmentType: d.judgmentType, domain: d.domain, locale: d.locale, license: d.license, cases: d.cases, runs: d.runs })));
|
|
30
|
+
}));
|
|
31
|
+
server.registerTool("hub_get", {
|
|
32
|
+
title: "Read a hub card",
|
|
33
|
+
description: "Read a published card: its question and answers, threshold, licence, lineage, author-reported agreement numbers, versions and some public cases. `ref` is hub:owner/slug or hub:owner/slug@rv_….",
|
|
34
|
+
inputSchema: { ref: z.string(), hub: z.string().url().optional() },
|
|
35
|
+
}, async ({ ref, hub }) => toolResult(async () => {
|
|
36
|
+
const card = await load(ref, hub);
|
|
37
|
+
return text({ ref: `hub:${card.publication.ref}@${card.version.id}`, hub: card.hub, ...describe(card.publication), versions: card.versions, rubric: card.version.rubric });
|
|
38
|
+
}));
|
|
39
|
+
server.registerTool("fork_rubric", {
|
|
40
|
+
title: "Fork a hub card",
|
|
41
|
+
description: "Copy a published card into this server's rubrics (a new rubric id; the card is not changed) so `evaluate` can use it. The rubric's metadata records where it came from and its licence.",
|
|
42
|
+
inputSchema: { ref: z.string(), hub: z.string().url().optional(), name: z.string().optional().describe("name for the copy (default: the card's)") },
|
|
43
|
+
}, async ({ ref, hub, name }) => toolResult(async () => {
|
|
44
|
+
const card = await load(ref, hub);
|
|
45
|
+
const forkedFrom = { hub: card.hub, ref: `hub:${card.publication.ref}@${card.version.id}`, versionId: card.version.id, license: card.publication.license };
|
|
46
|
+
const draft = forkDraft(card.version);
|
|
47
|
+
const rubric = { ...draft, ...(name ? { name } : {}), metadata: { ...draft.metadata, forkedFrom } };
|
|
48
|
+
const stored = opts.client ? await opts.client.rubrics.create(rubric) : await opts.engine.createRubric(rubric);
|
|
49
|
+
return text({ id: stored.id, name: stored.name, forkedFrom, publicCases: card.publication.cases.length });
|
|
50
|
+
}));
|
|
51
|
+
}
|
|
52
|
+
function describe(p) {
|
|
53
|
+
const c = p.version.rubric.criteria[0];
|
|
54
|
+
return {
|
|
55
|
+
title: p.title, description: p.description, license: p.license, judgmentType: p.judgmentType, domain: p.domain, locale: p.locale,
|
|
56
|
+
question: { id: c.id, name: c.name, description: c.description, anchors: c.anchors, choices: c.choices, levels: c.levels, threshold: c.threshold },
|
|
57
|
+
parent: p.parent, changeKinds: p.version.changeKinds, forkNote: p.version.forkNote, sources: p.sources,
|
|
58
|
+
runs: p.runs.map((r) => ({ origin: r.origin, cases: r.counts.cases, agreement: questionAgreement(p, r), casesPublic: r.casesPublic, labelSources: r.labelSources, models: r.fingerprint.models })),
|
|
59
|
+
cases: { total: p.cases.length, shown: p.cases.slice(0, CASES_SHOWN) },
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=hub.js.map
|
package/dist/hub.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hub.js","sourceRoot":"","sources":["../src/hub.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exposes rubric, evaluation and human-review operations as MCP tools.
|
|
3
|
+
* Local engines and remote clients share result projections; transport schemas validate tool arguments.
|
|
4
|
+
*/
|
|
5
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
6
|
+
import { Engine } from "@verdict-ai/core";
|
|
7
|
+
import { Verdict } from "@verdict-ai/sdk";
|
|
8
|
+
/**
|
|
9
|
+
* Verdict MCP server. Two modes:
|
|
10
|
+
* - local: runs the engine in-process (set VERDICT_DATA_DIR to persist; needs provider keys e.g. ANTHROPIC_API_KEY)
|
|
11
|
+
* - remote: proxies to a Verdict API (set VERDICT_API_URL + VERDICT_API_KEY)
|
|
12
|
+
*/
|
|
13
|
+
export interface McpOptions {
|
|
14
|
+
engine?: Engine;
|
|
15
|
+
client?: Verdict;
|
|
16
|
+
mode?: "local" | "remote";
|
|
17
|
+
apiUrl?: string;
|
|
18
|
+
apiKey?: string;
|
|
19
|
+
dataDir?: string;
|
|
20
|
+
allowLocalFiles?: boolean;
|
|
21
|
+
/** Hub for hub_search / hub_get / fork_rubric (default: VERDICT_HUB_URL). */
|
|
22
|
+
hubUrl?: string;
|
|
23
|
+
/** Network for hub reads (tests). */
|
|
24
|
+
fetch?: typeof fetch;
|
|
25
|
+
}
|
|
26
|
+
/** Returns a configured MCP server using local or remote dependencies; transport startup remains the caller responsibility. */
|
|
27
|
+
export declare function createMcpServer(opts?: McpOptions): McpServer;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { summarize } from "./summary.js";
|
|
2
|
+
import { evaluateSubject, compareSubjects } from "./operations.js";
|
|
3
|
+
import { registerAgreement } from "./agreement.js";
|
|
4
|
+
import { registerHub } from "./hub.js";
|
|
5
|
+
import { text, toolResult } from "./result.js";
|
|
6
|
+
import { readFile } from "node:fs/promises";
|
|
7
|
+
import { dirname, resolve } from "node:path";
|
|
8
|
+
/**
|
|
9
|
+
* Exposes rubric, evaluation and human-review operations as MCP tools.
|
|
10
|
+
* Local engines and remote clients share result projections; transport schemas validate tool arguments.
|
|
11
|
+
*/
|
|
12
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
13
|
+
import { Aggregation, calibrate, coerceScore, criterionScale, scaleRange, NotFoundError, ValidationError, Engine, FileStore, Input, lazyPlaywrightScreenshot, loadRubricText, MemoryStore, parseRubric } from "@verdict-ai/core";
|
|
14
|
+
import { Verdict } from "@verdict-ai/sdk";
|
|
15
|
+
import { z } from "zod";
|
|
16
|
+
/** Returns a configured MCP server using local or remote dependencies; transport startup remains the caller responsibility. */
|
|
17
|
+
export function createMcpServer(opts = {}) {
|
|
18
|
+
const mode = opts.mode ?? (process.env.VERDICT_API_URL ? "remote" : "local");
|
|
19
|
+
const client = opts.client ?? (mode === "remote" ? new Verdict({ baseUrl: opts.apiUrl ?? process.env.VERDICT_API_URL, apiKey: opts.apiKey ?? process.env.VERDICT_API_KEY }) : undefined);
|
|
20
|
+
const engine = opts.engine ?? (mode === "local" ? new Engine({ store: (opts.dataDir ?? process.env.VERDICT_DATA_DIR) ? new FileStore(opts.dataDir ?? process.env.VERDICT_DATA_DIR) : new MemoryStore(), ingest: { allowLocalFiles: opts.allowLocalFiles ?? true, screenshot: lazyPlaywrightScreenshot() } }) : undefined);
|
|
21
|
+
const server = new McpServer({ name: "verdict", version: "0.1.0" }, { instructions: "Verdict scores documents, websites, YouTube videos, JSON and text against customizable rubrics. Judges: decision models (Jev / Clef / OpenAI Decisions — typed questions, probabilities, one call per rubric), humans, deterministic benchmarks, optional generative LLM for rationales. Create or inline a rubric, then call evaluate." });
|
|
22
|
+
registerRubrics(server, engine, client);
|
|
23
|
+
registerEvaluations(server, engine, client);
|
|
24
|
+
registerHuman(server, engine, client);
|
|
25
|
+
registerAgreement(server, { engine: client ? undefined : engine, read: (path) => readFile(path, "utf8"), resolve, dirname });
|
|
26
|
+
registerHub(server, { hubUrl: opts.hubUrl ?? process.env.VERDICT_HUB_URL, fetch: opts.fetch, engine, client });
|
|
27
|
+
return server;
|
|
28
|
+
}
|
|
29
|
+
function registerRubrics(server, engine, client) {
|
|
30
|
+
server.registerTool("validate_rubric", {
|
|
31
|
+
title: "Validate rubric",
|
|
32
|
+
description: "Validate a rubric (JSON object or YAML string) and return it with defaults filled in. Use before evaluate to catch mistakes.",
|
|
33
|
+
inputSchema: { rubric: z.union([z.string(), z.record(z.string(), z.unknown())]) },
|
|
34
|
+
}, async ({ rubric }) => toolResult(async () => {
|
|
35
|
+
try {
|
|
36
|
+
return text({ valid: true, rubric: typeof rubric === "string" ? loadRubricText(rubric) : parseRubric(rubric) });
|
|
37
|
+
}
|
|
38
|
+
catch (e) {
|
|
39
|
+
return text({ valid: false, error: e.message });
|
|
40
|
+
}
|
|
41
|
+
}));
|
|
42
|
+
server.registerTool("create_rubric", {
|
|
43
|
+
title: "Create rubric",
|
|
44
|
+
description: "Store a rubric and get back its id for reuse. Criteria need id/name; optional weight, scale, anchors (= rubric levels for decision models), judge ({type: decision|human|benchmark|llm|panel}; default decision/typesafe). Aggregation supports weighted_mean, weighted_sum, mean, median, min, max, geometric_mean, formula; gates; grades; passThreshold.",
|
|
45
|
+
inputSchema: { rubric: z.union([z.string(), z.record(z.string(), z.unknown())]) },
|
|
46
|
+
}, async ({ rubric }) => toolResult(async () => {
|
|
47
|
+
const parsed = typeof rubric === "string" ? loadRubricText(rubric) : parseRubric(rubric);
|
|
48
|
+
return text(client ? await client.rubrics.create(parsed) : await engine.createRubric(parsed));
|
|
49
|
+
}));
|
|
50
|
+
server.registerTool("list_rubrics", { title: "List rubrics", description: "List stored rubrics.", inputSchema: {} }, async () => toolResult(async () => (text(client ? (await client.rubrics.list()).data.map((r) => ({ id: r.id, name: r.name, criteria: r.criteria.length })) : (await engine.store.listRubrics()).map((r) => ({ id: r.id, name: r.name, criteria: r.criteria.length }))))));
|
|
51
|
+
server.registerTool("calibration_report", {
|
|
52
|
+
title: "Calibration report", description: "Compare decision confidence against human consensus on stored evaluations.",
|
|
53
|
+
inputSchema: { rubricId: z.string(), target: z.number().min(0).max(1).optional(), buckets: z.number().int().min(1).max(1000).optional() },
|
|
54
|
+
}, async ({ rubricId, ...options }) => toolResult(async () => {
|
|
55
|
+
if (client)
|
|
56
|
+
return text(await client.rubrics.calibration(rubricId, options));
|
|
57
|
+
await engine.resolveRubric(rubricId);
|
|
58
|
+
return text(calibrate(await engine.store.listEvaluations({ rubricId, limit: 1000 }), options));
|
|
59
|
+
}));
|
|
60
|
+
}
|
|
61
|
+
function registerEvaluations(server, engine, client) {
|
|
62
|
+
server.registerTool("evaluate", {
|
|
63
|
+
title: "Evaluate",
|
|
64
|
+
description: "Score a subject against a rubric. `rubric` is a stored rubric id or an inline rubric. Inputs can be text, json, file (path or base64), url (set `screenshot: true` to let vision judges such as Clef see the page), image (PNG/JPEG/WebP, path or base64), or youtube. Returns the total score, grade, pass/fail, per-criterion scores with rationales, and any pending human tasks.",
|
|
65
|
+
inputSchema: {
|
|
66
|
+
rubric: z.union([z.string(), z.record(z.string(), z.unknown())]),
|
|
67
|
+
inputs: z.array(Input).min(1),
|
|
68
|
+
name: z.string().optional().describe("Subject name for reports"),
|
|
69
|
+
idempotencyKey: z.string().min(1).max(255).optional(),
|
|
70
|
+
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
71
|
+
},
|
|
72
|
+
}, async ({ rubric, inputs, name, metadata, idempotencyKey }) => toolResult(async () => {
|
|
73
|
+
await validateRubricReference(rubric, engine, client);
|
|
74
|
+
const result = await evaluateSubject({ engine, client }, { rubric, inputs, name, metadata, idempotencyKey });
|
|
75
|
+
return text({ ...summarize(result.evaluation), replayed: result.replayed });
|
|
76
|
+
}));
|
|
77
|
+
server.registerTool("compare", {
|
|
78
|
+
title: "Compare / rank",
|
|
79
|
+
description: "Evaluate several subjects against one rubric and return a ranking (leaderboard).",
|
|
80
|
+
inputSchema: {
|
|
81
|
+
rubric: z.union([z.string(), z.record(z.string(), z.unknown())]),
|
|
82
|
+
idempotencyKey: z.string().min(1).max(255).optional(),
|
|
83
|
+
subjects: z.array(z.object({ name: z.string(), inputs: z.array(Input).min(1) })).min(2),
|
|
84
|
+
},
|
|
85
|
+
}, async ({ rubric, subjects, idempotencyKey }) => toolResult(async () => {
|
|
86
|
+
await validateRubricReference(rubric, engine, client);
|
|
87
|
+
const result = await compareSubjects({ engine, client }, { rubric, subjects, idempotencyKey });
|
|
88
|
+
return text({ ranking: result.ranking, replayed: result.replayed });
|
|
89
|
+
}));
|
|
90
|
+
}
|
|
91
|
+
function registerHuman(server, engine, client) {
|
|
92
|
+
server.registerTool("get_evaluation", { title: "Get evaluation", description: "Fetch an evaluation by id (status, scores, rationales, pending human tasks).", inputSchema: { id: z.string() } }, async ({ id }) => toolResult(async () => {
|
|
93
|
+
if (client)
|
|
94
|
+
return text(summarize(await client.evaluations.get(id)));
|
|
95
|
+
const ev = await engine.store.getEvaluation(id);
|
|
96
|
+
return text(ev ? summarize(ev) : { error: `evaluation ${id} not found` });
|
|
97
|
+
}));
|
|
98
|
+
server.registerTool("submit_human_score", {
|
|
99
|
+
title: "Submit human score",
|
|
100
|
+
description: "Submit a human rater's score for a criterion that is waiting on a human. Score is a number on the criterion scale or an ordinal/binary label.",
|
|
101
|
+
inputSchema: { evaluationId: z.string(), criterionId: z.string(), raterId: z.string(), score: z.union([z.number(), z.string()]), rationale: z.string().optional() },
|
|
102
|
+
}, async ({ evaluationId, ...s }) => toolResult(async () => {
|
|
103
|
+
// Remote submissions use the API validation against its frozen rubric.
|
|
104
|
+
if (client)
|
|
105
|
+
return text(summarize(await client.evaluations.submitScore(evaluationId, s)));
|
|
106
|
+
const evaluation = await engine.store.getEvaluation(evaluationId);
|
|
107
|
+
if (!evaluation)
|
|
108
|
+
throw new NotFoundError(`evaluation ${evaluationId} not found`);
|
|
109
|
+
const criterion = evaluation.rubric.criteria.find(c => c.id === s.criterionId);
|
|
110
|
+
if (!criterion)
|
|
111
|
+
throw new ValidationError(`unknown criterion ${s.criterionId}`);
|
|
112
|
+
// Choices have optional score mappings; only scale-based submissions need range validation.
|
|
113
|
+
if (criterion.choices && !Object.hasOwn(criterion.choices, String(s.score)))
|
|
114
|
+
throw new ValidationError(`unknown choice ${s.score}`);
|
|
115
|
+
if (!criterion.choices) {
|
|
116
|
+
const scale = criterionScale(evaluation.rubric, criterion);
|
|
117
|
+
const [min, max] = scaleRange(scale);
|
|
118
|
+
const numeric = typeof s.score === "number" ? s.score : Number(s.score);
|
|
119
|
+
if (Number.isFinite(numeric) && (numeric < min || numeric > max))
|
|
120
|
+
throw new ValidationError(`score must be between ${min} and ${max}`);
|
|
121
|
+
coerceScore(s.score, scale);
|
|
122
|
+
}
|
|
123
|
+
return text(summarize(await engine.submitScore(evaluationId, s)));
|
|
124
|
+
}));
|
|
125
|
+
server.registerTool("reaggregate", {
|
|
126
|
+
title: "Re-aggregate",
|
|
127
|
+
description: "Recompute the total with a different aggregation (method, formula, weights via gates/grades/passThreshold) without re-running judges. Useful for what-if analysis.",
|
|
128
|
+
inputSchema: { evaluationId: z.string(), aggregation: z.record(z.string(), z.unknown()), persist: z.boolean().default(false) },
|
|
129
|
+
}, async ({ evaluationId, aggregation, persist }) => toolResult(async () => (text(summarize(client ? (await client.evaluations.reaggregate(evaluationId, Aggregation.partial().parse(aggregation), persist)) : await engine.reaggregate(evaluationId, Aggregation.partial().parse(aggregation), undefined, persist))))));
|
|
130
|
+
server.registerTool("list_human_tasks", { title: "List human tasks", description: "Criteria waiting on human raters.", inputSchema: { rater: z.string().optional() } }, async ({ rater }) => toolResult(async () => {
|
|
131
|
+
if (client)
|
|
132
|
+
return text((await client.tasks.list(rater)).data);
|
|
133
|
+
// why: filter only tenant-visible pending work; named assignments take precedence over allowed-rater pools.
|
|
134
|
+
const list = await engine.store.listEvaluations({ status: "pending_human", limit: TASK_INBOX_LIMIT });
|
|
135
|
+
return text(list.flatMap((e) => e.pendingTasks.filter((t) => !rater || (t.raterId ? t.raterId === rater : !t.allowedRaters || t.allowedRaters.includes(rater))).map((t) => ({ evaluationId: e.id, rubric: e.rubric.name, subject: e.subject.name, ...t }))));
|
|
136
|
+
}));
|
|
137
|
+
}
|
|
138
|
+
// why: match the REST inbox cap so local MCP calls do not scan unbounded evaluation history.
|
|
139
|
+
const TASK_INBOX_LIMIT = 500;
|
|
140
|
+
// Stored references need a lookup; inline rubrics are validated by the operation parser.
|
|
141
|
+
async function validateRubricReference(rubric, engine, client) {
|
|
142
|
+
if (typeof rubric !== "string")
|
|
143
|
+
return;
|
|
144
|
+
// Remote APIs resolve ids themselves; avoid adding a lookup to every remote evaluation.
|
|
145
|
+
if (client)
|
|
146
|
+
return;
|
|
147
|
+
await engine.resolveRubric(rubric);
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C;;;GAGG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,UAAU,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,wBAAwB,EAAE,cAAc,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACjO,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAqBxB,+HAA+H;AAC/H,MAAM,UAAU,eAAe,CAAC,OAAmB,EAAE;IACnD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAC7E,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACzL,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAiB,CAAC,CAAC,CAAC,CAAC,IAAI,WAAW,EAAE,EAAE,MAAM,EAAE,EAAE,eAAe,EAAE,IAAI,CAAC,eAAe,IAAI,IAAI,EAAE,UAAU,EAAE,wBAAwB,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAE3T,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,YAAY,EAAE,yUAAyU,EAAE,CAAC,CAAC;IAEja,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,iBAAiB,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IAC7H,WAAW,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC/G,OAAO,MAAM,CAAC;AAChB,CAAC;AAGD,SAAS,eAAe,CAAC,MAAiB,EAAE,MAA0B,EAAE,MAA2B;IACjG,MAAM,CAAC,YAAY,CAAC,iBAAiB,EAAE;QACrC,KAAK,EAAE,iBAAiB;QACxB,WAAW,EAAE,8HAA8H;QAC3I,WAAW,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE;KAClF,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,IAAI,EAAE;QAC7C,IAAI,CAAC;YAAC,OAAO,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAAC,CAAC;QACxH,OAAO,CAAC,EAAE,CAAC;YAAC,OAAO,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAG,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;QAAC,CAAC;IAC3E,CAAC,CAAC,CAAC,CAAC;IAEJ,MAAM,CAAC,YAAY,CAAC,eAAe,EAAE;QACnC,KAAK,EAAE,eAAe;QACtB,WAAW,EAAE,6VAA6V;QAC1W,WAAW,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE;KAClF,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,IAAI,EAAE;QAC7C,MAAM,MAAM,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACzF,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,MAAO,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;IACjG,CAAC,CAAC,CAAC,CAAC;IAEJ,MAAM,CAAC,YAAY,CAAC,cAAc,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,sBAAsB,EAAE,WAAW,EAAE,EAAE,EAAE,EAAE,KAAK,IAAI,EAAE,CAC9H,UAAU,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,MAAO,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAEjQ,MAAM,CAAC,YAAY,CAAC,oBAAoB,EAAE;QACxC,KAAK,EAAE,oBAAoB,EAAE,WAAW,EAAE,4EAA4E;QACtH,WAAW,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE;KAC1I,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,IAAI,EAAE;QAC3D,IAAI,MAAM;YAAE,OAAO,IAAI,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;QAC7E,MAAM,MAAO,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QACtC,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,MAAO,CAAC,KAAK,CAAC,eAAe,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;IAClG,CAAC,CAAC,CAAC,CAAC;AAEN,CAAC;AAED,SAAS,mBAAmB,CAAC,MAAiB,EAAE,MAA0B,EAAE,MAA2B;IACrG,MAAM,CAAC,YAAY,CAAC,UAAU,EAAE;QAC9B,KAAK,EAAE,UAAU;QACjB,WAAW,EAAE,sXAAsX;QACnY,WAAW,EAAE;YACX,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YAChE,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC7B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC;YAChE,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;YACrD,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE;SACvD;KACF,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,cAAc,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,IAAI,EAAE;QACrF,MAAM,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QACtD,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC,CAAC;QAC7G,OAAO,IAAI,CAAC,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC,CAAC;IAEJ,MAAM,CAAC,YAAY,CAAC,SAAS,EAAE;QAC7B,KAAK,EAAE,gBAAgB;QACvB,WAAW,EAAE,kFAAkF;QAC/F,WAAW,EAAE;YACX,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YAChE,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;YACrD,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;SACxF;KACF,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,IAAI,EAAE;QACvE,MAAM,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QACtD,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC,CAAC;QAC/F,OAAO,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC,CAAC;AAEN,CAAC;AAED,SAAS,aAAa,CAAC,MAAiB,EAAE,MAA0B,EAAE,MAA2B;IAC/F,MAAM,CAAC,YAAY,CAAC,gBAAgB,EAAE,EAAE,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,8EAA8E,EAAE,WAAW,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,IAAI,EAAE;QACvO,IAAI,MAAM;YAAE,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACrE,MAAM,EAAE,GAAG,MAAM,MAAO,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;QACjD,OAAO,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,CAAC;IAC5E,CAAC,CAAC,CAAC,CAAC;IAEJ,MAAM,CAAC,YAAY,CAAC,oBAAoB,EAAE;QACxC,KAAK,EAAE,oBAAoB;QAC3B,WAAW,EAAE,+IAA+I;QAC5J,WAAW,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE;KACpK,EAAE,KAAK,EAAE,EAAE,YAAY,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,IAAI,EAAE;QACzD,uEAAuE;QACvE,IAAI,MAAM;YAAE,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1F,MAAM,UAAU,GAAG,MAAM,MAAO,CAAC,KAAK,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;QACnE,IAAI,CAAC,UAAU;YAAE,MAAM,IAAI,aAAa,CAAC,cAAc,YAAY,YAAY,CAAC,CAAC;QACjF,MAAM,SAAS,GAAG,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,WAAW,CAAC,CAAC;QAC/E,IAAI,CAAC,SAAS;YAAE,MAAM,IAAI,eAAe,CAAC,qBAAqB,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;QAChF,4FAA4F;QAC5F,IAAI,SAAS,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;YAAE,MAAM,IAAI,eAAe,CAAC,kBAAkB,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;QACpI,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;YACvB,MAAM,KAAK,GAAG,cAAc,CAAC,UAAU,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;YAC3D,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;YACrC,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;YACxE,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,GAAG,GAAG,IAAI,OAAO,GAAG,GAAG,CAAC;gBAAE,MAAM,IAAI,eAAe,CAAC,yBAAyB,GAAG,QAAQ,GAAG,EAAE,CAAC,CAAC;YACvI,WAAW,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC9B,CAAC;QACD,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,MAAO,CAAC,WAAW,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC,CAAC;IAEJ,MAAM,CAAC,YAAY,CAAC,aAAa,EAAE;QACjC,KAAK,EAAE,cAAc;QACrB,WAAW,EAAE,oKAAoK;QACjL,WAAW,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;KAC/H,EAAE,KAAK,EAAE,EAAE,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,YAAY,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,MAAO,CAAC,WAAW,CAAC,YAAY,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAE1T,MAAM,CAAC,YAAY,CAAC,kBAAkB,EAAE,EAAE,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,mCAAmC,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,IAAI,EAAE;QACjN,IAAI,MAAM;YAAE,OAAO,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC/D,4GAA4G;QAC5G,MAAM,IAAI,GAAG,MAAM,MAAO,CAAC,KAAK,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAC;QACvG,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/P,CAAC,CAAC,CAAC,CAAC;AAEN,CAAC;AAGD,6FAA6F;AAC7F,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAG7B,yFAAyF;AACzF,KAAK,UAAU,uBAAuB,CAAC,MAAwC,EAAE,MAAe,EAAE,MAAgB;IAChH,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO;IACvC,wFAAwF;IACxF,IAAI,MAAM;QAAE,OAAO;IACnB,MAAM,MAAO,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { type Engine, type Input, type Subject } from "@verdict-ai/core";
|
|
2
|
+
import type { Verdict } from "@verdict-ai/sdk";
|
|
3
|
+
type Dependencies = {
|
|
4
|
+
engine?: Engine;
|
|
5
|
+
client?: Verdict;
|
|
6
|
+
};
|
|
7
|
+
type RubricReference = string | Record<string, unknown>;
|
|
8
|
+
/** Transport-independent operation; the idempotency key selects reservation before any judge work. */
|
|
9
|
+
export declare function evaluateSubject(dependencies: Dependencies, params: {
|
|
10
|
+
rubric: RubricReference;
|
|
11
|
+
inputs: Input[];
|
|
12
|
+
name?: string;
|
|
13
|
+
metadata?: Record<string, unknown>;
|
|
14
|
+
idempotencyKey?: string;
|
|
15
|
+
}): Promise<{
|
|
16
|
+
evaluation: import("@verdict-ai/sdk").EvaluationView;
|
|
17
|
+
replayed: boolean;
|
|
18
|
+
} | {
|
|
19
|
+
evaluation: import("@verdict-ai/core").Evaluation;
|
|
20
|
+
replayed: boolean;
|
|
21
|
+
}>;
|
|
22
|
+
/** Shares local and remote ranking semantics without depending on the MCP server. */
|
|
23
|
+
export declare function compareSubjects(dependencies: Dependencies, params: {
|
|
24
|
+
rubric: RubricReference;
|
|
25
|
+
subjects: Subject[];
|
|
26
|
+
idempotencyKey?: string;
|
|
27
|
+
}): Promise<{
|
|
28
|
+
replayed: boolean;
|
|
29
|
+
ranking: Array<{
|
|
30
|
+
rank: number;
|
|
31
|
+
evaluationId: string;
|
|
32
|
+
subject: string;
|
|
33
|
+
score?: number;
|
|
34
|
+
grade?: string;
|
|
35
|
+
passed?: boolean;
|
|
36
|
+
status: string;
|
|
37
|
+
}>;
|
|
38
|
+
evaluations: import("@verdict-ai/sdk").EvaluationView[];
|
|
39
|
+
} | {
|
|
40
|
+
ranking: {
|
|
41
|
+
rank: number;
|
|
42
|
+
evaluationId: string;
|
|
43
|
+
subject: string;
|
|
44
|
+
score: number | undefined;
|
|
45
|
+
grade: string | undefined;
|
|
46
|
+
passed: boolean | undefined;
|
|
47
|
+
status: import("@verdict-ai/core").EvaluationStatus;
|
|
48
|
+
}[];
|
|
49
|
+
evaluations: import("@verdict-ai/core").Evaluation[];
|
|
50
|
+
replayed: boolean;
|
|
51
|
+
}>;
|
|
52
|
+
export {};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { parseRubric, ValidationError } from "@verdict-ai/core";
|
|
2
|
+
function localEngine(dependencies) {
|
|
3
|
+
if (!dependencies.engine)
|
|
4
|
+
throw new ValidationError("local MCP operation requires an engine");
|
|
5
|
+
return dependencies.engine;
|
|
6
|
+
}
|
|
7
|
+
/** Transport-independent operation; the idempotency key selects reservation before any judge work. */
|
|
8
|
+
export async function evaluateSubject(dependencies, params) {
|
|
9
|
+
const { client } = dependencies;
|
|
10
|
+
const { inputs, name, metadata, idempotencyKey } = params;
|
|
11
|
+
const rubric = typeof params.rubric === "string" ? params.rubric : parseRubric(params.rubric);
|
|
12
|
+
if (client) {
|
|
13
|
+
const request = { rubric, inputs, name, metadata };
|
|
14
|
+
if (idempotencyKey)
|
|
15
|
+
return client.evaluations.createIdempotent(request, idempotencyKey);
|
|
16
|
+
return { evaluation: await client.evaluations.create(request), replayed: false };
|
|
17
|
+
}
|
|
18
|
+
const engine = localEngine(dependencies);
|
|
19
|
+
const request = { rubric, subject: { name, inputs }, metadata };
|
|
20
|
+
if (idempotencyKey)
|
|
21
|
+
return engine.evaluateIdempotent({ ...request, idempotencyKey });
|
|
22
|
+
return { evaluation: await engine.evaluate(request), replayed: false };
|
|
23
|
+
}
|
|
24
|
+
/** Shares local and remote ranking semantics without depending on the MCP server. */
|
|
25
|
+
export async function compareSubjects(dependencies, params) {
|
|
26
|
+
const { client } = dependencies;
|
|
27
|
+
const { subjects, idempotencyKey } = params;
|
|
28
|
+
const rubric = typeof params.rubric === "string" ? params.rubric : parseRubric(params.rubric);
|
|
29
|
+
if (client) {
|
|
30
|
+
if (idempotencyKey)
|
|
31
|
+
return client.batches.createIdempotent({ rubric, subjects }, idempotencyKey);
|
|
32
|
+
return { ...await client.batches.create({ rubric, subjects }), replayed: false };
|
|
33
|
+
}
|
|
34
|
+
const engine = localEngine(dependencies);
|
|
35
|
+
if (idempotencyKey)
|
|
36
|
+
return engine.evaluateBatchIdempotent(rubric, subjects, { idempotencyKey });
|
|
37
|
+
return { ...await engine.evaluateBatch(rubric, subjects), replayed: false };
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=operations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operations.js","sourceRoot":"","sources":["../src/operations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,eAAe,EAAyC,MAAM,kBAAkB,CAAC;AAMvG,SAAS,WAAW,CAAC,YAA0B;IAC7C,IAAI,CAAC,YAAY,CAAC,MAAM;QAAE,MAAM,IAAI,eAAe,CAAC,wCAAwC,CAAC,CAAC;IAC9F,OAAO,YAAY,CAAC,MAAM,CAAC;AAC7B,CAAC;AAED,sGAAsG;AACtG,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,YAA0B,EAAE,MAEjE;IACC,MAAM,EAAE,MAAM,EAAE,GAAG,YAAY,CAAC;IAChC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,MAAM,CAAC;IAC1D,MAAM,MAAM,GAAG,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC9F,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,OAAO,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;QACnD,IAAI,cAAc;YAAE,OAAO,MAAM,CAAC,WAAW,CAAC,gBAAgB,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;QACxF,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IACnF,CAAC;IACD,MAAM,MAAM,GAAG,WAAW,CAAC,YAAY,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,CAAC;IAChE,IAAI,cAAc;QAAE,OAAO,MAAM,CAAC,kBAAkB,CAAC,EAAE,GAAG,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC;IACrF,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;AACzE,CAAC;AAED,qFAAqF;AACrF,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,YAA0B,EAAE,MAEjE;IACC,MAAM,EAAE,MAAM,EAAE,GAAG,YAAY,CAAC;IAChC,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,MAAM,CAAC;IAC5C,MAAM,MAAM,GAAG,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC9F,IAAI,MAAM,EAAE,CAAC;QACX,IAAI,cAAc;YAAE,OAAO,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,cAAc,CAAC,CAAC;QACjG,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IACnF,CAAC;IACD,MAAM,MAAM,GAAG,WAAW,CAAC,YAAY,CAAC,CAAC;IACzC,IAAI,cAAc;QAAE,OAAO,MAAM,CAAC,uBAAuB,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,cAAc,EAAE,CAAC,CAAC;IAChG,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;AAC9E,CAAC"}
|
package/dist/result.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shapes MCP tool replies. Every tool answers with JSON text; failures become MCP error content instead of
|
|
3
|
+
* rejecting, so a client sees the message rather than a transport error.
|
|
4
|
+
*/
|
|
5
|
+
export declare const text: (v: unknown) => {
|
|
6
|
+
content: {
|
|
7
|
+
type: "text";
|
|
8
|
+
text: string;
|
|
9
|
+
}[];
|
|
10
|
+
};
|
|
11
|
+
/** Runs a tool handler; a rejection, including from a local adapter, becomes `isError` content. */
|
|
12
|
+
export declare function toolResult<T>(work: () => Promise<T>): Promise<T | {
|
|
13
|
+
content: {
|
|
14
|
+
type: "text";
|
|
15
|
+
text: string;
|
|
16
|
+
}[];
|
|
17
|
+
isError: boolean;
|
|
18
|
+
}>;
|
package/dist/result.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shapes MCP tool replies. Every tool answers with JSON text; failures become MCP error content instead of
|
|
3
|
+
* rejecting, so a client sees the message rather than a transport error.
|
|
4
|
+
*/
|
|
5
|
+
export const text = (v) => ({ content: [{ type: "text", text: JSON.stringify(v, null, 2) }] });
|
|
6
|
+
/** Runs a tool handler; a rejection, including from a local adapter, becomes `isError` content. */
|
|
7
|
+
export async function toolResult(work) {
|
|
8
|
+
try {
|
|
9
|
+
return await work();
|
|
10
|
+
}
|
|
11
|
+
catch (error) {
|
|
12
|
+
return { isError: true, ...text({ error: error instanceof Error ? error.message : String(error) }) };
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=result.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"result.js","sourceRoot":"","sources":["../src/result.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,CAAU,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;AAEjH,mGAAmG;AACnG,MAAM,CAAC,KAAK,UAAU,UAAU,CAAI,IAAsB;IACxD,IAAI,CAAC;QAAC,OAAO,MAAM,IAAI,EAAE,CAAC;IAAC,CAAC;IAC5B,OAAO,KAAK,EAAE,CAAC;QAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;IAAC,CAAC;AACzH,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { Evaluation } from "@verdict-ai/core";
|
|
2
|
+
type SummaryEvaluation = Pick<Evaluation, "id" | "status" | "job" | "aggregate" | "criteria" | "pendingTasks" | "error" | "usage">;
|
|
3
|
+
export declare function summarize(e: SummaryEvaluation): {
|
|
4
|
+
score: number | undefined;
|
|
5
|
+
grade: string | undefined;
|
|
6
|
+
passed: boolean | undefined;
|
|
7
|
+
partial: boolean;
|
|
8
|
+
criteria: {
|
|
9
|
+
id: string;
|
|
10
|
+
name: string;
|
|
11
|
+
status: "error" | "scored" | "pending" | "excluded";
|
|
12
|
+
choice: string | undefined;
|
|
13
|
+
score: number | undefined;
|
|
14
|
+
normalized: number | undefined;
|
|
15
|
+
pending: number;
|
|
16
|
+
confidence: number | undefined;
|
|
17
|
+
probabilities: Record<string, number> | undefined;
|
|
18
|
+
rationale: string | undefined;
|
|
19
|
+
quotes: string[];
|
|
20
|
+
}[];
|
|
21
|
+
pendingTasks: {
|
|
22
|
+
criterionId: string;
|
|
23
|
+
raterId?: string;
|
|
24
|
+
allowedRaters?: string[];
|
|
25
|
+
instructions?: string;
|
|
26
|
+
}[];
|
|
27
|
+
error: string | undefined;
|
|
28
|
+
usage: {
|
|
29
|
+
decisionCalls: number;
|
|
30
|
+
llmCalls: number;
|
|
31
|
+
inputTokens: number;
|
|
32
|
+
outputTokens: number;
|
|
33
|
+
durationMs: number;
|
|
34
|
+
};
|
|
35
|
+
job?: {
|
|
36
|
+
attempts: number;
|
|
37
|
+
maxAttempts: number;
|
|
38
|
+
lastError?: string;
|
|
39
|
+
nextAttemptAt?: string;
|
|
40
|
+
deadLettered?: boolean;
|
|
41
|
+
} | undefined;
|
|
42
|
+
id: string;
|
|
43
|
+
status: import("@verdict-ai/core").EvaluationStatus;
|
|
44
|
+
};
|
|
45
|
+
export {};
|
package/dist/summary.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export function summarize(e) {
|
|
2
|
+
return {
|
|
3
|
+
id: e.id,
|
|
4
|
+
status: e.status,
|
|
5
|
+
...(e.job ? { job: e.job } : {}),
|
|
6
|
+
score: e.aggregate?.score,
|
|
7
|
+
grade: e.aggregate?.grade,
|
|
8
|
+
passed: e.aggregate?.passed,
|
|
9
|
+
partial: e.aggregate?.partial,
|
|
10
|
+
criteria: e.criteria?.map((c) => ({ id: c.criterionId, name: c.name, status: c.status, choice: c.choice, score: c.score, normalized: c.normalized, pending: c.pending, confidence: c.ratings?.find((r) => typeof r.confidence === "number")?.confidence, probabilities: c.ratings?.find((r) => r.probabilities)?.probabilities, rationale: c.ratings?.find((r) => r.rationale)?.rationale, quotes: c.ratings?.flatMap((r) => r.quotes ?? []).slice(0, 3) })),
|
|
11
|
+
pendingTasks: e.pendingTasks,
|
|
12
|
+
error: e.error,
|
|
13
|
+
usage: e.usage,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=summary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summary.js","sourceRoot":"","sources":["../src/summary.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,SAAS,CAAC,CAAoB;IAC5C,OAAO;QACL,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChC,KAAK,EAAE,CAAC,CAAC,SAAS,EAAE,KAAK;QACzB,KAAK,EAAE,CAAC,CAAC,SAAS,EAAE,KAAK;QACzB,MAAM,EAAE,CAAC,CAAC,SAAS,EAAE,MAAM;QAC3B,OAAO,EAAE,CAAC,CAAC,SAAS,EAAE,OAAO;QAC7B,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,UAAU,KAAK,QAAQ,CAAC,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;QAC5b,YAAY,EAAE,CAAC,CAAC,YAAY;QAC5B,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,KAAK,EAAE,CAAC,CAAC,KAAK;KACf,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,60 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@verdict-ai/mcp",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Verdict MCP server — expose the evaluation engine to any agent.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"verdict-mcp": "./dist/bin.js"
|
|
10
|
+
},
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"import": "./dist/index.js"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@modelcontextprotocol/sdk": "^1.32.2",
|
|
19
|
+
"zod": "^4.6.7",
|
|
20
|
+
"@verdict-ai/core": "0.2.0",
|
|
21
|
+
"@verdict-ai/sdk": "0.2.0"
|
|
22
|
+
},
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "git+https://github.com/Ustay-coder/verdict.git",
|
|
27
|
+
"directory": "packages/mcp"
|
|
28
|
+
},
|
|
29
|
+
"homepage": "https://github.com/Ustay-coder/verdict#readme",
|
|
30
|
+
"bugs": {
|
|
31
|
+
"url": "https://github.com/Ustay-coder/verdict/issues"
|
|
32
|
+
},
|
|
33
|
+
"keywords": [
|
|
34
|
+
"evaluation",
|
|
35
|
+
"rubric",
|
|
36
|
+
"decision-model",
|
|
37
|
+
"jev",
|
|
38
|
+
"clef",
|
|
39
|
+
"scoring",
|
|
40
|
+
"llm-judge",
|
|
41
|
+
"mcp"
|
|
42
|
+
],
|
|
43
|
+
"engines": {
|
|
44
|
+
"node": ">=20"
|
|
45
|
+
},
|
|
46
|
+
"publishConfig": {
|
|
47
|
+
"access": "public"
|
|
48
|
+
},
|
|
49
|
+
"files": [
|
|
50
|
+
"dist",
|
|
51
|
+
"README.md",
|
|
52
|
+
"LICENSE"
|
|
53
|
+
],
|
|
54
|
+
"sideEffects": false,
|
|
55
|
+
"scripts": {
|
|
56
|
+
"build": "tsc -p tsconfig.json && chmod +x dist/bin.js",
|
|
57
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
58
|
+
"test": "vitest run --passWithNoTests"
|
|
59
|
+
}
|
|
6
60
|
}
|