anpord 0.1.13 → 0.1.16

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.
Files changed (65) hide show
  1. package/dist/api-context.cjs +18 -0
  2. package/dist/api-context.d.cts +8 -0
  3. package/dist/api-context.d.mts +8 -0
  4. package/dist/api-context.mjs +17 -0
  5. package/dist/api-mocks-B3qngoqS.cjs +68 -0
  6. package/dist/api-mocks-BfKw_hXc.mjs +33 -0
  7. package/dist/api-mocks-Bz3G00ve.d.cts +101 -0
  8. package/dist/api-mocks-Bz3G00ve.d.mts +101 -0
  9. package/dist/api-runtime.cjs +4 -0
  10. package/dist/api-runtime.d.cts +13 -0
  11. package/dist/api-runtime.d.mts +13 -0
  12. package/dist/api-runtime.mjs +2 -0
  13. package/dist/api.cjs +5 -0
  14. package/dist/api.d.cts +4 -0
  15. package/dist/api.d.mts +4 -0
  16. package/dist/api.mjs +2 -0
  17. package/dist/bin.cjs +8 -8
  18. package/dist/bin.mjs +6 -6
  19. package/dist/cli-runtime.cjs +1 -1
  20. package/dist/cli-runtime.mjs +1 -1
  21. package/dist/{client-BgRs8JvW.d.mts → client-C8tBcLYs.d.mts} +17 -17
  22. package/dist/{client-BirFO3jz.d.cts → client-CMkx-LKC.d.cts} +16 -16
  23. package/dist/{client-C-P2I00z.cjs → client-CfYNoI3L.cjs} +4 -91
  24. package/dist/{client-BfdjFtlV.mjs → client-YWKJd3f-.mjs} +3 -90
  25. package/dist/{compiler-uwb1pkdK.cjs → compiler-4FKsNxZ-.cjs} +89 -33
  26. package/dist/{compiler-D96wI7UP.mjs → compiler-Dsltkkj5.mjs} +77 -21
  27. package/dist/config.cjs +1 -1
  28. package/dist/config.d.cts +1 -1
  29. package/dist/config.d.mts +1 -1
  30. package/dist/config.mjs +1 -1
  31. package/dist/define-NZvmQuIv.d.cts +34 -0
  32. package/dist/define-NZvmQuIv.d.mts +34 -0
  33. package/dist/{eval-judges-DPPUftbh.d.cts → eval-judges-JiC8cUCE.d.cts} +1 -1
  34. package/dist/{eval-judges-DPPUftbh.d.mts → eval-judges-JiC8cUCE.d.mts} +1 -1
  35. package/dist/{eval-validations-BRdoZrTQ.mjs → eval-validations-Bmagd2y7.mjs} +2 -2
  36. package/dist/{eval-validations-_MlnQ_uv.cjs → eval-validations-CqMUt5ra.cjs} +7 -1
  37. package/dist/eval.cjs +1 -1
  38. package/dist/eval.d.cts +42 -21
  39. package/dist/eval.d.mts +42 -21
  40. package/dist/eval.mjs +1 -1
  41. package/dist/{evals-B6aT3xgH.d.cts → evals-B2UuSop0.d.cts} +136 -136
  42. package/dist/{evals-B6aT3xgH.d.mts → evals-B2UuSop0.d.mts} +136 -136
  43. package/dist/{types-Codjaq-o.d.mts → evals-api-CfAA3cew.d.mts} +12 -112
  44. package/dist/{types-ISsteq95.d.cts → evals-api-Clbj_nEN.d.cts} +11 -111
  45. package/dist/{evals-Dcc_x6jW.mjs → evals-api-DDv4gXU1.mjs} +95 -4
  46. package/dist/{evals-DouMsrsM.cjs → evals-api-kOuyIqvB.cjs} +103 -72
  47. package/dist/index.cjs +2 -2
  48. package/dist/index.d.cts +6 -6
  49. package/dist/index.d.mts +7 -7
  50. package/dist/index.mjs +2 -2
  51. package/dist/mcp-runtime.cjs +1 -1
  52. package/dist/mcp-runtime.mjs +1 -1
  53. package/dist/runtime-C0_JPkef.mjs +269 -0
  54. package/dist/runtime-YVJP5P2r.cjs +292 -0
  55. package/dist/source.d.cts +1 -1
  56. package/dist/source.d.mts +1 -1
  57. package/dist/types-BHokRQpg.d.mts +112 -0
  58. package/dist/types-UKEi5CCa.d.cts +112 -0
  59. package/dist/validator-runtime.cjs +6 -1
  60. package/dist/validator-runtime.d.cts +1 -1
  61. package/dist/validator-runtime.d.mts +1 -1
  62. package/dist/validator-runtime.mjs +6 -1
  63. package/dist/validators.d.cts +1 -1
  64. package/dist/validators.d.mts +1 -1
  65. package/package.json +21 -1
@@ -1,10 +1,11 @@
1
- const require_evals = require("./evals-DouMsrsM.cjs");
2
1
  const require_eval_judges = require("./eval-judges-BkmiVLLq.cjs");
2
+ const require_api_mocks = require("./api-mocks-B3qngoqS.cjs");
3
+ const require_evals_api = require("./evals-api-kOuyIqvB.cjs");
3
4
  const require_source = require("./source-DvlGawEw.cjs");
4
5
  let effect = require("effect");
6
+ let node_fs_promises = require("node:fs/promises");
5
7
  let node_path = require("node:path");
6
8
  let node_fs = require("node:fs");
7
- let node_fs_promises = require("node:fs/promises");
8
9
  let node_url = require("node:url");
9
10
  let esbuild = require("esbuild");
10
11
  let node_zlib = require("node:zlib");
@@ -43,7 +44,7 @@ const sourceFiles = (map, entry) => {
43
44
  content
44
45
  }];
45
46
  });
46
- return effect.Schema.decodeUnknownSync(require_evals.EvalSourceFiles)(files.toSorted((a, b) => Number(b.path === entryPath) - Number(a.path === entryPath) || a.path.localeCompare(b.path)));
47
+ return effect.Schema.decodeUnknownSync(require_evals_api.EvalSourceFiles)(files.toSorted((a, b) => Number(b.path === entryPath) - Number(a.path === entryPath) || a.path.localeCompare(b.path)));
47
48
  };
48
49
  //#endregion
49
50
  //#region src/evals/eval-bundle.ts
@@ -52,6 +53,24 @@ const authoringDir = (0, node_path.dirname)((0, node_url.fileURLToPath)(require(
52
53
  const ANPORD_MODULE = /^anpord$/;
53
54
  const ANY_MODULE = /.*/;
54
55
  const localModules = [
56
+ {
57
+ built: "api.mjs",
58
+ filter: /^anpord\/api$/,
59
+ namespace: "anpord-api-authoring",
60
+ source: "../mock-api/index.ts"
61
+ },
62
+ {
63
+ built: "api-runtime.mjs",
64
+ filter: /^anpord\/api\/runtime$/,
65
+ namespace: "anpord-api-runtime",
66
+ source: "../mock-api/runtime.ts"
67
+ },
68
+ {
69
+ built: "api-context.mjs",
70
+ filter: /^anpord\/api\/context$/,
71
+ namespace: "anpord-api-context",
72
+ source: "../mock-api/context.ts"
73
+ },
55
74
  {
56
75
  built: "validator-runtime.mjs",
57
76
  filter: /^anpord\/validators\/runtime$/,
@@ -128,6 +147,7 @@ const bundle = (contents, entry, options = {}) => effect.Effect.tryPromise({
128
147
  try: () => (0, esbuild.build)({
129
148
  absWorkingDir: process.cwd(),
130
149
  bundle: true,
150
+ banner: { js: "import { createRequire as anpordCreateRequire } from \"node:module\"; const require = anpordCreateRequire(import.meta.url);" },
131
151
  format: "esm",
132
152
  metafile: true,
133
153
  minify: options.minify,
@@ -158,6 +178,52 @@ const bundle = (contents, entry, options = {}) => effect.Effect.tryPromise({
158
178
  catch: (cause) => new Error(`Could not compile ${entry}`, { cause })
159
179
  });
160
180
  //#endregion
181
+ //#region src/evals/program-package.ts
182
+ const CHUNK_SIZE = 9e4;
183
+ const packageProgram = (root, entry, source) => {
184
+ const archive = (0, node_zlib.gzipSync)(source).toString("base64");
185
+ const chunks = Array.from({ length: Math.ceil(archive.length / CHUNK_SIZE) }, (_, index) => archive.slice(index * CHUNK_SIZE, (index + 1) * CHUNK_SIZE));
186
+ const names = chunks.map((_, index) => `${index}.txt`);
187
+ const loader = `#!/usr/bin/env node\nimport{readFile,writeFile}from"node:fs/promises";import{gunzipSync}from"node:zlib";const root=new URL("./",import.meta.url),names=${JSON.stringify(names)},data=(await Promise.all(names.map(name=>readFile(new URL(name,root),"utf8")))).join(""),runtime=new URL("runtime.mjs",root);await writeFile(runtime,gunzipSync(Buffer.from(data,"base64")));await import(runtime.href);`;
188
+ return {
189
+ entry: `${root}/${entry}`,
190
+ files: Object.fromEntries([[`${root}/${entry}`, loader], ...chunks.map((chunk, index) => [`${root}/${index}.txt`, chunk])])
191
+ };
192
+ };
193
+ //#endregion
194
+ //#region src/evals/api-profile.ts
195
+ const compileApis = (entry, definitions) => effect.Effect.gen(function* () {
196
+ if (definitions.length === 0) return {};
197
+ const names = definitions.map(({ name }) => name);
198
+ if (new Set(names).size !== names.length) return yield* effect.Effect.fail(/* @__PURE__ */ new Error("Duplicate API mock name"));
199
+ const { source } = yield* bundle(`import definition from ${JSON.stringify(entry)};
200
+ import { runApiServers } from "anpord/api/runtime";
201
+ runApiServers(definition.api ?? []);`, entry, { minify: true });
202
+ const program = packageProgram("workspace/.anpord/api", "server.mjs", source);
203
+ return {
204
+ ...program.files,
205
+ [require_api_mocks.API_PROGRAM]: JSON.stringify({ entry: program.entry.slice(10) })
206
+ };
207
+ });
208
+ const withApis = (task, files) => {
209
+ if (Object.keys(files).length === 0) return task;
210
+ const profile = task.profile ?? {
211
+ name: "anpord-api",
212
+ files: {}
213
+ };
214
+ for (const path of Object.keys(files)) if (profile.files[path] !== void 0) throw new Error(`Profile file ${path} is reserved for API mocks`);
215
+ return {
216
+ ...task,
217
+ profile: {
218
+ ...profile,
219
+ files: {
220
+ ...profile.files,
221
+ ...files
222
+ }
223
+ }
224
+ };
225
+ };
226
+ //#endregion
161
227
  //#region src/evals/case-modules.ts
162
228
  const realOrGiven = (path) => {
163
229
  try {
@@ -175,7 +241,7 @@ const exportingModule = (entry, inputs, name) => effect.Effect.gen(function* ()
175
241
  });
176
242
  const bundledCaseModule = (entry, inputs, name, wrap) => effect.Effect.gen(function* () {
177
243
  const module = yield* exportingModule(entry, inputs, name);
178
- const { source } = yield* bundle(wrap(module, name), entry);
244
+ const { source } = yield* bundle(wrap(module, name), entry, { minify: true });
179
245
  return {
180
246
  name,
181
247
  source
@@ -188,19 +254,6 @@ const appendInstall = (profile, command) => ({
188
254
  install: profile.install ? `${profile.install} && ${command}` : command
189
255
  });
190
256
  //#endregion
191
- //#region src/evals/program-package.ts
192
- const CHUNK_SIZE = 9e4;
193
- const packageProgram = (root, entry, source) => {
194
- const archive = (0, node_zlib.gzipSync)(source).toString("base64");
195
- const chunks = Array.from({ length: Math.ceil(archive.length / CHUNK_SIZE) }, (_, index) => archive.slice(index * CHUNK_SIZE, (index + 1) * CHUNK_SIZE));
196
- const names = chunks.map((_, index) => `${index}.txt`);
197
- const loader = `#!/usr/bin/env node\nimport{readFile,writeFile}from"node:fs/promises";import{gunzipSync}from"node:zlib";const root=new URL("./",import.meta.url),names=${JSON.stringify(names)},data=(await Promise.all(names.map(name=>readFile(new URL(name,root),"utf8")))).join(""),runtime=new URL("runtime.mjs",root);await writeFile(runtime,gunzipSync(Buffer.from(data,"base64")));await import(runtime.href);`;
198
- return {
199
- entry: `${root}/${entry}`,
200
- files: Object.fromEntries([[`${root}/${entry}`, loader], ...names.map((name, index) => [`${root}/${name}`, chunks[index]])])
201
- };
202
- };
203
- //#endregion
204
257
  //#region src/evals/runner-source.ts
205
258
  const validatorCaseEntry = (entry, index, names = []) => `import definition from ${JSON.stringify(entry)};
206
259
  import { runValidators } from "anpord/validators/runtime";
@@ -209,6 +262,7 @@ const names = ${JSON.stringify(names)};
209
262
  const checks = (Array.isArray(selected) ? selected : [selected]).flatMap((validate, index) => typeof validate === "function" ? [{ index, name: names.find(check => check.index === index)?.name ?? "Validator " + (index + 1), validate }] : []);
210
263
  await runValidators(checks, definition.captureValidation !== false);`;
211
264
  const prepareRuntime = `
265
+ import { apiContext } from "anpord/api/context";
212
266
  import { access, readFile } from "node:fs/promises";
213
267
  import { spawn } from "node:child_process";
214
268
 
@@ -236,6 +290,7 @@ const exec = (file, args = [], options = {}) => new Promise((resolve, reject) =>
236
290
  });
237
291
 
238
292
  const context = {
293
+ api: apiContext,
239
294
  cached: process.env.ANPORD_CACHE_RESTORED === "1",
240
295
  exec,
241
296
  exists: path => access(path).then(() => true, () => false),
@@ -321,7 +376,7 @@ const compileValidator = (entry, subject, caseIndex, captureSource, captureValid
321
376
  manifest,
322
377
  capture: captureValidation
323
378
  }] : [];
324
- return yield* effect.Schema.decodeUnknown(require_evals.EvalValidator)({
379
+ return yield* effect.Schema.decodeUnknown(require_evals_api.EvalValidator)({
325
380
  ...judges.length > 0 ? {
326
381
  kind: "judged",
327
382
  name: subject.name,
@@ -487,7 +542,7 @@ const adapters = {
487
542
  const applyMcpHarness = (harness, profile, servers) => {
488
543
  const adapter = adapters[harness];
489
544
  if (adapter === null) throw new Error(`MCP mock servers are not supported by ${harness}`);
490
- return effect.Schema.decodeUnknownSync(require_evals.HarnessProfile)(adapter.apply(profile, servers));
545
+ return effect.Schema.decodeUnknownSync(require_evals_api.HarnessProfile)(adapter.apply(profile, servers));
491
546
  };
492
547
  //#endregion
493
548
  //#region src/evals/mcp-profile.ts
@@ -533,17 +588,17 @@ var ProfilePathInvalid = class extends effect.Data.TaggedError("ProfilePathInval
533
588
  };
534
589
  var ProfileFileTooLarge = class extends effect.Data.TaggedError("ProfileFileTooLarge") {
535
590
  get message() {
536
- return `${this.path} is ${this.chars} characters; a profile file holds at most ${require_evals.PROFILE_LIMITS.fileChars}`;
591
+ return `${this.path} is ${this.chars} characters; a profile file holds at most ${require_evals_api.PROFILE_LIMITS.fileChars}`;
537
592
  }
538
593
  };
539
594
  var ProfileTooLarge = class extends effect.Data.TaggedError("ProfileTooLarge") {
540
595
  get message() {
541
- return `The profile's files hold ${this.chars} characters; at most ${require_evals.PROFILE_LIMITS.totalChars} fit`;
596
+ return `The profile's files hold ${this.chars} characters; at most ${require_evals_api.PROFILE_LIMITS.totalChars} fit`;
542
597
  }
543
598
  };
544
599
  var ProfileTooManyFiles = class extends effect.Data.TaggedError("ProfileTooManyFiles") {
545
600
  get message() {
546
- return `The profile has ${this.count} files; at most ${require_evals.PROFILE_LIMITS.files} fit`;
601
+ return `The profile has ${this.count} files; at most ${require_evals_api.PROFILE_LIMITS.files} fit`;
547
602
  }
548
603
  };
549
604
  var ProfileManifestInvalid = class extends effect.Data.TaggedError("ProfileManifestInvalid") {
@@ -570,7 +625,7 @@ var ProfileStepNotSupported = class extends effect.Data.TaggedError("ProfileStep
570
625
  //#region src/evals/profile-manifest.ts
571
626
  const Manifest = effect.Schema.Struct({
572
627
  env: effect.Schema.optional(effect.Schema.Record({
573
- key: require_evals.EnvName,
628
+ key: require_evals_api.EnvName,
574
629
  value: effect.Schema.String
575
630
  })),
576
631
  install: effect.Schema.optional(effect.Schema.String),
@@ -647,7 +702,7 @@ const shippedPaths = (dir) => effect.Effect.tryPromise({
647
702
  return (await Promise.all(SHIPPED_ROOTS.map((root) => walkRoot(dir, root)))).flat().sort();
648
703
  }
649
704
  });
650
- const validPath = (path) => effect.Schema.decodeUnknown(require_evals.ProfilePath)(path).pipe(effect.Effect.mapError(() => new ProfilePathInvalid({ path })));
705
+ const validPath = (path) => effect.Schema.decodeUnknown(require_evals_api.ProfilePath)(path).pipe(effect.Effect.mapError(() => new ProfilePathInvalid({ path })));
651
706
  /** Nothing when the file holds a NUL byte and so is not text. */
652
707
  const readShipped = (dir, path) => effect.Effect.gen(function* () {
653
708
  const bytes = yield* effect.Effect.tryPromise({
@@ -659,7 +714,7 @@ const readShipped = (dir, path) => effect.Effect.gen(function* () {
659
714
  });
660
715
  if (bytes.includes(0)) return [];
661
716
  const content = bytes.toString("utf8");
662
- if (content.length > require_evals.PROFILE_LIMITS.fileChars) return yield* new ProfileFileTooLarge({
717
+ if (content.length > require_evals_api.PROFILE_LIMITS.fileChars) return yield* new ProfileFileTooLarge({
663
718
  chars: content.length,
664
719
  path
665
720
  });
@@ -667,14 +722,14 @@ const readShipped = (dir, path) => effect.Effect.gen(function* () {
667
722
  });
668
723
  const shippedFiles = (dir) => effect.Effect.gen(function* () {
669
724
  const paths = yield* shippedPaths(dir);
670
- if (paths.length > require_evals.PROFILE_LIMITS.files) return yield* new ProfileTooManyFiles({ count: paths.length });
725
+ if (paths.length > require_evals_api.PROFILE_LIMITS.files) return yield* new ProfileTooManyFiles({ count: paths.length });
671
726
  const entries = yield* effect.Effect.forEach(paths, (path) => readShipped(dir, path), { concurrency: 8 }).pipe(effect.Effect.map((read) => read.flat()));
672
727
  const chars = entries.reduce((sum, [, content]) => sum + content.length, 0);
673
- if (chars > require_evals.PROFILE_LIMITS.totalChars) return yield* new ProfileTooLarge({ chars });
728
+ if (chars > require_evals_api.PROFILE_LIMITS.totalChars) return yield* new ProfileTooLarge({ chars });
674
729
  return Object.fromEntries(entries);
675
730
  });
676
731
  const fittingHarness = (base, profile) => {
677
- if (require_evals.profileFitsHarness({
732
+ if (require_evals_api.profileFitsHarness({
678
733
  harness: base,
679
734
  profile
680
735
  })) return effect.Effect.succeed(profile);
@@ -708,7 +763,7 @@ const profileTask = (entry, task) => effect.Effect.gen(function* () {
708
763
  }).pipe(effect.Effect.withSpan("Eval.profileTask", { attributes: { profile: task.harness.profile.name } }));
709
764
  //#endregion
710
765
  //#region src/evals/compiler.ts
711
- const taskOf = (entry, task, clis, mcp) => effect.Effect.gen(function* () {
766
+ const taskOf = (entry, task, clis, mcp, apis) => effect.Effect.gen(function* () {
712
767
  const compiled = typeof task.harness === "string" ? {
713
768
  harness: task.harness,
714
769
  model: task.model,
@@ -717,7 +772,7 @@ const taskOf = (entry, task, clis, mcp) => effect.Effect.gen(function* () {
717
772
  ...task,
718
773
  harness: task.harness
719
774
  });
720
- return yield* effect.Effect.try(() => withClis(withMcpServers(compiled, mcp), clis));
775
+ return yield* effect.Effect.try(() => withApis(withClis(withMcpServers(compiled, mcp), clis), apis));
721
776
  });
722
777
  const sourceFor = (definition, subject, fallback) => {
723
778
  const source = subject.source ?? definition.source;
@@ -734,6 +789,7 @@ const compileEvalEffect = (path) => effect.Effect.gen(function* () {
734
789
  if (!isDefinition(definition)) return yield* effect.Effect.fail(/* @__PURE__ */ new Error(`${entry} must default export defineEval({ ... })`));
735
790
  const clis = yield* compileClis(entry, definition.cli ?? []);
736
791
  const mcp = yield* compileMcpServers(entry, definition.mcp ?? []);
792
+ const apis = yield* compileApis(entry, definition.api ?? []);
737
793
  const fallback = definition.source === void 0 && definition.cases.some((subject) => subject.source === void 0) ? yield* localRepo((0, node_path.dirname)(entry)) : effect.Option.none();
738
794
  const cases = yield* effect.Effect.forEach(definition.cases, (subject, caseIndex) => effect.Effect.gen(function* () {
739
795
  if (subject.validate !== void 0 === (typeof subject.verify === "string")) return yield* effect.Effect.fail(/* @__PURE__ */ new Error(`${subject.name} must have exactly one of validate or verify`));
@@ -749,14 +805,14 @@ const compileEvalEffect = (path) => effect.Effect.gen(function* () {
749
805
  verify: subject.verify ?? null
750
806
  };
751
807
  }), { concurrency: 4 });
752
- const tasks = yield* effect.Effect.forEach(definition.tasks, (task) => taskOf(entry, task, clis, mcp), { concurrency: 4 });
753
- return {
808
+ const tasks = yield* effect.Effect.forEach(definition.tasks, (task) => taskOf(entry, task, clis, mcp, apis), { concurrency: 4 });
809
+ return yield* effect.Schema.decodeUnknown(require_evals_api.PublicStartEvalRequest)({
754
810
  cases,
755
811
  name: definition.name,
756
812
  prompt: definition.prompt,
757
813
  tasks,
758
814
  trials: definition.trials
759
- };
815
+ });
760
816
  }).pipe(effect.Effect.withSpan("Eval.compile"));
761
817
  const compileEval = (path) => effect.Effect.runPromise(compileEvalEffect(path));
762
818
  //#endregion
@@ -1,10 +1,11 @@
1
- import { S as EvalSourceFiles, _ as HarnessProfile, b as ProfilePath, d as EvalValidator, g as EnvName, x as profileFitsHarness, y as PROFILE_LIMITS } from "./evals-Dcc_x6jW.mjs";
2
1
  import { t as EvalJudge } from "./eval-judges-CwTvTq7N.mjs";
2
+ import { r as API_PROGRAM } from "./api-mocks-BfKw_hXc.mjs";
3
+ import { a as EvalValidator, c as PROFILE_LIMITS, d as EvalSourceFiles, l as ProfilePath, n as PublicStartEvalRequest, o as EnvName, s as HarnessProfile, u as profileFitsHarness } from "./evals-api-DDv4gXU1.mjs";
3
4
  import { a as parseRepo, i as cloneUrlOf, r as repo } from "./source-Fg1h2VNn.mjs";
4
5
  import { Config, Data, Effect, Option, Schema } from "effect";
6
+ import { mkdtemp, readFile, readdir, rm, stat, writeFile } from "node:fs/promises";
5
7
  import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
6
8
  import { existsSync, realpathSync } from "node:fs";
7
- import { mkdtemp, readFile, readdir, rm, stat, writeFile } from "node:fs/promises";
8
9
  import { fileURLToPath, pathToFileURL } from "node:url";
9
10
  import { build } from "esbuild";
10
11
  import { gzipSync } from "node:zlib";
@@ -52,6 +53,24 @@ const authoringDir = dirname(fileURLToPath(import.meta.url));
52
53
  const ANPORD_MODULE = /^anpord$/;
53
54
  const ANY_MODULE = /.*/;
54
55
  const localModules = [
56
+ {
57
+ built: "api.mjs",
58
+ filter: /^anpord\/api$/,
59
+ namespace: "anpord-api-authoring",
60
+ source: "../mock-api/index.ts"
61
+ },
62
+ {
63
+ built: "api-runtime.mjs",
64
+ filter: /^anpord\/api\/runtime$/,
65
+ namespace: "anpord-api-runtime",
66
+ source: "../mock-api/runtime.ts"
67
+ },
68
+ {
69
+ built: "api-context.mjs",
70
+ filter: /^anpord\/api\/context$/,
71
+ namespace: "anpord-api-context",
72
+ source: "../mock-api/context.ts"
73
+ },
55
74
  {
56
75
  built: "validator-runtime.mjs",
57
76
  filter: /^anpord\/validators\/runtime$/,
@@ -128,6 +147,7 @@ const bundle = (contents, entry, options = {}) => Effect.tryPromise({
128
147
  try: () => build({
129
148
  absWorkingDir: process.cwd(),
130
149
  bundle: true,
150
+ banner: { js: "import { createRequire as anpordCreateRequire } from \"node:module\"; const require = anpordCreateRequire(import.meta.url);" },
131
151
  format: "esm",
132
152
  metafile: true,
133
153
  minify: options.minify,
@@ -158,6 +178,52 @@ const bundle = (contents, entry, options = {}) => Effect.tryPromise({
158
178
  catch: (cause) => new Error(`Could not compile ${entry}`, { cause })
159
179
  });
160
180
  //#endregion
181
+ //#region src/evals/program-package.ts
182
+ const CHUNK_SIZE = 9e4;
183
+ const packageProgram = (root, entry, source) => {
184
+ const archive = gzipSync(source).toString("base64");
185
+ const chunks = Array.from({ length: Math.ceil(archive.length / CHUNK_SIZE) }, (_, index) => archive.slice(index * CHUNK_SIZE, (index + 1) * CHUNK_SIZE));
186
+ const names = chunks.map((_, index) => `${index}.txt`);
187
+ const loader = `#!/usr/bin/env node\nimport{readFile,writeFile}from"node:fs/promises";import{gunzipSync}from"node:zlib";const root=new URL("./",import.meta.url),names=${JSON.stringify(names)},data=(await Promise.all(names.map(name=>readFile(new URL(name,root),"utf8")))).join(""),runtime=new URL("runtime.mjs",root);await writeFile(runtime,gunzipSync(Buffer.from(data,"base64")));await import(runtime.href);`;
188
+ return {
189
+ entry: `${root}/${entry}`,
190
+ files: Object.fromEntries([[`${root}/${entry}`, loader], ...chunks.map((chunk, index) => [`${root}/${index}.txt`, chunk])])
191
+ };
192
+ };
193
+ //#endregion
194
+ //#region src/evals/api-profile.ts
195
+ const compileApis = (entry, definitions) => Effect.gen(function* () {
196
+ if (definitions.length === 0) return {};
197
+ const names = definitions.map(({ name }) => name);
198
+ if (new Set(names).size !== names.length) return yield* Effect.fail(/* @__PURE__ */ new Error("Duplicate API mock name"));
199
+ const { source } = yield* bundle(`import definition from ${JSON.stringify(entry)};
200
+ import { runApiServers } from "anpord/api/runtime";
201
+ runApiServers(definition.api ?? []);`, entry, { minify: true });
202
+ const program = packageProgram("workspace/.anpord/api", "server.mjs", source);
203
+ return {
204
+ ...program.files,
205
+ [API_PROGRAM]: JSON.stringify({ entry: program.entry.slice(10) })
206
+ };
207
+ });
208
+ const withApis = (task, files) => {
209
+ if (Object.keys(files).length === 0) return task;
210
+ const profile = task.profile ?? {
211
+ name: "anpord-api",
212
+ files: {}
213
+ };
214
+ for (const path of Object.keys(files)) if (profile.files[path] !== void 0) throw new Error(`Profile file ${path} is reserved for API mocks`);
215
+ return {
216
+ ...task,
217
+ profile: {
218
+ ...profile,
219
+ files: {
220
+ ...profile.files,
221
+ ...files
222
+ }
223
+ }
224
+ };
225
+ };
226
+ //#endregion
161
227
  //#region src/evals/case-modules.ts
162
228
  const realOrGiven = (path) => {
163
229
  try {
@@ -175,7 +241,7 @@ const exportingModule = (entry, inputs, name) => Effect.gen(function* () {
175
241
  });
176
242
  const bundledCaseModule = (entry, inputs, name, wrap) => Effect.gen(function* () {
177
243
  const module = yield* exportingModule(entry, inputs, name);
178
- const { source } = yield* bundle(wrap(module, name), entry);
244
+ const { source } = yield* bundle(wrap(module, name), entry, { minify: true });
179
245
  return {
180
246
  name,
181
247
  source
@@ -188,19 +254,6 @@ const appendInstall = (profile, command) => ({
188
254
  install: profile.install ? `${profile.install} && ${command}` : command
189
255
  });
190
256
  //#endregion
191
- //#region src/evals/program-package.ts
192
- const CHUNK_SIZE = 9e4;
193
- const packageProgram = (root, entry, source) => {
194
- const archive = gzipSync(source).toString("base64");
195
- const chunks = Array.from({ length: Math.ceil(archive.length / CHUNK_SIZE) }, (_, index) => archive.slice(index * CHUNK_SIZE, (index + 1) * CHUNK_SIZE));
196
- const names = chunks.map((_, index) => `${index}.txt`);
197
- const loader = `#!/usr/bin/env node\nimport{readFile,writeFile}from"node:fs/promises";import{gunzipSync}from"node:zlib";const root=new URL("./",import.meta.url),names=${JSON.stringify(names)},data=(await Promise.all(names.map(name=>readFile(new URL(name,root),"utf8")))).join(""),runtime=new URL("runtime.mjs",root);await writeFile(runtime,gunzipSync(Buffer.from(data,"base64")));await import(runtime.href);`;
198
- return {
199
- entry: `${root}/${entry}`,
200
- files: Object.fromEntries([[`${root}/${entry}`, loader], ...names.map((name, index) => [`${root}/${name}`, chunks[index]])])
201
- };
202
- };
203
- //#endregion
204
257
  //#region src/evals/runner-source.ts
205
258
  const validatorCaseEntry = (entry, index, names = []) => `import definition from ${JSON.stringify(entry)};
206
259
  import { runValidators } from "anpord/validators/runtime";
@@ -209,6 +262,7 @@ const names = ${JSON.stringify(names)};
209
262
  const checks = (Array.isArray(selected) ? selected : [selected]).flatMap((validate, index) => typeof validate === "function" ? [{ index, name: names.find(check => check.index === index)?.name ?? "Validator " + (index + 1), validate }] : []);
210
263
  await runValidators(checks, definition.captureValidation !== false);`;
211
264
  const prepareRuntime = `
265
+ import { apiContext } from "anpord/api/context";
212
266
  import { access, readFile } from "node:fs/promises";
213
267
  import { spawn } from "node:child_process";
214
268
 
@@ -236,6 +290,7 @@ const exec = (file, args = [], options = {}) => new Promise((resolve, reject) =>
236
290
  });
237
291
 
238
292
  const context = {
293
+ api: apiContext,
239
294
  cached: process.env.ANPORD_CACHE_RESTORED === "1",
240
295
  exec,
241
296
  exists: path => access(path).then(() => true, () => false),
@@ -708,7 +763,7 @@ const profileTask = (entry, task) => Effect.gen(function* () {
708
763
  }).pipe(Effect.withSpan("Eval.profileTask", { attributes: { profile: task.harness.profile.name } }));
709
764
  //#endregion
710
765
  //#region src/evals/compiler.ts
711
- const taskOf = (entry, task, clis, mcp) => Effect.gen(function* () {
766
+ const taskOf = (entry, task, clis, mcp, apis) => Effect.gen(function* () {
712
767
  const compiled = typeof task.harness === "string" ? {
713
768
  harness: task.harness,
714
769
  model: task.model,
@@ -717,7 +772,7 @@ const taskOf = (entry, task, clis, mcp) => Effect.gen(function* () {
717
772
  ...task,
718
773
  harness: task.harness
719
774
  });
720
- return yield* Effect.try(() => withClis(withMcpServers(compiled, mcp), clis));
775
+ return yield* Effect.try(() => withApis(withClis(withMcpServers(compiled, mcp), clis), apis));
721
776
  });
722
777
  const sourceFor = (definition, subject, fallback) => {
723
778
  const source = subject.source ?? definition.source;
@@ -734,6 +789,7 @@ const compileEvalEffect = (path) => Effect.gen(function* () {
734
789
  if (!isDefinition(definition)) return yield* Effect.fail(/* @__PURE__ */ new Error(`${entry} must default export defineEval({ ... })`));
735
790
  const clis = yield* compileClis(entry, definition.cli ?? []);
736
791
  const mcp = yield* compileMcpServers(entry, definition.mcp ?? []);
792
+ const apis = yield* compileApis(entry, definition.api ?? []);
737
793
  const fallback = definition.source === void 0 && definition.cases.some((subject) => subject.source === void 0) ? yield* localRepo(dirname(entry)) : Option.none();
738
794
  const cases = yield* Effect.forEach(definition.cases, (subject, caseIndex) => Effect.gen(function* () {
739
795
  if (subject.validate !== void 0 === (typeof subject.verify === "string")) return yield* Effect.fail(/* @__PURE__ */ new Error(`${subject.name} must have exactly one of validate or verify`));
@@ -749,14 +805,14 @@ const compileEvalEffect = (path) => Effect.gen(function* () {
749
805
  verify: subject.verify ?? null
750
806
  };
751
807
  }), { concurrency: 4 });
752
- const tasks = yield* Effect.forEach(definition.tasks, (task) => taskOf(entry, task, clis, mcp), { concurrency: 4 });
753
- return {
808
+ const tasks = yield* Effect.forEach(definition.tasks, (task) => taskOf(entry, task, clis, mcp, apis), { concurrency: 4 });
809
+ return yield* Schema.decodeUnknown(PublicStartEvalRequest)({
754
810
  cases,
755
811
  name: definition.name,
756
812
  prompt: definition.prompt,
757
813
  tasks,
758
814
  trials: definition.trials
759
- };
815
+ });
760
816
  }).pipe(Effect.withSpan("Eval.compile"));
761
817
  const compileEval = (path) => Effect.runPromise(compileEvalEffect(path));
762
818
  //#endregion
package/dist/config.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_client = require("./client-C-P2I00z.cjs");
2
+ const require_client = require("./client-CfYNoI3L.cjs");
3
3
  let effect = require("effect");
4
4
  //#region src/client/config.ts
5
5
  const apiKeyConfig = effect.Config.redacted("ANPORD_API_KEY");
package/dist/config.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { t as AnpordApi } from "./client-BirFO3jz.cjs";
1
+ import { t as AnpordApi } from "./client-CMkx-LKC.cjs";
2
2
  import { Config, Layer } from "effect";
3
3
  //#region src/client/config.d.ts
4
4
  declare const apiKeyConfig: Config.Config<import("effect/Redacted").Redacted<string>>;
package/dist/config.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { t as AnpordApi } from "./client-BgRs8JvW.mjs";
1
+ import { t as AnpordApi } from "./client-C8tBcLYs.mjs";
2
2
  import { Config, Layer } from "effect";
3
3
  //#region src/client/config.d.ts
4
4
  declare const apiKeyConfig: Config.Config<import("effect/Redacted").Redacted<string>>;
package/dist/config.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { n as DEFAULT_BASE_URL, r as layer } from "./client-BfdjFtlV.mjs";
1
+ import { n as DEFAULT_BASE_URL, r as layer } from "./client-YWKJd3f-.mjs";
2
2
  import { Config, Effect, Layer } from "effect";
3
3
  //#region src/client/config.ts
4
4
  const apiKeyConfig = Config.redacted("ANPORD_API_KEY");
@@ -0,0 +1,34 @@
1
+ import { StandardSchemaV1 } from "@standard-schema/spec";
2
+ //#region src/mock-api/define.d.ts
3
+ type Responses = Readonly<Record<number, StandardSchemaV1>>;
4
+ type ResponseOf<R extends Responses> = { [Status in keyof R & number]: {
5
+ readonly status: Status;
6
+ readonly body: StandardSchemaV1.InferInput<R[Status]>;
7
+ readonly headers?: Readonly<Record<string, string>>;
8
+ }; }[keyof R & number];
9
+ interface ApiHandlerContext {
10
+ readonly log: (value: unknown) => void;
11
+ readonly signal: AbortSignal;
12
+ }
13
+ interface EndpointDefinition {
14
+ readonly description?: string;
15
+ handler(input: unknown, context: ApiHandlerContext): ResponseOf<Responses> | Promise<ResponseOf<Responses>>;
16
+ readonly inputSchema: StandardSchemaV1;
17
+ readonly method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS";
18
+ readonly path: `/${string}`;
19
+ readonly responses: Responses;
20
+ }
21
+ type EndpointOptions<Input extends StandardSchemaV1, Output extends Responses, Result> = Omit<EndpointDefinition, "inputSchema" | "responses" | "handler"> & {
22
+ readonly inputSchema: Input;
23
+ readonly responses: Output;
24
+ handler(input: StandardSchemaV1.InferOutput<Input>, context: ApiHandlerContext): Result | Promise<Result>;
25
+ };
26
+ declare const endpoint: <Input extends StandardSchemaV1, const Output extends Responses, const Result extends ResponseOf<Output>>(definition: EndpointOptions<Input, Output, Result>) => EndpointOptions<Input, Output, Result>;
27
+ interface ApiDefinition {
28
+ readonly endpoints: readonly EndpointDefinition[];
29
+ readonly name: string;
30
+ readonly redact?: readonly string[];
31
+ }
32
+ declare const api: (definition: ApiDefinition) => ApiDefinition;
33
+ //#endregion
34
+ export { endpoint as a, api as i, ApiHandlerContext as n, EndpointDefinition as r, ApiDefinition as t };
@@ -0,0 +1,34 @@
1
+ import { StandardSchemaV1 } from "@standard-schema/spec";
2
+ //#region src/mock-api/define.d.ts
3
+ type Responses = Readonly<Record<number, StandardSchemaV1>>;
4
+ type ResponseOf<R extends Responses> = { [Status in keyof R & number]: {
5
+ readonly status: Status;
6
+ readonly body: StandardSchemaV1.InferInput<R[Status]>;
7
+ readonly headers?: Readonly<Record<string, string>>;
8
+ }; }[keyof R & number];
9
+ interface ApiHandlerContext {
10
+ readonly log: (value: unknown) => void;
11
+ readonly signal: AbortSignal;
12
+ }
13
+ interface EndpointDefinition {
14
+ readonly description?: string;
15
+ handler(input: unknown, context: ApiHandlerContext): ResponseOf<Responses> | Promise<ResponseOf<Responses>>;
16
+ readonly inputSchema: StandardSchemaV1;
17
+ readonly method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS";
18
+ readonly path: `/${string}`;
19
+ readonly responses: Responses;
20
+ }
21
+ type EndpointOptions<Input extends StandardSchemaV1, Output extends Responses, Result> = Omit<EndpointDefinition, "inputSchema" | "responses" | "handler"> & {
22
+ readonly inputSchema: Input;
23
+ readonly responses: Output;
24
+ handler(input: StandardSchemaV1.InferOutput<Input>, context: ApiHandlerContext): Result | Promise<Result>;
25
+ };
26
+ declare const endpoint: <Input extends StandardSchemaV1, const Output extends Responses, const Result extends ResponseOf<Output>>(definition: EndpointOptions<Input, Output, Result>) => EndpointOptions<Input, Output, Result>;
27
+ interface ApiDefinition {
28
+ readonly endpoints: readonly EndpointDefinition[];
29
+ readonly name: string;
30
+ readonly redact?: readonly string[];
31
+ }
32
+ declare const api: (definition: ApiDefinition) => ApiDefinition;
33
+ //#endregion
34
+ export { endpoint as a, api as i, ApiHandlerContext as n, EndpointDefinition as r, ApiDefinition as t };
@@ -17,7 +17,7 @@ declare const EvalJudge: Schema.Union<[Schema.Struct<{
17
17
  }>;
18
18
  }>, Schema.Struct<{
19
19
  provider: Schema.optional<typeof Schema.Never>;
20
- harness: Schema.SchemaClass<"codex" | "opencode" | "pi" | "fx" | "claude" | "gemini" | "qwen" | "cursor", "codex" | "opencode" | "pi" | "fx" | "claude" | "gemini" | "qwen" | "cursor", never>;
20
+ harness: Schema.SchemaClass<"cursor" | "codex" | "opencode" | "pi" | "fx" | "claude" | "gemini" | "qwen", "cursor" | "codex" | "opencode" | "pi" | "fx" | "claude" | "gemini" | "qwen", never>;
21
21
  kind: Schema.Literal<["judge"]>;
22
22
  name: Schema.filter<Schema.filter<typeof Schema.String>>;
23
23
  model: Schema.filter<Schema.filter<typeof Schema.String>>;
@@ -17,7 +17,7 @@ declare const EvalJudge: Schema.Union<[Schema.Struct<{
17
17
  }>;
18
18
  }>, Schema.Struct<{
19
19
  provider: Schema.optional<typeof Schema.Never>;
20
- harness: Schema.SchemaClass<"codex" | "opencode" | "pi" | "fx" | "claude" | "gemini" | "qwen" | "cursor", "codex" | "opencode" | "pi" | "fx" | "claude" | "gemini" | "qwen" | "cursor", never>;
20
+ harness: Schema.SchemaClass<"cursor" | "codex" | "opencode" | "pi" | "fx" | "claude" | "gemini" | "qwen", "cursor" | "codex" | "opencode" | "pi" | "fx" | "claude" | "gemini" | "qwen", never>;
21
21
  kind: Schema.Literal<["judge"]>;
22
22
  name: Schema.filter<Schema.filter<typeof Schema.String>>;
23
23
  model: Schema.filter<Schema.filter<typeof Schema.String>>;
@@ -12,7 +12,7 @@ const ValidationValue = Schema.Struct({
12
12
  }).annotations({ identifier: "ValidationValue" });
13
13
  const ValidationCall = Schema.Struct({
14
14
  index: Schema.NonNegativeInt,
15
- method: Schema.Literal("answer", "transcript", "readText", "exists", "exec", "cli.calls", "mcp.calls"),
15
+ method: Schema.Literal("answer", "transcript", "readText", "exists", "exec", "cli.calls", "api.calls", "api.url", "mcp.calls"),
16
16
  startedAt: Schema.Number,
17
17
  durationMs: Schema.NullOr(Schema.NonNegativeInt),
18
18
  input: ValidationValue,
@@ -110,4 +110,4 @@ const validationExecution = (identity, startedAt) => ({
110
110
  logs: []
111
111
  });
112
112
  //#endregion
113
- export { validationExecution as a, validationCapture as i, VALIDATION_FRAME as n, validationSnapshot as o, unavailableValue as r, EvalValidations as t };
113
+ export { validationCapture as a, unavailableValue as i, VALIDATION_FRAME as n, validationExecution as o, ValidationValue as r, validationSnapshot as s, EvalValidations as t };
@@ -12,7 +12,7 @@ const ValidationValue = effect.Schema.Struct({
12
12
  }).annotations({ identifier: "ValidationValue" });
13
13
  const ValidationCall = effect.Schema.Struct({
14
14
  index: effect.Schema.NonNegativeInt,
15
- method: effect.Schema.Literal("answer", "transcript", "readText", "exists", "exec", "cli.calls", "mcp.calls"),
15
+ method: effect.Schema.Literal("answer", "transcript", "readText", "exists", "exec", "cli.calls", "api.calls", "api.url", "mcp.calls"),
16
16
  startedAt: effect.Schema.Number,
17
17
  durationMs: effect.Schema.NullOr(effect.Schema.NonNegativeInt),
18
18
  input: ValidationValue,
@@ -122,6 +122,12 @@ Object.defineProperty(exports, "VALIDATION_FRAME", {
122
122
  return VALIDATION_FRAME;
123
123
  }
124
124
  });
125
+ Object.defineProperty(exports, "ValidationValue", {
126
+ enumerable: true,
127
+ get: function() {
128
+ return ValidationValue;
129
+ }
130
+ });
125
131
  Object.defineProperty(exports, "unavailableValue", {
126
132
  enumerable: true,
127
133
  get: function() {
package/dist/eval.cjs CHANGED
@@ -1,4 +1,4 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_compiler = require("./compiler-uwb1pkdK.cjs");
2
+ const require_compiler = require("./compiler-4FKsNxZ-.cjs");
3
3
  exports.compileEval = require_compiler.compileEval;
4
4
  exports.compileEvalEffect = require_compiler.compileEvalEffect;