@cursor/july 0.1.16 → 0.1.18
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/README.md +9 -4
- package/dist/bin/agent-serve.js +60 -2
- package/dist/channels/slack/api.d.ts.map +1 -1
- package/dist/channels/slack/api.js +13 -3
- package/dist/channels/slack/auth.d.ts +7 -1
- package/dist/channels/slack/auth.d.ts.map +1 -1
- package/dist/channels/slack/auth.js +14 -0
- package/dist/channels/slack/blocks.d.ts +61 -0
- package/dist/channels/slack/blocks.d.ts.map +1 -0
- package/dist/channels/slack/blocks.js +90 -0
- package/dist/channels/slack/cursor-account.d.ts.map +1 -1
- package/dist/channels/slack/cursor-account.js +1 -1
- package/dist/channels/slack/defaults.d.ts +2 -0
- package/dist/channels/slack/defaults.d.ts.map +1 -1
- package/dist/channels/slack/defaults.js +29 -3
- package/dist/channels/slack/dispatch.d.ts +3 -17
- package/dist/channels/slack/dispatch.d.ts.map +1 -1
- package/dist/channels/slack/dispatch.js +4 -1
- package/dist/channels/slack/inbound.d.ts.map +1 -1
- package/dist/channels/slack/inbound.js +6 -1
- package/dist/channels/slack/index.d.ts +2 -0
- package/dist/channels/slack/index.d.ts.map +1 -1
- package/dist/channels/slack/index.js +2 -0
- package/dist/channels/slack/init.d.ts.map +1 -1
- package/dist/channels/slack/init.js +4 -1
- package/dist/channels/slack/interactive.d.ts +39 -3
- package/dist/channels/slack/interactive.d.ts.map +1 -1
- package/dist/channels/slack/interactive.js +153 -7
- package/dist/channels/slack/manifest.d.ts +13 -0
- package/dist/channels/slack/manifest.d.ts.map +1 -1
- package/dist/channels/slack/manifest.js +36 -14
- package/dist/channels/slack/message-body.d.ts +13 -0
- package/dist/channels/slack/message-body.d.ts.map +1 -0
- package/dist/channels/slack/message-body.js +82 -0
- package/dist/channels/slack/setup.d.ts +4 -1
- package/dist/channels/slack/setup.d.ts.map +1 -1
- package/dist/channels/slack/setup.js +16 -2
- package/dist/channels/slack/slack-channel.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.js +24 -3
- package/dist/channels/slack/thread-context.d.ts +0 -2
- package/dist/channels/slack/thread-context.d.ts.map +1 -1
- package/dist/channels/slack/thread-context.js +1 -65
- package/dist/channels/slack/types.d.ts +93 -1
- package/dist/channels/slack/types.d.ts.map +1 -1
- package/dist/connections.d.ts +4 -1
- package/dist/connections.d.ts.map +1 -1
- package/dist/connections.js +4 -1
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +3 -3
- package/dist/docs/assets/{app.DjHC-Ggf.js → app.BR5EdVSq.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.BOzkeUi8.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.DwviwmIq.js → VPLocalSearchBox.CNCzfUKC.js} +1 -1
- package/dist/docs/assets/chunks/{theme.BIpeYSon.js → theme.CwKvMSWv.js} +2 -2
- package/dist/docs/assets/{example-agents_security-reviewer.md.BZSNycMf.js → example-agents_security-reviewer.md.Dhj_m7_B.js} +1 -1
- package/dist/docs/assets/{guides_mcp-oauth.md.DqmEOQY1.js → guides_mcp-oauth.md.Dd8EgSem.js} +3 -2
- package/dist/docs/assets/{guides_mcp-oauth.md.DqmEOQY1.lean.js → guides_mcp-oauth.md.Dd8EgSem.lean.js} +1 -1
- package/dist/docs/assets/{guides_slack.md.FWale6Ip.js → guides_slack.md.D_xFKlnF.js} +1 -1
- package/dist/docs/assets/{reference_connections.md.CsSr3rDz.js → reference_connections.md.B9Q3TOve.js} +12 -5
- package/dist/docs/assets/{reference_connections.md.CsSr3rDz.lean.js → reference_connections.md.B9Q3TOve.lean.js} +1 -1
- package/dist/docs/building-with-agents.html +3 -3
- package/dist/docs/concepts.html +3 -3
- package/dist/docs/deployment.html +3 -3
- package/dist/docs/evals.html +3 -3
- package/dist/docs/example-agents/approval-buddy.html +3 -3
- package/dist/docs/example-agents/benny.html +3 -3
- package/dist/docs/example-agents/bugbot.html +3 -3
- package/dist/docs/example-agents/codebase-wiki.html +3 -3
- package/dist/docs/example-agents/codeowners-review.html +3 -3
- package/dist/docs/example-agents/concierge.html +3 -3
- package/dist/docs/example-agents/fsd.html +3 -3
- package/dist/docs/example-agents/index.html +3 -3
- package/dist/docs/example-agents/knowledge-base.html +3 -3
- package/dist/docs/example-agents/oncall.html +3 -3
- package/dist/docs/example-agents/security-reviewer.html +5 -5
- package/dist/docs/example-agents/slack-agent.html +3 -3
- package/dist/docs/example-agents/weather-agent.html +3 -3
- package/dist/docs/guides/agent-to-agent.html +3 -3
- package/dist/docs/guides/cloud-runtime.html +3 -3
- package/dist/docs/guides/github.html +3 -3
- package/dist/docs/guides/human-in-the-loop.html +3 -3
- package/dist/docs/guides/mcp-oauth.html +6 -5
- package/dist/docs/guides/slack.html +5 -5
- package/dist/docs/guides/webhooks.html +3 -3
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +3 -3
- package/dist/docs/index.html +3 -3
- package/dist/docs/quickstart.html +3 -3
- package/dist/docs/reference/agent-config.html +3 -3
- package/dist/docs/reference/channels.html +3 -3
- package/dist/docs/reference/cli.html +3 -3
- package/dist/docs/reference/connections.html +14 -7
- package/dist/docs/reference/hooks.html +3 -3
- package/dist/docs/reference/http-api.html +3 -3
- package/dist/docs/reference/instructions.html +3 -3
- package/dist/docs/reference/playground.html +3 -3
- package/dist/docs/reference/project-layout.html +3 -3
- package/dist/docs/reference/prompt.html +3 -3
- package/dist/docs/reference/schedules.html +3 -3
- package/dist/docs/reference/sessions.html +3 -3
- package/dist/docs/reference/skills.html +3 -3
- package/dist/docs/reference/subagents.html +3 -3
- package/dist/docs/reference/tools.html +3 -3
- package/dist/docs/scaffolding-agents.html +3 -3
- package/dist/docs/storage.html +3 -3
- package/dist/docs/troubleshooting.html +3 -3
- package/dist/evals/assertions.d.ts +190 -0
- package/dist/evals/assertions.d.ts.map +1 -0
- package/dist/evals/assertions.js +461 -0
- package/dist/evals/expect.d.ts +95 -0
- package/dist/evals/expect.d.ts.map +1 -0
- package/dist/evals/expect.js +194 -0
- package/dist/evals/judge.d.ts +133 -0
- package/dist/evals/judge.d.ts.map +1 -0
- package/dist/evals/judge.js +228 -0
- package/dist/evals/loaders.d.ts +51 -0
- package/dist/evals/loaders.d.ts.map +1 -0
- package/dist/evals/loaders.js +124 -0
- package/dist/evals/matchers.d.ts +95 -0
- package/dist/evals/matchers.d.ts.map +1 -0
- package/dist/evals/matchers.js +145 -0
- package/dist/evals/reporters.d.ts +70 -0
- package/dist/evals/reporters.d.ts.map +1 -0
- package/dist/evals/reporters.js +221 -0
- package/dist/evals/results.d.ts +103 -0
- package/dist/evals/results.d.ts.map +1 -0
- package/dist/evals/results.js +28 -0
- package/dist/evals/run-facts.d.ts +77 -0
- package/dist/evals/run-facts.d.ts.map +1 -0
- package/dist/evals/run-facts.js +187 -0
- package/dist/evals.d.ts +118 -31
- package/dist/evals.d.ts.map +1 -1
- package/dist/evals.js +46 -12
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/internal/builtin-tools/index.d.ts +10 -0
- package/dist/internal/builtin-tools/index.d.ts.map +1 -0
- package/dist/internal/builtin-tools/index.js +27 -0
- package/dist/internal/builtin-tools/reminders.d.ts +9 -0
- package/dist/internal/builtin-tools/reminders.d.ts.map +1 -0
- package/dist/internal/builtin-tools/reminders.js +138 -0
- package/dist/internal/cli-ax.d.ts +27 -0
- package/dist/internal/cli-ax.d.ts.map +1 -1
- package/dist/internal/cli-ax.js +90 -12
- package/dist/internal/cli-mcp.d.ts +8 -0
- package/dist/internal/cli-mcp.d.ts.map +1 -1
- package/dist/internal/cli-mcp.js +98 -0
- package/dist/internal/cli-slack.d.ts +29 -1
- package/dist/internal/cli-slack.d.ts.map +1 -1
- package/dist/internal/cli-slack.js +799 -13
- package/dist/internal/cursor-event-relay.d.ts +30 -0
- package/dist/internal/cursor-event-relay.d.ts.map +1 -1
- package/dist/internal/cursor-event-relay.js +37 -0
- package/dist/internal/deploy-client.d.ts +7 -0
- package/dist/internal/deploy-client.d.ts.map +1 -1
- package/dist/internal/deploy-client.js +9 -0
- package/dist/internal/discovery.d.ts.map +1 -1
- package/dist/internal/discovery.js +70 -9
- package/dist/internal/distribution.d.ts.map +1 -1
- package/dist/internal/distribution.js +2 -0
- package/dist/internal/eval-judge-model.d.ts +59 -0
- package/dist/internal/eval-judge-model.d.ts.map +1 -0
- package/dist/internal/eval-judge-model.js +131 -0
- package/dist/internal/eval-run-store.d.ts.map +1 -1
- package/dist/internal/eval-run-store.js +12 -20
- package/dist/internal/eval-runner.d.ts +31 -25
- package/dist/internal/eval-runner.d.ts.map +1 -1
- package/dist/internal/eval-runner.js +329 -126
- package/dist/internal/evals-client.d.ts.map +1 -1
- package/dist/internal/evals-client.js +4 -1
- package/dist/internal/local-env.d.ts +8 -0
- package/dist/internal/local-env.d.ts.map +1 -0
- package/dist/internal/local-env.js +47 -0
- package/dist/internal/playground/static.d.ts +3 -0
- package/dist/internal/playground/static.d.ts.map +1 -1
- package/dist/internal/playground/static.js +3 -0
- package/dist/internal/reminder-runner.d.ts +7 -0
- package/dist/internal/reminder-runner.d.ts.map +1 -1
- package/dist/internal/reminder-runner.js +21 -0
- package/dist/internal/run-client.d.ts +15 -0
- package/dist/internal/run-client.d.ts.map +1 -1
- package/dist/internal/run-client.js +3 -2
- package/dist/internal/sdk-runner.d.ts +51 -1
- package/dist/internal/sdk-runner.d.ts.map +1 -1
- package/dist/internal/sdk-runner.js +176 -36
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +11 -1
- package/dist/internal/session-engine.d.ts +18 -5
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +81 -19
- package/dist/internal/slack-provision-client.d.ts +133 -0
- package/dist/internal/slack-provision-client.d.ts.map +1 -0
- package/dist/internal/slack-provision-client.js +286 -0
- package/dist/playground/assets/cursor-icons-16-f_W_ogc-.woff2 +0 -0
- package/dist/playground/assets/index-DRjS5klQ.js +85 -0
- package/dist/playground/assets/index-TCDs-UhZ.css +1 -0
- package/dist/playground/index.html +2 -2
- package/dist/types.d.ts +98 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +26 -0
- package/docs/example-agents/security-reviewer.md +1 -1
- package/docs/guides/mcp-oauth.md +10 -5
- package/docs/guides/slack.md +3 -2
- package/docs/reference/connections.md +28 -18
- package/package.json +20 -2
- package/skills/create-agent/SKILL.md +15 -7
- package/skills/debug/SKILL.md +3 -1
- package/skills/mcp-auth/SKILL.md +1 -1
- package/skills/setup-slack/SKILL.md +177 -11
- package/src/bin/agent-serve.ts +63 -2
- package/src/channels/slack/api.ts +16 -3
- package/src/channels/slack/auth.ts +16 -1
- package/src/channels/slack/blocks.ts +139 -0
- package/src/channels/slack/cursor-account.ts +1 -0
- package/src/channels/slack/defaults.ts +32 -4
- package/src/channels/slack/dispatch.ts +6 -19
- package/src/channels/slack/inbound.ts +6 -1
- package/src/channels/slack/index.ts +2 -0
- package/src/channels/slack/init.ts +3 -0
- package/src/channels/slack/interactive.ts +184 -19
- package/src/channels/slack/manifest.ts +37 -6
- package/src/channels/slack/message-body.ts +90 -0
- package/src/channels/slack/setup.ts +16 -2
- package/src/channels/slack/slack-channel.ts +37 -6
- package/src/channels/slack/thread-context.ts +1 -69
- package/src/channels/slack/types.ts +105 -1
- package/src/connections.ts +4 -1
- package/src/evals/assertions.ts +704 -0
- package/src/evals/expect.ts +272 -0
- package/src/evals/judge.ts +346 -0
- package/src/evals/loaders.ts +113 -0
- package/src/evals/matchers.ts +246 -0
- package/src/evals/reporters.ts +274 -0
- package/src/evals/results.ts +132 -0
- package/src/evals/run-facts.ts +274 -0
- package/src/evals.ts +205 -42
- package/src/index.ts +2 -0
- package/src/internal/builtin-tools/index.ts +40 -0
- package/src/internal/builtin-tools/reminders.ts +158 -0
- package/src/internal/cli-ax.ts +134 -15
- package/src/internal/cli-mcp.ts +118 -5
- package/src/internal/cli-slack.ts +1017 -15
- package/src/internal/cursor-event-relay.ts +67 -0
- package/src/internal/deploy-client.ts +10 -0
- package/src/internal/discovery.ts +83 -5
- package/src/internal/distribution.ts +2 -0
- package/src/internal/eval-judge-model.ts +148 -0
- package/src/internal/eval-run-store.ts +10 -14
- package/src/internal/eval-runner.ts +460 -214
- package/src/internal/evals-client.ts +5 -0
- package/src/internal/local-env.ts +53 -0
- package/src/internal/playground/static.ts +3 -0
- package/src/internal/reminder-runner.ts +30 -0
- package/src/internal/run-client.ts +17 -1
- package/src/internal/sdk-runner.ts +234 -35
- package/src/internal/server.ts +12 -0
- package/src/internal/session-engine.ts +103 -21
- package/src/internal/slack-provision-client.ts +442 -0
- package/src/types.ts +125 -4
- package/dist/channels/slack/post-update-delivery.d.ts +0 -85
- package/dist/channels/slack/post-update-delivery.d.ts.map +0 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.DZtu0ZIc.js +0 -1
- package/dist/internal/json-dir-store.d.ts +0 -32
- package/dist/internal/json-dir-store.d.ts.map +0 -1
- package/dist/internal/persistence-coordinator.d.ts +0 -127
- package/dist/internal/persistence-coordinator.d.ts.map +0 -1
- package/dist/persistence.d.ts +0 -184
- package/dist/persistence.d.ts.map +0 -1
- package/dist/playground/assets/cursor-icons-16-CQ50JpfO.woff2 +0 -0
- package/dist/playground/assets/index-Bwl4Onx4.js +0 -85
- package/dist/playground/assets/index-ByV4nfch.css +0 -1
- /package/dist/docs/assets/{example-agents_security-reviewer.md.BZSNycMf.lean.js → example-agents_security-reviewer.md.Dhj_m7_B.lean.js} +0 -0
- /package/dist/docs/assets/{guides_slack.md.FWale6Ip.lean.js → guides_slack.md.D_xFKlnF.lean.js} +0 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fixture loaders for dataset-driven evals.
|
|
3
|
+
*
|
|
4
|
+
* Eval modules are ESM, so top-level `await` can load a dataset and fan one
|
|
5
|
+
* file out over it:
|
|
6
|
+
*
|
|
7
|
+
* ```ts
|
|
8
|
+
* // evals/sql.eval.ts
|
|
9
|
+
* import { defineEval } from "@cursor/july/evals";
|
|
10
|
+
* import { loadYaml } from "@cursor/july/evals/loaders";
|
|
11
|
+
* import { equals } from "@cursor/july/evals";
|
|
12
|
+
*
|
|
13
|
+
* const rows = await loadYaml<{ task: string; prompt: string; sql: string }[]>(
|
|
14
|
+
* "evals/data/cases.yaml"
|
|
15
|
+
* );
|
|
16
|
+
*
|
|
17
|
+
* export default rows.map((row) =>
|
|
18
|
+
* defineEval({
|
|
19
|
+
* description: row.task,
|
|
20
|
+
* async test(t) {
|
|
21
|
+
* await t.send(row.prompt);
|
|
22
|
+
* t.succeeded();
|
|
23
|
+
* t.check(t.reply, equals(row.sql));
|
|
24
|
+
* },
|
|
25
|
+
* })
|
|
26
|
+
* );
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* Paths resolve from the app root (the directory holding `agent/` and
|
|
30
|
+
* `evals/`), not from the eval file, so a fixture path reads the same however
|
|
31
|
+
* deep the eval sits. These loaders are for fixtures — do not use them for
|
|
32
|
+
* runtime agent code.
|
|
33
|
+
*/
|
|
34
|
+
/**
|
|
35
|
+
* App root used to resolve relative fixture paths.
|
|
36
|
+
*
|
|
37
|
+
* `eval` sets `AGENT_SERVE_EVAL_ROOT` to the project it discovered, which keeps
|
|
38
|
+
* fixture paths stable no matter what cwd the CLI was invoked from. Falls back
|
|
39
|
+
* to the process cwd.
|
|
40
|
+
*/
|
|
41
|
+
export declare const EVAL_ROOT_ENV = "AGENT_SERVE_EVAL_ROOT";
|
|
42
|
+
export declare function evalFixtureRoot(): string;
|
|
43
|
+
/** Resolve a fixture path against the app root. */
|
|
44
|
+
export declare function resolveFixturePath(path: string): string;
|
|
45
|
+
/** Load a JSON fixture. */
|
|
46
|
+
export declare function loadJson<T = unknown>(path: string): Promise<T>;
|
|
47
|
+
/** Load a newline-delimited JSON fixture, skipping blank lines. */
|
|
48
|
+
export declare function loadJsonl<T = unknown>(path: string): Promise<T[]>;
|
|
49
|
+
/** Load a YAML fixture. */
|
|
50
|
+
export declare function loadYaml<T = unknown>(path: string): Promise<T>;
|
|
51
|
+
//# sourceMappingURL=loaders.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loaders.d.ts","sourceRoot":"","sources":["../../src/evals/loaders.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAKH;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,0BAA0B,CAAC;AAErD,wBAAgB,eAAe,IAAI,MAAM,CAGxC;AAED,mDAAmD;AACnD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvD;AAYD,2BAA2B;AAC3B,wBAAsB,QAAQ,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAQpE;AAED,mEAAmE;AACnE,wBAAsB,SAAS,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAoBvE;AAED,2BAA2B;AAC3B,wBAAsB,QAAQ,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAWpE"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fixture loaders for dataset-driven evals.
|
|
3
|
+
*
|
|
4
|
+
* Eval modules are ESM, so top-level `await` can load a dataset and fan one
|
|
5
|
+
* file out over it:
|
|
6
|
+
*
|
|
7
|
+
* ```ts
|
|
8
|
+
* // evals/sql.eval.ts
|
|
9
|
+
* import { defineEval } from "@cursor/july/evals";
|
|
10
|
+
* import { loadYaml } from "@cursor/july/evals/loaders";
|
|
11
|
+
* import { equals } from "@cursor/july/evals";
|
|
12
|
+
*
|
|
13
|
+
* const rows = await loadYaml<{ task: string; prompt: string; sql: string }[]>(
|
|
14
|
+
* "evals/data/cases.yaml"
|
|
15
|
+
* );
|
|
16
|
+
*
|
|
17
|
+
* export default rows.map((row) =>
|
|
18
|
+
* defineEval({
|
|
19
|
+
* description: row.task,
|
|
20
|
+
* async test(t) {
|
|
21
|
+
* await t.send(row.prompt);
|
|
22
|
+
* t.succeeded();
|
|
23
|
+
* t.check(t.reply, equals(row.sql));
|
|
24
|
+
* },
|
|
25
|
+
* })
|
|
26
|
+
* );
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* Paths resolve from the app root (the directory holding `agent/` and
|
|
30
|
+
* `evals/`), not from the eval file, so a fixture path reads the same however
|
|
31
|
+
* deep the eval sits. These loaders are for fixtures — do not use them for
|
|
32
|
+
* runtime agent code.
|
|
33
|
+
*/
|
|
34
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
35
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
36
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
37
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
38
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
39
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
40
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
41
|
+
});
|
|
42
|
+
};
|
|
43
|
+
import { readFile } from "node:fs/promises";
|
|
44
|
+
import { isAbsolute, resolve } from "node:path";
|
|
45
|
+
/**
|
|
46
|
+
* App root used to resolve relative fixture paths.
|
|
47
|
+
*
|
|
48
|
+
* `eval` sets `AGENT_SERVE_EVAL_ROOT` to the project it discovered, which keeps
|
|
49
|
+
* fixture paths stable no matter what cwd the CLI was invoked from. Falls back
|
|
50
|
+
* to the process cwd.
|
|
51
|
+
*/
|
|
52
|
+
export const EVAL_ROOT_ENV = "AGENT_SERVE_EVAL_ROOT";
|
|
53
|
+
export function evalFixtureRoot() {
|
|
54
|
+
const root = process.env[EVAL_ROOT_ENV];
|
|
55
|
+
return root === undefined || root.trim() === "" ? process.cwd() : root;
|
|
56
|
+
}
|
|
57
|
+
/** Resolve a fixture path against the app root. */
|
|
58
|
+
export function resolveFixturePath(path) {
|
|
59
|
+
return isAbsolute(path) ? path : resolve(evalFixtureRoot(), path);
|
|
60
|
+
}
|
|
61
|
+
function readFixture(path) {
|
|
62
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
63
|
+
const absolute = resolveFixturePath(path);
|
|
64
|
+
try {
|
|
65
|
+
return yield readFile(absolute, "utf8");
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
69
|
+
throw new Error(`failed to load eval fixture ${absolute}: ${detail}`);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
/** Load a JSON fixture. */
|
|
74
|
+
export function loadJson(path) {
|
|
75
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
76
|
+
const text = yield readFixture(path);
|
|
77
|
+
try {
|
|
78
|
+
return JSON.parse(text);
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
82
|
+
throw new Error(`${resolveFixturePath(path)} is not valid JSON: ${detail}`);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
/** Load a newline-delimited JSON fixture, skipping blank lines. */
|
|
87
|
+
export function loadJsonl(path) {
|
|
88
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
89
|
+
const text = yield readFixture(path);
|
|
90
|
+
const rows = [];
|
|
91
|
+
let lineNumber = 0;
|
|
92
|
+
for (const line of text.split("\n")) {
|
|
93
|
+
lineNumber++;
|
|
94
|
+
const trimmed = line.trim();
|
|
95
|
+
if (trimmed === "") {
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
try {
|
|
99
|
+
rows.push(JSON.parse(trimmed));
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
103
|
+
throw new Error(`${resolveFixturePath(path)}:${lineNumber} is not valid JSON: ${detail}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return rows;
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
/** Load a YAML fixture. */
|
|
110
|
+
export function loadYaml(path) {
|
|
111
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
112
|
+
const text = yield readFixture(path);
|
|
113
|
+
// Imported lazily so a project that only uses JSON fixtures never pays for
|
|
114
|
+
// the YAML parser at eval-discovery time.
|
|
115
|
+
const { load } = yield import("js-yaml");
|
|
116
|
+
try {
|
|
117
|
+
return load(text);
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
121
|
+
throw new Error(`${resolveFixturePath(path)} is not valid YAML: ${detail}`);
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Matcher mini-language shared by tool-call, subagent, and event assertions.
|
|
3
|
+
*
|
|
4
|
+
* A matcher is a literal, a RegExp, or a predicate:
|
|
5
|
+
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* t.calledTool("bash", { input: { command: /^pwd/ }, count: 1 });
|
|
8
|
+
* t.calledTool("echo", { count: (n) => n >= 2 });
|
|
9
|
+
* t.calledTool("read", { output: (value) => String(value).includes("hello") });
|
|
10
|
+
* ```
|
|
11
|
+
*
|
|
12
|
+
* Object literals partial-deep-match, so `{ input: { city: "NYC" } }` matches a
|
|
13
|
+
* call whose args also carry unrelated keys. Nested values may themselves be
|
|
14
|
+
* matchers.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Literal forms a matcher can take.
|
|
18
|
+
*
|
|
19
|
+
* Spelled out rather than written as `unknown` so the union keeps its function
|
|
20
|
+
* member: `unknown` would absorb it, and TypeScript could no longer infer the
|
|
21
|
+
* parameter type of an inline predicate. Nested values are matchers in turn, so
|
|
22
|
+
* a predicate buried in an object literal gets its parameter type too.
|
|
23
|
+
*/
|
|
24
|
+
export type EvalMatcherLiteral = string | number | boolean | null | Date | readonly EvalMatcher[] | {
|
|
25
|
+
readonly [key: string]: EvalMatcher | undefined;
|
|
26
|
+
};
|
|
27
|
+
/** A literal to partial-match, a RegExp to test, or a predicate. */
|
|
28
|
+
export type EvalMatcher<T = unknown> = EvalMatcherLiteral | RegExp | ((value: T) => boolean);
|
|
29
|
+
/** An exact count, or a predicate over the observed count. */
|
|
30
|
+
export type EvalCountMatcher = number | ((count: number) => boolean);
|
|
31
|
+
/** Lifecycle state of one tool call, derived from the session event stream. */
|
|
32
|
+
export type EvalToolCallStatus =
|
|
33
|
+
/** `action.result` arrived without `isError`. */
|
|
34
|
+
"completed"
|
|
35
|
+
/** `action.result` arrived with `isError: true`. */
|
|
36
|
+
| "failed"
|
|
37
|
+
/** Requested, no result yet (includes calls parked on human approval). */
|
|
38
|
+
| "pending"
|
|
39
|
+
/** A human denied the approval request for this call. */
|
|
40
|
+
| "rejected";
|
|
41
|
+
/** Constraints for {@link import("../evals.js").EvalAssertions.calledTool}. */
|
|
42
|
+
export interface EvalToolCallMatcher {
|
|
43
|
+
/** Match the tool's arguments (partial-deep for object literals). */
|
|
44
|
+
input?: EvalMatcher;
|
|
45
|
+
/** Match the tool's result payload. */
|
|
46
|
+
output?: EvalMatcher;
|
|
47
|
+
/**
|
|
48
|
+
* Restrict to one lifecycle state. Omitted matches **any** state, which is
|
|
49
|
+
* request-based and therefore backwards compatible with `calledTool(name)`.
|
|
50
|
+
*/
|
|
51
|
+
status?: EvalToolCallStatus;
|
|
52
|
+
/** Require an exact number of matching calls, or satisfy a predicate. */
|
|
53
|
+
count?: EvalCountMatcher;
|
|
54
|
+
}
|
|
55
|
+
/** Constraints for {@link import("../evals.js").EvalAssertions.calledSubagent}. */
|
|
56
|
+
export interface EvalSubagentMatcher {
|
|
57
|
+
/** Match the delegating `task` call id. */
|
|
58
|
+
callId?: EvalMatcher<string>;
|
|
59
|
+
/** Match the subagent's final output text. */
|
|
60
|
+
output?: EvalMatcher;
|
|
61
|
+
/** `completed` once `subagent.completed` arrived, else `pending`. */
|
|
62
|
+
status?: "completed" | "pending";
|
|
63
|
+
count?: EvalCountMatcher;
|
|
64
|
+
}
|
|
65
|
+
/** Constraints for {@link import("../evals.js").EvalAssertions.event}. */
|
|
66
|
+
export interface EvalEventMatcher {
|
|
67
|
+
/** Partial-deep match against the event's `data` payload. */
|
|
68
|
+
data?: EvalMatcher;
|
|
69
|
+
count?: EvalCountMatcher;
|
|
70
|
+
}
|
|
71
|
+
/** One entry of {@link import("../evals.js").EvalAssertions.eventOrder}. */
|
|
72
|
+
export interface EvalEventOrderMatcher extends EvalEventMatcher {
|
|
73
|
+
type: string;
|
|
74
|
+
}
|
|
75
|
+
/** Stable string form used when a RegExp is tested against a non-string. */
|
|
76
|
+
export declare function stringifyForMatch(value: unknown): string;
|
|
77
|
+
/**
|
|
78
|
+
* Whether `actual` satisfies `matcher`.
|
|
79
|
+
*
|
|
80
|
+
* - `undefined` matcher matches anything (the constraint was not supplied).
|
|
81
|
+
* - A function is called with `actual`.
|
|
82
|
+
* - A RegExp is tested against {@link stringifyForMatch}.
|
|
83
|
+
* - An object or array literal partial-deep-matches, and its own values may be
|
|
84
|
+
* matchers.
|
|
85
|
+
* - Anything else compares by deep equality.
|
|
86
|
+
*/
|
|
87
|
+
export declare function matchValue<T = unknown>(actual: T, matcher: EvalMatcher<T> | undefined): boolean;
|
|
88
|
+
/** Whether an observed count satisfies a {@link EvalCountMatcher}. */
|
|
89
|
+
export declare function matchCount(observed: number, matcher: EvalCountMatcher | undefined): boolean;
|
|
90
|
+
/** Human-readable matcher summary for assertion names and failure details. */
|
|
91
|
+
export declare function describeMatcher(matcher: EvalMatcher | undefined): string;
|
|
92
|
+
/** Compact `{ input: …, count: 2 }` summary for assertion names. */
|
|
93
|
+
export declare function describeMatcherObject(matcher: Record<string, unknown> | undefined): string;
|
|
94
|
+
export declare function deepEqual(a: unknown, b: unknown): boolean;
|
|
95
|
+
//# sourceMappingURL=matchers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matchers.d.ts","sourceRoot":"","sources":["../../src/evals/matchers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;GAOG;AACH,MAAM,MAAM,kBAAkB,GAC1B,MAAM,GACN,MAAM,GACN,OAAO,GACP,IAAI,GACJ,IAAI,GACJ,SAAS,WAAW,EAAE,GACtB;IAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAAA;CAAE,CAAC;AAExD,oEAAoE;AACpE,MAAM,MAAM,WAAW,CAAC,CAAC,GAAG,OAAO,IAC/B,kBAAkB,GAClB,MAAM,GACN,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC;AAE5B,8DAA8D;AAC9D,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC;AAErE,+EAA+E;AAC/E,MAAM,MAAM,kBAAkB;AAC5B,iDAAiD;AAC/C,WAAW;AACb,oDAAoD;GAClD,QAAQ;AACV,0EAA0E;GACxE,SAAS;AACX,yDAAyD;GACvD,UAAU,CAAC;AAEf,+EAA+E;AAC/E,MAAM,WAAW,mBAAmB;IAClC,qEAAqE;IACrE,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,uCAAuC;IACvC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;OAGG;IACH,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,yEAAyE;IACzE,KAAK,CAAC,EAAE,gBAAgB,CAAC;CAC1B;AAED,mFAAmF;AACnF,MAAM,WAAW,mBAAmB;IAClC,2CAA2C;IAC3C,MAAM,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC7B,8CAA8C;IAC9C,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,qEAAqE;IACrE,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IACjC,KAAK,CAAC,EAAE,gBAAgB,CAAC;CAC1B;AAED,0EAA0E;AAC1E,MAAM,WAAW,gBAAgB;IAC/B,6DAA6D;IAC7D,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,KAAK,CAAC,EAAE,gBAAgB,CAAC;CAC1B;AAED,4EAA4E;AAC5E,MAAM,WAAW,qBAAsB,SAAQ,gBAAgB;IAC7D,IAAI,EAAE,MAAM,CAAC;CACd;AAYD,4EAA4E;AAC5E,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAkBxD;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,CAAC,GAAG,OAAO,EACpC,MAAM,EAAE,CAAC,EACT,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,SAAS,GAClC,OAAO,CA2BT;AAED,sEAAsE;AACtE,wBAAgB,UAAU,CACxB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,gBAAgB,GAAG,SAAS,GACpC,OAAO,CAQT;AAED,8EAA8E;AAC9E,wBAAgB,eAAe,CAAC,OAAO,EAAE,WAAW,GAAG,SAAS,GAAG,MAAM,CAWxE;AAED,oEAAoE;AACpE,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAC3C,MAAM,CAQR;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,GAAG,OAAO,CAwCzD"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Matcher mini-language shared by tool-call, subagent, and event assertions.
|
|
3
|
+
*
|
|
4
|
+
* A matcher is a literal, a RegExp, or a predicate:
|
|
5
|
+
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* t.calledTool("bash", { input: { command: /^pwd/ }, count: 1 });
|
|
8
|
+
* t.calledTool("echo", { count: (n) => n >= 2 });
|
|
9
|
+
* t.calledTool("read", { output: (value) => String(value).includes("hello") });
|
|
10
|
+
* ```
|
|
11
|
+
*
|
|
12
|
+
* Object literals partial-deep-match, so `{ input: { city: "NYC" } }` matches a
|
|
13
|
+
* call whose args also carry unrelated keys. Nested values may themselves be
|
|
14
|
+
* matchers.
|
|
15
|
+
*/
|
|
16
|
+
function isPlainObject(value) {
|
|
17
|
+
return (typeof value === "object" &&
|
|
18
|
+
value !== null &&
|
|
19
|
+
!Array.isArray(value) &&
|
|
20
|
+
!(value instanceof RegExp) &&
|
|
21
|
+
!(value instanceof Date));
|
|
22
|
+
}
|
|
23
|
+
/** Stable string form used when a RegExp is tested against a non-string. */
|
|
24
|
+
export function stringifyForMatch(value) {
|
|
25
|
+
var _a;
|
|
26
|
+
if (typeof value === "string") {
|
|
27
|
+
return value;
|
|
28
|
+
}
|
|
29
|
+
if (value === undefined) {
|
|
30
|
+
return "";
|
|
31
|
+
}
|
|
32
|
+
if (value === null) {
|
|
33
|
+
return "null";
|
|
34
|
+
}
|
|
35
|
+
if (typeof value === "object") {
|
|
36
|
+
try {
|
|
37
|
+
return (_a = JSON.stringify(value)) !== null && _a !== void 0 ? _a : "";
|
|
38
|
+
}
|
|
39
|
+
catch (_b) {
|
|
40
|
+
return String(value);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return String(value);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Whether `actual` satisfies `matcher`.
|
|
47
|
+
*
|
|
48
|
+
* - `undefined` matcher matches anything (the constraint was not supplied).
|
|
49
|
+
* - A function is called with `actual`.
|
|
50
|
+
* - A RegExp is tested against {@link stringifyForMatch}.
|
|
51
|
+
* - An object or array literal partial-deep-matches, and its own values may be
|
|
52
|
+
* matchers.
|
|
53
|
+
* - Anything else compares by deep equality.
|
|
54
|
+
*/
|
|
55
|
+
export function matchValue(actual, matcher) {
|
|
56
|
+
if (matcher === undefined) {
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
if (typeof matcher === "function") {
|
|
60
|
+
return matcher(actual) === true;
|
|
61
|
+
}
|
|
62
|
+
if (matcher instanceof RegExp) {
|
|
63
|
+
return matcher.test(stringifyForMatch(actual));
|
|
64
|
+
}
|
|
65
|
+
if (Array.isArray(matcher)) {
|
|
66
|
+
if (!Array.isArray(actual) || actual.length !== matcher.length) {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
return matcher.every((entry, index) => matchValue(actual[index], entry));
|
|
70
|
+
}
|
|
71
|
+
if (isPlainObject(matcher)) {
|
|
72
|
+
if (!isPlainObject(actual)) {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
return Object.entries(matcher).every(([key, entry]) => matchValue(actual[key], entry));
|
|
76
|
+
}
|
|
77
|
+
return deepEqual(actual, matcher);
|
|
78
|
+
}
|
|
79
|
+
/** Whether an observed count satisfies a {@link EvalCountMatcher}. */
|
|
80
|
+
export function matchCount(observed, matcher) {
|
|
81
|
+
if (matcher === undefined) {
|
|
82
|
+
return observed > 0;
|
|
83
|
+
}
|
|
84
|
+
if (typeof matcher === "function") {
|
|
85
|
+
return matcher(observed) === true;
|
|
86
|
+
}
|
|
87
|
+
return observed === matcher;
|
|
88
|
+
}
|
|
89
|
+
/** Human-readable matcher summary for assertion names and failure details. */
|
|
90
|
+
export function describeMatcher(matcher) {
|
|
91
|
+
if (matcher === undefined) {
|
|
92
|
+
return "any";
|
|
93
|
+
}
|
|
94
|
+
if (typeof matcher === "function") {
|
|
95
|
+
return "predicate";
|
|
96
|
+
}
|
|
97
|
+
if (matcher instanceof RegExp) {
|
|
98
|
+
return String(matcher);
|
|
99
|
+
}
|
|
100
|
+
return stringifyForMatch(matcher);
|
|
101
|
+
}
|
|
102
|
+
/** Compact `{ input: …, count: 2 }` summary for assertion names. */
|
|
103
|
+
export function describeMatcherObject(matcher) {
|
|
104
|
+
if (matcher === undefined) {
|
|
105
|
+
return "";
|
|
106
|
+
}
|
|
107
|
+
const parts = Object.entries(matcher)
|
|
108
|
+
.filter(([, value]) => value !== undefined)
|
|
109
|
+
.map(([key, value]) => `${key}=${describeMatcher(value)}`);
|
|
110
|
+
return parts.length === 0 ? "" : `, {${parts.join(", ")}}`;
|
|
111
|
+
}
|
|
112
|
+
export function deepEqual(a, b) {
|
|
113
|
+
if (Object.is(a, b)) {
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
if (a instanceof RegExp && b instanceof RegExp) {
|
|
117
|
+
return String(a) === String(b);
|
|
118
|
+
}
|
|
119
|
+
if (typeof a !== "object" ||
|
|
120
|
+
typeof b !== "object" ||
|
|
121
|
+
a === null ||
|
|
122
|
+
b === null) {
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
if (Array.isArray(a) !== Array.isArray(b)) {
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
129
|
+
if (a.length !== b.length) {
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
return a.every((item, i) => deepEqual(item, b[i]));
|
|
133
|
+
}
|
|
134
|
+
const aKeys = Object.keys(a);
|
|
135
|
+
const bKeys = Object.keys(b);
|
|
136
|
+
if (aKeys.length !== bKeys.length) {
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
for (const key of aKeys) {
|
|
140
|
+
if (!deepEqual(a[key], b[key])) {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in eval reporters.
|
|
3
|
+
*
|
|
4
|
+
* The CLI already prints a console summary; reporters add destinations on top.
|
|
5
|
+
* Attach them in `evals/evals.config.ts` to observe every case in the run, or
|
|
6
|
+
* on a single `defineEval({ reporters })` to scope a destination to that case.
|
|
7
|
+
*
|
|
8
|
+
* ```ts
|
|
9
|
+
* // evals/evals.config.ts
|
|
10
|
+
* import { defineEvalConfig } from "@cursor/july/evals";
|
|
11
|
+
* import { JUnit } from "@cursor/july/evals/reporters";
|
|
12
|
+
*
|
|
13
|
+
* export default defineEvalConfig({
|
|
14
|
+
* maxConcurrency: 20,
|
|
15
|
+
* reporters: [JUnit({ filePath: ".agent-serve/junit.xml" })],
|
|
16
|
+
* });
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* `agentkit eval --junit <path>` and `--artifacts <dir>` attach these same two
|
|
20
|
+
* reporters without touching the eval files, which is usually the better fit:
|
|
21
|
+
* CI owns the output paths, not the eval author.
|
|
22
|
+
*/
|
|
23
|
+
import type { EvalReporter, EvalRunSummary } from "./results.js";
|
|
24
|
+
export type { EvalReporter, EvalReporterEvalInfo, EvalReporterTarget, EvalRunResult, EvalRunSummary, } from "./results.js";
|
|
25
|
+
export interface JUnitReporterOptions {
|
|
26
|
+
/** Where to write the XML. Relative paths resolve from the process cwd. */
|
|
27
|
+
filePath: string;
|
|
28
|
+
/** `<testsuite name>`; defaults to `agentkit-evals`. */
|
|
29
|
+
suiteName?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Write JUnit XML so CI shows per-case annotations.
|
|
33
|
+
*
|
|
34
|
+
* Each case becomes one `<testcase>` named by its path-derived id. Failed gates
|
|
35
|
+
* and execution errors become `<failure>`, `t.skip(reason)` becomes `<skipped>`,
|
|
36
|
+
* and a soft threshold miss becomes a `<failure>` only under `--strict` (it is
|
|
37
|
+
* reported as a `<system-out>` score line otherwise).
|
|
38
|
+
*/
|
|
39
|
+
export declare function JUnit(options: JUnitReporterOptions): EvalReporter;
|
|
40
|
+
/** Render a {@link EvalRunSummary} as JUnit XML. Exported for tests. */
|
|
41
|
+
export declare function renderJUnitXml(summary: EvalRunSummary, suiteName: string): string;
|
|
42
|
+
export interface ArtifactsReporterOptions {
|
|
43
|
+
/** Run directory. Relative paths resolve from the process cwd. */
|
|
44
|
+
dir: string;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Persist the full story of a run to disk.
|
|
48
|
+
*
|
|
49
|
+
* Console output stays tight on purpose; when a case fails, the artifact has
|
|
50
|
+
* everything — every assertion with its score, the captured event stream, the
|
|
51
|
+
* tool calls, and `t.log` lines.
|
|
52
|
+
*
|
|
53
|
+
* ```text
|
|
54
|
+
* <dir>/summary.json run totals + config
|
|
55
|
+
* <dir>/results.jsonl one line per case, in completion order
|
|
56
|
+
* <dir>/evals/<case-id>.json per-case detail
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
export declare function Artifacts(options: ArtifactsReporterOptions): EvalReporter;
|
|
60
|
+
/**
|
|
61
|
+
* Turn a case id into a safe relative path.
|
|
62
|
+
*
|
|
63
|
+
* Ids are already path-shaped (`weather/nyc`), and `defineEval` rejects `..` in
|
|
64
|
+
* case ids, but the artifact writer sanitizes anyway so a hand-built result can
|
|
65
|
+
* never escape the run directory.
|
|
66
|
+
*/
|
|
67
|
+
export declare function sanitizeCaseId(id: string): string;
|
|
68
|
+
/** Fan one lifecycle call out to several reporters, isolating failures. */
|
|
69
|
+
export declare function combineReporters(reporters: readonly EvalReporter[], onError?: (error: unknown) => void): EvalReporter;
|
|
70
|
+
//# sourceMappingURL=reporters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reporters.d.ts","sourceRoot":"","sources":["../../src/evals/reporters.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAIH,OAAO,KAAK,EACV,YAAY,EAIZ,cAAc,EACf,MAAM,cAAc,CAAC;AAEtB,YAAY,EACV,YAAY,EACZ,oBAAoB,EACpB,kBAAkB,EAClB,aAAa,EACb,cAAc,GACf,MAAM,cAAc,CAAC;AAEtB,MAAM,WAAW,oBAAoB;IACnC,2EAA2E;IAC3E,QAAQ,EAAE,MAAM,CAAC;IACjB,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,wBAAgB,KAAK,CAAC,OAAO,EAAE,oBAAoB,GAAG,YAAY,CAYjE;AAED,wEAAwE;AACxE,wBAAgB,cAAc,CAC5B,OAAO,EAAE,cAAc,EACvB,SAAS,EAAE,MAAM,GAChB,MAAM,CAiDR;AA8CD,MAAM,WAAW,wBAAwB;IACvC,kEAAkE;IAClE,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,wBAAwB,GAAG,YAAY,CA8CzE;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAMjD;AAED,2EAA2E;AAC3E,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,SAAS,YAAY,EAAE,EAClC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GACjC,YAAY,CAmBd"}
|