@tangle-network/agent-eval 0.145.18 → 0.145.20
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/CHANGELOG.md +41 -0
- package/dist/analyst/index.d.ts +1 -1
- package/dist/analyst/index.js +1 -1
- package/dist/{benchmark-command-CyqmP3uA.js → benchmark-command-CkgLXHoN.js} +2 -2
- package/dist/{benchmark-command-CyqmP3uA.js.map → benchmark-command-CkgLXHoN.js.map} +1 -1
- package/dist/cli.js +1 -1
- package/dist/index-D_P7Ye43.d.ts +198 -0
- package/dist/index-D_P7Ye43.d.ts.map +1 -0
- package/dist/matrix/index.d.ts +3 -2
- package/dist/matrix/index.js +2 -2
- package/dist/{matrix-BzQnu2S6.js → matrix-pWinRMPl.js} +148 -6
- package/dist/matrix-pWinRMPl.js.map +1 -0
- package/dist/multishot/index.d.ts +111 -48
- package/dist/multishot/index.d.ts.map +1 -1
- package/dist/multishot/index.js +245 -94
- package/dist/multishot/index.js.map +1 -1
- package/dist/openapi.json +1 -1
- package/dist/run-record-D2lDdSAz.js.map +1 -1
- package/dist/run-record-DVV82Gwh.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/index-CvjYbU0D.d.ts +0 -102
- package/dist/index-CvjYbU0D.d.ts.map +0 -1
- package/dist/matrix-BzQnu2S6.js.map +0 -1
package/dist/multishot/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { i as isModelPriced, n as estimateCost } from "../metrics-Cl0L1KUy.js";
|
|
2
|
-
import { t as runAgentMatrix } from "../matrix-
|
|
2
|
+
import { r as withCellSpend, t as runAgentMatrix } from "../matrix-pWinRMPl.js";
|
|
3
3
|
import { mkdirSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
//#region src/multishot/router.ts
|
|
@@ -379,9 +379,114 @@ var MultishotFatalToolError = class extends Error {
|
|
|
379
379
|
this.name = "MultishotFatalToolError";
|
|
380
380
|
}
|
|
381
381
|
};
|
|
382
|
+
var MultishotShotResultError = class extends Error {
|
|
383
|
+
constructor(reason) {
|
|
384
|
+
super(`multishot: shot returned an invalid MultishotResult — ${reason}`);
|
|
385
|
+
this.name = "MultishotShotResultError";
|
|
386
|
+
}
|
|
387
|
+
};
|
|
388
|
+
const MULTISHOT_ROLES = /* @__PURE__ */ new Set([
|
|
389
|
+
"user",
|
|
390
|
+
"assistant",
|
|
391
|
+
"tool"
|
|
392
|
+
]);
|
|
393
|
+
/** Contract guard for the value a caller-supplied shot resolves with. The
|
|
394
|
+
* matrix writes per-cell artifacts, builds judge inputs, and meters cost from
|
|
395
|
+
* this value, so a malformed result must stop the cell instead of scoring a
|
|
396
|
+
* degraded one. Two silent degradations this closes: an artifact with no
|
|
397
|
+
* `type` matches neither the code nor the content artifact set, so the cell
|
|
398
|
+
* scores as though the artifact was never produced; a non-finite `costUsd`
|
|
399
|
+
* reaches `summary.totalCostUsd` and makes every cost number NaN.
|
|
400
|
+
*
|
|
401
|
+
* A rejected cell is still billed: the matrix cell reads the shot's own
|
|
402
|
+
* `costUsd` when it is a usable amount and declares that spend on the throw,
|
|
403
|
+
* so money the shot spent before returning a malformed result stays in the
|
|
404
|
+
* cumulative sum the cost ceiling reads. A result whose `costUsd` is itself
|
|
405
|
+
* malformed carries no usable amount, and the cell records as `uncaptured`.
|
|
406
|
+
*
|
|
407
|
+
* Every required field of `MultishotMessage` and `MultishotArtifact` is
|
|
408
|
+
* checked, including `toolCalls` elements and `invocation.args`. Optional
|
|
409
|
+
* fields are checked only when present. */
|
|
410
|
+
function assertMultishotShotResult(value) {
|
|
411
|
+
if (typeof value !== "object" || value === null) throw new MultishotShotResultError(`expected an object, received ${describeValue(value)}`);
|
|
412
|
+
const result = value;
|
|
413
|
+
if (!Array.isArray(result.transcript)) throw new MultishotShotResultError(`transcript must be an array, received ${describeValue(result.transcript)}`);
|
|
414
|
+
if (!Array.isArray(result.artifacts)) throw new MultishotShotResultError(`artifacts must be an array, received ${describeValue(result.artifacts)}`);
|
|
415
|
+
result.transcript.forEach(assertMessage);
|
|
416
|
+
result.artifacts.forEach(assertArtifact);
|
|
417
|
+
assertFiniteCount(result.toolCalls, "toolCalls");
|
|
418
|
+
assertFiniteCount(result.durationMs, "durationMs");
|
|
419
|
+
assertFiniteCount(result.costUsd, "costUsd");
|
|
420
|
+
if (result.costProvenance !== void 0) assertCostProvenance(result.costProvenance);
|
|
421
|
+
}
|
|
422
|
+
function assertCostProvenance(value) {
|
|
423
|
+
const row = requireRow(value, "costProvenance");
|
|
424
|
+
if (row.kind !== "observed" && row.kind !== "estimated" && row.kind !== "uncaptured") throw new MultishotShotResultError(`costProvenance.kind must be observed, estimated or uncaptured, received ${describeValue(row.kind)}`);
|
|
425
|
+
if (row.kind === "uncaptured") {
|
|
426
|
+
if (row.usd !== null) throw new MultishotShotResultError(`uncaptured costProvenance.usd must be null, received ${describeValue(row.usd)}`);
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
assertFiniteCount(row.usd, "costProvenance.usd");
|
|
430
|
+
}
|
|
431
|
+
function assertMessage(value, index) {
|
|
432
|
+
const row = requireRow(value, `transcript[${index}]`);
|
|
433
|
+
if (typeof row.role !== "string" || !MULTISHOT_ROLES.has(row.role)) throw new MultishotShotResultError(`transcript[${index}].role must be user, assistant or tool, received ${describeValue(row.role)}`);
|
|
434
|
+
assertString(row.content, `transcript[${index}].content`);
|
|
435
|
+
if (row.toolCallId !== void 0) assertString(row.toolCallId, `transcript[${index}].toolCallId`);
|
|
436
|
+
if (row.toolCalls === void 0) return;
|
|
437
|
+
if (!Array.isArray(row.toolCalls)) throw new MultishotShotResultError(`transcript[${index}].toolCalls must be an array when present, received ${describeValue(row.toolCalls)}`);
|
|
438
|
+
row.toolCalls.forEach((call, callIndex) => {
|
|
439
|
+
const field = `transcript[${index}].toolCalls[${callIndex}]`;
|
|
440
|
+
const row = requireRow(call, field);
|
|
441
|
+
assertString(row.id, `${field}.id`);
|
|
442
|
+
assertString(row.name, `${field}.name`);
|
|
443
|
+
requireRow(row.args, `${field}.args`);
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
function assertArtifact(value, index) {
|
|
447
|
+
const row = requireRow(value, `artifacts[${index}]`);
|
|
448
|
+
assertString(row.type, `artifacts[${index}].type`);
|
|
449
|
+
assertString(row.content, `artifacts[${index}].content`);
|
|
450
|
+
assertFiniteCount(row.turn, `artifacts[${index}].turn`);
|
|
451
|
+
const invocation = requireRow(row.invocation, `artifacts[${index}].invocation`);
|
|
452
|
+
assertString(invocation.name, `artifacts[${index}].invocation.name`);
|
|
453
|
+
requireRow(invocation.args, `artifacts[${index}].invocation.args`);
|
|
454
|
+
}
|
|
455
|
+
function requireRow(value, field) {
|
|
456
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) throw new MultishotShotResultError(`${field} must be an object, received ${describeValue(value)}`);
|
|
457
|
+
return value;
|
|
458
|
+
}
|
|
459
|
+
function assertString(value, field) {
|
|
460
|
+
if (typeof value !== "string") throw new MultishotShotResultError(`${field} must be a string, received ${describeValue(value)}`);
|
|
461
|
+
}
|
|
462
|
+
function assertFiniteCount(value, field) {
|
|
463
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < 0) throw new MultishotShotResultError(`${field} must be a finite number >= 0, received ${describeValue(value)}`);
|
|
464
|
+
}
|
|
465
|
+
function describeValue(value) {
|
|
466
|
+
if (value === null) return "null";
|
|
467
|
+
if (Array.isArray(value)) return "an array";
|
|
468
|
+
if (typeof value === "object") return "an object";
|
|
469
|
+
return `${typeof value} ${String(value)}`;
|
|
470
|
+
}
|
|
382
471
|
//#endregion
|
|
383
472
|
//#region src/multishot/multishot.ts
|
|
384
473
|
async function runMultishot(opts) {
|
|
474
|
+
const meter = {
|
|
475
|
+
costUsd: 0,
|
|
476
|
+
startedAt: Date.now(),
|
|
477
|
+
uncaptured: false
|
|
478
|
+
};
|
|
479
|
+
try {
|
|
480
|
+
return await runShotTurns(opts, meter);
|
|
481
|
+
} catch (err) {
|
|
482
|
+
throw withCellSpend(err, {
|
|
483
|
+
costUsd: meter.costUsd,
|
|
484
|
+
durationMs: Date.now() - meter.startedAt,
|
|
485
|
+
kind: meter.uncaptured ? "uncaptured" : "estimated"
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
async function runShotTurns(opts, meter) {
|
|
385
490
|
const apiKey = opts.apiKey ?? requireRouterApiKey();
|
|
386
491
|
const baseUrl = opts.baseUrl ?? defaultRouterBaseUrl();
|
|
387
492
|
const maxTurns = opts.maxTurns ?? 10;
|
|
@@ -407,11 +512,9 @@ async function runMultishot(opts) {
|
|
|
407
512
|
const agentTransport = opts.agentTransport ?? routerTransport;
|
|
408
513
|
const driverTransport = opts.driverTransport ?? routerTransport;
|
|
409
514
|
const shape = defaultShapeFromProfile(opts.profile, opts.shape);
|
|
410
|
-
const start = Date.now();
|
|
411
515
|
const transcript = [];
|
|
412
516
|
const artifacts = [];
|
|
413
517
|
let toolCalls = 0;
|
|
414
|
-
let totalCostUsd = 0;
|
|
415
518
|
const opener = shape.buildOpener(opts.persona);
|
|
416
519
|
transcript.push({
|
|
417
520
|
role: "user",
|
|
@@ -436,7 +539,8 @@ async function runMultishot(opts) {
|
|
|
436
539
|
maxTokens: dispatchesThisTurn === 0 ? agentMaxTokens : toolFollowupMaxTokens,
|
|
437
540
|
signal: opts.signal
|
|
438
541
|
});
|
|
439
|
-
|
|
542
|
+
meter.costUsd += agentCostUsd ?? estimateRouterCost(agentModel, agentUsage);
|
|
543
|
+
if (agentCostUsd === void 0 && agentUsage === void 0) meter.uncaptured = true;
|
|
440
544
|
const agentText = (agentMsg.content ?? "").trim();
|
|
441
545
|
const agentToolCalls = (agentMsg.tool_calls ?? []).map((tc) => ({
|
|
442
546
|
id: tc.id,
|
|
@@ -475,7 +579,7 @@ async function runMultishot(opts) {
|
|
|
475
579
|
signal: opts.signal
|
|
476
580
|
});
|
|
477
581
|
toolResult = r.content;
|
|
478
|
-
|
|
582
|
+
meter.costUsd += r.costUsd;
|
|
479
583
|
const artifactType = artifactTypeFor(tc.name);
|
|
480
584
|
if (artifactType) artifacts.push({
|
|
481
585
|
type: artifactType,
|
|
@@ -512,9 +616,9 @@ async function runMultishot(opts) {
|
|
|
512
616
|
turn,
|
|
513
617
|
models: driverModels,
|
|
514
618
|
maxTokens: driverMaxTokens,
|
|
515
|
-
signal: opts.signal
|
|
619
|
+
signal: opts.signal,
|
|
620
|
+
meter
|
|
516
621
|
});
|
|
517
|
-
totalCostUsd += driver.costUsd;
|
|
518
622
|
agentMessages.push({
|
|
519
623
|
role: "user",
|
|
520
624
|
content: driver.content
|
|
@@ -529,8 +633,15 @@ async function runMultishot(opts) {
|
|
|
529
633
|
transcript,
|
|
530
634
|
artifacts,
|
|
531
635
|
toolCalls,
|
|
532
|
-
durationMs: Date.now() -
|
|
533
|
-
costUsd:
|
|
636
|
+
durationMs: Date.now() - meter.startedAt,
|
|
637
|
+
costUsd: meter.costUsd,
|
|
638
|
+
costProvenance: meter.uncaptured ? {
|
|
639
|
+
kind: "uncaptured",
|
|
640
|
+
usd: null
|
|
641
|
+
} : {
|
|
642
|
+
kind: "estimated",
|
|
643
|
+
usd: meter.costUsd
|
|
644
|
+
}
|
|
534
645
|
};
|
|
535
646
|
}
|
|
536
647
|
async function driverTurn(opts) {
|
|
@@ -559,11 +670,10 @@ async function driverTurn(opts) {
|
|
|
559
670
|
maxTokens: opts.maxTokens,
|
|
560
671
|
signal: opts.signal
|
|
561
672
|
});
|
|
673
|
+
opts.meter.costUsd += costUsd ?? estimateRouterCost(model, usage);
|
|
674
|
+
if (costUsd === void 0 && usage === void 0) opts.meter.uncaptured = true;
|
|
562
675
|
const content = (message.content ?? "").trim();
|
|
563
|
-
if (content.length > 0) return {
|
|
564
|
-
content,
|
|
565
|
-
costUsd: costUsd ?? estimateRouterCost(model, usage)
|
|
566
|
-
};
|
|
676
|
+
if (content.length > 0) return { content };
|
|
567
677
|
}
|
|
568
678
|
throw new MultishotDriverEmptyError(opts.turn);
|
|
569
679
|
}
|
|
@@ -610,6 +720,7 @@ function computeCellComposite(input) {
|
|
|
610
720
|
async function runMultishotMatrix(opts) {
|
|
611
721
|
const codeTypes = new Set(opts.judges.codeArtifactTypes ?? ["code"]);
|
|
612
722
|
const contentTypes = new Set(opts.judges.contentArtifactTypes ?? ["research"]);
|
|
723
|
+
const runShot = opts.runShot ?? runMultishot;
|
|
613
724
|
mkdirSync(opts.runDir, { recursive: true });
|
|
614
725
|
const matrix = await runAgentMatrix({
|
|
615
726
|
axes: [{
|
|
@@ -625,12 +736,14 @@ async function runMultishotMatrix(opts) {
|
|
|
625
736
|
reps: opts.reps ?? 1,
|
|
626
737
|
maxConcurrency: opts.maxConcurrency ?? 2,
|
|
627
738
|
costCeiling: opts.costCeiling,
|
|
739
|
+
maxCellCostUsd: opts.maxCellCostUsd,
|
|
628
740
|
async runCell(cell) {
|
|
741
|
+
const cellStartedAt = Date.now();
|
|
629
742
|
const profile = cell.axes.profile?.value;
|
|
630
743
|
const persona = cell.axes.persona?.value;
|
|
631
744
|
const profileId = String(cell.axes.profile?.id ?? "unknown");
|
|
632
745
|
const personaId = String(cell.axes.persona?.id ?? "unknown");
|
|
633
|
-
const sim = await
|
|
746
|
+
const sim = await runShot({
|
|
634
747
|
profile,
|
|
635
748
|
persona,
|
|
636
749
|
shape: opts.shape,
|
|
@@ -650,86 +763,111 @@ async function runMultishotMatrix(opts) {
|
|
|
650
763
|
apiKey: opts.apiKey,
|
|
651
764
|
baseUrl: opts.baseUrl
|
|
652
765
|
});
|
|
653
|
-
const
|
|
654
|
-
const
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
766
|
+
const shotCostUsd = shotCostSubtotal(sim);
|
|
767
|
+
const shotCostComplete = sim?.costProvenance?.kind !== "uncaptured";
|
|
768
|
+
let judgeCostUsd = 0;
|
|
769
|
+
let judgeCostComplete = false;
|
|
770
|
+
let phase = "validate";
|
|
771
|
+
try {
|
|
772
|
+
assertMultishotShotResult(sim);
|
|
773
|
+
const codeArtifacts = sim.artifacts.filter((a) => codeTypes.has(a.type));
|
|
774
|
+
const contentArtifacts = sim.artifacts.filter((a) => contentTypes.has(a.type));
|
|
775
|
+
phase = "judging";
|
|
776
|
+
const [conversationRun, codeReviewRuns, contentReviewRuns] = await Promise.all([
|
|
777
|
+
runJudge(withJudgeMaxTokens(opts.judges.conversation, opts.judgeMaxTokens), {
|
|
778
|
+
transcript: sim.transcript,
|
|
779
|
+
persona
|
|
780
|
+
}),
|
|
781
|
+
opts.judges.codeReview ? Promise.all(codeArtifacts.map((artifact) => runJudge(withJudgeMaxTokens(opts.judges.codeReview, opts.judgeMaxTokens), {
|
|
782
|
+
artifact,
|
|
783
|
+
persona
|
|
784
|
+
}).then((result) => ({
|
|
785
|
+
score: {
|
|
786
|
+
...result.score,
|
|
787
|
+
turn: artifact.turn,
|
|
788
|
+
type: artifact.type
|
|
789
|
+
},
|
|
790
|
+
cost: result.cost
|
|
791
|
+
})))) : Promise.resolve([]),
|
|
792
|
+
opts.judges.contentQuality ? Promise.all(contentArtifacts.map((artifact) => runJudge(withJudgeMaxTokens(opts.judges.contentQuality, opts.judgeMaxTokens), {
|
|
793
|
+
artifact,
|
|
794
|
+
persona
|
|
795
|
+
}).then((result) => ({
|
|
796
|
+
score: {
|
|
797
|
+
...result.score,
|
|
798
|
+
turn: artifact.turn,
|
|
799
|
+
type: artifact.type
|
|
800
|
+
},
|
|
801
|
+
cost: result.cost
|
|
802
|
+
})))) : Promise.resolve([])
|
|
803
|
+
]);
|
|
804
|
+
const judgeRuns = [
|
|
805
|
+
conversationRun,
|
|
806
|
+
...codeReviewRuns,
|
|
807
|
+
...contentReviewRuns
|
|
808
|
+
];
|
|
809
|
+
judgeCostUsd = judgeRuns.reduce((sum, run) => sum + (run.cost.usd ?? 0), 0);
|
|
810
|
+
judgeCostComplete = judgeRuns.every((run) => run.cost.kind !== "uncaptured");
|
|
811
|
+
phase = "scoring";
|
|
812
|
+
const conversation = conversationRun.score;
|
|
813
|
+
const codeReviews = codeReviewRuns.map((run) => run.score);
|
|
814
|
+
const contentReviews = contentReviewRuns.map((run) => run.score);
|
|
815
|
+
const { composite, codeComposite, contentComposite, allJudgesFailed } = computeCellComposite({
|
|
816
|
+
conversation,
|
|
817
|
+
codeReviews: opts.judges.codeReview ? codeReviews : void 0,
|
|
818
|
+
contentReviews: opts.judges.contentQuality ? contentReviews : void 0
|
|
819
|
+
});
|
|
820
|
+
const cellScore = {
|
|
821
|
+
composite,
|
|
822
|
+
conversation
|
|
823
|
+
};
|
|
824
|
+
if (opts.judges.codeReview) cellScore.codeReview = {
|
|
825
|
+
perArtifact: codeReviews,
|
|
826
|
+
composite: codeComposite
|
|
827
|
+
};
|
|
828
|
+
if (opts.judges.contentQuality) cellScore.contentQuality = {
|
|
829
|
+
perArtifact: contentReviews,
|
|
830
|
+
composite: contentComposite
|
|
831
|
+
};
|
|
832
|
+
const cellDir = join(opts.runDir, profileId, personaId, `rep-${cell.rep}`);
|
|
833
|
+
mkdirSync(cellDir, { recursive: true });
|
|
834
|
+
writeFileSync(join(cellDir, "transcript.json"), JSON.stringify(sim.transcript, null, 2));
|
|
835
|
+
writeFileSync(join(cellDir, "artifacts.json"), JSON.stringify(sim.artifacts, null, 2));
|
|
836
|
+
writeFileSync(join(cellDir, "scores.json"), JSON.stringify(cellScore, null, 2));
|
|
837
|
+
const notes = [`convo=${conversation.composite.toFixed(1)}`];
|
|
838
|
+
if (opts.judges.codeReview) notes.push(`code=${codeComposite.toFixed(1)}`);
|
|
839
|
+
if (opts.judges.contentQuality) notes.push(`content=${contentComposite.toFixed(1)}`);
|
|
840
|
+
if (allJudgesFailed) notes.push("all-judges-failed");
|
|
841
|
+
if (!judgeCostComplete) notes.push("judge-cost-incomplete");
|
|
842
|
+
return {
|
|
843
|
+
output: {
|
|
844
|
+
turns: sim.transcript.length,
|
|
845
|
+
toolCalls: sim.toolCalls,
|
|
846
|
+
artifactCount: sim.artifacts.length
|
|
668
847
|
},
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
persona
|
|
674
|
-
}).then((result) => ({
|
|
675
|
-
score: {
|
|
676
|
-
...result.score,
|
|
677
|
-
turn: artifact.turn,
|
|
678
|
-
type: artifact.type
|
|
848
|
+
verdict: {
|
|
849
|
+
valid: composite >= 5,
|
|
850
|
+
score: composite,
|
|
851
|
+
notes: notes.join(" ")
|
|
679
852
|
},
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
})
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
};
|
|
699
|
-
if (opts.judges.contentQuality) cellScore.contentQuality = {
|
|
700
|
-
perArtifact: contentReviews,
|
|
701
|
-
composite: contentComposite
|
|
702
|
-
};
|
|
703
|
-
const cellDir = join(opts.runDir, profileId, personaId, `rep-${cell.rep}`);
|
|
704
|
-
mkdirSync(cellDir, { recursive: true });
|
|
705
|
-
writeFileSync(join(cellDir, "transcript.json"), JSON.stringify(sim.transcript, null, 2));
|
|
706
|
-
writeFileSync(join(cellDir, "artifacts.json"), JSON.stringify(sim.artifacts, null, 2));
|
|
707
|
-
writeFileSync(join(cellDir, "scores.json"), JSON.stringify(cellScore, null, 2));
|
|
708
|
-
const notes = [`convo=${conversation.composite.toFixed(1)}`];
|
|
709
|
-
if (opts.judges.codeReview) notes.push(`code=${codeComposite.toFixed(1)}`);
|
|
710
|
-
if (opts.judges.contentQuality) notes.push(`content=${contentComposite.toFixed(1)}`);
|
|
711
|
-
if (allJudgesFailed) notes.push("all-judges-failed");
|
|
712
|
-
const judgeRuns = [
|
|
713
|
-
conversationRun,
|
|
714
|
-
...codeReviewRuns,
|
|
715
|
-
...contentReviewRuns
|
|
716
|
-
];
|
|
717
|
-
const judgeCostUsd = judgeRuns.reduce((sum, run) => sum + (run.cost.usd ?? 0), 0);
|
|
718
|
-
if (judgeRuns.some((run) => run.cost.kind === "uncaptured")) notes.push("judge-cost-incomplete");
|
|
719
|
-
return {
|
|
720
|
-
output: {
|
|
721
|
-
turns: sim.transcript.length,
|
|
722
|
-
toolCalls: sim.toolCalls,
|
|
723
|
-
artifactCount: sim.artifacts.length
|
|
724
|
-
},
|
|
725
|
-
verdict: {
|
|
726
|
-
valid: composite >= 5,
|
|
727
|
-
score: composite,
|
|
728
|
-
notes: notes.join(" ")
|
|
729
|
-
},
|
|
730
|
-
costUsd: sim.costUsd + judgeCostUsd,
|
|
731
|
-
durationMs: sim.durationMs
|
|
732
|
-
};
|
|
853
|
+
costUsd: sim.costUsd + judgeCostUsd,
|
|
854
|
+
costProvenance: judgeCostComplete && shotCostComplete ? {
|
|
855
|
+
kind: "estimated",
|
|
856
|
+
usd: sim.costUsd + judgeCostUsd
|
|
857
|
+
} : {
|
|
858
|
+
kind: "uncaptured",
|
|
859
|
+
usd: null
|
|
860
|
+
},
|
|
861
|
+
durationMs: sim.durationMs
|
|
862
|
+
};
|
|
863
|
+
} catch (err) {
|
|
864
|
+
if (shotCostUsd === void 0) throw err;
|
|
865
|
+
throw withCellSpend(err, {
|
|
866
|
+
costUsd: shotCostUsd + judgeCostUsd,
|
|
867
|
+
durationMs: Date.now() - cellStartedAt,
|
|
868
|
+
kind: shotCostComplete && (phase === "validate" || phase === "scoring" && judgeCostComplete) ? "estimated" : "uncaptured"
|
|
869
|
+
});
|
|
870
|
+
}
|
|
733
871
|
}
|
|
734
872
|
});
|
|
735
873
|
const summary = {
|
|
@@ -737,6 +875,8 @@ async function runMultishotMatrix(opts) {
|
|
|
737
875
|
passRate: matrix.summary.overallPassRate,
|
|
738
876
|
meanScore: matrix.summary.overallMeanScore,
|
|
739
877
|
totalCostUsd: matrix.summary.totalCostUsd,
|
|
878
|
+
costUncapturedCells: matrix.summary.costUncapturedCells,
|
|
879
|
+
ceilingChargedUsd: matrix.summary.ceilingChargedUsd,
|
|
740
880
|
durationMs: matrix.summary.durationMs,
|
|
741
881
|
runsExecuted: matrix.summary.runsExecuted,
|
|
742
882
|
cellsSkipped: matrix.summary.cellsSkipped,
|
|
@@ -744,11 +884,14 @@ async function runMultishotMatrix(opts) {
|
|
|
744
884
|
byPersona: matrix.byAxis.persona
|
|
745
885
|
};
|
|
746
886
|
writeFileSync(join(opts.runDir, "summary.json"), JSON.stringify(summary, null, 2));
|
|
887
|
+
const uncaptured = matrix.summary.costUncapturedCells;
|
|
888
|
+
const costLabel = uncaptured > 0 ? "Cost (at least)" : "Cost";
|
|
747
889
|
const md = [
|
|
748
890
|
`# Multishot matrix`,
|
|
749
891
|
``,
|
|
750
|
-
`**Cells**: ${matrix.summary.totalCells} | **Pass rate**: ${(matrix.summary.overallPassRate * 100).toFixed(0)}% | **Mean**: ${matrix.summary.overallMeanScore.toFixed(2)} |
|
|
892
|
+
`**Cells**: ${matrix.summary.totalCells} | **Pass rate**: ${(matrix.summary.overallPassRate * 100).toFixed(0)}% | **Mean**: ${matrix.summary.overallMeanScore.toFixed(2)} | **${costLabel}**: $${matrix.summary.totalCostUsd.toFixed(2)} | **Duration**: ${(matrix.summary.durationMs / 1e3).toFixed(0)}s`,
|
|
751
893
|
``,
|
|
894
|
+
...uncaptured > 0 ? [`> ${uncaptured} of ${matrix.summary.runsExecuted} cells reported a cost subtotal, not a total. Real spend is higher than every cost figure below.`, ``] : [],
|
|
752
895
|
`## By profile`,
|
|
753
896
|
``,
|
|
754
897
|
"| profile | pass | mean | cost |",
|
|
@@ -765,6 +908,14 @@ async function runMultishotMatrix(opts) {
|
|
|
765
908
|
writeFileSync(join(opts.runDir, "summary.md"), md.join("\n"));
|
|
766
909
|
return { matrix };
|
|
767
910
|
}
|
|
911
|
+
/** The shot's own spend, when the value it resolved with reports a usable
|
|
912
|
+
* amount. `undefined` when it does not — a malformed shot result is exactly
|
|
913
|
+
* the case where the number cannot be trusted, and billing a wrong figure is
|
|
914
|
+
* worse than recording the cell as uncaptured. */
|
|
915
|
+
function shotCostSubtotal(sim) {
|
|
916
|
+
const value = sim?.costUsd;
|
|
917
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : void 0;
|
|
918
|
+
}
|
|
768
919
|
function withJudgeMaxTokens(judge, maxTokens) {
|
|
769
920
|
if (maxTokens === void 0 || judge.maxTokens !== void 0) return judge;
|
|
770
921
|
return {
|
|
@@ -773,6 +924,6 @@ function withJudgeMaxTokens(judge, maxTokens) {
|
|
|
773
924
|
};
|
|
774
925
|
}
|
|
775
926
|
//#endregion
|
|
776
|
-
export { DEFAULT_CODER_MODEL, DEFAULT_DELEGATE_CODE_TOOL, DEFAULT_DELEGATE_RESEARCH_TOOL, DEFAULT_JUDGE_MODEL, DEFAULT_RESEARCHER_MODEL, MultishotDriverEmptyError, MultishotFatalToolError, computeCellComposite, createCodeExecutor, createResearchExecutor, defaultDelegationTools, defaultMultishotDriverSystemPrompt, defaultMultishotOpener, defaultRouterBaseUrl, defaultShapeFromProfile, estimateRouterCost, renderDimensions, renderJsonFooter, renderPersonaFacts, requireRouterApiKey, routerCompletion, runJudge, runMultishot, runMultishotMatrix };
|
|
927
|
+
export { DEFAULT_CODER_MODEL, DEFAULT_DELEGATE_CODE_TOOL, DEFAULT_DELEGATE_RESEARCH_TOOL, DEFAULT_JUDGE_MODEL, DEFAULT_RESEARCHER_MODEL, MultishotDriverEmptyError, MultishotFatalToolError, MultishotShotResultError, assertMultishotShotResult, computeCellComposite, createCodeExecutor, createResearchExecutor, defaultDelegationTools, defaultMultishotDriverSystemPrompt, defaultMultishotOpener, defaultRouterBaseUrl, defaultShapeFromProfile, estimateRouterCost, renderDimensions, renderJsonFooter, renderPersonaFacts, requireRouterApiKey, routerCompletion, runJudge, runMultishot, runMultishotMatrix };
|
|
777
928
|
|
|
778
929
|
//# sourceMappingURL=index.js.map
|