@tangle-network/agent-eval 0.119.0 → 0.119.1
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 +6 -0
- package/dist/analyst/index.d.ts +30 -39
- package/dist/analyst/index.js +9 -5
- package/dist/analyst/index.js.map +1 -1
- package/dist/benchmarks/index.js +5 -5
- package/dist/campaign/index.d.ts +28 -29
- package/dist/campaign/index.js +5 -5
- package/dist/{chunk-LMJ2TGWJ.js → chunk-JM2SKQMS.js} +2 -2
- package/dist/{chunk-RLCJQ6VZ.js → chunk-PSXJ32SR.js} +157 -3
- package/dist/chunk-PSXJ32SR.js.map +1 -0
- package/dist/{chunk-6QIM2EAP.js → chunk-PXD6ZFNY.js} +99 -1
- package/dist/chunk-PXD6ZFNY.js.map +1 -0
- package/dist/{chunk-GERDAIAL.js → chunk-QWMPPZ3X.js} +3 -3
- package/dist/{chunk-7A4LIMMY.js → chunk-S5TT5R3L.js} +229 -97
- package/dist/chunk-S5TT5R3L.js.map +1 -0
- package/dist/{chunk-ZYHJNKI3.js → chunk-ULOKLHIQ.js} +42 -5
- package/dist/chunk-ULOKLHIQ.js.map +1 -0
- package/dist/{chunk-FIUFRXP3.js → chunk-WW2A73HW.js} +49 -91
- package/dist/chunk-WW2A73HW.js.map +1 -0
- package/dist/{chunk-F6YUH3L4.js → chunk-XMBOU5W7.js} +12 -165
- package/dist/chunk-XMBOU5W7.js.map +1 -0
- package/dist/contract/index.d.ts +25 -16
- package/dist/contract/index.js +281 -5
- package/dist/contract/index.js.map +1 -1
- package/dist/index.d.ts +71 -68
- package/dist/index.js +31 -32
- package/dist/index.js.map +1 -1
- package/dist/openapi.json +1 -1
- package/dist/traces.d.ts +39 -25
- package/dist/traces.js +3 -5
- package/docs/trace-analysis.md +6 -2
- package/package.json +2 -2
- package/dist/chunk-6QIM2EAP.js.map +0 -1
- package/dist/chunk-7A4LIMMY.js.map +0 -1
- package/dist/chunk-F6YUH3L4.js.map +0 -1
- package/dist/chunk-FIUFRXP3.js.map +0 -1
- package/dist/chunk-RLCJQ6VZ.js.map +0 -1
- package/dist/chunk-ZYHJNKI3.js.map +0 -1
- /package/dist/{chunk-LMJ2TGWJ.js.map → chunk-JM2SKQMS.js.map} +0 -0
- /package/dist/{chunk-GERDAIAL.js.map → chunk-QWMPPZ3X.js.map} +0 -0
package/dist/contract/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AgentImprovementMeasuredComparison, Sha256Digest } from '@tangle-network/agent-interface';
|
|
1
2
|
import { AxFunction, AxAIService } from '@ax-llm/ax';
|
|
2
3
|
import { z } from 'zod';
|
|
3
4
|
|
|
@@ -1122,6 +1123,8 @@ interface AnalystCost {
|
|
|
1122
1123
|
est_usd_per_run?: number;
|
|
1123
1124
|
/** Models the analyst expects to use (informational). */
|
|
1124
1125
|
models?: string[];
|
|
1126
|
+
/** Maximum post-cancellation wait for provider usage. Model analysts default to 5 seconds. */
|
|
1127
|
+
settlement_timeout_ms?: number;
|
|
1125
1128
|
}
|
|
1126
1129
|
interface AnalystRequirements {
|
|
1127
1130
|
/** Min number of shots / samples the analyst needs to produce signal. */
|
|
@@ -1145,7 +1148,7 @@ interface AnalystContext {
|
|
|
1145
1148
|
runId: string;
|
|
1146
1149
|
/** Stable correlation id so logs from a single registry.run() share a tag. */
|
|
1147
1150
|
correlationId: string;
|
|
1148
|
-
/**
|
|
1151
|
+
/** Enforced wall-clock deadline (epoch ms). */
|
|
1149
1152
|
deadlineMs?: number;
|
|
1150
1153
|
/** Per-analyst USD budget. Analysts MAY check before issuing LLM calls. */
|
|
1151
1154
|
budgetUsd?: number;
|
|
@@ -4000,6 +4003,15 @@ interface DefinedAgentEval<TScenario extends Scenario, TArtifact> {
|
|
|
4000
4003
|
*/
|
|
4001
4004
|
declare function defineAgentEval<TScenario extends Scenario, TArtifact>(defaults: DefineAgentEvalOptions<TScenario, TArtifact>): DefinedAgentEval<TScenario, TArtifact>;
|
|
4002
4005
|
|
|
4006
|
+
interface MeasuredComparisonFromSelfImproveResultOptions<TScenario extends Scenario, TArtifact> {
|
|
4007
|
+
result: SelfImproveResult<TScenario, TArtifact>;
|
|
4008
|
+
benchmark: AgentImprovementMeasuredComparison['benchmark'];
|
|
4009
|
+
baselineProfileDigest: Sha256Digest;
|
|
4010
|
+
candidateBundleDigest: Sha256Digest;
|
|
4011
|
+
}
|
|
4012
|
+
/** Convert one paired self-improvement result into the portable Interface evidence record. */
|
|
4013
|
+
declare function measuredComparisonFromSelfImproveResult<TScenario extends Scenario, TArtifact>(options: MeasuredComparisonFromSelfImproveResultOptions<TScenario, TArtifact>): AgentImprovementMeasuredComparison;
|
|
4014
|
+
|
|
4003
4015
|
/**
|
|
4004
4016
|
* Typed Ax output for analyst findings.
|
|
4005
4017
|
*
|
|
@@ -4065,8 +4077,8 @@ type CanonicalRawAnalystFinding = z.infer<typeof CanonicalRawAnalystFindingSchem
|
|
|
4065
4077
|
* Analyst-kind factory — the typed way to define trace analysts.
|
|
4066
4078
|
*
|
|
4067
4079
|
* A "kind" is a specialized analyst whose actor prompt, tool subset,
|
|
4068
|
-
* and Ax
|
|
4069
|
-
* classification, knowledge gap discovery, knowledge poisoning,
|
|
4080
|
+
* and bounded Ax subqueries target one failure-mode lens (failure-mode
|
|
4081
|
+
* classification, knowledge gap discovery, knowledge poisoning,
|
|
4070
4082
|
* self-improvement, ...). Kinds emit findings in the typed
|
|
4071
4083
|
* `CanonicalRawAnalystFinding` shape via a JSON-array Ax output; the factory
|
|
4072
4084
|
* validates each row with Zod and lifts it into `AnalystFinding[]`.
|
|
@@ -4077,12 +4089,11 @@ type CanonicalRawAnalystFinding = z.infer<typeof CanonicalRawAnalystFindingSchem
|
|
|
4077
4089
|
* - Each kind picks a narrow tool subset from `ANALYST_TOOL_GROUPS`.
|
|
4078
4090
|
* A kind that never needs full-trace dumps can drop `viewTrace` /
|
|
4079
4091
|
* `viewSpans` and stay cheap.
|
|
4080
|
-
* - Each kind declares its
|
|
4081
|
-
*
|
|
4082
|
-
* (poisoning) usually stay at 0 since they have a tighter brief.
|
|
4092
|
+
* - Each kind declares its subquery + parallelism budget. Discovery-heavy
|
|
4093
|
+
* kinds can fan out more bounded semantic questions than narrow lenses.
|
|
4083
4094
|
*
|
|
4084
4095
|
* Optimizer hook: kinds may declare `goldens` — labeled examples used
|
|
4085
|
-
* by `
|
|
4096
|
+
* by `AxBootstrapFewShot` / `AxGEPA` to fit the actor
|
|
4086
4097
|
* description programmatically. Stored on the kind, not the registry,
|
|
4087
4098
|
* because the right metric is kind-specific.
|
|
4088
4099
|
*/
|
|
@@ -4102,20 +4113,18 @@ interface TraceAnalystKindSpec {
|
|
|
4102
4113
|
version: string;
|
|
4103
4114
|
/** Actor system prompt. Must instruct the LLM to emit `findings` per the schema. */
|
|
4104
4115
|
actorDescription: string;
|
|
4105
|
-
/** Responder system prompt; falls back to a minimal "format the findings" instruction. */
|
|
4106
|
-
responderDescription?: string;
|
|
4107
4116
|
/** Tool functions the actor may call. Pick narrow subsets via `ANALYST_TOOL_GROUPS`. */
|
|
4108
4117
|
buildTools: (store: TraceAnalysisStore) => AxFunction[];
|
|
4109
|
-
/**
|
|
4110
|
-
|
|
4111
|
-
|
|
4112
|
-
|
|
4118
|
+
/** Bounded semantic subqueries. `maxCalls: 0` disables model fan-out. */
|
|
4119
|
+
subqueries?: {
|
|
4120
|
+
maxCalls: number;
|
|
4121
|
+
maxParallel?: number;
|
|
4113
4122
|
};
|
|
4114
4123
|
/** Actor turn cap. Default 12. */
|
|
4115
4124
|
maxTurns?: number;
|
|
4116
4125
|
/** Runtime char cap. Default 6000. */
|
|
4117
4126
|
maxRuntimeChars?: number;
|
|
4118
|
-
/** Maximum output tokens for every actor
|
|
4127
|
+
/** Maximum output tokens for every actor and subquery model call. Default 4096. */
|
|
4119
4128
|
maxOutputTokens?: number;
|
|
4120
4129
|
/** Cost classification surfaced in `registry.list()` and budget enforcement. */
|
|
4121
4130
|
cost: AnalystCost;
|
|
@@ -4219,7 +4228,7 @@ interface RegistryRunOpts {
|
|
|
4219
4228
|
skip?: string[];
|
|
4220
4229
|
/** Budget policy — totalUsd + optional weights/allocator. Falls back to options.defaultBudget. */
|
|
4221
4230
|
budget?: BudgetPolicy;
|
|
4222
|
-
/**
|
|
4231
|
+
/** Active-work cap for the complete registry run. Model receipt settlement may follow. */
|
|
4223
4232
|
timeoutMs?: number;
|
|
4224
4233
|
/** Abort signal — forwarded into every analyst's context. */
|
|
4225
4234
|
signal?: AbortSignal;
|
|
@@ -4933,4 +4942,4 @@ interface FromOtelSpansOptions {
|
|
|
4933
4942
|
}
|
|
4934
4943
|
declare function fromOtelSpans(opts: FromOtelSpansOptions): RunRecord[];
|
|
4935
4944
|
|
|
4936
|
-
export { type AgentEvalAgent, type AgentEvalEvaluateOptions, type AgentEvalImproveOptions, type AgentTraceContributor, type AgentTraceContributorType, type AgentTraceConversation, type AgentTraceFile, type AgentTraceIndex, type AgentTraceRange, type AgentTraceRecord, type AnalystFinding, type AnalyzeRunsOptions, type AuthoringProvenance, type AxisEvidence, type AxisVerdict, type BuildEvidenceVectorOptions, type CampaignAggregates, type CampaignArtifactWriter, type CampaignCellResult, type CampaignCostMeter, type CampaignResult, type CampaignStorage, type CampaignTraceWriter, type ChatClient, type CodeAgentSessionDiagnostic, type CodeAgentSessionIntakeOptions, type CodeAgentSessionIntakeResult, type CodeAgentSessionMetrics, type CodeAgentSessionSource, type CodeSurface, type CostLedgerHandle, type CostProvenanceSummary, type CreateChatClientOpts, type DefaultAnalystRegistryOptions, type DefaultProductionGateOptions, type DefineAgentEvalOptions, type DefinedAgentEval, type DeploymentOutcome, type DispatchFn as Dispatch, type DispatchContext, type EvalCellScoreDelta, type EvalDimensionDelta, type EvalGenerationDiff, type EvalReportingSuiteInput, type EvalReportingSuiteOptions, type EvalReportingSuiteResult, type EvalRunDiff, type EvidenceVector, type EvolutionaryProposerOptions, type ExecutionInsight, type ExecutionReport, type FailureClusterInsight, type FeedbackTableMeta, type FeedbackTableRow, FileSystemOutcomeStore, type FileSystemOutcomeStoreOptions, type FromFeedbackTableOptions, type FromFeedbackTableResult, type FromOtelSpansOptions, type FromRunRecordDirOptions, type FromRunRecordDirResult, type Gate, type GateContext, type GateDecision, type GateResult, type GenerationCandidate, type GenerationRecord, type GepaProposerOptions, type HeldOutGateOptions, type HostedTenant, InMemoryOutcomeStore, type InsightReport, type InterRaterInsight, type JudgeConfig, type JudgeDimension, type JudgeInsight, type JudgeScore, type LiftInsight, type MutableSurface, type Mutator, type ObjectiveSource, type OptimizationProposer, type OptimizerConfig, type OutcomeCorrelationInsight, type OutcomeStore, type ParetoSignificanceGateOptions, type ParsedCodeAgentJsonl, type PartitionByAuthoringModelResult, type PromotionObjective, type PromotionPolicy, REFERENCE_EQUIVALENCE_INPUT_LIMITS, REFERENCE_EQUIVALENCE_JUDGE_VERSION, type Recommendation, type ReferenceEquivalenceJudgeInput, type ReferenceEquivalenceJudgeOptions, type ReferenceEquivalenceJudgeResult, type ReferenceEquivalenceScenario, type ReleaseSummary, type RunCampaignOptions, type RunEvalOptions, type RunImprovementLoopOptions, type RunImprovementLoopResult, type RunRecordRejection, type ScalarDistribution, type Scenario, type SelfImproveBudget, type SelfImproveLlm, type SelfImproveOptions, type SelfImproveProgressEvent, type SelfImproveResult, SelfImproveRunError, type SessionScript, type SummarizeExecutionOptions, type SurfaceProposer, type TokenUsageInsight, analyzeRuns, buildDefaultAnalystRegistry, buildEvidenceVector, composeGate, createChatClient, createReferenceEquivalenceJudge, defaultProductionGate, defineAgentEval, diffGenerations, diffRunBaselineToWinner, diffRuns, evalReportingSuite, evolutionaryProposer, fromClaudeCodeSession, fromCodexSession, fromFeedbackTable, fromKimiCodeSession, fromOpenCodeSession, fromOtelSpans, fromPiSession, fromPigraphSession, fromRunRecordDir, fsCampaignStorage, gepaProposer, heldOutGate, inMemoryCampaignStorage, paretoPolicy, paretoSignificanceGate, parseAgentTrace, parseCodeAgentJsonl, partitionRunsByAuthoringModel, runCampaign, runEval, runImprovementLoop, runReferenceEquivalenceJudge, selfImprove, summarizeExecution };
|
|
4945
|
+
export { type AgentEvalAgent, type AgentEvalEvaluateOptions, type AgentEvalImproveOptions, type AgentTraceContributor, type AgentTraceContributorType, type AgentTraceConversation, type AgentTraceFile, type AgentTraceIndex, type AgentTraceRange, type AgentTraceRecord, type AnalystFinding, type AnalyzeRunsOptions, type AuthoringProvenance, type AxisEvidence, type AxisVerdict, type BuildEvidenceVectorOptions, type CampaignAggregates, type CampaignArtifactWriter, type CampaignCellResult, type CampaignCostMeter, type CampaignResult, type CampaignStorage, type CampaignTraceWriter, type ChatClient, type CodeAgentSessionDiagnostic, type CodeAgentSessionIntakeOptions, type CodeAgentSessionIntakeResult, type CodeAgentSessionMetrics, type CodeAgentSessionSource, type CodeSurface, type CostLedgerHandle, type CostProvenanceSummary, type CreateChatClientOpts, type DefaultAnalystRegistryOptions, type DefaultProductionGateOptions, type DefineAgentEvalOptions, type DefinedAgentEval, type DeploymentOutcome, type DispatchFn as Dispatch, type DispatchContext, type EvalCellScoreDelta, type EvalDimensionDelta, type EvalGenerationDiff, type EvalReportingSuiteInput, type EvalReportingSuiteOptions, type EvalReportingSuiteResult, type EvalRunDiff, type EvidenceVector, type EvolutionaryProposerOptions, type ExecutionInsight, type ExecutionReport, type FailureClusterInsight, type FeedbackTableMeta, type FeedbackTableRow, FileSystemOutcomeStore, type FileSystemOutcomeStoreOptions, type FromFeedbackTableOptions, type FromFeedbackTableResult, type FromOtelSpansOptions, type FromRunRecordDirOptions, type FromRunRecordDirResult, type Gate, type GateContext, type GateDecision, type GateResult, type GenerationCandidate, type GenerationRecord, type GepaProposerOptions, type HeldOutGateOptions, type HostedTenant, InMemoryOutcomeStore, type InsightReport, type InterRaterInsight, type JudgeConfig, type JudgeDimension, type JudgeInsight, type JudgeScore, type LiftInsight, type MeasuredComparisonFromSelfImproveResultOptions, type MutableSurface, type Mutator, type ObjectiveSource, type OptimizationProposer, type OptimizerConfig, type OutcomeCorrelationInsight, type OutcomeStore, type ParetoSignificanceGateOptions, type ParsedCodeAgentJsonl, type PartitionByAuthoringModelResult, type PromotionObjective, type PromotionPolicy, REFERENCE_EQUIVALENCE_INPUT_LIMITS, REFERENCE_EQUIVALENCE_JUDGE_VERSION, type Recommendation, type ReferenceEquivalenceJudgeInput, type ReferenceEquivalenceJudgeOptions, type ReferenceEquivalenceJudgeResult, type ReferenceEquivalenceScenario, type ReleaseSummary, type RunCampaignOptions, type RunEvalOptions, type RunImprovementLoopOptions, type RunImprovementLoopResult, type RunRecordRejection, type ScalarDistribution, type Scenario, type SelfImproveBudget, type SelfImproveLlm, type SelfImproveOptions, type SelfImproveProgressEvent, type SelfImproveResult, SelfImproveRunError, type SessionScript, type SummarizeExecutionOptions, type SurfaceProposer, type TokenUsageInsight, analyzeRuns, buildDefaultAnalystRegistry, buildEvidenceVector, composeGate, createChatClient, createReferenceEquivalenceJudge, defaultProductionGate, defineAgentEval, diffGenerations, diffRunBaselineToWinner, diffRuns, evalReportingSuite, evolutionaryProposer, fromClaudeCodeSession, fromCodexSession, fromFeedbackTable, fromKimiCodeSession, fromOpenCodeSession, fromOtelSpans, fromPiSession, fromPigraphSession, fromRunRecordDir, fsCampaignStorage, gepaProposer, heldOutGate, inMemoryCampaignStorage, measuredComparisonFromSelfImproveResult, paretoPolicy, paretoSignificanceGate, parseAgentTrace, parseCodeAgentJsonl, partitionRunsByAuthoringModel, runCampaign, runEval, runImprovementLoop, runReferenceEquivalenceJudge, selfImprove, summarizeExecution };
|
package/dist/contract/index.js
CHANGED
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
evolutionaryProposer,
|
|
27
27
|
gepaProposer,
|
|
28
28
|
heldOutGate,
|
|
29
|
+
pairArms,
|
|
29
30
|
paretoPolicy,
|
|
30
31
|
paretoSignificanceGate,
|
|
31
32
|
powerPreflight,
|
|
@@ -34,8 +35,9 @@ import {
|
|
|
34
35
|
runReferenceEquivalenceJudge,
|
|
35
36
|
surfaceContentHash,
|
|
36
37
|
surfaceHash
|
|
37
|
-
} from "../chunk-
|
|
38
|
+
} from "../chunk-PSXJ32SR.js";
|
|
38
39
|
import {
|
|
40
|
+
canonicalJson,
|
|
39
41
|
createRunCostLedger,
|
|
40
42
|
fsCampaignStorage,
|
|
41
43
|
inMemoryCampaignStorage,
|
|
@@ -45,9 +47,9 @@ import {
|
|
|
45
47
|
import {
|
|
46
48
|
buildDefaultAnalystRegistry,
|
|
47
49
|
createChatClient
|
|
48
|
-
} from "../chunk-
|
|
50
|
+
} from "../chunk-QWMPPZ3X.js";
|
|
49
51
|
import "../chunk-HHWE3POT.js";
|
|
50
|
-
import "../chunk-
|
|
52
|
+
import "../chunk-S5TT5R3L.js";
|
|
51
53
|
import {
|
|
52
54
|
FileSystemOutcomeStore,
|
|
53
55
|
InMemoryOutcomeStore
|
|
@@ -55,7 +57,9 @@ import {
|
|
|
55
57
|
import "../chunk-ARU2PZFM.js";
|
|
56
58
|
import "../chunk-NJC7U437.js";
|
|
57
59
|
import "../chunk-DPZAEKA6.js";
|
|
58
|
-
import
|
|
60
|
+
import {
|
|
61
|
+
pairedBootstrap
|
|
62
|
+
} from "../chunk-PJQFMIOX.js";
|
|
59
63
|
import "../chunk-JHOJHHU7.js";
|
|
60
64
|
import "../chunk-VI2UW6B6.js";
|
|
61
65
|
import {
|
|
@@ -65,7 +69,7 @@ import {
|
|
|
65
69
|
import "../chunk-PXE2VKMX.js";
|
|
66
70
|
import "../chunk-ZET2UAYW.js";
|
|
67
71
|
import "../chunk-GGE4NNQT.js";
|
|
68
|
-
import "../chunk-
|
|
72
|
+
import "../chunk-PXD6ZFNY.js";
|
|
69
73
|
import "../chunk-PC4UYEBM.js";
|
|
70
74
|
import {
|
|
71
75
|
parseRunRecordSafe
|
|
@@ -536,6 +540,277 @@ function requirePositiveInteger(value, field) {
|
|
|
536
540
|
return value;
|
|
537
541
|
}
|
|
538
542
|
|
|
543
|
+
// src/contract/measured-comparison.ts
|
|
544
|
+
import { createHash as createHash2 } from "crypto";
|
|
545
|
+
import {
|
|
546
|
+
agentImprovementMeasuredComparisonSchema
|
|
547
|
+
} from "@tangle-network/agent-interface";
|
|
548
|
+
function measuredComparisonFromSelfImproveResult(options) {
|
|
549
|
+
const { result } = options;
|
|
550
|
+
const power = result.power;
|
|
551
|
+
if (!power) throw new Error("agent improvement comparison requires heldout power analysis");
|
|
552
|
+
if (result.provenance.gate.reasons.length === 0) {
|
|
553
|
+
throw new Error("agent improvement comparison requires measured decision reasons");
|
|
554
|
+
}
|
|
555
|
+
const pairs = pairMeasuredCells(
|
|
556
|
+
result.raw.baselineOnHoldout.cells,
|
|
557
|
+
result.raw.winnerOnHoldout.cells
|
|
558
|
+
);
|
|
559
|
+
const composite = measuredObjective(
|
|
560
|
+
{
|
|
561
|
+
kind: "objective",
|
|
562
|
+
name: "composite",
|
|
563
|
+
direction: "higher-is-better",
|
|
564
|
+
unit: "score"
|
|
565
|
+
},
|
|
566
|
+
pairs,
|
|
567
|
+
measuredComposite
|
|
568
|
+
);
|
|
569
|
+
assertMeasuredNumber(result.lift, composite.delta, "heldout lift");
|
|
570
|
+
assertMeasuredNumber(result.baseline.compositeMean, composite.baseline, "heldout baseline");
|
|
571
|
+
assertMeasuredNumber(result.winner.compositeMean, composite.candidate, "heldout candidate");
|
|
572
|
+
assertMeasuredNumber(result.provenance.heldOutLift, composite.delta, "provenance heldout lift");
|
|
573
|
+
if (result.gateDecision !== result.provenance.gate.decision || power.n !== composite.n || power.confidence !== 0.95) {
|
|
574
|
+
throw new Error("agent improvement measurement sources do not agree");
|
|
575
|
+
}
|
|
576
|
+
return agentImprovementMeasuredComparisonSchema.parse({
|
|
577
|
+
schemaVersion: 1,
|
|
578
|
+
kind: "agent-improvement-measured-comparison",
|
|
579
|
+
benchmark: options.benchmark,
|
|
580
|
+
baselineProfileDigest: options.baselineProfileDigest,
|
|
581
|
+
candidateBundleDigest: options.candidateBundleDigest,
|
|
582
|
+
overall: {
|
|
583
|
+
name: "composite",
|
|
584
|
+
baseline: composite.baseline,
|
|
585
|
+
candidate: composite.candidate,
|
|
586
|
+
delta: composite.delta,
|
|
587
|
+
confidenceInterval: composite.confidenceInterval,
|
|
588
|
+
n: composite.n,
|
|
589
|
+
direction: "higher-is-better",
|
|
590
|
+
unit: "score"
|
|
591
|
+
},
|
|
592
|
+
objectives: measuredObjectives(pairs),
|
|
593
|
+
...result.winner.label || result.winner.rationale ? {
|
|
594
|
+
candidate: {
|
|
595
|
+
...result.winner.label ? { label: result.winner.label } : {},
|
|
596
|
+
...result.winner.rationale ? { rationale: result.winner.rationale } : {}
|
|
597
|
+
}
|
|
598
|
+
} : {},
|
|
599
|
+
decision: {
|
|
600
|
+
outcome: result.gateDecision,
|
|
601
|
+
reasons: result.provenance.gate.reasons,
|
|
602
|
+
contributingChecks: result.provenance.gate.contributingGates.map((check) => ({
|
|
603
|
+
name: check.name,
|
|
604
|
+
passed: check.passed
|
|
605
|
+
}))
|
|
606
|
+
},
|
|
607
|
+
power: {
|
|
608
|
+
sufficient: power.scaleAssumed && !power.underpowered,
|
|
609
|
+
n: power.n,
|
|
610
|
+
minimumDetectableDelta: power.mde,
|
|
611
|
+
confidenceLevel: power.confidence,
|
|
612
|
+
scaleAssumed: power.scaleAssumed,
|
|
613
|
+
sharedScorerChannel: power.sharedChannelCaveat !== void 0,
|
|
614
|
+
reason: power.recommendation
|
|
615
|
+
},
|
|
616
|
+
provenance: {
|
|
617
|
+
kind: "agent-eval-loop",
|
|
618
|
+
schema: result.provenance.schema,
|
|
619
|
+
runId: result.provenance.runId,
|
|
620
|
+
recordDigest: digest(result.provenance),
|
|
621
|
+
baselineContentHash: result.provenance.baselineContentHash,
|
|
622
|
+
candidateContentHash: result.provenance.winnerContentHash
|
|
623
|
+
},
|
|
624
|
+
diff: result.diff,
|
|
625
|
+
evaluation: {
|
|
626
|
+
generationsExplored: result.generationsExplored,
|
|
627
|
+
durationMs: result.durationMs,
|
|
628
|
+
totalCostUsd: result.totalCostUsd
|
|
629
|
+
}
|
|
630
|
+
});
|
|
631
|
+
}
|
|
632
|
+
function measuredObjectives(pairs) {
|
|
633
|
+
const qualityColumns = /* @__PURE__ */ new Map();
|
|
634
|
+
for (const [baseline, candidate] of pairs) {
|
|
635
|
+
for (const cell of [baseline, candidate]) {
|
|
636
|
+
for (const [objective, score] of Object.entries(cell.judgeScores)) {
|
|
637
|
+
if (score.failed) continue;
|
|
638
|
+
qualityColumns.set(`objective:${objective}`, {
|
|
639
|
+
kind: "objective",
|
|
640
|
+
name: objective,
|
|
641
|
+
direction: "higher-is-better",
|
|
642
|
+
unit: "score"
|
|
643
|
+
});
|
|
644
|
+
for (const name of Object.keys(score.dimensions)) {
|
|
645
|
+
qualityColumns.set(`dimension:${objective}:${name}`, {
|
|
646
|
+
kind: "dimension",
|
|
647
|
+
objective,
|
|
648
|
+
name,
|
|
649
|
+
direction: "higher-is-better",
|
|
650
|
+
unit: "score"
|
|
651
|
+
});
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
return [
|
|
657
|
+
...[...qualityColumns.entries()].sort(([left], [right]) => left.localeCompare(right)).map(
|
|
658
|
+
([, column]) => measuredObjective(column, pairs, (cell) => measuredQuality(cell, column))
|
|
659
|
+
),
|
|
660
|
+
measuredCostObjective(pairs),
|
|
661
|
+
measuredObjective(
|
|
662
|
+
{
|
|
663
|
+
kind: "latency",
|
|
664
|
+
name: "latency",
|
|
665
|
+
direction: "lower-is-better",
|
|
666
|
+
unit: "milliseconds"
|
|
667
|
+
},
|
|
668
|
+
pairs,
|
|
669
|
+
(cell) => cell.durationMs
|
|
670
|
+
)
|
|
671
|
+
];
|
|
672
|
+
}
|
|
673
|
+
function measuredCostObjective(pairs) {
|
|
674
|
+
const cells = pairs.flat();
|
|
675
|
+
for (const cell of cells) finiteMeasuredValue(cell.costUsd, "cost:cost");
|
|
676
|
+
const reported = cells.some(
|
|
677
|
+
(cell) => cell.costUsd !== 0 || cell.tokenUsage !== void 0 && (cell.tokenUsage.input > 0 || cell.tokenUsage.output > 0)
|
|
678
|
+
);
|
|
679
|
+
if (!reported) {
|
|
680
|
+
return {
|
|
681
|
+
kind: "cost",
|
|
682
|
+
name: "cost",
|
|
683
|
+
availability: "unavailable",
|
|
684
|
+
reason: "heldout cells did not report model usage or cost",
|
|
685
|
+
direction: "lower-is-better",
|
|
686
|
+
unit: "usd"
|
|
687
|
+
};
|
|
688
|
+
}
|
|
689
|
+
return measuredObjective(
|
|
690
|
+
{
|
|
691
|
+
kind: "cost",
|
|
692
|
+
name: "cost",
|
|
693
|
+
direction: "lower-is-better",
|
|
694
|
+
unit: "usd"
|
|
695
|
+
},
|
|
696
|
+
pairs,
|
|
697
|
+
(cell) => cell.costUsd
|
|
698
|
+
);
|
|
699
|
+
}
|
|
700
|
+
function measuredComposite(cell) {
|
|
701
|
+
const values = Object.values(cell.judgeScores).filter((score) => !score.failed).map((score) => score.composite).filter(Number.isFinite);
|
|
702
|
+
if (values.length === 0) {
|
|
703
|
+
throw new Error(`heldout cell ${measuredCellKey(cell)} has no successful composite score`);
|
|
704
|
+
}
|
|
705
|
+
return measuredMean(values);
|
|
706
|
+
}
|
|
707
|
+
function pairMeasuredCells(baselineCells, candidateCells) {
|
|
708
|
+
const errors = [...baselineCells, ...candidateCells].filter((cell) => cell.error);
|
|
709
|
+
if (errors.length > 0) {
|
|
710
|
+
throw new Error(
|
|
711
|
+
`measured objectives cannot publish ${errors.length} errored heldout cells: ${errors.map((cell) => measuredCellKey(cell)).join(", ")}`
|
|
712
|
+
);
|
|
713
|
+
}
|
|
714
|
+
const rows = [
|
|
715
|
+
...baselineCells.map((cell) => ({
|
|
716
|
+
pairKey: cell.scenarioId,
|
|
717
|
+
repKey: String(cell.rep),
|
|
718
|
+
arm: "baseline",
|
|
719
|
+
cell
|
|
720
|
+
})),
|
|
721
|
+
...candidateCells.map((cell) => ({
|
|
722
|
+
pairKey: cell.scenarioId,
|
|
723
|
+
repKey: String(cell.rep),
|
|
724
|
+
arm: "candidate",
|
|
725
|
+
cell
|
|
726
|
+
}))
|
|
727
|
+
];
|
|
728
|
+
const paired = pairArms(rows, { baselineArm: "baseline", treatmentArm: "candidate" });
|
|
729
|
+
if (paired.pairs.length === 0 || paired.unpairedBaseline.length > 0 || paired.unpairedTreatment.length > 0) {
|
|
730
|
+
throw new Error("measured objectives require the same non-empty paired heldout cells");
|
|
731
|
+
}
|
|
732
|
+
return paired.pairs.map(
|
|
733
|
+
(pair) => [pair.baseline.cell, pair.treatment.cell]
|
|
734
|
+
);
|
|
735
|
+
}
|
|
736
|
+
function measuredObjective(identity, pairs, value) {
|
|
737
|
+
const key = measuredObjectiveKey(identity);
|
|
738
|
+
const baseline = pairs.map(([cell]) => finiteMeasuredValue(value(cell), key));
|
|
739
|
+
const candidate = pairs.map(([, cell]) => finiteMeasuredValue(value(cell), key));
|
|
740
|
+
const interval = pairedBootstrap(baseline, candidate, {
|
|
741
|
+
confidence: 0.95,
|
|
742
|
+
resamples: 2e3,
|
|
743
|
+
statistic: "mean",
|
|
744
|
+
seed: measuredSeed(key)
|
|
745
|
+
});
|
|
746
|
+
const baselineMean = measuredMean(baseline);
|
|
747
|
+
const candidateMean = measuredMean(candidate);
|
|
748
|
+
return {
|
|
749
|
+
...identity,
|
|
750
|
+
availability: "measured",
|
|
751
|
+
baseline: baselineMean,
|
|
752
|
+
candidate: candidateMean,
|
|
753
|
+
delta: candidateMean - baselineMean,
|
|
754
|
+
confidenceInterval: {
|
|
755
|
+
level: interval.confidence,
|
|
756
|
+
lower: interval.low,
|
|
757
|
+
upper: interval.high,
|
|
758
|
+
method: "paired-bootstrap",
|
|
759
|
+
statistic: "mean",
|
|
760
|
+
resamples: interval.resamples
|
|
761
|
+
},
|
|
762
|
+
n: interval.n
|
|
763
|
+
};
|
|
764
|
+
}
|
|
765
|
+
function measuredQuality(cell, column) {
|
|
766
|
+
const objective = column.kind === "objective" ? column.name : column.objective;
|
|
767
|
+
const score = cell.judgeScores[objective];
|
|
768
|
+
if (!score || score.failed) {
|
|
769
|
+
throw new Error(
|
|
770
|
+
`heldout cell ${measuredCellKey(cell)} is missing measured objective '${objective}'`
|
|
771
|
+
);
|
|
772
|
+
}
|
|
773
|
+
const value = column.kind === "objective" ? score.composite : score.dimensions[column.name];
|
|
774
|
+
if (value === void 0) {
|
|
775
|
+
throw new Error(
|
|
776
|
+
`heldout cell ${measuredCellKey(cell)} is missing '${objective}' dimension '${column.name}'`
|
|
777
|
+
);
|
|
778
|
+
}
|
|
779
|
+
return finiteMeasuredValue(value, measuredObjectiveKey(column));
|
|
780
|
+
}
|
|
781
|
+
function measuredObjectiveKey(identity) {
|
|
782
|
+
return identity.kind === "dimension" ? `${identity.kind}:${identity.objective}:${identity.name}` : `${identity.kind}:${identity.name}`;
|
|
783
|
+
}
|
|
784
|
+
function measuredCellKey(cell) {
|
|
785
|
+
return `${cell.scenarioId}:${cell.rep}`;
|
|
786
|
+
}
|
|
787
|
+
function finiteMeasuredValue(value, name) {
|
|
788
|
+
if (!Number.isFinite(value)) throw new Error(`measured objective '${name}' is not finite`);
|
|
789
|
+
return value;
|
|
790
|
+
}
|
|
791
|
+
function measuredMean(values) {
|
|
792
|
+
if (values.length === 0) throw new Error("measured objective has no paired values");
|
|
793
|
+
return values.reduce((sum, value) => sum + value, 0) / values.length;
|
|
794
|
+
}
|
|
795
|
+
function measuredSeed(value) {
|
|
796
|
+
let seed = 2166136261;
|
|
797
|
+
for (const byte of Buffer.from(value, "utf8")) {
|
|
798
|
+
seed = Math.imul(seed ^ byte, 16777619) >>> 0;
|
|
799
|
+
}
|
|
800
|
+
return seed;
|
|
801
|
+
}
|
|
802
|
+
function assertMeasuredNumber(actual, expected, name) {
|
|
803
|
+
const tolerance = Number.EPSILON * Math.max(1, Math.abs(actual), Math.abs(expected)) * 8;
|
|
804
|
+
if (!Number.isFinite(actual) || !Number.isFinite(expected) || Math.abs(actual - expected) > tolerance) {
|
|
805
|
+
throw new Error(`${name} does not agree across the measured comparison`);
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
function digest(value) {
|
|
809
|
+
const json = JSON.stringify(value);
|
|
810
|
+
if (json === void 0) throw new Error("agent improvement provenance is not serializable");
|
|
811
|
+
return `sha256:${createHash2("sha256").update(canonicalJson(JSON.parse(json))).digest("hex")}`;
|
|
812
|
+
}
|
|
813
|
+
|
|
539
814
|
// src/contract/eval-reporting-suite.ts
|
|
540
815
|
import { mkdir, writeFile } from "fs/promises";
|
|
541
816
|
import { dirname, join as join2 } from "path";
|
|
@@ -1074,6 +1349,7 @@ export {
|
|
|
1074
1349
|
gepaProposer,
|
|
1075
1350
|
heldOutGate,
|
|
1076
1351
|
inMemoryCampaignStorage,
|
|
1352
|
+
measuredComparisonFromSelfImproveResult,
|
|
1077
1353
|
paretoPolicy,
|
|
1078
1354
|
paretoSignificanceGate,
|
|
1079
1355
|
parseAgentTrace,
|