anpord 0.1.22 → 0.1.24
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/dist/api-context.d.cts +1 -1
- package/dist/api-context.d.mts +1 -1
- package/dist/{api-mocks-B8a93t2t.d.cts → api-mocks-ofqP55P_.d.cts} +8 -8
- package/dist/{api-mocks-B8a93t2t.d.mts → api-mocks-ofqP55P_.d.mts} +8 -8
- package/dist/api-runtime.d.cts +1 -1
- package/dist/api-runtime.d.mts +1 -1
- package/dist/api.d.cts +1 -1
- package/dist/api.d.mts +1 -1
- package/dist/bin.cjs +101 -11
- package/dist/bin.mjs +101 -11
- package/dist/{client-CE9VurDH.d.cts → client-B3LQU8cc.d.cts} +668 -668
- package/dist/{client-EdYxRHX0.d.mts → client-Cg1qFD01.d.mts} +668 -668
- package/dist/config.d.cts +1 -1
- package/dist/config.d.mts +1 -1
- package/dist/{eval-turns-Uwe0G7PS.d.cts → eval-turns-CTCoSuB6.d.cts} +1 -1
- package/dist/{eval-turns-Uwe0G7PS.d.mts → eval-turns-CTCoSuB6.d.mts} +1 -1
- package/dist/eval.d.cts +1 -1
- package/dist/eval.d.mts +1 -1
- package/dist/{evals-M2G4zvnS.d.cts → evals-Dw2Ek-mx.d.cts} +36 -36
- package/dist/{evals-M2G4zvnS.d.mts → evals-Dw2Ek-mx.d.mts} +36 -36
- package/dist/index.d.cts +3 -3
- package/dist/index.d.mts +3 -3
- package/dist/source.d.cts +1 -1
- package/dist/source.d.mts +1 -1
- package/dist/{types-C1Np-yYM.d.cts → types-BnCBSiXY.d.cts} +16 -16
- package/dist/{types-B1rRGWeL.d.mts → types-DiNkJRDh.d.mts} +16 -16
- package/dist/validator-runtime.d.cts +1 -1
- package/dist/validator-runtime.d.mts +1 -1
- package/dist/validators.d.cts +1 -1
- package/dist/validators.d.mts +1 -1
- package/package.json +1 -1
package/dist/api-context.d.cts
CHANGED
package/dist/api-context.d.mts
CHANGED
|
@@ -58,6 +58,14 @@ declare const ApiCall_base: Schema.Class<ApiCall, {
|
|
|
58
58
|
}>>>;
|
|
59
59
|
}>, never, {
|
|
60
60
|
readonly api: string;
|
|
61
|
+
} & {
|
|
62
|
+
readonly status: number;
|
|
63
|
+
} & {
|
|
64
|
+
readonly startedAt: number;
|
|
65
|
+
} & {
|
|
66
|
+
readonly path: string;
|
|
67
|
+
} & {
|
|
68
|
+
readonly index: number;
|
|
61
69
|
} & {
|
|
62
70
|
readonly output: {
|
|
63
71
|
readonly text: string;
|
|
@@ -72,14 +80,6 @@ declare const ApiCall_base: Schema.Class<ApiCall, {
|
|
|
72
80
|
readonly format: "text" | "json";
|
|
73
81
|
readonly state: "captured" | "disabled" | "unavailable";
|
|
74
82
|
};
|
|
75
|
-
} & {
|
|
76
|
-
readonly status: number;
|
|
77
|
-
} & {
|
|
78
|
-
readonly startedAt: number;
|
|
79
|
-
} & {
|
|
80
|
-
readonly path: string;
|
|
81
|
-
} & {
|
|
82
|
-
readonly index: number;
|
|
83
83
|
} & {
|
|
84
84
|
readonly error: string | null;
|
|
85
85
|
} & {
|
|
@@ -58,6 +58,14 @@ declare const ApiCall_base: Schema.Class<ApiCall, {
|
|
|
58
58
|
}>>>;
|
|
59
59
|
}>, never, {
|
|
60
60
|
readonly api: string;
|
|
61
|
+
} & {
|
|
62
|
+
readonly status: number;
|
|
63
|
+
} & {
|
|
64
|
+
readonly startedAt: number;
|
|
65
|
+
} & {
|
|
66
|
+
readonly path: string;
|
|
67
|
+
} & {
|
|
68
|
+
readonly index: number;
|
|
61
69
|
} & {
|
|
62
70
|
readonly output: {
|
|
63
71
|
readonly text: string;
|
|
@@ -72,14 +80,6 @@ declare const ApiCall_base: Schema.Class<ApiCall, {
|
|
|
72
80
|
readonly format: "text" | "json";
|
|
73
81
|
readonly state: "captured" | "disabled" | "unavailable";
|
|
74
82
|
};
|
|
75
|
-
} & {
|
|
76
|
-
readonly status: number;
|
|
77
|
-
} & {
|
|
78
|
-
readonly startedAt: number;
|
|
79
|
-
} & {
|
|
80
|
-
readonly path: string;
|
|
81
|
-
} & {
|
|
82
|
-
readonly index: number;
|
|
83
83
|
} & {
|
|
84
84
|
readonly error: string | null;
|
|
85
85
|
} & {
|
package/dist/api-runtime.d.cts
CHANGED
package/dist/api-runtime.d.mts
CHANGED
package/dist/api.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as ApiCall } from "./api-mocks-
|
|
1
|
+
import { t as ApiCall } from "./api-mocks-ofqP55P_.cjs";
|
|
2
2
|
import { a as endpoint, i as api, n as ApiHandlerContext, r as EndpointDefinition, t as ApiDefinition } from "./define-NZvmQuIv.cjs";
|
|
3
3
|
import { withApi } from "./api-runtime.cjs";
|
|
4
4
|
export { type ApiCall, type ApiDefinition, type ApiHandlerContext, type EndpointDefinition, api, endpoint, withApi };
|
package/dist/api.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as ApiCall } from "./api-mocks-
|
|
1
|
+
import { t as ApiCall } from "./api-mocks-ofqP55P_.mjs";
|
|
2
2
|
import { a as endpoint, i as api, n as ApiHandlerContext, r as EndpointDefinition, t as ApiDefinition } from "./define-NZvmQuIv.mjs";
|
|
3
3
|
import { withApi } from "./api-runtime.mjs";
|
|
4
4
|
export { type ApiCall, type ApiDefinition, type ApiHandlerContext, type EndpointDefinition, api, endpoint, withApi };
|
package/dist/bin.cjs
CHANGED
|
@@ -19,7 +19,7 @@ let yaml = require("yaml");
|
|
|
19
19
|
let node_crypto = require("node:crypto");
|
|
20
20
|
let node_child_process = require("node:child_process");
|
|
21
21
|
//#region package.json
|
|
22
|
-
var version$1 = "0.1.
|
|
22
|
+
var version$1 = "0.1.24";
|
|
23
23
|
//#endregion
|
|
24
24
|
//#region ../template/src/extract.ts
|
|
25
25
|
/** Reads escapes too, so text the renderer leaves literal is never reported as
|
|
@@ -220,6 +220,86 @@ var NoEvalFiles = class extends effect.Data.TaggedError("NoEvalFiles") {
|
|
|
220
220
|
}
|
|
221
221
|
};
|
|
222
222
|
//#endregion
|
|
223
|
+
//#region ../schema/src/domain/usage-health.ts
|
|
224
|
+
const CACHE_FLOOR = 5e4;
|
|
225
|
+
const PER_TURN_CEILING = 12e3;
|
|
226
|
+
const perTurnInput = ({ turns, usage }) => turns <= 0 ? usage.inputTokens : Math.round(usage.inputTokens / turns);
|
|
227
|
+
const usageConcerns = (reading) => {
|
|
228
|
+
const { usage } = reading;
|
|
229
|
+
const served = usage.inputTokens + usage.cacheReadTokens;
|
|
230
|
+
const concerns = [];
|
|
231
|
+
if (perTurnInput(reading) >= PER_TURN_CEILING) concerns.push("context-grew-fast");
|
|
232
|
+
if (served >= CACHE_FLOOR && usage.cacheReadTokens === 0) concerns.push("nothing-cached");
|
|
233
|
+
return concerns;
|
|
234
|
+
};
|
|
235
|
+
const CONCERN_REASONS = {
|
|
236
|
+
"context-grew-fast": "Each turn carried a large context, which is what happens when an agent reads a dependency or a long file into the conversation and then re-sends it every turn after.",
|
|
237
|
+
"nothing-cached": "Nothing was served from cache, so every turn paid full price for the turns before it."
|
|
238
|
+
};
|
|
239
|
+
//#endregion
|
|
240
|
+
//#region src/cli/eval-usage.ts
|
|
241
|
+
const THOUSAND = 1e3;
|
|
242
|
+
const MILLION = 1e6;
|
|
243
|
+
const CENT = .01;
|
|
244
|
+
const trialsOf = (run) => run.cells.flatMap((cell) => cell.trials);
|
|
245
|
+
const runUsage = (run) => {
|
|
246
|
+
const concerns = /* @__PURE__ */ new Set();
|
|
247
|
+
let inputTokens = 0;
|
|
248
|
+
let outputTokens = 0;
|
|
249
|
+
let totalTokens = 0;
|
|
250
|
+
for (const trial of trialsOf(run)) {
|
|
251
|
+
if (!trial.usage) continue;
|
|
252
|
+
inputTokens += trial.usage.inputTokens;
|
|
253
|
+
outputTokens += trial.usage.outputTokens;
|
|
254
|
+
totalTokens += trial.usage.totalTokens;
|
|
255
|
+
for (const concern of usageConcerns({
|
|
256
|
+
turns: trial.commands,
|
|
257
|
+
usage: trial.usage
|
|
258
|
+
})) concerns.add(concern);
|
|
259
|
+
}
|
|
260
|
+
return {
|
|
261
|
+
concerns: [...concerns],
|
|
262
|
+
inputTokens,
|
|
263
|
+
outputTokens,
|
|
264
|
+
totalTokens,
|
|
265
|
+
usd: run.costs?.estimatedEquivalentUsd ?? null
|
|
266
|
+
};
|
|
267
|
+
};
|
|
268
|
+
const formatTokens = (value) => {
|
|
269
|
+
if (value >= MILLION) return `${(value / MILLION).toFixed(1)}M`;
|
|
270
|
+
return value >= THOUSAND ? `${Math.round(value / THOUSAND)}k` : String(value);
|
|
271
|
+
};
|
|
272
|
+
const formatUsd = (value) => value < CENT ? "<$0.01" : `$${value.toFixed(2)}`;
|
|
273
|
+
const usageLines = (usage) => {
|
|
274
|
+
if (usage.totalTokens === 0) return [];
|
|
275
|
+
const spend = usage.usd === null ? "" : `, ${formatUsd(usage.usd)} est.`;
|
|
276
|
+
return [`${formatTokens(usage.totalTokens)} tokens (${formatTokens(usage.inputTokens)} in, ${formatTokens(usage.outputTokens)} out)${spend}`, ...usage.concerns.map((concern) => CONCERN_REASONS[concern])];
|
|
277
|
+
};
|
|
278
|
+
const localUsage = (cases) => {
|
|
279
|
+
const concerns = /* @__PURE__ */ new Set();
|
|
280
|
+
let inputTokens = 0;
|
|
281
|
+
let outputTokens = 0;
|
|
282
|
+
let totalTokens = 0;
|
|
283
|
+
for (const one of cases) {
|
|
284
|
+
if (!one.usage) continue;
|
|
285
|
+
inputTokens += one.usage.inputTokens;
|
|
286
|
+
outputTokens += one.usage.outputTokens;
|
|
287
|
+
totalTokens += one.usage.inputTokens + one.usage.outputTokens;
|
|
288
|
+
for (const concern of usageConcerns({
|
|
289
|
+
turns: one.turns,
|
|
290
|
+
usage: one.usage
|
|
291
|
+
})) concerns.add(concern);
|
|
292
|
+
}
|
|
293
|
+
return {
|
|
294
|
+
concerns: [...concerns],
|
|
295
|
+
inputTokens,
|
|
296
|
+
outputTokens,
|
|
297
|
+
totalTokens,
|
|
298
|
+
usd: null
|
|
299
|
+
};
|
|
300
|
+
};
|
|
301
|
+
const localUsageLines = (cases) => usageLines(localUsage(cases)).map((line) => ` ${line}`);
|
|
302
|
+
//#endregion
|
|
223
303
|
//#region src/cli/eval-grid.ts
|
|
224
304
|
const DIM = "\x1B[2m";
|
|
225
305
|
const BOLD = "\x1B[1m";
|
|
@@ -289,7 +369,10 @@ const formatGrid = (run, trials, elapsedMs) => {
|
|
|
289
369
|
}
|
|
290
370
|
lines.push("");
|
|
291
371
|
}
|
|
292
|
-
|
|
372
|
+
const usage = runUsage(run);
|
|
373
|
+
const [spend, ...concerns] = usageLines(usage);
|
|
374
|
+
lines.push(paint(DIM, spend === void 0 ? ` ${formatElapsed(elapsedMs)} elapsed` : ` ${formatElapsed(elapsedMs)} elapsed · ${spend}`));
|
|
375
|
+
for (const concern of concerns) lines.push(paint(YELLOW, ` ${concern}`));
|
|
293
376
|
return lines;
|
|
294
377
|
};
|
|
295
378
|
const up = (rows) => `[${rows}A[0J`;
|
|
@@ -4485,7 +4568,7 @@ const SandboxProviderLive = effect.Layer.effect(SandboxProvider, effect.Effect.g
|
|
|
4485
4568
|
//#endregion
|
|
4486
4569
|
//#region ../eval/src/local-layer.ts
|
|
4487
4570
|
const LocalAdaptersLive = effect.Layer.effect(SandboxAdapters, effect.Effect.map(effect.Effect.cached(makeLocalAdapter), (local) => SandboxAdapters.of({ resolve: (provider) => provider === "local" ? local : effect.Effect.dieMessage(`a local run cannot open a ${provider} sandbox`) })));
|
|
4488
|
-
const evalLocalWith = (credentials) => LocalTrialsLive.pipe(effect.Layer.provide(AgentTrialJudgedLive.pipe(effect.Layer.provide(AgentTrialLive.pipe(effect.Layer.provide(ScorerChecksLive.pipe(effect.Layer.provide(ScorerGroundTruthLive))), effect.Layer.provide(SuspenderSleeping), effect.Layer.provide(SimulatedUserLive.pipe(effect.Layer.provide(_effect_platform.FetchHttpClient.layer))))), effect.Layer.provide(JudgeModelLive.pipe(effect.Layer.provide(_effect_platform.FetchHttpClient.layer))), effect.Layer.provide(effect.Layer.mergeAll(HarnessesLive, HarnessVersionsLive)))), effect.Layer.provide(credentials), effect.Layer.provide(SandboxProviderLive.pipe(effect.Layer.provide(LocalAdaptersLive))));
|
|
4571
|
+
const evalLocalWith = (credentials) => LocalTrialsLive.pipe(effect.Layer.provide(AgentTrialJudgedLive.pipe(effect.Layer.provide(AgentTrialLive.pipe(effect.Layer.provide(ScorerChecksLive.pipe(effect.Layer.provide(ScorerGroundTruthLive))), effect.Layer.provide(SuspenderSleeping), effect.Layer.provide(SimulatedUserLive.pipe(effect.Layer.provide(_effect_platform.FetchHttpClient.layer))))), effect.Layer.provide(JudgeModelLive.pipe(effect.Layer.provide(_effect_platform.FetchHttpClient.layer))), effect.Layer.provide(effect.Layer.mergeAll(HarnessesLive, HarnessVersionsLive)))), effect.Layer.provide(credentials), effect.Layer.provide(SandboxProviderLive.pipe(effect.Layer.provide(LocalAdaptersLive))), effect.Layer.provideMerge(HarnessVersionsLive));
|
|
4489
4572
|
const EvalLocalLive = evalLocalWith(CredentialResolverFromEnv);
|
|
4490
4573
|
//#endregion
|
|
4491
4574
|
//#region src/cli/local-env.ts
|
|
@@ -4514,19 +4597,21 @@ const localEnv = (directory) => Object.assign({}, ...FILES.map((file) => read(di
|
|
|
4514
4597
|
//#region src/cli/eval-local.ts
|
|
4515
4598
|
const runLocally = (request, options = {}) => effect.Effect.gen(function* () {
|
|
4516
4599
|
const trials = yield* LocalTrials;
|
|
4600
|
+
const versions = yield* HarnessVersions;
|
|
4517
4601
|
const forwarded = localEnv(process.cwd());
|
|
4518
4602
|
const task = request.tasks[0];
|
|
4519
4603
|
if (task === void 0) return [];
|
|
4604
|
+
const harnessVersion = yield* versions.version(task.harness);
|
|
4520
4605
|
return yield* effect.Effect.forEach(request.cases, (subject) => trials.run({
|
|
4521
4606
|
caseName: subject.name,
|
|
4522
4607
|
forwarded,
|
|
4523
4608
|
harness: task.harness,
|
|
4524
|
-
harnessVersion
|
|
4609
|
+
harnessVersion,
|
|
4525
4610
|
model: task.model,
|
|
4526
4611
|
prepare: subject.prepare ?? null,
|
|
4527
4612
|
profile: profileOfRequest(task.profile),
|
|
4528
4613
|
prompt: request.prompt,
|
|
4529
|
-
source: { kind: "empty" },
|
|
4614
|
+
source: subject.source ?? { kind: "empty" },
|
|
4530
4615
|
user: subject.user ?? null,
|
|
4531
4616
|
validator: subject.validator ?? null,
|
|
4532
4617
|
verifyCommand: subject.verify
|
|
@@ -4541,11 +4626,17 @@ const runLocally = (request, options = {}) => effect.Effect.gen(function* () {
|
|
|
4541
4626
|
}) ?? effect.Effect.void), effect.Effect.map((outcome) => ({
|
|
4542
4627
|
durationMs: outcome.durationMs,
|
|
4543
4628
|
name: subject.name,
|
|
4544
|
-
status: outcome.outcome.status
|
|
4629
|
+
status: outcome.outcome.status,
|
|
4630
|
+
turns: outcome.outcome.commandCount,
|
|
4631
|
+
usage: effect.Option.getOrNull(outcome.result.usage)
|
|
4545
4632
|
}))), { concurrency: 1 });
|
|
4546
4633
|
}).pipe(effect.Effect.provide(options.credentials === void 0 ? EvalLocalLive : evalLocalWith(credentialResolverFrom(options.credentials))), effect.Effect.scoped, effect.Effect.withConfigProvider(effect.ConfigProvider.fromEnv().pipe(effect.ConfigProvider.orElse(() => effect.ConfigProvider.fromMap(/* @__PURE__ */ new Map([["ANPORD_LOCAL_SANDBOX", "true"]]))))));
|
|
4547
4634
|
const seconds = (ms) => `${(ms / 1e3).toFixed(1)}s`;
|
|
4548
|
-
const reportLocal = (file, cases) => effect.Effect.forEach([
|
|
4635
|
+
const reportLocal = (file, cases) => effect.Effect.forEach([
|
|
4636
|
+
`${file}: ${cases.length} case(s) on this machine`,
|
|
4637
|
+
...cases.map((one) => ` ${one.status} ${one.name} ${seconds(one.durationMs)}`),
|
|
4638
|
+
...localUsageLines(cases)
|
|
4639
|
+
], note);
|
|
4549
4640
|
const localProblems = (cases) => cases.flatMap((one) => one.status === "passed" ? [] : [`${one.name} ${one.status}`]);
|
|
4550
4641
|
//#endregion
|
|
4551
4642
|
//#region src/cli/eval-outcome.ts
|
|
@@ -4822,20 +4913,19 @@ const recordedLocally = (file) => effect.Effect.gen(function* () {
|
|
|
4822
4913
|
trigger
|
|
4823
4914
|
} });
|
|
4824
4915
|
yield* reportStarted(file, started.id);
|
|
4916
|
+
yield* effect.Effect.addFinalizer(() => api.evals.finishRun({ payload: { id: started.id } }).pipe(effect.Effect.ignore));
|
|
4825
4917
|
const leased = yield* api.evals.credentials({ payload: {
|
|
4826
4918
|
harness: payload.tasks[0]?.harness ?? "codex",
|
|
4827
4919
|
id: started.id
|
|
4828
4920
|
} }).pipe(effect.Effect.map((lease) => lease.values), effect.Effect.catchAll(() => effect.Effect.succeed(void 0)));
|
|
4829
|
-
|
|
4921
|
+
return yield* runLocally(payload, {
|
|
4830
4922
|
credentials: leased,
|
|
4831
4923
|
onTrial: (trial) => api.evals.reportTrial({ payload: {
|
|
4832
4924
|
id: started.id,
|
|
4833
4925
|
trial
|
|
4834
4926
|
} }).pipe(effect.Effect.ignore)
|
|
4835
4927
|
});
|
|
4836
|
-
|
|
4837
|
-
return cases;
|
|
4838
|
-
}).pipe(effect.Effect.provide(require_config.ClientLayer));
|
|
4928
|
+
}).pipe(effect.Effect.scoped, effect.Effect.provide(require_config.ClientLayer));
|
|
4839
4929
|
const runOneEvalLocally = (file) => require_config.apiKeyConfig.pipe(effect.Effect.matchEffect({
|
|
4840
4930
|
onFailure: () => require_compiler.compileEvalEffect(file).pipe(effect.Effect.flatMap((payload) => runLocally(payload))),
|
|
4841
4931
|
onSuccess: () => recordedLocally(file)
|
package/dist/bin.mjs
CHANGED
|
@@ -19,7 +19,7 @@ import { parseDocument } from "yaml";
|
|
|
19
19
|
import { createHash } from "node:crypto";
|
|
20
20
|
import { spawn } from "node:child_process";
|
|
21
21
|
//#region package.json
|
|
22
|
-
var version$1 = "0.1.
|
|
22
|
+
var version$1 = "0.1.24";
|
|
23
23
|
//#endregion
|
|
24
24
|
//#region ../template/src/extract.ts
|
|
25
25
|
/** Reads escapes too, so text the renderer leaves literal is never reported as
|
|
@@ -220,6 +220,86 @@ var NoEvalFiles = class extends Data.TaggedError("NoEvalFiles") {
|
|
|
220
220
|
}
|
|
221
221
|
};
|
|
222
222
|
//#endregion
|
|
223
|
+
//#region ../schema/src/domain/usage-health.ts
|
|
224
|
+
const CACHE_FLOOR = 5e4;
|
|
225
|
+
const PER_TURN_CEILING = 12e3;
|
|
226
|
+
const perTurnInput = ({ turns, usage }) => turns <= 0 ? usage.inputTokens : Math.round(usage.inputTokens / turns);
|
|
227
|
+
const usageConcerns = (reading) => {
|
|
228
|
+
const { usage } = reading;
|
|
229
|
+
const served = usage.inputTokens + usage.cacheReadTokens;
|
|
230
|
+
const concerns = [];
|
|
231
|
+
if (perTurnInput(reading) >= PER_TURN_CEILING) concerns.push("context-grew-fast");
|
|
232
|
+
if (served >= CACHE_FLOOR && usage.cacheReadTokens === 0) concerns.push("nothing-cached");
|
|
233
|
+
return concerns;
|
|
234
|
+
};
|
|
235
|
+
const CONCERN_REASONS = {
|
|
236
|
+
"context-grew-fast": "Each turn carried a large context, which is what happens when an agent reads a dependency or a long file into the conversation and then re-sends it every turn after.",
|
|
237
|
+
"nothing-cached": "Nothing was served from cache, so every turn paid full price for the turns before it."
|
|
238
|
+
};
|
|
239
|
+
//#endregion
|
|
240
|
+
//#region src/cli/eval-usage.ts
|
|
241
|
+
const THOUSAND = 1e3;
|
|
242
|
+
const MILLION = 1e6;
|
|
243
|
+
const CENT = .01;
|
|
244
|
+
const trialsOf = (run) => run.cells.flatMap((cell) => cell.trials);
|
|
245
|
+
const runUsage = (run) => {
|
|
246
|
+
const concerns = /* @__PURE__ */ new Set();
|
|
247
|
+
let inputTokens = 0;
|
|
248
|
+
let outputTokens = 0;
|
|
249
|
+
let totalTokens = 0;
|
|
250
|
+
for (const trial of trialsOf(run)) {
|
|
251
|
+
if (!trial.usage) continue;
|
|
252
|
+
inputTokens += trial.usage.inputTokens;
|
|
253
|
+
outputTokens += trial.usage.outputTokens;
|
|
254
|
+
totalTokens += trial.usage.totalTokens;
|
|
255
|
+
for (const concern of usageConcerns({
|
|
256
|
+
turns: trial.commands,
|
|
257
|
+
usage: trial.usage
|
|
258
|
+
})) concerns.add(concern);
|
|
259
|
+
}
|
|
260
|
+
return {
|
|
261
|
+
concerns: [...concerns],
|
|
262
|
+
inputTokens,
|
|
263
|
+
outputTokens,
|
|
264
|
+
totalTokens,
|
|
265
|
+
usd: run.costs?.estimatedEquivalentUsd ?? null
|
|
266
|
+
};
|
|
267
|
+
};
|
|
268
|
+
const formatTokens = (value) => {
|
|
269
|
+
if (value >= MILLION) return `${(value / MILLION).toFixed(1)}M`;
|
|
270
|
+
return value >= THOUSAND ? `${Math.round(value / THOUSAND)}k` : String(value);
|
|
271
|
+
};
|
|
272
|
+
const formatUsd = (value) => value < CENT ? "<$0.01" : `$${value.toFixed(2)}`;
|
|
273
|
+
const usageLines = (usage) => {
|
|
274
|
+
if (usage.totalTokens === 0) return [];
|
|
275
|
+
const spend = usage.usd === null ? "" : `, ${formatUsd(usage.usd)} est.`;
|
|
276
|
+
return [`${formatTokens(usage.totalTokens)} tokens (${formatTokens(usage.inputTokens)} in, ${formatTokens(usage.outputTokens)} out)${spend}`, ...usage.concerns.map((concern) => CONCERN_REASONS[concern])];
|
|
277
|
+
};
|
|
278
|
+
const localUsage = (cases) => {
|
|
279
|
+
const concerns = /* @__PURE__ */ new Set();
|
|
280
|
+
let inputTokens = 0;
|
|
281
|
+
let outputTokens = 0;
|
|
282
|
+
let totalTokens = 0;
|
|
283
|
+
for (const one of cases) {
|
|
284
|
+
if (!one.usage) continue;
|
|
285
|
+
inputTokens += one.usage.inputTokens;
|
|
286
|
+
outputTokens += one.usage.outputTokens;
|
|
287
|
+
totalTokens += one.usage.inputTokens + one.usage.outputTokens;
|
|
288
|
+
for (const concern of usageConcerns({
|
|
289
|
+
turns: one.turns,
|
|
290
|
+
usage: one.usage
|
|
291
|
+
})) concerns.add(concern);
|
|
292
|
+
}
|
|
293
|
+
return {
|
|
294
|
+
concerns: [...concerns],
|
|
295
|
+
inputTokens,
|
|
296
|
+
outputTokens,
|
|
297
|
+
totalTokens,
|
|
298
|
+
usd: null
|
|
299
|
+
};
|
|
300
|
+
};
|
|
301
|
+
const localUsageLines = (cases) => usageLines(localUsage(cases)).map((line) => ` ${line}`);
|
|
302
|
+
//#endregion
|
|
223
303
|
//#region src/cli/eval-grid.ts
|
|
224
304
|
const DIM = "\x1B[2m";
|
|
225
305
|
const BOLD = "\x1B[1m";
|
|
@@ -289,7 +369,10 @@ const formatGrid = (run, trials, elapsedMs) => {
|
|
|
289
369
|
}
|
|
290
370
|
lines.push("");
|
|
291
371
|
}
|
|
292
|
-
|
|
372
|
+
const usage = runUsage(run);
|
|
373
|
+
const [spend, ...concerns] = usageLines(usage);
|
|
374
|
+
lines.push(paint(DIM, spend === void 0 ? ` ${formatElapsed(elapsedMs)} elapsed` : ` ${formatElapsed(elapsedMs)} elapsed · ${spend}`));
|
|
375
|
+
for (const concern of concerns) lines.push(paint(YELLOW, ` ${concern}`));
|
|
293
376
|
return lines;
|
|
294
377
|
};
|
|
295
378
|
const up = (rows) => `[${rows}A[0J`;
|
|
@@ -4485,7 +4568,7 @@ const SandboxProviderLive = Layer.effect(SandboxProvider, Effect.gen(function* (
|
|
|
4485
4568
|
//#endregion
|
|
4486
4569
|
//#region ../eval/src/local-layer.ts
|
|
4487
4570
|
const LocalAdaptersLive = Layer.effect(SandboxAdapters, Effect.map(Effect.cached(makeLocalAdapter), (local) => SandboxAdapters.of({ resolve: (provider) => provider === "local" ? local : Effect.dieMessage(`a local run cannot open a ${provider} sandbox`) })));
|
|
4488
|
-
const evalLocalWith = (credentials) => LocalTrialsLive.pipe(Layer.provide(AgentTrialJudgedLive.pipe(Layer.provide(AgentTrialLive.pipe(Layer.provide(ScorerChecksLive.pipe(Layer.provide(ScorerGroundTruthLive))), Layer.provide(SuspenderSleeping), Layer.provide(SimulatedUserLive.pipe(Layer.provide(FetchHttpClient.layer))))), Layer.provide(JudgeModelLive.pipe(Layer.provide(FetchHttpClient.layer))), Layer.provide(Layer.mergeAll(HarnessesLive, HarnessVersionsLive)))), Layer.provide(credentials), Layer.provide(SandboxProviderLive.pipe(Layer.provide(LocalAdaptersLive))));
|
|
4571
|
+
const evalLocalWith = (credentials) => LocalTrialsLive.pipe(Layer.provide(AgentTrialJudgedLive.pipe(Layer.provide(AgentTrialLive.pipe(Layer.provide(ScorerChecksLive.pipe(Layer.provide(ScorerGroundTruthLive))), Layer.provide(SuspenderSleeping), Layer.provide(SimulatedUserLive.pipe(Layer.provide(FetchHttpClient.layer))))), Layer.provide(JudgeModelLive.pipe(Layer.provide(FetchHttpClient.layer))), Layer.provide(Layer.mergeAll(HarnessesLive, HarnessVersionsLive)))), Layer.provide(credentials), Layer.provide(SandboxProviderLive.pipe(Layer.provide(LocalAdaptersLive))), Layer.provideMerge(HarnessVersionsLive));
|
|
4489
4572
|
const EvalLocalLive = evalLocalWith(CredentialResolverFromEnv);
|
|
4490
4573
|
//#endregion
|
|
4491
4574
|
//#region src/cli/local-env.ts
|
|
@@ -4514,19 +4597,21 @@ const localEnv = (directory) => Object.assign({}, ...FILES.map((file) => read(di
|
|
|
4514
4597
|
//#region src/cli/eval-local.ts
|
|
4515
4598
|
const runLocally = (request, options = {}) => Effect.gen(function* () {
|
|
4516
4599
|
const trials = yield* LocalTrials;
|
|
4600
|
+
const versions = yield* HarnessVersions;
|
|
4517
4601
|
const forwarded = localEnv(process.cwd());
|
|
4518
4602
|
const task = request.tasks[0];
|
|
4519
4603
|
if (task === void 0) return [];
|
|
4604
|
+
const harnessVersion = yield* versions.version(task.harness);
|
|
4520
4605
|
return yield* Effect.forEach(request.cases, (subject) => trials.run({
|
|
4521
4606
|
caseName: subject.name,
|
|
4522
4607
|
forwarded,
|
|
4523
4608
|
harness: task.harness,
|
|
4524
|
-
harnessVersion
|
|
4609
|
+
harnessVersion,
|
|
4525
4610
|
model: task.model,
|
|
4526
4611
|
prepare: subject.prepare ?? null,
|
|
4527
4612
|
profile: profileOfRequest(task.profile),
|
|
4528
4613
|
prompt: request.prompt,
|
|
4529
|
-
source: { kind: "empty" },
|
|
4614
|
+
source: subject.source ?? { kind: "empty" },
|
|
4530
4615
|
user: subject.user ?? null,
|
|
4531
4616
|
validator: subject.validator ?? null,
|
|
4532
4617
|
verifyCommand: subject.verify
|
|
@@ -4541,11 +4626,17 @@ const runLocally = (request, options = {}) => Effect.gen(function* () {
|
|
|
4541
4626
|
}) ?? Effect.void), Effect.map((outcome) => ({
|
|
4542
4627
|
durationMs: outcome.durationMs,
|
|
4543
4628
|
name: subject.name,
|
|
4544
|
-
status: outcome.outcome.status
|
|
4629
|
+
status: outcome.outcome.status,
|
|
4630
|
+
turns: outcome.outcome.commandCount,
|
|
4631
|
+
usage: Option.getOrNull(outcome.result.usage)
|
|
4545
4632
|
}))), { concurrency: 1 });
|
|
4546
4633
|
}).pipe(Effect.provide(options.credentials === void 0 ? EvalLocalLive : evalLocalWith(credentialResolverFrom(options.credentials))), Effect.scoped, Effect.withConfigProvider(ConfigProvider.fromEnv().pipe(ConfigProvider.orElse(() => ConfigProvider.fromMap(/* @__PURE__ */ new Map([["ANPORD_LOCAL_SANDBOX", "true"]]))))));
|
|
4547
4634
|
const seconds = (ms) => `${(ms / 1e3).toFixed(1)}s`;
|
|
4548
|
-
const reportLocal = (file, cases) => Effect.forEach([
|
|
4635
|
+
const reportLocal = (file, cases) => Effect.forEach([
|
|
4636
|
+
`${file}: ${cases.length} case(s) on this machine`,
|
|
4637
|
+
...cases.map((one) => ` ${one.status} ${one.name} ${seconds(one.durationMs)}`),
|
|
4638
|
+
...localUsageLines(cases)
|
|
4639
|
+
], note);
|
|
4549
4640
|
const localProblems = (cases) => cases.flatMap((one) => one.status === "passed" ? [] : [`${one.name} ${one.status}`]);
|
|
4550
4641
|
//#endregion
|
|
4551
4642
|
//#region src/cli/eval-outcome.ts
|
|
@@ -4822,20 +4913,19 @@ const recordedLocally = (file) => Effect.gen(function* () {
|
|
|
4822
4913
|
trigger
|
|
4823
4914
|
} });
|
|
4824
4915
|
yield* reportStarted(file, started.id);
|
|
4916
|
+
yield* Effect.addFinalizer(() => api.evals.finishRun({ payload: { id: started.id } }).pipe(Effect.ignore));
|
|
4825
4917
|
const leased = yield* api.evals.credentials({ payload: {
|
|
4826
4918
|
harness: payload.tasks[0]?.harness ?? "codex",
|
|
4827
4919
|
id: started.id
|
|
4828
4920
|
} }).pipe(Effect.map((lease) => lease.values), Effect.catchAll(() => Effect.succeed(void 0)));
|
|
4829
|
-
|
|
4921
|
+
return yield* runLocally(payload, {
|
|
4830
4922
|
credentials: leased,
|
|
4831
4923
|
onTrial: (trial) => api.evals.reportTrial({ payload: {
|
|
4832
4924
|
id: started.id,
|
|
4833
4925
|
trial
|
|
4834
4926
|
} }).pipe(Effect.ignore)
|
|
4835
4927
|
});
|
|
4836
|
-
|
|
4837
|
-
return cases;
|
|
4838
|
-
}).pipe(Effect.provide(ClientLayer));
|
|
4928
|
+
}).pipe(Effect.scoped, Effect.provide(ClientLayer));
|
|
4839
4929
|
const runOneEvalLocally = (file) => apiKeyConfig.pipe(Effect.matchEffect({
|
|
4840
4930
|
onFailure: () => compileEvalEffect(file).pipe(Effect.flatMap((payload) => runLocally(payload))),
|
|
4841
4931
|
onSuccess: () => recordedLocally(file)
|