anpord 0.1.2 → 0.1.4
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 +69 -4
- package/dist/cli.cjs +274 -19
- package/dist/cli.mjs +275 -20
- package/dist/client-BCZEcfVE.cjs +759 -0
- package/dist/client-BfhmGRQl.mjs +718 -0
- package/dist/compiler-CKiewwUc.mjs +188 -0
- package/dist/compiler-CZoX4jkx.cjs +198 -0
- package/dist/config.cjs +1 -1
- package/dist/config.mjs +1 -1
- package/dist/{errors-C0E5A8fN.cjs → errors-Boum34f5.cjs} +30 -0
- package/dist/{errors-DEfS6oaQ.mjs → errors-C9bQUcA3.mjs} +25 -1
- package/dist/eval.cjs +4 -0
- package/dist/eval.d.cts +25 -0
- package/dist/eval.d.mts +25 -0
- package/dist/eval.mjs +2 -0
- package/dist/evals-api-DUNVUGUy.d.mts +93 -0
- package/dist/evals-api-sqVNeWet.d.cts +93 -0
- package/dist/index.cjs +428 -8
- package/dist/index.d.cts +2372 -195
- package/dist/index.d.mts +2372 -195
- package/dist/index.mjs +424 -10
- package/dist/source-DQ8HChlm.d.cts +478 -0
- package/dist/source-DQ8HChlm.d.mts +478 -0
- package/dist/source-DvlGawEw.cjs +76 -0
- package/dist/source-Fg1h2VNn.mjs +47 -0
- package/dist/source.cjs +5 -0
- package/dist/source.d.cts +2 -0
- package/dist/source.d.mts +2 -0
- package/dist/source.mjs +2 -0
- package/package.json +18 -4
- package/dist/client-Cno4LwRq.cjs +0 -277
- package/dist/client-bJBNwTKq.mjs +0 -236
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { a as parseRepo, i as cloneUrlOf, r as repo } from "./source-Fg1h2VNn.mjs";
|
|
2
|
+
import { Effect, Option } from "effect";
|
|
3
|
+
import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import { dirname, join, resolve, sep } from "node:path";
|
|
6
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
7
|
+
import { build } from "esbuild";
|
|
8
|
+
import { execFile } from "node:child_process";
|
|
9
|
+
import { promisify } from "node:util";
|
|
10
|
+
//#region src/evals/local-repo.ts
|
|
11
|
+
const run = promisify(execFile);
|
|
12
|
+
const git = (args, cwd) => Effect.tryPromise(() => run("git", [...args], { cwd })).pipe(Effect.map(({ stdout }) => stdout.trim()), Effect.orElseSucceed(() => ""));
|
|
13
|
+
const environment = () => globalThis.process?.env ?? {};
|
|
14
|
+
const remoteUrl = (cwd) => Effect.gen(function* () {
|
|
15
|
+
const { GITHUB_REPOSITORY } = environment();
|
|
16
|
+
const origin = yield* git([
|
|
17
|
+
"remote",
|
|
18
|
+
"get-url",
|
|
19
|
+
"origin"
|
|
20
|
+
], cwd);
|
|
21
|
+
return origin === "" && GITHUB_REPOSITORY !== void 0 ? GITHUB_REPOSITORY : origin;
|
|
22
|
+
});
|
|
23
|
+
const fetchableRef = (cwd) => Effect.gen(function* () {
|
|
24
|
+
const { GITHUB_HEAD_REF } = environment();
|
|
25
|
+
if (GITHUB_HEAD_REF !== void 0 && GITHUB_HEAD_REF !== "") return GITHUB_HEAD_REF;
|
|
26
|
+
const [head, onRemote] = yield* Effect.all([git(["rev-parse", "HEAD"], cwd), git([
|
|
27
|
+
"branch",
|
|
28
|
+
"--remotes",
|
|
29
|
+
"--contains",
|
|
30
|
+
"HEAD"
|
|
31
|
+
], cwd)], { concurrency: 2 });
|
|
32
|
+
return head === "" || onRemote === "" ? null : head;
|
|
33
|
+
});
|
|
34
|
+
const localRepo = (cwd) => Effect.gen(function* () {
|
|
35
|
+
const [remote, ref] = yield* Effect.all([remoteUrl(cwd), fetchableRef(cwd)], { concurrency: 2 });
|
|
36
|
+
const parsed = remote === "" ? null : parseRepo(remote);
|
|
37
|
+
return parsed === null ? Option.none() : Option.some({
|
|
38
|
+
kind: "repo",
|
|
39
|
+
ref,
|
|
40
|
+
url: cloneUrlOf(parsed)
|
|
41
|
+
});
|
|
42
|
+
}).pipe(Effect.withSpan("Eval.localRepo"));
|
|
43
|
+
//#endregion
|
|
44
|
+
//#region src/evals/runner-source.ts
|
|
45
|
+
const runtime = `
|
|
46
|
+
import { access, readFile } from "node:fs/promises";
|
|
47
|
+
import { spawn } from "node:child_process";
|
|
48
|
+
|
|
49
|
+
const exec = (command) => new Promise((resolve, reject) => {
|
|
50
|
+
const child = spawn("/bin/sh", ["-lc", command], { cwd: process.cwd() });
|
|
51
|
+
let stderr = "";
|
|
52
|
+
let stdout = "";
|
|
53
|
+
child.stderr.on("data", chunk => { stderr += chunk; });
|
|
54
|
+
child.stdout.on("data", chunk => { stdout += chunk; });
|
|
55
|
+
child.on("error", reject);
|
|
56
|
+
child.on("close", code => resolve({ exitCode: code ?? 1, stderr, stdout }));
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const context = {
|
|
60
|
+
exec,
|
|
61
|
+
exists: path => access(path).then(() => true, () => false),
|
|
62
|
+
readText: path => readFile(path, "utf8"),
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
try {
|
|
66
|
+
const raw = await validate(context);
|
|
67
|
+
const result = typeof raw === "boolean" ? { passed: raw } : raw;
|
|
68
|
+
if (typeof result?.passed !== "boolean") throw new Error("A validator must return a boolean or { passed, message? }");
|
|
69
|
+
console.log("ANPORD_VALIDATOR_RESULT=" + JSON.stringify(result));
|
|
70
|
+
} catch (error) {
|
|
71
|
+
console.error(error instanceof Error ? error.stack : String(error));
|
|
72
|
+
process.exitCode = 1;
|
|
73
|
+
}
|
|
74
|
+
`;
|
|
75
|
+
const validatorEntry = (module, name) => `import { ${name} as validate } from ${JSON.stringify(module)};\n${runtime}`;
|
|
76
|
+
const definitionEntry = (entry) => `import definition from ${JSON.stringify(entry)}; export default definition;`;
|
|
77
|
+
//#endregion
|
|
78
|
+
//#region src/evals/compiler.ts
|
|
79
|
+
const authoringExports = ["export const defineEval = value => value;", `export { empty, files, repo } from "./source";`].join("\n");
|
|
80
|
+
const authoringDir = dirname(fileURLToPath(import.meta.url));
|
|
81
|
+
const ANPORD_MODULE = /^anpord$/;
|
|
82
|
+
const ANY_MODULE = /.*/;
|
|
83
|
+
const authoringModule = {
|
|
84
|
+
name: "anpord-authoring",
|
|
85
|
+
setup: (compiler) => {
|
|
86
|
+
compiler.onResolve({ filter: ANPORD_MODULE }, () => ({
|
|
87
|
+
namespace: "anpord-authoring",
|
|
88
|
+
path: "anpord"
|
|
89
|
+
}));
|
|
90
|
+
compiler.onLoad({
|
|
91
|
+
filter: ANY_MODULE,
|
|
92
|
+
namespace: "anpord-authoring"
|
|
93
|
+
}, () => ({
|
|
94
|
+
contents: authoringExports,
|
|
95
|
+
loader: "js",
|
|
96
|
+
resolveDir: authoringDir
|
|
97
|
+
}));
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
const bundle = (contents, entry) => Effect.tryPromise({
|
|
101
|
+
try: () => build({
|
|
102
|
+
absWorkingDir: process.cwd(),
|
|
103
|
+
bundle: true,
|
|
104
|
+
format: "esm",
|
|
105
|
+
metafile: true,
|
|
106
|
+
platform: "node",
|
|
107
|
+
resolveExtensions: [
|
|
108
|
+
".ts",
|
|
109
|
+
".mjs",
|
|
110
|
+
".js",
|
|
111
|
+
".cjs",
|
|
112
|
+
".json"
|
|
113
|
+
],
|
|
114
|
+
plugins: [authoringModule],
|
|
115
|
+
stdin: {
|
|
116
|
+
contents,
|
|
117
|
+
resolveDir: process.cwd(),
|
|
118
|
+
sourcefile: "anpord-eval-entry.ts"
|
|
119
|
+
},
|
|
120
|
+
target: "node18",
|
|
121
|
+
treeShaking: true,
|
|
122
|
+
write: false
|
|
123
|
+
}).then((result) => ({
|
|
124
|
+
inputs: Object.keys(result.metafile?.inputs ?? {}).map((path) => resolve(path)),
|
|
125
|
+
source: result.outputFiles[0]?.text ?? ""
|
|
126
|
+
})),
|
|
127
|
+
catch: (cause) => new Error(`Could not compile ${entry}`, { cause })
|
|
128
|
+
});
|
|
129
|
+
const loadDefinition = (entry) => bundle(definitionEntry(entry), entry).pipe(Effect.flatMap(({ inputs, source }) => Effect.acquireUseRelease(Effect.tryPromise(() => mkdtemp(join(tmpdir(), "anpord-eval-"))), (directory) => Effect.tryPromise({
|
|
130
|
+
try: async () => {
|
|
131
|
+
const output = join(directory, "definition.mjs");
|
|
132
|
+
await writeFile(output, source);
|
|
133
|
+
return {
|
|
134
|
+
definition: (await import(pathToFileURL(output).href)).default,
|
|
135
|
+
inputs
|
|
136
|
+
};
|
|
137
|
+
},
|
|
138
|
+
catch: (cause) => new Error(`Could not load ${entry}: ${cause instanceof Error ? cause.message : String(cause)}`, { cause })
|
|
139
|
+
}), (directory) => Effect.promise(() => rm(directory, {
|
|
140
|
+
force: true,
|
|
141
|
+
recursive: true
|
|
142
|
+
})).pipe(Effect.ignore))));
|
|
143
|
+
const validatorModule = (entry, inputs, name) => Effect.gen(function* () {
|
|
144
|
+
const pattern = new RegExp(`\\bexport\\s+(?:async\\s+)?(?:const|function)\\s+${name}\\b`);
|
|
145
|
+
const matches = yield* Effect.filter(inputs.filter((path) => path !== entry && !path.includes(`${sep}node_modules${sep}`)), (path) => Effect.tryPromise(() => readFile(path, "utf8")).pipe(Effect.map((source) => pattern.test(source)), Effect.orElseSucceed(() => false)), { concurrency: 8 });
|
|
146
|
+
if (matches.length !== 1) return yield* Effect.fail(/* @__PURE__ */ new Error(`${name} must be one named function or const export from a separate TypeScript file`));
|
|
147
|
+
return matches[0];
|
|
148
|
+
});
|
|
149
|
+
const isDefinition = (value) => typeof value === "object" && value !== null && typeof value.name === "string" && typeof value.prompt === "string" && Array.isArray(value.cases) && Array.isArray(value.tasks) && Number.isInteger(value.trials);
|
|
150
|
+
const sourceFor = (definition, subject, fallback) => {
|
|
151
|
+
const source = subject.source ?? definition.source;
|
|
152
|
+
if (source !== void 0) return { source: typeof source === "string" ? repo(source) : source };
|
|
153
|
+
return Option.match(fallback, {
|
|
154
|
+
onNone: () => ({}),
|
|
155
|
+
onSome: (source) => ({ source })
|
|
156
|
+
});
|
|
157
|
+
};
|
|
158
|
+
const compileEvalEffect = (path) => Effect.gen(function* () {
|
|
159
|
+
const entry = resolve(path);
|
|
160
|
+
const loaded = yield* loadDefinition(entry);
|
|
161
|
+
const definition = loaded.definition;
|
|
162
|
+
if (!isDefinition(definition)) return yield* Effect.fail(/* @__PURE__ */ new Error(`${entry} must default export defineEval({ ... })`));
|
|
163
|
+
const fallback = definition.source === void 0 && definition.cases.some((subject) => subject.source === void 0) ? yield* localRepo(dirname(entry)) : Option.none();
|
|
164
|
+
return {
|
|
165
|
+
cases: yield* Effect.forEach(definition.cases, (subject) => Effect.gen(function* () {
|
|
166
|
+
const hasValidator = typeof subject.validate === "function";
|
|
167
|
+
if (hasValidator === (typeof subject.verify === "string")) return yield* Effect.fail(/* @__PURE__ */ new Error(`${subject.name} must have exactly one of validate or verify`));
|
|
168
|
+
const validator = hasValidator ? {
|
|
169
|
+
name: subject.validate?.name || subject.name,
|
|
170
|
+
source: (yield* bundle(validatorEntry(yield* validatorModule(entry, loaded.inputs, subject.validate?.name || subject.name), subject.validate?.name || subject.name), entry)).source
|
|
171
|
+
} : null;
|
|
172
|
+
return {
|
|
173
|
+
name: subject.name,
|
|
174
|
+
setup: subject.setup ?? null,
|
|
175
|
+
...sourceFor(definition, subject, fallback),
|
|
176
|
+
validator,
|
|
177
|
+
variables: subject.variables ?? {},
|
|
178
|
+
verify: subject.verify ?? null
|
|
179
|
+
};
|
|
180
|
+
}), { concurrency: 4 }),
|
|
181
|
+
prompt: definition.prompt,
|
|
182
|
+
tasks: [...definition.tasks],
|
|
183
|
+
trials: definition.trials
|
|
184
|
+
};
|
|
185
|
+
}).pipe(Effect.withSpan("Eval.compile"));
|
|
186
|
+
const compileEval = (path) => Effect.runPromise(compileEvalEffect(path));
|
|
187
|
+
//#endregion
|
|
188
|
+
export { compileEvalEffect as n, compileEval as t };
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
const require_source = require("./source-DvlGawEw.cjs");
|
|
2
|
+
let effect = require("effect");
|
|
3
|
+
let node_fs_promises = require("node:fs/promises");
|
|
4
|
+
let node_os = require("node:os");
|
|
5
|
+
let node_path = require("node:path");
|
|
6
|
+
let node_url = require("node:url");
|
|
7
|
+
let esbuild = require("esbuild");
|
|
8
|
+
let node_child_process = require("node:child_process");
|
|
9
|
+
//#region src/evals/local-repo.ts
|
|
10
|
+
const run = (0, require("node:util").promisify)(node_child_process.execFile);
|
|
11
|
+
const git = (args, cwd) => effect.Effect.tryPromise(() => run("git", [...args], { cwd })).pipe(effect.Effect.map(({ stdout }) => stdout.trim()), effect.Effect.orElseSucceed(() => ""));
|
|
12
|
+
const environment = () => globalThis.process?.env ?? {};
|
|
13
|
+
const remoteUrl = (cwd) => effect.Effect.gen(function* () {
|
|
14
|
+
const { GITHUB_REPOSITORY } = environment();
|
|
15
|
+
const origin = yield* git([
|
|
16
|
+
"remote",
|
|
17
|
+
"get-url",
|
|
18
|
+
"origin"
|
|
19
|
+
], cwd);
|
|
20
|
+
return origin === "" && GITHUB_REPOSITORY !== void 0 ? GITHUB_REPOSITORY : origin;
|
|
21
|
+
});
|
|
22
|
+
const fetchableRef = (cwd) => effect.Effect.gen(function* () {
|
|
23
|
+
const { GITHUB_HEAD_REF } = environment();
|
|
24
|
+
if (GITHUB_HEAD_REF !== void 0 && GITHUB_HEAD_REF !== "") return GITHUB_HEAD_REF;
|
|
25
|
+
const [head, onRemote] = yield* effect.Effect.all([git(["rev-parse", "HEAD"], cwd), git([
|
|
26
|
+
"branch",
|
|
27
|
+
"--remotes",
|
|
28
|
+
"--contains",
|
|
29
|
+
"HEAD"
|
|
30
|
+
], cwd)], { concurrency: 2 });
|
|
31
|
+
return head === "" || onRemote === "" ? null : head;
|
|
32
|
+
});
|
|
33
|
+
const localRepo = (cwd) => effect.Effect.gen(function* () {
|
|
34
|
+
const [remote, ref] = yield* effect.Effect.all([remoteUrl(cwd), fetchableRef(cwd)], { concurrency: 2 });
|
|
35
|
+
const parsed = remote === "" ? null : require_source.parseRepo(remote);
|
|
36
|
+
return parsed === null ? effect.Option.none() : effect.Option.some({
|
|
37
|
+
kind: "repo",
|
|
38
|
+
ref,
|
|
39
|
+
url: require_source.cloneUrlOf(parsed)
|
|
40
|
+
});
|
|
41
|
+
}).pipe(effect.Effect.withSpan("Eval.localRepo"));
|
|
42
|
+
//#endregion
|
|
43
|
+
//#region src/evals/runner-source.ts
|
|
44
|
+
const runtime = `
|
|
45
|
+
import { access, readFile } from "node:fs/promises";
|
|
46
|
+
import { spawn } from "node:child_process";
|
|
47
|
+
|
|
48
|
+
const exec = (command) => new Promise((resolve, reject) => {
|
|
49
|
+
const child = spawn("/bin/sh", ["-lc", command], { cwd: process.cwd() });
|
|
50
|
+
let stderr = "";
|
|
51
|
+
let stdout = "";
|
|
52
|
+
child.stderr.on("data", chunk => { stderr += chunk; });
|
|
53
|
+
child.stdout.on("data", chunk => { stdout += chunk; });
|
|
54
|
+
child.on("error", reject);
|
|
55
|
+
child.on("close", code => resolve({ exitCode: code ?? 1, stderr, stdout }));
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
const context = {
|
|
59
|
+
exec,
|
|
60
|
+
exists: path => access(path).then(() => true, () => false),
|
|
61
|
+
readText: path => readFile(path, "utf8"),
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
const raw = await validate(context);
|
|
66
|
+
const result = typeof raw === "boolean" ? { passed: raw } : raw;
|
|
67
|
+
if (typeof result?.passed !== "boolean") throw new Error("A validator must return a boolean or { passed, message? }");
|
|
68
|
+
console.log("ANPORD_VALIDATOR_RESULT=" + JSON.stringify(result));
|
|
69
|
+
} catch (error) {
|
|
70
|
+
console.error(error instanceof Error ? error.stack : String(error));
|
|
71
|
+
process.exitCode = 1;
|
|
72
|
+
}
|
|
73
|
+
`;
|
|
74
|
+
const validatorEntry = (module, name) => `import { ${name} as validate } from ${JSON.stringify(module)};\n${runtime}`;
|
|
75
|
+
const definitionEntry = (entry) => `import definition from ${JSON.stringify(entry)}; export default definition;`;
|
|
76
|
+
//#endregion
|
|
77
|
+
//#region src/evals/compiler.ts
|
|
78
|
+
const authoringExports = ["export const defineEval = value => value;", `export { empty, files, repo } from "./source";`].join("\n");
|
|
79
|
+
const authoringDir = (0, node_path.dirname)((0, node_url.fileURLToPath)(require("url").pathToFileURL(__filename).href));
|
|
80
|
+
const ANPORD_MODULE = /^anpord$/;
|
|
81
|
+
const ANY_MODULE = /.*/;
|
|
82
|
+
const authoringModule = {
|
|
83
|
+
name: "anpord-authoring",
|
|
84
|
+
setup: (compiler) => {
|
|
85
|
+
compiler.onResolve({ filter: ANPORD_MODULE }, () => ({
|
|
86
|
+
namespace: "anpord-authoring",
|
|
87
|
+
path: "anpord"
|
|
88
|
+
}));
|
|
89
|
+
compiler.onLoad({
|
|
90
|
+
filter: ANY_MODULE,
|
|
91
|
+
namespace: "anpord-authoring"
|
|
92
|
+
}, () => ({
|
|
93
|
+
contents: authoringExports,
|
|
94
|
+
loader: "js",
|
|
95
|
+
resolveDir: authoringDir
|
|
96
|
+
}));
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
const bundle = (contents, entry) => effect.Effect.tryPromise({
|
|
100
|
+
try: () => (0, esbuild.build)({
|
|
101
|
+
absWorkingDir: process.cwd(),
|
|
102
|
+
bundle: true,
|
|
103
|
+
format: "esm",
|
|
104
|
+
metafile: true,
|
|
105
|
+
platform: "node",
|
|
106
|
+
resolveExtensions: [
|
|
107
|
+
".ts",
|
|
108
|
+
".mjs",
|
|
109
|
+
".js",
|
|
110
|
+
".cjs",
|
|
111
|
+
".json"
|
|
112
|
+
],
|
|
113
|
+
plugins: [authoringModule],
|
|
114
|
+
stdin: {
|
|
115
|
+
contents,
|
|
116
|
+
resolveDir: process.cwd(),
|
|
117
|
+
sourcefile: "anpord-eval-entry.ts"
|
|
118
|
+
},
|
|
119
|
+
target: "node18",
|
|
120
|
+
treeShaking: true,
|
|
121
|
+
write: false
|
|
122
|
+
}).then((result) => ({
|
|
123
|
+
inputs: Object.keys(result.metafile?.inputs ?? {}).map((path) => (0, node_path.resolve)(path)),
|
|
124
|
+
source: result.outputFiles[0]?.text ?? ""
|
|
125
|
+
})),
|
|
126
|
+
catch: (cause) => new Error(`Could not compile ${entry}`, { cause })
|
|
127
|
+
});
|
|
128
|
+
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({
|
|
129
|
+
try: async () => {
|
|
130
|
+
const output = (0, node_path.join)(directory, "definition.mjs");
|
|
131
|
+
await (0, node_fs_promises.writeFile)(output, source);
|
|
132
|
+
return {
|
|
133
|
+
definition: (await import((0, node_url.pathToFileURL)(output).href)).default,
|
|
134
|
+
inputs
|
|
135
|
+
};
|
|
136
|
+
},
|
|
137
|
+
catch: (cause) => new Error(`Could not load ${entry}: ${cause instanceof Error ? cause.message : String(cause)}`, { cause })
|
|
138
|
+
}), (directory) => effect.Effect.promise(() => (0, node_fs_promises.rm)(directory, {
|
|
139
|
+
force: true,
|
|
140
|
+
recursive: true
|
|
141
|
+
})).pipe(effect.Effect.ignore))));
|
|
142
|
+
const validatorModule = (entry, inputs, name) => effect.Effect.gen(function* () {
|
|
143
|
+
const pattern = new RegExp(`\\bexport\\s+(?:async\\s+)?(?:const|function)\\s+${name}\\b`);
|
|
144
|
+
const matches = yield* effect.Effect.filter(inputs.filter((path) => 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 });
|
|
145
|
+
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`));
|
|
146
|
+
return matches[0];
|
|
147
|
+
});
|
|
148
|
+
const isDefinition = (value) => typeof value === "object" && value !== null && typeof value.name === "string" && typeof value.prompt === "string" && Array.isArray(value.cases) && Array.isArray(value.tasks) && Number.isInteger(value.trials);
|
|
149
|
+
const sourceFor = (definition, subject, fallback) => {
|
|
150
|
+
const source = subject.source ?? definition.source;
|
|
151
|
+
if (source !== void 0) return { source: typeof source === "string" ? require_source.repo(source) : source };
|
|
152
|
+
return effect.Option.match(fallback, {
|
|
153
|
+
onNone: () => ({}),
|
|
154
|
+
onSome: (source) => ({ source })
|
|
155
|
+
});
|
|
156
|
+
};
|
|
157
|
+
const compileEvalEffect = (path) => effect.Effect.gen(function* () {
|
|
158
|
+
const entry = (0, node_path.resolve)(path);
|
|
159
|
+
const loaded = yield* loadDefinition(entry);
|
|
160
|
+
const definition = loaded.definition;
|
|
161
|
+
if (!isDefinition(definition)) return yield* effect.Effect.fail(/* @__PURE__ */ new Error(`${entry} must default export defineEval({ ... })`));
|
|
162
|
+
const fallback = definition.source === void 0 && definition.cases.some((subject) => subject.source === void 0) ? yield* localRepo((0, node_path.dirname)(entry)) : effect.Option.none();
|
|
163
|
+
return {
|
|
164
|
+
cases: yield* effect.Effect.forEach(definition.cases, (subject) => effect.Effect.gen(function* () {
|
|
165
|
+
const hasValidator = typeof subject.validate === "function";
|
|
166
|
+
if (hasValidator === (typeof subject.verify === "string")) return yield* effect.Effect.fail(/* @__PURE__ */ new Error(`${subject.name} must have exactly one of validate or verify`));
|
|
167
|
+
const validator = hasValidator ? {
|
|
168
|
+
name: subject.validate?.name || subject.name,
|
|
169
|
+
source: (yield* bundle(validatorEntry(yield* validatorModule(entry, loaded.inputs, subject.validate?.name || subject.name), subject.validate?.name || subject.name), entry)).source
|
|
170
|
+
} : null;
|
|
171
|
+
return {
|
|
172
|
+
name: subject.name,
|
|
173
|
+
setup: subject.setup ?? null,
|
|
174
|
+
...sourceFor(definition, subject, fallback),
|
|
175
|
+
validator,
|
|
176
|
+
variables: subject.variables ?? {},
|
|
177
|
+
verify: subject.verify ?? null
|
|
178
|
+
};
|
|
179
|
+
}), { concurrency: 4 }),
|
|
180
|
+
prompt: definition.prompt,
|
|
181
|
+
tasks: [...definition.tasks],
|
|
182
|
+
trials: definition.trials
|
|
183
|
+
};
|
|
184
|
+
}).pipe(effect.Effect.withSpan("Eval.compile"));
|
|
185
|
+
const compileEval = (path) => effect.Effect.runPromise(compileEvalEffect(path));
|
|
186
|
+
//#endregion
|
|
187
|
+
Object.defineProperty(exports, "compileEval", {
|
|
188
|
+
enumerable: true,
|
|
189
|
+
get: function() {
|
|
190
|
+
return compileEval;
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
Object.defineProperty(exports, "compileEvalEffect", {
|
|
194
|
+
enumerable: true,
|
|
195
|
+
get: function() {
|
|
196
|
+
return compileEvalEffect;
|
|
197
|
+
}
|
|
198
|
+
});
|
package/dist/config.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_client = require("./client-
|
|
2
|
+
const require_client = require("./client-BCZEcfVE.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.mjs
CHANGED
|
@@ -1,4 +1,27 @@
|
|
|
1
1
|
let effect_ParseResult = require("effect/ParseResult");
|
|
2
|
+
//#region ../template/src/syntax.ts
|
|
3
|
+
/**
|
|
4
|
+
* What a variable looks like, defined once.
|
|
5
|
+
*
|
|
6
|
+
* The editor's atom node, the extractor and the renderer have to agree
|
|
7
|
+
* exactly: a name the editor draws as a chip but the renderer does not fill
|
|
8
|
+
* reaches the model as literal braces, and nobody notices until the output is
|
|
9
|
+
* wrong.
|
|
10
|
+
*/
|
|
11
|
+
const VARIABLE_PATTERN = String.raw`\{\{\s*([\w.-]+)\s*\}\}`;
|
|
12
|
+
/**
|
|
13
|
+
* Escapes and variables together, escapes first.
|
|
14
|
+
*
|
|
15
|
+
* They cannot be two passes: `{{{{name}}}}` contains `{{name}}` starting at
|
|
16
|
+
* its third brace, so a substitution pass run on its own would fill the very
|
|
17
|
+
* text the escape exists to protect. Reading both in one sweep is what keeps
|
|
18
|
+
* the extractor and the renderer agreeing on what counts as a variable.
|
|
19
|
+
*
|
|
20
|
+
* A fresh instance each call, because a global regular expression carries its
|
|
21
|
+
* own `lastIndex` and a shared one silently skips matches on a second pass.
|
|
22
|
+
*/
|
|
23
|
+
const tokenMatcher = () => new RegExp(String.raw`(\{\{\{\{)|(\}\}\}\})|${VARIABLE_PATTERN}`, "g");
|
|
24
|
+
//#endregion
|
|
2
25
|
//#region src/client/errors.ts
|
|
3
26
|
var MissingApiKey = class extends Error {
|
|
4
27
|
name = "MissingApiKey";
|
|
@@ -21,6 +44,7 @@ const statusOf = (error) => {
|
|
|
21
44
|
switch (error._tag) {
|
|
22
45
|
case "BadRequest": return 400;
|
|
23
46
|
case "Unauthorized": return 401;
|
|
47
|
+
case "Forbidden": return 403;
|
|
24
48
|
case "NotFound": return 404;
|
|
25
49
|
case "Conflict": return 409;
|
|
26
50
|
case "InternalError": return 500;
|
|
@@ -65,3 +89,9 @@ Object.defineProperty(exports, "asAnpordError", {
|
|
|
65
89
|
return asAnpordError;
|
|
66
90
|
}
|
|
67
91
|
});
|
|
92
|
+
Object.defineProperty(exports, "tokenMatcher", {
|
|
93
|
+
enumerable: true,
|
|
94
|
+
get: function() {
|
|
95
|
+
return tokenMatcher;
|
|
96
|
+
}
|
|
97
|
+
});
|
|
@@ -1,4 +1,27 @@
|
|
|
1
1
|
import { ArrayFormatter } from "effect/ParseResult";
|
|
2
|
+
//#region ../template/src/syntax.ts
|
|
3
|
+
/**
|
|
4
|
+
* What a variable looks like, defined once.
|
|
5
|
+
*
|
|
6
|
+
* The editor's atom node, the extractor and the renderer have to agree
|
|
7
|
+
* exactly: a name the editor draws as a chip but the renderer does not fill
|
|
8
|
+
* reaches the model as literal braces, and nobody notices until the output is
|
|
9
|
+
* wrong.
|
|
10
|
+
*/
|
|
11
|
+
const VARIABLE_PATTERN = String.raw`\{\{\s*([\w.-]+)\s*\}\}`;
|
|
12
|
+
/**
|
|
13
|
+
* Escapes and variables together, escapes first.
|
|
14
|
+
*
|
|
15
|
+
* They cannot be two passes: `{{{{name}}}}` contains `{{name}}` starting at
|
|
16
|
+
* its third brace, so a substitution pass run on its own would fill the very
|
|
17
|
+
* text the escape exists to protect. Reading both in one sweep is what keeps
|
|
18
|
+
* the extractor and the renderer agreeing on what counts as a variable.
|
|
19
|
+
*
|
|
20
|
+
* A fresh instance each call, because a global regular expression carries its
|
|
21
|
+
* own `lastIndex` and a shared one silently skips matches on a second pass.
|
|
22
|
+
*/
|
|
23
|
+
const tokenMatcher = () => new RegExp(String.raw`(\{\{\{\{)|(\}\}\}\})|${VARIABLE_PATTERN}`, "g");
|
|
24
|
+
//#endregion
|
|
2
25
|
//#region src/client/errors.ts
|
|
3
26
|
var MissingApiKey = class extends Error {
|
|
4
27
|
name = "MissingApiKey";
|
|
@@ -21,6 +44,7 @@ const statusOf = (error) => {
|
|
|
21
44
|
switch (error._tag) {
|
|
22
45
|
case "BadRequest": return 400;
|
|
23
46
|
case "Unauthorized": return 401;
|
|
47
|
+
case "Forbidden": return 403;
|
|
24
48
|
case "NotFound": return 404;
|
|
25
49
|
case "Conflict": return 409;
|
|
26
50
|
case "InternalError": return 500;
|
|
@@ -47,4 +71,4 @@ const asAnpordError = (error) => error instanceof AnpordError ? error : new Anpo
|
|
|
47
71
|
status: statusOf(error)
|
|
48
72
|
});
|
|
49
73
|
//#endregion
|
|
50
|
-
export { MissingApiKey as n, asAnpordError as r, AnpordError as t };
|
|
74
|
+
export { tokenMatcher as i, MissingApiKey as n, asAnpordError as r, AnpordError as t };
|
package/dist/eval.cjs
ADDED
package/dist/eval.d.cts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { t as PublicStartEvalRequest } from "./evals-api-sqVNeWet.cjs";
|
|
2
|
+
import { Effect } from "effect";
|
|
3
|
+
//#region src/evals/compiler.d.ts
|
|
4
|
+
declare const compileEvalEffect: (path: string) => Effect.Effect<{
|
|
5
|
+
cases: {
|
|
6
|
+
validator: {
|
|
7
|
+
name: string;
|
|
8
|
+
source: string;
|
|
9
|
+
} | null;
|
|
10
|
+
variables: Readonly<Record<string, string>>;
|
|
11
|
+
verify: string | null;
|
|
12
|
+
name: string;
|
|
13
|
+
setup: string | null;
|
|
14
|
+
}[];
|
|
15
|
+
prompt: string;
|
|
16
|
+
tasks: {
|
|
17
|
+
readonly harness: "codex" | "opencode" | "pi" | "fx" | "claude" | "gemini" | "qwen" | "cursor";
|
|
18
|
+
readonly model: string;
|
|
19
|
+
readonly provider: "daytona" | "e2b" | "upstash" | "modal" | "cloudflare" | "vercel";
|
|
20
|
+
}[];
|
|
21
|
+
trials: number;
|
|
22
|
+
}, Error, never>;
|
|
23
|
+
declare const compileEval: (path: string) => Promise<PublicStartEvalRequest>;
|
|
24
|
+
//#endregion
|
|
25
|
+
export { compileEval, compileEvalEffect };
|
package/dist/eval.d.mts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { t as PublicStartEvalRequest } from "./evals-api-DUNVUGUy.mjs";
|
|
2
|
+
import { Effect } from "effect";
|
|
3
|
+
//#region src/evals/compiler.d.ts
|
|
4
|
+
declare const compileEvalEffect: (path: string) => Effect.Effect<{
|
|
5
|
+
cases: {
|
|
6
|
+
validator: {
|
|
7
|
+
name: string;
|
|
8
|
+
source: string;
|
|
9
|
+
} | null;
|
|
10
|
+
variables: Readonly<Record<string, string>>;
|
|
11
|
+
verify: string | null;
|
|
12
|
+
name: string;
|
|
13
|
+
setup: string | null;
|
|
14
|
+
}[];
|
|
15
|
+
prompt: string;
|
|
16
|
+
tasks: {
|
|
17
|
+
readonly harness: "codex" | "opencode" | "pi" | "fx" | "claude" | "gemini" | "qwen" | "cursor";
|
|
18
|
+
readonly model: string;
|
|
19
|
+
readonly provider: "daytona" | "e2b" | "upstash" | "modal" | "cloudflare" | "vercel";
|
|
20
|
+
}[];
|
|
21
|
+
trials: number;
|
|
22
|
+
}, Error, never>;
|
|
23
|
+
declare const compileEval: (path: string) => Promise<PublicStartEvalRequest>;
|
|
24
|
+
//#endregion
|
|
25
|
+
export { compileEval, compileEvalEffect };
|
package/dist/eval.mjs
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { HttpApiEndpoint, HttpApiGroup, HttpApiMiddleware, HttpApiSecurity } from "@effect/platform";
|
|
2
|
+
import { Context, Schema } from "effect";
|
|
3
|
+
//#region ../schema/src/domain/errors.d.ts
|
|
4
|
+
declare const NotFound_base: Schema.TaggedErrorClass<NotFound, "NotFound", {
|
|
5
|
+
readonly _tag: Schema.tag<"NotFound">;
|
|
6
|
+
} & {
|
|
7
|
+
message: typeof Schema.String;
|
|
8
|
+
}>;
|
|
9
|
+
declare class NotFound extends NotFound_base {}
|
|
10
|
+
declare const Conflict_base: Schema.TaggedErrorClass<Conflict, "Conflict", {
|
|
11
|
+
readonly _tag: Schema.tag<"Conflict">;
|
|
12
|
+
} & {
|
|
13
|
+
message: typeof Schema.String;
|
|
14
|
+
}>;
|
|
15
|
+
declare class Conflict extends Conflict_base {}
|
|
16
|
+
declare const BadRequest_base: Schema.TaggedErrorClass<BadRequest, "BadRequest", {
|
|
17
|
+
readonly _tag: Schema.tag<"BadRequest">;
|
|
18
|
+
} & {
|
|
19
|
+
message: typeof Schema.String;
|
|
20
|
+
}>;
|
|
21
|
+
declare class BadRequest extends BadRequest_base {}
|
|
22
|
+
declare const Unauthorized_base: Schema.TaggedErrorClass<Unauthorized, "Unauthorized", {
|
|
23
|
+
readonly _tag: Schema.tag<"Unauthorized">;
|
|
24
|
+
} & {
|
|
25
|
+
message: typeof Schema.String;
|
|
26
|
+
}>;
|
|
27
|
+
declare class Unauthorized extends Unauthorized_base {}
|
|
28
|
+
declare const Forbidden_base: Schema.TaggedErrorClass<Forbidden, "Forbidden", {
|
|
29
|
+
readonly _tag: Schema.tag<"Forbidden">;
|
|
30
|
+
} & {
|
|
31
|
+
message: typeof Schema.String;
|
|
32
|
+
}>;
|
|
33
|
+
/** Distinct from Unauthorized: the caller is who they say they are, and the
|
|
34
|
+
* answer is still no. Signing in again cannot help, so the client must not
|
|
35
|
+
* treat this as an expired session. */
|
|
36
|
+
declare class Forbidden extends Forbidden_base {}
|
|
37
|
+
//#endregion
|
|
38
|
+
//#region ../schema/src/public/evals-api.d.ts
|
|
39
|
+
declare const PublicStartEvalRequest: Schema.Struct<{
|
|
40
|
+
cases: Schema.filter<Schema.Array$<Schema.refine<{
|
|
41
|
+
readonly name: string;
|
|
42
|
+
readonly setup?: string | null | undefined;
|
|
43
|
+
readonly source?: {
|
|
44
|
+
readonly kind: "empty";
|
|
45
|
+
} | {
|
|
46
|
+
readonly kind: "repo";
|
|
47
|
+
readonly ref: string | null;
|
|
48
|
+
readonly url: string;
|
|
49
|
+
} | {
|
|
50
|
+
readonly kind: "files";
|
|
51
|
+
readonly files: {
|
|
52
|
+
readonly [x: string]: string;
|
|
53
|
+
};
|
|
54
|
+
} | undefined;
|
|
55
|
+
readonly validator?: {
|
|
56
|
+
readonly name: string;
|
|
57
|
+
readonly source: string;
|
|
58
|
+
} | null | undefined;
|
|
59
|
+
readonly variables?: {
|
|
60
|
+
readonly [x: string]: string;
|
|
61
|
+
} | undefined;
|
|
62
|
+
readonly verify: string | null;
|
|
63
|
+
}, Schema.Struct<{
|
|
64
|
+
name: typeof Schema.String;
|
|
65
|
+
setup: Schema.optional<Schema.NullOr<typeof Schema.String>>;
|
|
66
|
+
source: Schema.optional<Schema.Union<[Schema.Struct<{
|
|
67
|
+
kind: Schema.Literal<["empty"]>;
|
|
68
|
+
}>, Schema.Struct<{
|
|
69
|
+
kind: Schema.Literal<["repo"]>;
|
|
70
|
+
ref: Schema.NullOr<typeof Schema.String>;
|
|
71
|
+
url: Schema.refine<string, typeof Schema.String>;
|
|
72
|
+
}>, Schema.Struct<{
|
|
73
|
+
files: Schema.Record$<typeof Schema.String, typeof Schema.String>;
|
|
74
|
+
kind: Schema.Literal<["files"]>;
|
|
75
|
+
}>]>>;
|
|
76
|
+
validator: Schema.optional<Schema.NullOr<Schema.Struct<{
|
|
77
|
+
name: Schema.filter<Schema.filter<typeof Schema.String>>;
|
|
78
|
+
source: Schema.filter<Schema.filter<typeof Schema.String>>;
|
|
79
|
+
}>>>;
|
|
80
|
+
variables: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.String>>;
|
|
81
|
+
verify: Schema.NullOr<typeof Schema.String>;
|
|
82
|
+
}>>>>;
|
|
83
|
+
prompt: typeof Schema.String;
|
|
84
|
+
tasks: Schema.filter<Schema.Array$<Schema.Struct<{
|
|
85
|
+
harness: Schema.Literal<["codex", "opencode", "pi", "fx", "claude", "gemini", "qwen", "cursor"]>;
|
|
86
|
+
model: Schema.filter<typeof Schema.String>;
|
|
87
|
+
provider: Schema.Literal<["daytona", "e2b", "upstash", "modal", "cloudflare", "vercel"]>;
|
|
88
|
+
}>>>;
|
|
89
|
+
trials: Schema.filter<typeof Schema.Int>;
|
|
90
|
+
}>;
|
|
91
|
+
type PublicStartEvalRequest = typeof PublicStartEvalRequest.Type;
|
|
92
|
+
//#endregion
|
|
93
|
+
export { NotFound as a, Forbidden as i, BadRequest as n, Unauthorized as o, Conflict as r, PublicStartEvalRequest as t };
|