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
package/dist/cli.mjs
CHANGED
|
@@ -1,20 +1,200 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as ChannelName, o as PromptId, r as layer, s as VersionNumber, t as AnpordApi } from "./client-
|
|
2
|
+
import { a as ChannelName, o as PromptId, r as layer, s as VersionNumber, t as AnpordApi } from "./client-BfhmGRQl.mjs";
|
|
3
3
|
import { clientOptionsConfig } from "./config.mjs";
|
|
4
|
-
import { r as asAnpordError } from "./errors-
|
|
4
|
+
import { i as tokenMatcher, r as asAnpordError } from "./errors-C9bQUcA3.mjs";
|
|
5
|
+
import { n as compileEvalEffect } from "./compiler-CKiewwUc.mjs";
|
|
5
6
|
import { FileSystem } from "@effect/platform";
|
|
6
|
-
import { Cause, Console, Effect, Layer, Option } from "effect";
|
|
7
|
+
import { Cause, Clock, Console, Data, Duration, Effect, Layer, Option, Ref } from "effect";
|
|
7
8
|
import { Args, Command, Options } from "@effect/cli";
|
|
8
9
|
import { NodeContext, NodeRuntime } from "@effect/platform-node";
|
|
10
|
+
//#region package.json
|
|
11
|
+
var version$1 = "0.1.4";
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region ../template/src/extract.ts
|
|
14
|
+
/**
|
|
15
|
+
* Distinct variable names in source order, so callers can count or list them.
|
|
16
|
+
*
|
|
17
|
+
* Escaped braces are read here too, so a name the renderer will treat as
|
|
18
|
+
* literal text is never reported as a variable the editor should draw.
|
|
19
|
+
*/
|
|
20
|
+
function extractVariables(template) {
|
|
21
|
+
const names = [];
|
|
22
|
+
for (const [, open, close, name] of template.matchAll(tokenMatcher())) if (open === void 0 && close === void 0 && name !== void 0) names.push(name);
|
|
23
|
+
return [...new Set(names)];
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
//#region src/cli/declarations.ts
|
|
27
|
+
/**
|
|
28
|
+
* The generated file has to open by importing the module it augments.
|
|
29
|
+
*
|
|
30
|
+
* Without it `declare module` shadows the module rather than adding to it, and
|
|
31
|
+
* every import of the SDK stops resolving with an error naming the missing
|
|
32
|
+
* export rather than the file that hid it.
|
|
33
|
+
*/
|
|
34
|
+
const PREAMBLE = [
|
|
35
|
+
"// Generated by `anpord generate`. Do not edit.",
|
|
36
|
+
"// Run it again after changing which variables a prompt uses.",
|
|
37
|
+
"import \"anpord\";",
|
|
38
|
+
"",
|
|
39
|
+
"declare module \"anpord\" {",
|
|
40
|
+
" interface AnpordPromptVariables {"
|
|
41
|
+
].join("\n");
|
|
42
|
+
/** Quoted, because an id may carry characters an identifier cannot. */
|
|
43
|
+
const entry = (id, names) => {
|
|
44
|
+
return ` "${id}": ${names.length === 0 ? "Record<string, never>" : `{ ${names.map((name) => `"${name}": string`).join("; ")} }`};`;
|
|
45
|
+
};
|
|
46
|
+
const declarationFile = (prompts) => [
|
|
47
|
+
PREAMBLE,
|
|
48
|
+
...[...prompts].sort(([left], [right]) => left.localeCompare(right)).map(([id, names]) => entry(id, names)),
|
|
49
|
+
" }",
|
|
50
|
+
"}",
|
|
51
|
+
""
|
|
52
|
+
].join("\n");
|
|
53
|
+
//#endregion
|
|
54
|
+
//#region src/cli/eval-files.ts
|
|
55
|
+
const SUFFIX = ".eval.ts";
|
|
56
|
+
const SKIPPED = /* @__PURE__ */ new Set([
|
|
57
|
+
"node_modules",
|
|
58
|
+
"dist",
|
|
59
|
+
"build",
|
|
60
|
+
".git"
|
|
61
|
+
]);
|
|
62
|
+
const hidden = (segment) => segment.startsWith(".");
|
|
63
|
+
const wanted = (path) => {
|
|
64
|
+
const segments = path.split("/");
|
|
65
|
+
return path.endsWith(SUFFIX) && segments.every((segment) => !(SKIPPED.has(segment) || hidden(segment)));
|
|
66
|
+
};
|
|
67
|
+
const evalFilesIn = (directory) => Effect.gen(function* () {
|
|
68
|
+
return (yield* (yield* FileSystem.FileSystem).readDirectory(directory, { recursive: true })).filter(wanted).sort();
|
|
69
|
+
}).pipe(Effect.withSpan("Cli.evalFilesIn"));
|
|
70
|
+
//#endregion
|
|
71
|
+
//#region src/cli/eval-gate.ts
|
|
72
|
+
const regressions = (run) => run.cells.filter((cell) => cell.comparison?.verdict === "regressed");
|
|
73
|
+
const unscored = (run) => run.cells.filter((cell) => (cell.distribution?.scored ?? 0) === 0);
|
|
74
|
+
const problemsWith = (run, failOn) => {
|
|
75
|
+
if (run.status === "failed") return [run.failure ?? "The run failed."];
|
|
76
|
+
if (failOn === "never") return [];
|
|
77
|
+
const found = regressions(run).map((cell) => `${cell.caseName} regressed against its baseline.`);
|
|
78
|
+
return failOn === "unscored" ? [...found, ...unscored(run).map((cell) => `${cell.caseName} produced no scored trials.`)] : found;
|
|
79
|
+
};
|
|
80
|
+
const failWhen = (problems) => problems.length === 0 ? Effect.void : Effect.fail(new EvalGateFailed({ problems }));
|
|
81
|
+
var EvalGateFailed = class extends Data.TaggedError("EvalGateFailed") {
|
|
82
|
+
get message() {
|
|
83
|
+
return this.problems.join("\n");
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
var NoEvalFiles = class extends Data.TaggedError("NoEvalFiles") {
|
|
87
|
+
get message() {
|
|
88
|
+
return "No *.eval.ts file here. Name one, or pass a file to run.";
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
//#endregion
|
|
9
92
|
//#region src/cli/render.ts
|
|
10
93
|
const json = (value) => Console.log(JSON.stringify(value, null, 2));
|
|
11
94
|
const promptContent = (prompt) => Effect.sync(() => {
|
|
12
95
|
process.stdout.write(prompt.content);
|
|
13
96
|
if (!prompt.content.endsWith("\n")) process.stdout.write("\n");
|
|
14
97
|
});
|
|
98
|
+
/** A result the caller may pipe into another tool, so it belongs on stdout
|
|
99
|
+
* alongside the prompt content rather than beside the status messages. */
|
|
100
|
+
const row = (line) => Effect.sync(() => {
|
|
101
|
+
process.stdout.write(`${line}\n`);
|
|
102
|
+
});
|
|
15
103
|
const note = (message) => Effect.sync(() => {
|
|
16
104
|
process.stderr.write(`${message}\n`);
|
|
17
105
|
});
|
|
106
|
+
const attended = Effect.sync(() => globalThis.process?.stdout?.isTTY === true);
|
|
107
|
+
//#endregion
|
|
108
|
+
//#region src/cli/eval-grid.ts
|
|
109
|
+
const DIM = "\x1B[2m";
|
|
110
|
+
const BOLD = "\x1B[1m";
|
|
111
|
+
const GREEN = "\x1B[32m";
|
|
112
|
+
const RED = "\x1B[31m";
|
|
113
|
+
const YELLOW = "\x1B[33m";
|
|
114
|
+
const RESET = "\x1B[0m";
|
|
115
|
+
const DONE = "●";
|
|
116
|
+
const RUNNING = "◐";
|
|
117
|
+
const FILLED = "▰";
|
|
118
|
+
const HOLLOW = "▱";
|
|
119
|
+
const PERCENT = 100;
|
|
120
|
+
const SECONDS = 1e3;
|
|
121
|
+
const MINUTE = 60;
|
|
122
|
+
const paint = (colour, text) => `${colour}${text}${RESET}`;
|
|
123
|
+
const elapsedOf = (ms) => {
|
|
124
|
+
const total = Math.floor(ms / SECONDS);
|
|
125
|
+
const minutes = Math.floor(total / MINUTE);
|
|
126
|
+
return minutes === 0 ? `${total}s` : `${minutes}m${String(total % MINUTE).padStart(2, "0")}s`;
|
|
127
|
+
};
|
|
128
|
+
const markOf = (cell) => {
|
|
129
|
+
if (cell.status === "finished") return paint(GREEN, DONE);
|
|
130
|
+
return cell.status === "failed" ? paint(RED, DONE) : paint(YELLOW, RUNNING);
|
|
131
|
+
};
|
|
132
|
+
const trialsOf = (cell, trials) => {
|
|
133
|
+
const settled = cell.trials.filter((trial) => trial.status !== "queued" && trial.status !== "running").length;
|
|
134
|
+
return `${FILLED.repeat(settled)}${paint(DIM, HOLLOW.repeat(Math.max(0, trials - settled)))}`;
|
|
135
|
+
};
|
|
136
|
+
const rateOf = (cell) => {
|
|
137
|
+
const rate = cell.distribution?.passRate;
|
|
138
|
+
if (rate === void 0 || cell.distribution?.scored === 0) return paint(DIM, "—");
|
|
139
|
+
const shown = `${Math.round(rate * PERCENT)}%`;
|
|
140
|
+
return paint(rate === 1 ? GREEN : RED, shown);
|
|
141
|
+
};
|
|
142
|
+
const variantOf = (run, cell) => {
|
|
143
|
+
const task = run.tasks[cell.taskIndex];
|
|
144
|
+
return task === void 0 ? "?" : `${task.harness}/${task.model}`;
|
|
145
|
+
};
|
|
146
|
+
const widest = (run) => run.cells.reduce((width, cell) => Math.max(width, variantOf(run, cell).length), 0);
|
|
147
|
+
const gridOf = (run, trials, elapsedMs) => {
|
|
148
|
+
const width = widest(run);
|
|
149
|
+
const lines = [];
|
|
150
|
+
for (const caseName of run.cases) {
|
|
151
|
+
lines.push(` ${BOLD}${caseName}${RESET}`);
|
|
152
|
+
for (const cell of run.cells.filter((one) => one.caseName === caseName)) lines.push(` ${markOf(cell)} ${variantOf(run, cell).padEnd(width)} ${trialsOf(cell, trials)} ${rateOf(cell)}`);
|
|
153
|
+
lines.push("");
|
|
154
|
+
}
|
|
155
|
+
lines.push(paint(DIM, ` ${elapsedOf(elapsedMs)} elapsed`));
|
|
156
|
+
return lines;
|
|
157
|
+
};
|
|
158
|
+
const up = (rows) => `[${rows}A[0J`;
|
|
159
|
+
const liveGrid = (trials, interactive) => Effect.gen(function* () {
|
|
160
|
+
const drawn = yield* Ref.make(0);
|
|
161
|
+
return (run, elapsedMs) => Effect.gen(function* () {
|
|
162
|
+
if (!interactive) return;
|
|
163
|
+
const rows = yield* Ref.getAndSet(drawn, 0);
|
|
164
|
+
const lines = gridOf(run, trials, elapsedMs);
|
|
165
|
+
yield* note(`${rows === 0 ? "" : up(rows)}${lines.join("\n")}`);
|
|
166
|
+
yield* Ref.set(drawn, lines.length);
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
const summaryOf = (run, trials, drawn) => drawn ? "" : gridOf(run, trials, 0).join("\n");
|
|
170
|
+
//#endregion
|
|
171
|
+
//#region src/cli/eval-run.ts
|
|
172
|
+
const FIRST_POLL = 2e3;
|
|
173
|
+
const SLOWEST_POLL = 1e4;
|
|
174
|
+
const WIDENING = 1.5;
|
|
175
|
+
const running = ({ run }) => run === null || run.status === "running";
|
|
176
|
+
const widen = (gap) => Math.min(Math.round(gap * WIDENING), SLOWEST_POLL);
|
|
177
|
+
const waitForRun = (id, onProgress) => Effect.gen(function* () {
|
|
178
|
+
const api = yield* AnpordApi;
|
|
179
|
+
const startedAt = yield* Clock.currentTimeMillis;
|
|
180
|
+
const step = ({ gap, run }) => Effect.gen(function* () {
|
|
181
|
+
if (run !== null) yield* Effect.sleep(Duration.millis(gap));
|
|
182
|
+
const next = yield* api.evals.get({ payload: { id } });
|
|
183
|
+
yield* onProgress(next, (yield* Clock.currentTimeMillis) - startedAt);
|
|
184
|
+
return {
|
|
185
|
+
gap: widen(gap),
|
|
186
|
+
run: next
|
|
187
|
+
};
|
|
188
|
+
});
|
|
189
|
+
const { run } = yield* Effect.iterate({
|
|
190
|
+
gap: FIRST_POLL,
|
|
191
|
+
run: null
|
|
192
|
+
}, {
|
|
193
|
+
body: step,
|
|
194
|
+
while: running
|
|
195
|
+
});
|
|
196
|
+
return run ?? (yield* api.evals.get({ payload: { id } }));
|
|
197
|
+
}).pipe(Effect.withSpan("Cli.waitForRun", { attributes: { runId: id } }));
|
|
18
198
|
//#endregion
|
|
19
199
|
//#region src/cli/commands.ts
|
|
20
200
|
const promptId = Args.text({ name: "id" }).pipe(Args.withDescription("The prompt's id, such as support-reply"), Args.withSchema(PromptId));
|
|
@@ -38,7 +218,7 @@ const get = Command.make("get", {
|
|
|
38
218
|
const list = Command.make("list", { asJson }, ({ asJson: wantsJson }) => Effect.gen(function* () {
|
|
39
219
|
const { data } = yield* (yield* AnpordApi).prompts.list({ payload: {} });
|
|
40
220
|
if (wantsJson) return yield* json(data);
|
|
41
|
-
return yield* Effect.forEach(data, (
|
|
221
|
+
return yield* Effect.forEach(data, (summary) => row(`${summary.id}\tv${summary.latestVersion ?? "-"}\t${summary.name}`));
|
|
42
222
|
})).pipe(Command.withDescription("List every prompt"));
|
|
43
223
|
const versions = Command.make("versions", { promptId }, ({ promptId: id }) => Effect.gen(function* () {
|
|
44
224
|
const prompt = yield* (yield* AnpordApi).prompts.get({ payload: {
|
|
@@ -59,25 +239,100 @@ const promote = Command.make("promote", {
|
|
|
59
239
|
} });
|
|
60
240
|
return yield* note(`${id} v${pin} is now ${to}`);
|
|
61
241
|
})).pipe(Command.withDescription("Point a channel at a version"));
|
|
62
|
-
|
|
242
|
+
/**
|
|
243
|
+
* Read from the stream rather than by opening `/dev/stdin` as a file. The path
|
|
244
|
+
* only names the pipe, so reading it races whoever is writing: a body arriving
|
|
245
|
+
* in more than one chunk, which is what a pipe does under load, was read as
|
|
246
|
+
* whatever had landed by then.
|
|
247
|
+
*/
|
|
248
|
+
const readStdin = Effect.async((resume) => {
|
|
249
|
+
let body = "";
|
|
250
|
+
process.stdin.setEncoding("utf8");
|
|
251
|
+
process.stdin.on("data", (chunk) => {
|
|
252
|
+
body += chunk;
|
|
253
|
+
});
|
|
254
|
+
process.stdin.on("end", () => resume(Effect.succeed(body)));
|
|
255
|
+
process.stdin.on("error", (cause) => resume(Effect.fail(new Error("Could not read the content from stdin", { cause }))));
|
|
256
|
+
});
|
|
63
257
|
const target = Args.all([promptId, Args.text({ name: "content" }).pipe(Args.withDescription("The new content, or - to read stdin"))]);
|
|
258
|
+
const push = Command.make("push", {
|
|
259
|
+
message,
|
|
260
|
+
target
|
|
261
|
+
}, ({ message: why, target: [id, content] }) => Effect.gen(function* () {
|
|
262
|
+
const api = yield* AnpordApi;
|
|
263
|
+
const body = content === "-" ? yield* readStdin : content;
|
|
264
|
+
const prompt = yield* api.prompts.update({ payload: {
|
|
265
|
+
content: body,
|
|
266
|
+
id,
|
|
267
|
+
message: Option.getOrUndefined(why)
|
|
268
|
+
} });
|
|
269
|
+
return yield* note(`${id} is now v${prompt.version}`);
|
|
270
|
+
})).pipe(Command.withDescription("Add a version to a prompt"));
|
|
271
|
+
const out = Options.file("out").pipe(Options.withDescription("Where to write the declarations"), Options.withDefault("anpord-env.d.ts"));
|
|
272
|
+
/** Reading one prompt at a time because the list carries no content, bounded
|
|
273
|
+
* so a large organisation does not open a connection per prompt. */
|
|
274
|
+
const READ_AT_ONCE = 8;
|
|
275
|
+
const writeDeclarations = ({ out: path }) => Effect.gen(function* () {
|
|
276
|
+
const api = yield* AnpordApi;
|
|
277
|
+
const fs = yield* FileSystem.FileSystem;
|
|
278
|
+
const { data } = yield* api.prompts.list({ payload: {} });
|
|
279
|
+
const prompts = yield* Effect.forEach(data, (summary) => api.prompts.get({ payload: { id: summary.id } }).pipe(Effect.map((prompt) => [prompt.id, extractVariables(prompt.content)])), { concurrency: READ_AT_ONCE });
|
|
280
|
+
yield* fs.writeFileString(path, declarationFile(prompts));
|
|
281
|
+
return yield* note(`Wrote ${prompts.length} ${prompts.length === 1 ? "prompt" : "prompts"} to ${path}`);
|
|
282
|
+
});
|
|
283
|
+
const DESCRIPTION = "Write TypeScript declarations for prompt variables";
|
|
284
|
+
const generate = Command.make("generate", { out }, writeDeclarations).pipe(Command.withDescription(DESCRIPTION));
|
|
285
|
+
/** A second command rather than an alias, because a command carries one name
|
|
286
|
+
* and the shorter one is what anybody types twice. */
|
|
287
|
+
const gen = Command.make("gen", { out }, writeDeclarations).pipe(Command.withDescription(DESCRIPTION));
|
|
288
|
+
const evalFile = Args.text({ name: "file" }).pipe(Args.withDescription("A TypeScript file that default exports defineEval(...); every *.eval.ts is run when omitted"), Args.optional);
|
|
289
|
+
const noWait = Options.boolean("no-wait").pipe(Options.withDescription("Start the run and print its id, without waiting"));
|
|
290
|
+
const failOn = Options.choice("fail-on", [
|
|
291
|
+
"never",
|
|
292
|
+
"regressed",
|
|
293
|
+
"unscored"
|
|
294
|
+
]).pipe(Options.withDescription("What makes the command exit nonzero"), Options.withDefault("regressed"));
|
|
295
|
+
const runOneEval = (file, options) => Effect.gen(function* () {
|
|
296
|
+
const api = yield* AnpordApi;
|
|
297
|
+
const payload = yield* compileEvalEffect(file);
|
|
298
|
+
const started = yield* api.evals.start({ payload });
|
|
299
|
+
if (options.skipWait) {
|
|
300
|
+
yield* json(started);
|
|
301
|
+
return [];
|
|
302
|
+
}
|
|
303
|
+
const live = !options.wantsJson && (yield* attended);
|
|
304
|
+
if (live || options.label) yield* note(`${file} · run ${started.id}`);
|
|
305
|
+
const draw = yield* liveGrid(payload.trials, live);
|
|
306
|
+
const run = yield* waitForRun(started.id, draw);
|
|
307
|
+
yield* options.wantsJson ? json(run) : note(summaryOf(run, payload.trials, live));
|
|
308
|
+
return problemsWith(run, options.gate);
|
|
309
|
+
});
|
|
64
310
|
const commands = [
|
|
311
|
+
Command.make("eval", {
|
|
312
|
+
asJson,
|
|
313
|
+
evalFile,
|
|
314
|
+
failOn,
|
|
315
|
+
noWait
|
|
316
|
+
}, ({ asJson: wantsJson, evalFile: file, failOn: gate, noWait: skipWait }) => Effect.gen(function* () {
|
|
317
|
+
const files = yield* Option.match(file, {
|
|
318
|
+
onNone: () => evalFilesIn("."),
|
|
319
|
+
onSome: (one) => Effect.succeed([one])
|
|
320
|
+
});
|
|
321
|
+
if (files.length === 0) return yield* Effect.fail(new NoEvalFiles());
|
|
322
|
+
const found = yield* Effect.forEach(files, (one) => runOneEval(one, {
|
|
323
|
+
gate,
|
|
324
|
+
label: files.length > 1,
|
|
325
|
+
skipWait,
|
|
326
|
+
wantsJson
|
|
327
|
+
}));
|
|
328
|
+
return yield* failWhen(found.flat());
|
|
329
|
+
})).pipe(Command.withDescription("Compile and run an eval from TypeScript")),
|
|
330
|
+
gen,
|
|
331
|
+
generate,
|
|
65
332
|
get,
|
|
66
333
|
list,
|
|
67
334
|
promote,
|
|
68
|
-
|
|
69
|
-
message,
|
|
70
|
-
target
|
|
71
|
-
}, ({ message: why, target: [id, content] }) => Effect.gen(function* () {
|
|
72
|
-
const api = yield* AnpordApi;
|
|
73
|
-
const body = content === "-" ? yield* readStdin : content;
|
|
74
|
-
const prompt = yield* api.prompts.update({ payload: {
|
|
75
|
-
content: body,
|
|
76
|
-
id,
|
|
77
|
-
message: Option.getOrUndefined(why)
|
|
78
|
-
} });
|
|
79
|
-
return yield* note(`${id} is now v${prompt.version}`);
|
|
80
|
-
})).pipe(Command.withDescription("Add a version to a prompt")),
|
|
335
|
+
push,
|
|
81
336
|
versions
|
|
82
337
|
];
|
|
83
338
|
//#endregion
|
|
@@ -94,11 +349,11 @@ const reportFailure = (error) => Effect.sync(() => {
|
|
|
94
349
|
});
|
|
95
350
|
//#endregion
|
|
96
351
|
//#region src/cli/main.ts
|
|
97
|
-
const anpord = Command.make("anpord").pipe(Command.withDescription("
|
|
352
|
+
const anpord = Command.make("anpord").pipe(Command.withDescription("Run evals and manage prompts from the terminal"), Command.withSubcommands(commands));
|
|
98
353
|
const ClientLayer = Layer.unwrapEffect(Effect.map(clientOptionsConfig, layer));
|
|
99
354
|
Command.run(anpord, {
|
|
100
355
|
name: "Anpord",
|
|
101
|
-
version:
|
|
356
|
+
version: version$1
|
|
102
357
|
})(process.argv).pipe(Effect.provide(Layer.mergeAll(ClientLayer, NodeContext.layer)), Effect.catchAllCause((cause) => Cause.isInterruptedOnly(cause) ? Effect.void : reportFailure(Cause.failureOption(cause).pipe(Option.getOrElse(() => Cause.squash(cause))))), NodeRuntime.runMain({ disableErrorReporting: true }));
|
|
103
358
|
//#endregion
|
|
104
359
|
export {};
|