anpord 0.1.13 → 0.1.17

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 (70) hide show
  1. package/README.md +1 -1
  2. package/dist/api-context.cjs +18 -0
  3. package/dist/api-context.d.cts +8 -0
  4. package/dist/api-context.d.mts +8 -0
  5. package/dist/api-context.mjs +17 -0
  6. package/dist/api-mocks-BXZmPUwV.d.cts +101 -0
  7. package/dist/api-mocks-BXZmPUwV.d.mts +101 -0
  8. package/dist/api-mocks-CuVw86Qw.cjs +68 -0
  9. package/dist/api-mocks-wNUnpzJf.mjs +33 -0
  10. package/dist/api-runtime.cjs +4 -0
  11. package/dist/api-runtime.d.cts +13 -0
  12. package/dist/api-runtime.d.mts +13 -0
  13. package/dist/api-runtime.mjs +2 -0
  14. package/dist/api.cjs +5 -0
  15. package/dist/api.d.cts +4 -0
  16. package/dist/api.d.mts +4 -0
  17. package/dist/api.mjs +2 -0
  18. package/dist/bin.cjs +8 -8
  19. package/dist/bin.mjs +6 -6
  20. package/dist/cli-runtime.cjs +9 -26
  21. package/dist/cli-runtime.mjs +5 -22
  22. package/dist/{client-BirFO3jz.d.cts → client-BVoIRPot.d.cts} +1082 -1082
  23. package/dist/{client-BfdjFtlV.mjs → client-DE3YNtWc.mjs} +3 -90
  24. package/dist/{client-C-P2I00z.cjs → client-DziJjMFh.cjs} +4 -91
  25. package/dist/{client-BgRs8JvW.d.mts → client-_OgJhHpJ.d.mts} +1083 -1083
  26. package/dist/{compiler-D96wI7UP.mjs → compiler-C62ss3a4.mjs} +161 -61
  27. package/dist/{compiler-uwb1pkdK.cjs → compiler-CYwJNlT4.cjs} +202 -72
  28. package/dist/config.cjs +1 -1
  29. package/dist/config.d.cts +1 -1
  30. package/dist/config.d.mts +1 -1
  31. package/dist/config.mjs +1 -1
  32. package/dist/define-NZvmQuIv.d.cts +34 -0
  33. package/dist/define-NZvmQuIv.d.mts +34 -0
  34. package/dist/{eval-judges-DPPUftbh.d.cts → eval-judges-0FkhUOIB.d.cts} +2 -2
  35. package/dist/{eval-judges-DPPUftbh.d.mts → eval-judges-0FkhUOIB.d.mts} +2 -2
  36. package/dist/{eval-judges-BkmiVLLq.cjs → eval-judges-1zF4PVqV.cjs} +1 -1
  37. package/dist/{eval-judges-CwTvTq7N.mjs → eval-judges-Bee_ABJt.mjs} +1 -1
  38. package/dist/{eval-validations-_MlnQ_uv.cjs → eval-validations-BdlPhudg.cjs} +8 -2
  39. package/dist/{eval-validations-BRdoZrTQ.mjs → eval-validations-BvX9dkYh.mjs} +3 -3
  40. package/dist/eval.cjs +4 -1
  41. package/dist/eval.d.cts +275 -25
  42. package/dist/eval.d.mts +275 -25
  43. package/dist/eval.mjs +2 -2
  44. package/dist/{evals-B6aT3xgH.d.cts → evals-CFxc4IrF.d.cts} +124 -124
  45. package/dist/{evals-B6aT3xgH.d.mts → evals-CFxc4IrF.d.mts} +124 -124
  46. package/dist/{evals-DouMsrsM.cjs → evals-api-CqhPZCr5.cjs} +104 -73
  47. package/dist/{evals-Dcc_x6jW.mjs → evals-api-CsdU741J.mjs} +96 -5
  48. package/dist/index.cjs +8 -8
  49. package/dist/index.d.cts +12 -8
  50. package/dist/index.d.mts +13 -9
  51. package/dist/index.mjs +7 -7
  52. package/dist/mcp-runtime.cjs +9 -18
  53. package/dist/mcp-runtime.mjs +5 -14
  54. package/dist/mock-journal-Bnaozlx4.cjs +39 -0
  55. package/dist/mock-journal-rbsXfDRs.mjs +22 -0
  56. package/dist/runtime-CXcsGvwP.cjs +292 -0
  57. package/dist/runtime-DDUrsAI-.mjs +269 -0
  58. package/dist/source.d.cts +1 -1
  59. package/dist/source.d.mts +1 -1
  60. package/dist/{types-Codjaq-o.d.mts → types-BjQf9IIi.d.mts} +21 -11
  61. package/dist/{types-ISsteq95.d.cts → types-C2nRDJ95.d.cts} +20 -10
  62. package/dist/validator-runtime.cjs +6 -1
  63. package/dist/validator-runtime.d.cts +1 -1
  64. package/dist/validator-runtime.d.mts +1 -1
  65. package/dist/validator-runtime.mjs +6 -1
  66. package/dist/validators.cjs +1 -1
  67. package/dist/validators.d.cts +1 -1
  68. package/dist/validators.d.mts +1 -1
  69. package/dist/validators.mjs +1 -1
  70. package/package.json +21 -1
@@ -1,10 +1,11 @@
1
- const require_evals = require("./evals-DouMsrsM.cjs");
2
- const require_eval_judges = require("./eval-judges-BkmiVLLq.cjs");
1
+ const require_eval_judges = require("./eval-judges-1zF4PVqV.cjs");
2
+ const require_api_mocks = require("./api-mocks-CuVw86Qw.cjs");
3
+ const require_evals_api = require("./evals-api-CqhPZCr5.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,15 +44,33 @@ 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
50
- const authoringExports = ["export const defineEval = value => value;", `export { empty, files, repo } from "./source";`].join("\n");
51
+ const authoringExports = ["export const defineEval = (first, second) => typeof first === 'string' ? second : first;", `export { empty, files, repo } from "./source";`].join("\n");
51
52
  const authoringDir = (0, node_path.dirname)((0, node_url.fileURLToPath)(require("url").pathToFileURL(__filename).href));
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,36 +178,6 @@ const bundle = (contents, entry, options = {}) => effect.Effect.tryPromise({
158
178
  catch: (cause) => new Error(`Could not compile ${entry}`, { cause })
159
179
  });
160
180
  //#endregion
161
- //#region src/evals/case-modules.ts
162
- const realOrGiven = (path) => {
163
- try {
164
- return node_fs.realpathSync.native(path);
165
- } catch {
166
- return path;
167
- }
168
- };
169
- const sameFile = (one, other) => one === other || realOrGiven(one) === realOrGiven(other);
170
- const exportingModule = (entry, inputs, name) => effect.Effect.gen(function* () {
171
- const pattern = new RegExp(`\\bexport\\s+(?:async\\s+)?(?:const|function)\\s+${name}\\b`);
172
- const matches = yield* effect.Effect.filter(inputs.filter((path) => !(sameFile(path, entry) || path.includes(`${node_path.sep}node_modules${node_path.sep}`))), (path) => effect.Effect.tryPromise(() => (0, node_fs_promises.readFile)(path, "utf8")).pipe(effect.Effect.map((source) => pattern.test(source)), effect.Effect.orElseSucceed(() => false)), { concurrency: 8 });
173
- if (matches.length !== 1) return yield* effect.Effect.fail(/* @__PURE__ */ new Error(`${name} must be one named function or const export from a separate TypeScript file`));
174
- return matches[0];
175
- });
176
- const bundledCaseModule = (entry, inputs, name, wrap) => effect.Effect.gen(function* () {
177
- const module = yield* exportingModule(entry, inputs, name);
178
- const { source } = yield* bundle(wrap(module, name), entry);
179
- return {
180
- name,
181
- source
182
- };
183
- });
184
- //#endregion
185
- //#region src/evals/profile-compose.ts
186
- const appendInstall = (profile, command) => ({
187
- ...profile,
188
- install: profile.install ? `${profile.install} && ${command}` : command
189
- });
190
- //#endregion
191
181
  //#region src/evals/program-package.ts
192
182
  const CHUNK_SIZE = 9e4;
193
183
  const packageProgram = (root, entry, source) => {
@@ -197,18 +187,20 @@ const packageProgram = (root, entry, source) => {
197
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);`;
198
188
  return {
199
189
  entry: `${root}/${entry}`,
200
- files: Object.fromEntries([[`${root}/${entry}`, loader], ...names.map((name, index) => [`${root}/${name}`, chunks[index]])])
190
+ files: Object.fromEntries([[`${root}/${entry}`, loader], ...chunks.map((chunk, index) => [`${root}/${index}.txt`, chunk])])
201
191
  };
202
192
  };
203
193
  //#endregion
204
194
  //#region src/evals/runner-source.ts
205
- const validatorCaseEntry = (entry, index, names = []) => `import definition from ${JSON.stringify(entry)};
195
+ const importsDefinition = ({ entry, exportName }) => exportName === null ? `import definition from ${JSON.stringify(entry)};` : `import { ${exportName} as definition } from ${JSON.stringify(entry)};`;
196
+ const validatorCaseEntry = (ref, index, names = []) => `${importsDefinition(ref)}
206
197
  import { runValidators } from "anpord/validators/runtime";
207
198
  const selected = definition.cases[${index}].validate;
208
199
  const names = ${JSON.stringify(names)};
209
200
  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
201
  await runValidators(checks, definition.captureValidation !== false);`;
211
202
  const prepareRuntime = `
203
+ import { apiContext } from "anpord/api/context";
212
204
  import { access, readFile } from "node:fs/promises";
213
205
  import { spawn } from "node:child_process";
214
206
 
@@ -236,6 +228,7 @@ const exec = (file, args = [], options = {}) => new Promise((resolve, reject) =>
236
228
  });
237
229
 
238
230
  const context = {
231
+ api: apiContext,
239
232
  cached: process.env.ANPORD_CACHE_RESTORED === "1",
240
233
  exec,
241
234
  exists: path => access(path).then(() => true, () => false),
@@ -252,25 +245,88 @@ try {
252
245
  }
253
246
  `;
254
247
  const prepareEntry = (module, name) => `import { ${name} as setup } from ${JSON.stringify(module)};\n${prepareRuntime}`;
255
- const definitionEntry = (entry) => `import definition from ${JSON.stringify(entry)}; export default definition;`;
256
- const mcpEntry = (entry, index) => `import definition from ${JSON.stringify(entry)};
248
+ const definitionEntry = (ref) => `${importsDefinition(ref)} export default definition;`;
249
+ const mcpEntry = (ref, index) => `${importsDefinition(ref)}
257
250
  import { runMcpServer } from "anpord/mcp/runtime";
258
251
  const server = definition.mcp?.[${index}];
259
252
  if (server === undefined) throw new Error("MCP server ${index} is missing");
260
253
  runMcpServer(server);`;
261
- const cliEntry = (entry, index) => `import { fileURLToPath } from "node:url";
262
- import definition from ${JSON.stringify(entry)};
254
+ const cliEntry = (ref, index) => `import { fileURLToPath } from "node:url";
255
+ ${importsDefinition(ref)}
263
256
  import { runCli } from "anpord/cli/runtime";
264
257
  const cli = definition.cli?.[${index}];
265
258
  if (cli === undefined) throw new Error("CLI ${index} is missing");
266
259
  await runCli(cli, fileURLToPath(new URL("../../cli-calls.jsonl", import.meta.url)));`;
267
260
  //#endregion
261
+ //#region src/evals/api-profile.ts
262
+ const compileApis = (ref, definitions) => effect.Effect.gen(function* () {
263
+ if (definitions.length === 0) return {};
264
+ const names = definitions.map(({ name }) => name);
265
+ if (new Set(names).size !== names.length) return yield* effect.Effect.fail(/* @__PURE__ */ new Error("Duplicate API mock name"));
266
+ const { source } = yield* bundle(`${importsDefinition(ref)}
267
+ import { runApiServers } from "anpord/api/runtime";
268
+ runApiServers(definition.api ?? []);`, ref.entry, { minify: true });
269
+ const program = packageProgram("workspace/.anpord/api", "server.mjs", source);
270
+ return {
271
+ ...program.files,
272
+ [require_api_mocks.API_PROGRAM]: JSON.stringify({ entry: program.entry.slice(10) })
273
+ };
274
+ });
275
+ const withApis = (task, files) => {
276
+ if (Object.keys(files).length === 0) return task;
277
+ const profile = task.profile ?? {
278
+ name: "anpord-api",
279
+ files: {}
280
+ };
281
+ for (const path of Object.keys(files)) if (profile.files[path] !== void 0) throw new Error(`Profile file ${path} is reserved for API mocks`);
282
+ return {
283
+ ...task,
284
+ profile: {
285
+ ...profile,
286
+ files: {
287
+ ...profile.files,
288
+ ...files
289
+ }
290
+ }
291
+ };
292
+ };
293
+ //#endregion
294
+ //#region src/evals/case-modules.ts
295
+ const realOrGiven = (path) => {
296
+ try {
297
+ return node_fs.realpathSync.native(path);
298
+ } catch {
299
+ return path;
300
+ }
301
+ };
302
+ const sameFile = (one, other) => one === other || realOrGiven(one) === realOrGiven(other);
303
+ const exportingModule = (entry, inputs, name) => effect.Effect.gen(function* () {
304
+ const pattern = new RegExp(`\\bexport\\s+(?:async\\s+)?(?:const|function)\\s+${name}\\b`);
305
+ const matches = yield* effect.Effect.filter(inputs.filter((path) => !(sameFile(path, entry) || path.includes(`${node_path.sep}node_modules${node_path.sep}`))), (path) => effect.Effect.tryPromise(() => (0, node_fs_promises.readFile)(path, "utf8")).pipe(effect.Effect.map((source) => pattern.test(source)), effect.Effect.orElseSucceed(() => false)), { concurrency: 8 });
306
+ if (matches.length !== 1) return yield* effect.Effect.fail(/* @__PURE__ */ new Error(`${name} must be one named function or const export from a separate TypeScript file`));
307
+ return matches[0];
308
+ });
309
+ const bundledCaseModule = (entry, inputs, name, wrap) => effect.Effect.gen(function* () {
310
+ const module = yield* exportingModule(entry, inputs, name);
311
+ const { source } = yield* bundle(wrap(module, name), entry, { minify: true });
312
+ return {
313
+ name,
314
+ source
315
+ };
316
+ });
317
+ //#endregion
318
+ //#region src/evals/profile-compose.ts
319
+ const appendInstall = (profile, command) => ({
320
+ ...profile,
321
+ install: profile.install ? `${profile.install} && ${command}` : command
322
+ });
323
+ //#endregion
268
324
  //#region src/evals/cli-profile.ts
269
- const compileClis = (entry, definitions) => effect.Effect.gen(function* () {
325
+ const compileClis = (ref, definitions) => effect.Effect.gen(function* () {
270
326
  const paths = definitions.map(({ path }) => path);
271
327
  const duplicate = paths.find((path, index) => paths.indexOf(path) !== index);
272
328
  if (duplicate !== void 0) return yield* effect.Effect.fail(/* @__PURE__ */ new Error(`Duplicate CLI: ${duplicate}`));
273
- return yield* effect.Effect.forEach(definitions, (definition, index) => bundle(cliEntry(entry, index), entry, { minify: true }).pipe(effect.Effect.map(({ source }) => ({
329
+ return yield* effect.Effect.forEach(definitions, (definition, index) => bundle(cliEntry(ref, index), ref.entry, { minify: true }).pipe(effect.Effect.map(({ source }) => ({
274
330
  ...packageProgram(`workspace/.anpord/cli/${index}`, "cli.mjs", source),
275
331
  path: definition.path
276
332
  }))), { concurrency: 4 });
@@ -300,7 +356,7 @@ const withClis = (task, clis) => {
300
356
  };
301
357
  //#endregion
302
358
  //#region src/evals/compile-validator.ts
303
- const compileValidator = (entry, subject, caseIndex, captureSource, captureValidation = true) => effect.Effect.gen(function* () {
359
+ const compileValidator = (ref, subject, caseIndex, captureSource, captureValidation = true) => effect.Effect.gen(function* () {
304
360
  if (subject.validate === void 0) return null;
305
361
  const validations = Array.isArray(subject.validate) ? subject.validate : [subject.validate];
306
362
  if (validations.length === 0 || validations.length > 20) return yield* effect.Effect.fail(/* @__PURE__ */ new Error("Use between 1 and 20 validators"));
@@ -311,7 +367,7 @@ const compileValidator = (entry, subject, caseIndex, captureSource, captureValid
311
367
  name: value.name || `Validator ${index + 1}`
312
368
  }] : []);
313
369
  const hasCode = manifest.length > 0;
314
- const compiled = yield* bundle(hasCode ? validatorCaseEntry(entry, caseIndex, manifest) : definitionEntry(entry), entry, {
370
+ const compiled = yield* bundle(hasCode ? validatorCaseEntry(ref, caseIndex, manifest) : definitionEntry(ref), ref.entry, {
315
371
  minify: true,
316
372
  captureSource
317
373
  });
@@ -321,7 +377,7 @@ const compileValidator = (entry, subject, caseIndex, captureSource, captureValid
321
377
  manifest,
322
378
  capture: captureValidation
323
379
  }] : [];
324
- return yield* effect.Schema.decodeUnknown(require_evals.EvalValidator)({
380
+ return yield* effect.Schema.decodeUnknown(require_evals_api.EvalValidator)({
325
381
  ...judges.length > 0 ? {
326
382
  kind: "judged",
327
383
  name: subject.name,
@@ -334,7 +390,7 @@ const compileValidator = (entry, subject, caseIndex, captureSource, captureValid
334
390
  });
335
391
  //#endregion
336
392
  //#region src/evals/definition-loader.ts
337
- const loadDefinition = (entry) => bundle(definitionEntry(entry), entry).pipe(effect.Effect.flatMap(({ inputs, source }) => effect.Effect.acquireUseRelease(effect.Effect.tryPromise(() => (0, node_fs_promises.mkdtemp)((0, node_path.join)((0, node_os.tmpdir)(), "anpord-eval-"))), (directory) => effect.Effect.tryPromise({
393
+ const loadDefinition = (ref) => bundle(definitionEntry(ref), ref.entry).pipe(effect.Effect.flatMap(({ inputs, source }) => effect.Effect.acquireUseRelease(effect.Effect.tryPromise(() => (0, node_fs_promises.mkdtemp)((0, node_path.join)((0, node_os.tmpdir)(), "anpord-eval-"))), (directory) => effect.Effect.tryPromise({
338
394
  try: async () => {
339
395
  const output = (0, node_path.join)(directory, "definition.mjs");
340
396
  await (0, node_fs_promises.writeFile)(output, source);
@@ -343,7 +399,7 @@ const loadDefinition = (entry) => bundle(definitionEntry(entry), entry).pipe(eff
343
399
  inputs
344
400
  };
345
401
  },
346
- catch: (cause) => new Error(`Could not load ${entry}: ${cause instanceof Error ? cause.message : String(cause)}`, { cause })
402
+ catch: (cause) => new Error(`Could not load ${ref.entry}: ${cause instanceof Error ? cause.message : String(cause)}`, { cause })
347
403
  }), (directory) => effect.Effect.promise(() => (0, node_fs_promises.rm)(directory, {
348
404
  force: true,
349
405
  recursive: true
@@ -391,6 +447,39 @@ const localRepo = (cwd) => effect.Effect.gen(function* () {
391
447
  });
392
448
  }).pipe(effect.Effect.withSpan("Eval.localRepo"));
393
449
  //#endregion
450
+ //#region src/evals/define.ts
451
+ const SOURCE_URL = Symbol.for("anpord.sourceUrl");
452
+ function defineEval(first, second) {
453
+ if (typeof first !== "string") return first;
454
+ return Object.defineProperty(second, SOURCE_URL, {
455
+ enumerable: false,
456
+ value: first
457
+ });
458
+ }
459
+ const sourceUrlOf = (definition) => definition[SOURCE_URL];
460
+ //#endregion
461
+ //#region src/evals/locate.ts
462
+ const HINT = "Pass import.meta.url as the first argument to defineEval, or compile by path.";
463
+ const exportHolding = async (entry, definition) => {
464
+ const module = await import(entry);
465
+ if (module.default === definition) return null;
466
+ const named = Object.keys(module).find((key) => module[key] === definition);
467
+ if (named === void 0) throw new Error(`The definition passed is not exported from ${entry}. ${HINT}`);
468
+ return named;
469
+ };
470
+ const locate = (definition) => effect.Effect.gen(function* () {
471
+ const url = sourceUrlOf(definition);
472
+ if (url === void 0) return yield* effect.Effect.fail(/* @__PURE__ */ new Error(`This eval does not know where it was written. ${HINT}`));
473
+ const exportName = yield* effect.Effect.tryPromise({
474
+ catch: (cause) => cause instanceof Error ? cause : new Error(String(cause)),
475
+ try: () => exportHolding(url, definition)
476
+ });
477
+ return {
478
+ entry: (0, node_url.fileURLToPath)(url),
479
+ exportName
480
+ };
481
+ });
482
+ //#endregion
394
483
  //#region src/evals/mcp-harness.ts
395
484
  const Entries = effect.Schema.Record({
396
485
  key: effect.Schema.String,
@@ -487,15 +576,15 @@ const adapters = {
487
576
  const applyMcpHarness = (harness, profile, servers) => {
488
577
  const adapter = adapters[harness];
489
578
  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));
579
+ return effect.Schema.decodeUnknownSync(require_evals_api.HarnessProfile)(adapter.apply(profile, servers));
491
580
  };
492
581
  //#endregion
493
582
  //#region src/evals/mcp-profile.ts
494
- const compileMcpServers = (entry, definitions) => effect.Effect.gen(function* () {
583
+ const compileMcpServers = (ref, definitions) => effect.Effect.gen(function* () {
495
584
  const names = definitions.map(({ name }) => name);
496
585
  const duplicate = names.find((name, index) => names.indexOf(name) !== index);
497
586
  if (duplicate !== void 0) return yield* effect.Effect.fail(/* @__PURE__ */ new Error(`Duplicate MCP server: ${duplicate}`));
498
- return yield* effect.Effect.forEach(definitions, (definition, index) => bundle(mcpEntry(entry, index), entry, { minify: true }).pipe(effect.Effect.map(({ source }) => ({
587
+ return yield* effect.Effect.forEach(definitions, (definition, index) => bundle(mcpEntry(ref, index), ref.entry, { minify: true }).pipe(effect.Effect.map(({ source }) => ({
499
588
  ...packageProgram(`workspace/.anpord/mcp/${index}`, "server.mjs", source),
500
589
  name: definition.name
501
590
  }))), { concurrency: 4 });
@@ -533,17 +622,17 @@ var ProfilePathInvalid = class extends effect.Data.TaggedError("ProfilePathInval
533
622
  };
534
623
  var ProfileFileTooLarge = class extends effect.Data.TaggedError("ProfileFileTooLarge") {
535
624
  get message() {
536
- return `${this.path} is ${this.chars} characters; a profile file holds at most ${require_evals.PROFILE_LIMITS.fileChars}`;
625
+ return `${this.path} is ${this.chars} characters; a profile file holds at most ${require_evals_api.PROFILE_LIMITS.fileChars}`;
537
626
  }
538
627
  };
539
628
  var ProfileTooLarge = class extends effect.Data.TaggedError("ProfileTooLarge") {
540
629
  get message() {
541
- return `The profile's files hold ${this.chars} characters; at most ${require_evals.PROFILE_LIMITS.totalChars} fit`;
630
+ return `The profile's files hold ${this.chars} characters; at most ${require_evals_api.PROFILE_LIMITS.totalChars} fit`;
542
631
  }
543
632
  };
544
633
  var ProfileTooManyFiles = class extends effect.Data.TaggedError("ProfileTooManyFiles") {
545
634
  get message() {
546
- return `The profile has ${this.count} files; at most ${require_evals.PROFILE_LIMITS.files} fit`;
635
+ return `The profile has ${this.count} files; at most ${require_evals_api.PROFILE_LIMITS.files} fit`;
547
636
  }
548
637
  };
549
638
  var ProfileManifestInvalid = class extends effect.Data.TaggedError("ProfileManifestInvalid") {
@@ -570,7 +659,7 @@ var ProfileStepNotSupported = class extends effect.Data.TaggedError("ProfileStep
570
659
  //#region src/evals/profile-manifest.ts
571
660
  const Manifest = effect.Schema.Struct({
572
661
  env: effect.Schema.optional(effect.Schema.Record({
573
- key: require_evals.EnvName,
662
+ key: require_evals_api.EnvName,
574
663
  value: effect.Schema.String
575
664
  })),
576
665
  install: effect.Schema.optional(effect.Schema.String),
@@ -647,7 +736,7 @@ const shippedPaths = (dir) => effect.Effect.tryPromise({
647
736
  return (await Promise.all(SHIPPED_ROOTS.map((root) => walkRoot(dir, root)))).flat().sort();
648
737
  }
649
738
  });
650
- const validPath = (path) => effect.Schema.decodeUnknown(require_evals.ProfilePath)(path).pipe(effect.Effect.mapError(() => new ProfilePathInvalid({ path })));
739
+ const validPath = (path) => effect.Schema.decodeUnknown(require_evals_api.ProfilePath)(path).pipe(effect.Effect.mapError(() => new ProfilePathInvalid({ path })));
651
740
  /** Nothing when the file holds a NUL byte and so is not text. */
652
741
  const readShipped = (dir, path) => effect.Effect.gen(function* () {
653
742
  const bytes = yield* effect.Effect.tryPromise({
@@ -659,7 +748,7 @@ const readShipped = (dir, path) => effect.Effect.gen(function* () {
659
748
  });
660
749
  if (bytes.includes(0)) return [];
661
750
  const content = bytes.toString("utf8");
662
- if (content.length > require_evals.PROFILE_LIMITS.fileChars) return yield* new ProfileFileTooLarge({
751
+ if (content.length > require_evals_api.PROFILE_LIMITS.fileChars) return yield* new ProfileFileTooLarge({
663
752
  chars: content.length,
664
753
  path
665
754
  });
@@ -667,14 +756,14 @@ const readShipped = (dir, path) => effect.Effect.gen(function* () {
667
756
  });
668
757
  const shippedFiles = (dir) => effect.Effect.gen(function* () {
669
758
  const paths = yield* shippedPaths(dir);
670
- if (paths.length > require_evals.PROFILE_LIMITS.files) return yield* new ProfileTooManyFiles({ count: paths.length });
759
+ if (paths.length > require_evals_api.PROFILE_LIMITS.files) return yield* new ProfileTooManyFiles({ count: paths.length });
671
760
  const entries = yield* effect.Effect.forEach(paths, (path) => readShipped(dir, path), { concurrency: 8 }).pipe(effect.Effect.map((read) => read.flat()));
672
761
  const chars = entries.reduce((sum, [, content]) => sum + content.length, 0);
673
- if (chars > require_evals.PROFILE_LIMITS.totalChars) return yield* new ProfileTooLarge({ chars });
762
+ if (chars > require_evals_api.PROFILE_LIMITS.totalChars) return yield* new ProfileTooLarge({ chars });
674
763
  return Object.fromEntries(entries);
675
764
  });
676
765
  const fittingHarness = (base, profile) => {
677
- if (require_evals.profileFitsHarness({
766
+ if (require_evals_api.profileFitsHarness({
678
767
  harness: base,
679
768
  profile
680
769
  })) return effect.Effect.succeed(profile);
@@ -708,7 +797,7 @@ const profileTask = (entry, task) => effect.Effect.gen(function* () {
708
797
  }).pipe(effect.Effect.withSpan("Eval.profileTask", { attributes: { profile: task.harness.profile.name } }));
709
798
  //#endregion
710
799
  //#region src/evals/compiler.ts
711
- const taskOf = (entry, task, clis, mcp) => effect.Effect.gen(function* () {
800
+ const taskOf = (entry, task, clis, mcp, apis) => effect.Effect.gen(function* () {
712
801
  const compiled = typeof task.harness === "string" ? {
713
802
  harness: task.harness,
714
803
  model: task.model,
@@ -717,7 +806,7 @@ const taskOf = (entry, task, clis, mcp) => effect.Effect.gen(function* () {
717
806
  ...task,
718
807
  harness: task.harness
719
808
  });
720
- return yield* effect.Effect.try(() => withClis(withMcpServers(compiled, mcp), clis));
809
+ return yield* effect.Effect.try(() => withApis(withClis(withMcpServers(compiled, mcp), clis), apis));
721
810
  });
722
811
  const sourceFor = (definition, subject, fallback) => {
723
812
  const source = subject.source ?? definition.source;
@@ -727,17 +816,21 @@ const sourceFor = (definition, subject, fallback) => {
727
816
  onSome: (source) => ({ source })
728
817
  });
729
818
  };
730
- const compileEvalEffect = (path) => effect.Effect.gen(function* () {
731
- const entry = (0, node_path.resolve)(path);
732
- const loaded = yield* loadDefinition(entry);
819
+ const compileRefEffect = (ref) => effect.Effect.gen(function* () {
820
+ const entry = ref.entry;
821
+ const loaded = yield* loadDefinition(ref);
733
822
  const definition = loaded.definition;
734
- if (!isDefinition(definition)) return yield* effect.Effect.fail(/* @__PURE__ */ new Error(`${entry} must default export defineEval({ ... })`));
735
- const clis = yield* compileClis(entry, definition.cli ?? []);
736
- const mcp = yield* compileMcpServers(entry, definition.mcp ?? []);
823
+ if (!isDefinition(definition)) {
824
+ const named = ref.exportName === null ? "default export" : `export ${ref.exportName}`;
825
+ return yield* effect.Effect.fail(/* @__PURE__ */ new Error(`${entry} must ${named} defineEval({ ... })`));
826
+ }
827
+ const clis = yield* compileClis(ref, definition.cli ?? []);
828
+ const mcp = yield* compileMcpServers(ref, definition.mcp ?? []);
829
+ const apis = yield* compileApis(ref, definition.api ?? []);
737
830
  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
831
  const cases = yield* effect.Effect.forEach(definition.cases, (subject, caseIndex) => effect.Effect.gen(function* () {
739
832
  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`));
740
- const validator = yield* compileValidator(entry, subject, caseIndex, definition.captureSource !== false, definition.captureValidation !== false);
833
+ const validator = yield* compileValidator(ref, subject, caseIndex, definition.captureSource !== false, definition.captureValidation !== false);
741
834
  const prepare = typeof subject.prepare === "function" ? yield* bundledCaseModule(entry, loaded.inputs, subject.prepare.name || `${subject.name}-prepare`, prepareEntry) : null;
742
835
  return {
743
836
  ...subject.cache === void 0 ? {} : { cache: subject.cache },
@@ -749,17 +842,36 @@ const compileEvalEffect = (path) => effect.Effect.gen(function* () {
749
842
  verify: subject.verify ?? null
750
843
  };
751
844
  }), { concurrency: 4 });
752
- const tasks = yield* effect.Effect.forEach(definition.tasks, (task) => taskOf(entry, task, clis, mcp), { concurrency: 4 });
753
- return {
845
+ const tasks = yield* effect.Effect.forEach(definition.tasks, (task) => taskOf(entry, task, clis, mcp, apis), { concurrency: 4 });
846
+ return yield* effect.Schema.decodeUnknown(require_evals_api.PublicStartEvalRequest)({
754
847
  cases,
755
848
  name: definition.name,
756
849
  prompt: definition.prompt,
757
850
  tasks,
758
851
  trials: definition.trials
759
- };
852
+ });
760
853
  }).pipe(effect.Effect.withSpan("Eval.compile"));
854
+ const compileDefinitionEffect = (definition) => effect.Effect.flatMap(locate(definition), compileRefEffect);
855
+ const compileDefinition = (definition) => effect.Effect.runPromise(compileDefinitionEffect(definition));
856
+ const refOfPath = (path) => ({
857
+ entry: (0, node_path.resolve)(path),
858
+ exportName: null
859
+ });
860
+ const compileEvalEffect = (path) => compileRefEffect(refOfPath(path));
761
861
  const compileEval = (path) => effect.Effect.runPromise(compileEvalEffect(path));
762
862
  //#endregion
863
+ Object.defineProperty(exports, "compileDefinition", {
864
+ enumerable: true,
865
+ get: function() {
866
+ return compileDefinition;
867
+ }
868
+ });
869
+ Object.defineProperty(exports, "compileDefinitionEffect", {
870
+ enumerable: true,
871
+ get: function() {
872
+ return compileDefinitionEffect;
873
+ }
874
+ });
763
875
  Object.defineProperty(exports, "compileEval", {
764
876
  enumerable: true,
765
877
  get: function() {
@@ -772,3 +884,21 @@ Object.defineProperty(exports, "compileEvalEffect", {
772
884
  return compileEvalEffect;
773
885
  }
774
886
  });
887
+ Object.defineProperty(exports, "compileRefEffect", {
888
+ enumerable: true,
889
+ get: function() {
890
+ return compileRefEffect;
891
+ }
892
+ });
893
+ Object.defineProperty(exports, "defineEval", {
894
+ enumerable: true,
895
+ get: function() {
896
+ return defineEval;
897
+ }
898
+ });
899
+ Object.defineProperty(exports, "sourceUrlOf", {
900
+ enumerable: true,
901
+ get: function() {
902
+ return sourceUrlOf;
903
+ }
904
+ });
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-DziJjMFh.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-BVoIRPot.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-_OgJhHpJ.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-DE3YNtWc.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 };
@@ -6,7 +6,7 @@ declare const EvalJudge: Schema.Union<[Schema.Struct<{
6
6
  kind: Schema.Literal<["judge"]>;
7
7
  name: Schema.filter<Schema.filter<typeof Schema.String>>;
8
8
  model: Schema.filter<Schema.filter<typeof Schema.String>>;
9
- rubric: Schema.filter<Schema.filter<typeof Schema.String>>;
9
+ prompt: Schema.filter<Schema.filter<typeof Schema.String>>;
10
10
  expected: Schema.optional<Schema.filter<typeof Schema.String>>;
11
11
  choices: Schema.filter<Schema.Record$<Schema.filter<typeof Schema.String>, Schema.filter<typeof Schema.Number>>>;
12
12
  threshold: Schema.optionalWith<Schema.filter<typeof Schema.Number>, {
@@ -21,7 +21,7 @@ declare const EvalJudge: Schema.Union<[Schema.Struct<{
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>>;
24
- rubric: Schema.filter<Schema.filter<typeof Schema.String>>;
24
+ prompt: Schema.filter<Schema.filter<typeof Schema.String>>;
25
25
  expected: Schema.optional<Schema.filter<typeof Schema.String>>;
26
26
  choices: Schema.filter<Schema.Record$<Schema.filter<typeof Schema.String>, Schema.filter<typeof Schema.Number>>>;
27
27
  threshold: Schema.optionalWith<Schema.filter<typeof Schema.Number>, {
@@ -6,7 +6,7 @@ declare const EvalJudge: Schema.Union<[Schema.Struct<{
6
6
  kind: Schema.Literal<["judge"]>;
7
7
  name: Schema.filter<Schema.filter<typeof Schema.String>>;
8
8
  model: Schema.filter<Schema.filter<typeof Schema.String>>;
9
- rubric: Schema.filter<Schema.filter<typeof Schema.String>>;
9
+ prompt: Schema.filter<Schema.filter<typeof Schema.String>>;
10
10
  expected: Schema.optional<Schema.filter<typeof Schema.String>>;
11
11
  choices: Schema.filter<Schema.Record$<Schema.filter<typeof Schema.String>, Schema.filter<typeof Schema.Number>>>;
12
12
  threshold: Schema.optionalWith<Schema.filter<typeof Schema.Number>, {
@@ -21,7 +21,7 @@ declare const EvalJudge: Schema.Union<[Schema.Struct<{
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>>;
24
- rubric: Schema.filter<Schema.filter<typeof Schema.String>>;
24
+ prompt: Schema.filter<Schema.filter<typeof Schema.String>>;
25
25
  expected: Schema.optional<Schema.filter<typeof Schema.String>>;
26
26
  choices: Schema.filter<Schema.Record$<Schema.filter<typeof Schema.String>, Schema.filter<typeof Schema.Number>>>;
27
27
  threshold: Schema.optionalWith<Schema.filter<typeof Schema.Number>, {
@@ -9,7 +9,7 @@ const fields = {
9
9
  kind: effect.Schema.Literal("judge"),
10
10
  name: text.pipe(effect.Schema.maxLength(100)),
11
11
  model: text.pipe(effect.Schema.maxLength(200)),
12
- rubric: text.pipe(effect.Schema.maxLength(32e3)),
12
+ prompt: text.pipe(effect.Schema.maxLength(32e3)),
13
13
  expected: effect.Schema.optional(effect.Schema.String.pipe(effect.Schema.maxLength(32e3))),
14
14
  choices: effect.Schema.Record({
15
15
  key: text,
@@ -9,7 +9,7 @@ const fields = {
9
9
  kind: Schema.Literal("judge"),
10
10
  name: text.pipe(Schema.maxLength(100)),
11
11
  model: text.pipe(Schema.maxLength(200)),
12
- rubric: text.pipe(Schema.maxLength(32e3)),
12
+ prompt: text.pipe(Schema.maxLength(32e3)),
13
13
  expected: Schema.optional(Schema.String.pipe(Schema.maxLength(32e3))),
14
14
  choices: Schema.Record({
15
15
  key: text,