@tangle-network/agent-eval 0.126.5 → 0.126.7
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 +13 -0
- package/README.md +1 -1
- package/dist/analyst/index.d.ts +1 -1
- package/dist/benchmarks/index.js +2 -2
- package/dist/campaign/index.d.ts +2 -0
- package/dist/campaign/index.js +2 -2
- package/dist/{chunk-3I74FLK6.js → chunk-BTACVO2W.js} +6 -1
- package/dist/chunk-BTACVO2W.js.map +1 -0
- package/dist/{chunk-P6WN2KF5.js → chunk-E3IADPLG.js} +2 -2
- package/dist/contract/index.d.ts +46 -3
- package/dist/contract/index.js +184 -97
- package/dist/contract/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/openapi.json +1 -1
- package/package.json +19 -13
- package/dist/chunk-3I74FLK6.js.map +0 -1
- /package/dist/{chunk-P6WN2KF5.js.map → chunk-E3IADPLG.js.map} +0 -0
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
pairHoldout,
|
|
8
8
|
recoverTruncatedJson,
|
|
9
9
|
surfaceContentHash
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-BTACVO2W.js";
|
|
11
11
|
import {
|
|
12
12
|
SearchLedgerConflictError,
|
|
13
13
|
SearchLedgerError,
|
|
@@ -4634,4 +4634,4 @@ export {
|
|
|
4634
4634
|
verifyCodeSurface,
|
|
4635
4635
|
resolveWorktreePath
|
|
4636
4636
|
};
|
|
4637
|
-
//# sourceMappingURL=chunk-
|
|
4637
|
+
//# sourceMappingURL=chunk-E3IADPLG.js.map
|
package/dist/contract/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { AgentCandidateExperiment, AgentCandidateBundle, AgentCandidateBenchmarkTask, AgentCandidateBenchmarkCellRef, AgentCandidateExperimentMeasurement, AgentImprovementMeasuredComparison, CandidateExecutionEvidence, AgentCandidateBenchmarkSuiteInputs, AgentCandidateBenchmarkTaskMaterial, AgentCandidateExperimentMaterial } from '@tangle-network/agent-interface';
|
|
2
|
+
import { AgentCandidateExperiment, AgentCandidateBundle, AgentCandidateBenchmarkTask, AgentCandidateBenchmarkCellRef, AgentCandidateExperimentMeasurement, AgentImprovementMeasuredComparison, AgentCandidateEvaluationPolicy, CandidateExecutionEvidence, AgentCandidateBenchmarkSuiteInputs, AgentCandidateBenchmarkTaskMaterial, AgentCandidateExperimentMaterial } from '@tangle-network/agent-interface';
|
|
3
3
|
import { AxFunction, AxAIService } from '@ax-llm/ax';
|
|
4
4
|
|
|
5
5
|
type CostChannel = 'agent' | 'judge' | 'verifier' | 'analyst' | 'driver' | (string & {});
|
|
@@ -1911,6 +1911,8 @@ interface OptimizationMethodProvenance {
|
|
|
1911
1911
|
modules?: OptimizationModuleSource[];
|
|
1912
1912
|
/** Python implementation used by the bridge process. */
|
|
1913
1913
|
python?: OptimizationPythonRuntime;
|
|
1914
|
+
/** Exact model identifier configured for optimizer-owned model calls. */
|
|
1915
|
+
optimizerModel?: string;
|
|
1914
1916
|
runId: string;
|
|
1915
1917
|
/** Content identity shared by compatible resumptions. */
|
|
1916
1918
|
compatibleRunId?: string;
|
|
@@ -3966,6 +3968,39 @@ interface CompareCandidateExperimentOptions {
|
|
|
3966
3968
|
searchCostUsd?: number;
|
|
3967
3969
|
metadata?: AgentImprovementMeasuredComparison['metadata'];
|
|
3968
3970
|
}
|
|
3971
|
+
/** One exact baseline/candidate observation of the same held-out cell. */
|
|
3972
|
+
interface PairedMeasurement<TRun> {
|
|
3973
|
+
cellId: string;
|
|
3974
|
+
baseline: TRun;
|
|
3975
|
+
candidate: TRun;
|
|
3976
|
+
}
|
|
3977
|
+
/** Maps a product-owned run receipt into the measurements required for a fair paired decision. */
|
|
3978
|
+
interface PairedMeasurementAdapter<TRun> {
|
|
3979
|
+
score(run: TRun): number;
|
|
3980
|
+
dimensions(run: TRun): readonly {
|
|
3981
|
+
name: string;
|
|
3982
|
+
score: number;
|
|
3983
|
+
}[];
|
|
3984
|
+
costUsd(run: TRun): number;
|
|
3985
|
+
latencyMs(run: TRun): number;
|
|
3986
|
+
completed(run: TRun): boolean;
|
|
3987
|
+
passed(run: TRun): boolean;
|
|
3988
|
+
}
|
|
3989
|
+
interface EvaluatePairedMeasurementsOptions<TRun> {
|
|
3990
|
+
measurements: readonly PairedMeasurement<TRun>[];
|
|
3991
|
+
policy: AgentCandidateEvaluationPolicy;
|
|
3992
|
+
adapter: PairedMeasurementAdapter<TRun>;
|
|
3993
|
+
/** Whether both arms use the same scorer family as the promotion decision. */
|
|
3994
|
+
sharedScorerChannel: boolean;
|
|
3995
|
+
/** Search or preparation spend that belongs to the same frozen budget. */
|
|
3996
|
+
additionalCostUsd?: number;
|
|
3997
|
+
}
|
|
3998
|
+
/** Statistical and operational result derived from complete paired receipts. */
|
|
3999
|
+
type PairedMeasurementEvaluation = Pick<AgentImprovementMeasuredComparison, 'overall' | 'objectives' | 'decision' | 'power'> & {
|
|
4000
|
+
executionCostUsd: number;
|
|
4001
|
+
totalCostUsd: number;
|
|
4002
|
+
executionDurationMs: number;
|
|
4003
|
+
};
|
|
3969
4004
|
/** Content-address one task before any measured execution can see it. */
|
|
3970
4005
|
declare function sealCandidateBenchmarkTask(material: AgentCandidateBenchmarkTaskMaterial): AgentCandidateBenchmarkTask;
|
|
3971
4006
|
/** Freeze task order, repetitions, and every seed before either arm runs. */
|
|
@@ -3975,6 +4010,14 @@ declare function sealCandidateExperiment(material: AgentCandidateExperimentMater
|
|
|
3975
4010
|
declare function verifyCandidateExperiment(input: unknown): AgentCandidateExperiment;
|
|
3976
4011
|
/** Execute each signed cell for both arms. The callback is Runtime's one executor. */
|
|
3977
4012
|
declare function runCandidateExperiment(options: RunCandidateExperimentOptions): Promise<AgentCandidateExperimentMeasurement[]>;
|
|
4013
|
+
/**
|
|
4014
|
+
* Calculate the shared paired decision from any complete receipt shape.
|
|
4015
|
+
*
|
|
4016
|
+
* Callers still own sealing their tasks, verifying each receipt against its
|
|
4017
|
+
* expected arm and state, and proving every expected cell exists. This function
|
|
4018
|
+
* only validates the projected measurements and derives their shared decision.
|
|
4019
|
+
*/
|
|
4020
|
+
declare function evaluatePairedMeasurements<TRun>(options: EvaluatePairedMeasurementsOptions<TRun>): PairedMeasurementEvaluation;
|
|
3978
4021
|
/** Build the only publishable comparison: paired statistics over Runtime receipts. */
|
|
3979
4022
|
declare function measuredComparisonFromCandidateExperiment(options: CompareCandidateExperimentOptions): AgentImprovementMeasuredComparison;
|
|
3980
4023
|
/** Recompute every statistic and decision from the signed experiment receipts. */
|
|
@@ -4520,7 +4563,7 @@ type RawAnalystFinding = z.infer<typeof RawAnalystFindingSchema>;
|
|
|
4520
4563
|
* item so persisted rows and older model fixtures remain readable. New output
|
|
4521
4564
|
* always receives the plural shape.
|
|
4522
4565
|
*/
|
|
4523
|
-
declare const CanonicalRawAnalystFindingSchema: z.
|
|
4566
|
+
declare const CanonicalRawAnalystFindingSchema: z.ZodPreprocess<z.ZodObject<{
|
|
4524
4567
|
evidence: z.ZodArray<z.ZodObject<{
|
|
4525
4568
|
uri: z.ZodString;
|
|
4526
4569
|
excerpt: z.ZodOptional<z.ZodString>;
|
|
@@ -5463,4 +5506,4 @@ interface FromOtelSpansOptions {
|
|
|
5463
5506
|
}
|
|
5464
5507
|
declare function fromOtelSpans(opts: FromOtelSpansOptions): RunRecord[];
|
|
5465
5508
|
|
|
5466
|
-
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 CampaignCellFailureReceipt, type CampaignCellResult, type CampaignCostMeter, type CampaignResult, type CampaignStorage, type CampaignTraceWriter, type CandidateExperimentExecutionInput, type ChatClient, type CodeAgentSessionAction, type CodeAgentSessionActionKind, type CodeAgentSessionActionStatus, type CodeAgentSessionActionSurface, type CodeAgentSessionDiagnostic, type CodeAgentSessionExecutionReceipt, type CodeAgentSessionIntakeOptions, type CodeAgentSessionIntakeResult, type CodeAgentSessionMetrics, type CodeAgentSessionObservation, type CodeAgentSessionSource, type CodeAgentSessionTerminalStatus, type CodeSurface, type CompareCandidateExperimentOptions, type CompareOptimizationMethodsOptions, type ComparisonCost, 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 ExecutionInsight, type ExecutionReport, type ExternalOptimizationExample, type ExternalTextEvaluationResponse, type ExternalTextOptimizationMethodConfig, type ExternalTextOptimizerContext, type ExternalTextOptimizerResult, 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 GepaAdaptiveEngineRun, type GepaEngineOptions, type GepaEngineRun, type GepaOptimizationMethodConfig, type GepaOptimizationRecipe, type GepaRunnerCommand, type HeldOutGateOptions, type HostedTenant, InMemoryOutcomeStore, type InsightReport, type InterRaterInsight, type JudgeConfig, type JudgeDimension, type JudgeInsight, type JudgeScore, type LiftInsight, type LlmJudgeDimension, type LlmJudgeOptions, type MutableSurface, type ObjectiveSource, type OpenAICompatibleOptimizerModel, type OptimizationMethod, type OptimizationMethodComparison, type OptimizationMethodInput, type OptimizationMethodProvenance, type OptimizationMethodResult, type OptimizationPackageSource, type OptimizationProposer, type OptimizationTokenUsage, type OptimizerConfig, type OptimizerModelBudget, 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 RunCandidateExperimentOptions, type RunEvalOptions, type RunImprovementLoopOptions, type RunImprovementLoopResult, type RunRecordRejection, type ScalarDistribution, type Scenario$1 as Scenario, type SealCandidateBenchmarkSuiteOptions, type SelfImproveBudget, type SelfImproveOptions, type SelfImproveProgressEvent, type SelfImproveResult, SelfImproveRunError, type SessionScript, type SkillOptOptimizationMethodConfig, type SkillOptRunnerCommand, type SkillOptTrainerConfig, type SummarizeExecutionOptions, type SurfaceProposer, type TokenUsageInsight, analyzeRuns, buildDefaultAnalystRegistry, buildEvidenceVector, campaignSplitDigest, compareOptimizationMethods, composeGate, createChatClient, createReferenceEquivalenceJudge, defaultProductionGate, defineAgentEval, diffGenerations, diffRunBaselineToWinner, diffRuns, evalReportingSuite, externalTextOptimizationMethod, fromClaudeCodeSession, fromCodexSession, fromFeedbackTable, fromKimiCodeSession, fromOpenCodeSession, fromOtelSpans, fromPiSession, fromPigraphSession, fromRunRecordDir, fsCampaignStorage, gepaOptimizationMethod, heldOutGate, inMemoryCampaignStorage, llmJudge, measuredComparisonFromCandidateExperiment, observeCodeAgentSession, paretoPolicy, paretoSignificanceGate, parseAgentTrace, parseCodeAgentJsonl, partitionRunsByAuthoringModel, runCampaign, runCandidateExperiment, runEval, runImprovementLoop, runReferenceEquivalenceJudge, sealCandidateBenchmarkSuite, sealCandidateBenchmarkTask, sealCandidateExperiment, selfImprove, skillOptOptimizationMethod, summarizeExecution, verifyCandidateBenchmarkSuite, verifyCandidateBenchmarkSuiteInputs, verifyCandidateBenchmarkTask, verifyCandidateExperiment, verifyCandidateExperimentComparison };
|
|
5509
|
+
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 CampaignCellFailureReceipt, type CampaignCellResult, type CampaignCostMeter, type CampaignResult, type CampaignStorage, type CampaignTraceWriter, type CandidateExperimentExecutionInput, type ChatClient, type CodeAgentSessionAction, type CodeAgentSessionActionKind, type CodeAgentSessionActionStatus, type CodeAgentSessionActionSurface, type CodeAgentSessionDiagnostic, type CodeAgentSessionExecutionReceipt, type CodeAgentSessionIntakeOptions, type CodeAgentSessionIntakeResult, type CodeAgentSessionMetrics, type CodeAgentSessionObservation, type CodeAgentSessionSource, type CodeAgentSessionTerminalStatus, type CodeSurface, type CompareCandidateExperimentOptions, type CompareOptimizationMethodsOptions, type ComparisonCost, 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 EvaluatePairedMeasurementsOptions, type EvidenceVector, type ExecutionInsight, type ExecutionReport, type ExternalOptimizationExample, type ExternalTextEvaluationResponse, type ExternalTextOptimizationMethodConfig, type ExternalTextOptimizerContext, type ExternalTextOptimizerResult, 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 GepaAdaptiveEngineRun, type GepaEngineOptions, type GepaEngineRun, type GepaOptimizationMethodConfig, type GepaOptimizationRecipe, type GepaRunnerCommand, type HeldOutGateOptions, type HostedTenant, InMemoryOutcomeStore, type InsightReport, type InterRaterInsight, type JudgeConfig, type JudgeDimension, type JudgeInsight, type JudgeScore, type LiftInsight, type LlmJudgeDimension, type LlmJudgeOptions, type MutableSurface, type ObjectiveSource, type OpenAICompatibleOptimizerModel, type OptimizationMethod, type OptimizationMethodComparison, type OptimizationMethodInput, type OptimizationMethodProvenance, type OptimizationMethodResult, type OptimizationPackageSource, type OptimizationProposer, type OptimizationTokenUsage, type OptimizerConfig, type OptimizerModelBudget, type OutcomeCorrelationInsight, type OutcomeStore, type PairedMeasurement, type PairedMeasurementAdapter, type PairedMeasurementEvaluation, 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 RunCandidateExperimentOptions, type RunEvalOptions, type RunImprovementLoopOptions, type RunImprovementLoopResult, type RunRecordRejection, type ScalarDistribution, type Scenario$1 as Scenario, type SealCandidateBenchmarkSuiteOptions, type SelfImproveBudget, type SelfImproveOptions, type SelfImproveProgressEvent, type SelfImproveResult, SelfImproveRunError, type SessionScript, type SkillOptOptimizationMethodConfig, type SkillOptRunnerCommand, type SkillOptTrainerConfig, type SummarizeExecutionOptions, type SurfaceProposer, type TokenUsageInsight, analyzeRuns, buildDefaultAnalystRegistry, buildEvidenceVector, campaignSplitDigest, compareOptimizationMethods, composeGate, createChatClient, createReferenceEquivalenceJudge, defaultProductionGate, defineAgentEval, diffGenerations, diffRunBaselineToWinner, diffRuns, evalReportingSuite, evaluatePairedMeasurements, externalTextOptimizationMethod, fromClaudeCodeSession, fromCodexSession, fromFeedbackTable, fromKimiCodeSession, fromOpenCodeSession, fromOtelSpans, fromPiSession, fromPigraphSession, fromRunRecordDir, fsCampaignStorage, gepaOptimizationMethod, heldOutGate, inMemoryCampaignStorage, llmJudge, measuredComparisonFromCandidateExperiment, observeCodeAgentSession, paretoPolicy, paretoSignificanceGate, parseAgentTrace, parseCodeAgentJsonl, partitionRunsByAuthoringModel, runCampaign, runCandidateExperiment, runEval, runImprovementLoop, runReferenceEquivalenceJudge, sealCandidateBenchmarkSuite, sealCandidateBenchmarkTask, sealCandidateExperiment, selfImprove, skillOptOptimizationMethod, summarizeExecution, verifyCandidateBenchmarkSuite, verifyCandidateBenchmarkSuiteInputs, verifyCandidateBenchmarkTask, verifyCandidateExperiment, verifyCandidateExperimentComparison };
|
package/dist/contract/index.js
CHANGED
|
@@ -40,7 +40,7 @@ import {
|
|
|
40
40
|
skillOptOptimizationMethod,
|
|
41
41
|
surfaceContentHash,
|
|
42
42
|
surfaceHash
|
|
43
|
-
} from "../chunk-
|
|
43
|
+
} from "../chunk-BTACVO2W.js";
|
|
44
44
|
import {
|
|
45
45
|
campaignSplitDigest,
|
|
46
46
|
createRunCostLedger,
|
|
@@ -698,6 +698,7 @@ import {
|
|
|
698
698
|
agentCandidateBenchmarkSuiteSchema,
|
|
699
699
|
agentCandidateBenchmarkTaskSchema,
|
|
700
700
|
agentCandidateBundleSchema,
|
|
701
|
+
agentCandidateEvaluationPolicySchema,
|
|
701
702
|
agentCandidateExperimentSchema,
|
|
702
703
|
agentImprovementMeasuredComparisonSchema,
|
|
703
704
|
candidateExecutionEvidenceSchema,
|
|
@@ -800,19 +801,28 @@ async function runCandidateExperiment(options) {
|
|
|
800
801
|
await Promise.all(lanes);
|
|
801
802
|
return measurements;
|
|
802
803
|
}
|
|
803
|
-
function
|
|
804
|
-
|
|
804
|
+
function evaluatePairedMeasurements(options) {
|
|
805
|
+
if (options.measurements.length === 0) {
|
|
806
|
+
throw new Error("paired measurement evaluation requires at least one paired cell");
|
|
807
|
+
}
|
|
808
|
+
const additionalCostUsd = options.additionalCostUsd ?? 0;
|
|
809
|
+
if (!Number.isFinite(additionalCostUsd) || additionalCostUsd < 0) {
|
|
810
|
+
throw new Error("paired measurement evaluation additionalCostUsd must be a non-negative number");
|
|
811
|
+
}
|
|
812
|
+
if (typeof options.sharedScorerChannel !== "boolean") {
|
|
813
|
+
throw new Error("paired measurement evaluation sharedScorerChannel must be a boolean");
|
|
814
|
+
}
|
|
815
|
+
const policy = agentCandidateEvaluationPolicySchema.parse(options.policy);
|
|
805
816
|
const measurements = options.measurements.map(
|
|
806
|
-
(measurement, index) =>
|
|
817
|
+
(measurement, index) => projectPairedMeasurement(measurement, index, options.adapter)
|
|
807
818
|
);
|
|
808
|
-
const
|
|
809
|
-
if (
|
|
810
|
-
throw new Error(
|
|
811
|
-
`candidate experiment is incomplete (${measurements.length}/${expectedN} paired cells)`
|
|
812
|
-
);
|
|
819
|
+
const cellIds2 = measurements.map((measurement) => measurement.cellId);
|
|
820
|
+
if (new Set(cellIds2).size !== cellIds2.length) {
|
|
821
|
+
throw new Error("paired measurement evaluation cell ids must be unique");
|
|
813
822
|
}
|
|
814
|
-
|
|
815
|
-
|
|
823
|
+
const dimensions = sharedProjectedDimensions(measurements);
|
|
824
|
+
const baselineScores = measurements.map((measurement) => measurement.baseline.score);
|
|
825
|
+
const candidateScores = measurements.map((measurement) => measurement.candidate.score);
|
|
816
826
|
const {
|
|
817
827
|
confidenceLevel: confidence,
|
|
818
828
|
resamples,
|
|
@@ -822,15 +832,23 @@ function measuredComparisonFromCandidateExperiment(options) {
|
|
|
822
832
|
budgetUsd,
|
|
823
833
|
criticalDimensions,
|
|
824
834
|
regressionTolerance
|
|
825
|
-
} =
|
|
826
|
-
const
|
|
827
|
-
|
|
835
|
+
} = policy;
|
|
836
|
+
const significance = heldoutSignificance(
|
|
837
|
+
{ before: baselineScores, after: candidateScores, cellIds: cellIds2 },
|
|
838
|
+
{
|
|
839
|
+
confidence,
|
|
840
|
+
resamples,
|
|
841
|
+
seed: bootstrapSeed,
|
|
842
|
+
statistic: "mean",
|
|
843
|
+
deltaThreshold,
|
|
844
|
+
minProductiveRuns
|
|
845
|
+
}
|
|
846
|
+
);
|
|
828
847
|
const overall = measuredEstimate(baselineScores, candidateScores, {
|
|
829
848
|
confidence,
|
|
830
849
|
resamples,
|
|
831
850
|
seed: bootstrapSeed
|
|
832
851
|
});
|
|
833
|
-
const dimensions = sharedDimensions(measurements);
|
|
834
852
|
const objectives = [
|
|
835
853
|
{
|
|
836
854
|
kind: "objective",
|
|
@@ -848,21 +866,33 @@ function measuredComparisonFromCandidateExperiment(options) {
|
|
|
848
866
|
unit: "score",
|
|
849
867
|
availability: "measured",
|
|
850
868
|
...measuredEstimate(
|
|
851
|
-
measurements.map(
|
|
852
|
-
measurements.map(
|
|
853
|
-
{
|
|
869
|
+
measurements.map((measurement) => dimensionScore(measurement.baseline, name)),
|
|
870
|
+
measurements.map((measurement) => dimensionScore(measurement.candidate, name)),
|
|
871
|
+
{
|
|
872
|
+
confidence,
|
|
873
|
+
resamples,
|
|
874
|
+
seed: bootstrapSeed + index + 1
|
|
875
|
+
}
|
|
854
876
|
)
|
|
855
877
|
}))
|
|
856
878
|
];
|
|
857
879
|
const cost = measuredEstimate(
|
|
858
|
-
measurements.map(
|
|
859
|
-
measurements.map(
|
|
860
|
-
{
|
|
880
|
+
measurements.map((measurement) => measurement.baseline.costUsd),
|
|
881
|
+
measurements.map((measurement) => measurement.candidate.costUsd),
|
|
882
|
+
{
|
|
883
|
+
confidence,
|
|
884
|
+
resamples,
|
|
885
|
+
seed: bootstrapSeed + dimensions.length + 1
|
|
886
|
+
}
|
|
861
887
|
);
|
|
862
888
|
const latency = measuredEstimate(
|
|
863
|
-
measurements.map(
|
|
864
|
-
measurements.map(
|
|
865
|
-
{
|
|
889
|
+
measurements.map((measurement) => measurement.baseline.latencyMs),
|
|
890
|
+
measurements.map((measurement) => measurement.candidate.latencyMs),
|
|
891
|
+
{
|
|
892
|
+
confidence,
|
|
893
|
+
resamples,
|
|
894
|
+
seed: bootstrapSeed + dimensions.length + 2
|
|
895
|
+
}
|
|
866
896
|
);
|
|
867
897
|
objectives.push(
|
|
868
898
|
{
|
|
@@ -882,23 +912,12 @@ function measuredComparisonFromCandidateExperiment(options) {
|
|
|
882
912
|
...latency
|
|
883
913
|
}
|
|
884
914
|
);
|
|
885
|
-
const significance = heldoutSignificance(
|
|
886
|
-
{ before: baselineScores, after: candidateScores, cellIds: cellIds(experiment) },
|
|
887
|
-
{
|
|
888
|
-
confidence,
|
|
889
|
-
resamples,
|
|
890
|
-
seed: bootstrapSeed,
|
|
891
|
-
statistic: "mean",
|
|
892
|
-
deltaThreshold,
|
|
893
|
-
minProductiveRuns
|
|
894
|
-
}
|
|
895
|
-
);
|
|
896
915
|
const power = baselineScores.length >= 3 ? powerPreflight({
|
|
897
916
|
baselineComposites: baselineScores,
|
|
898
917
|
pairedN: baselineScores.length,
|
|
899
918
|
deltaThreshold,
|
|
900
919
|
confidence,
|
|
901
|
-
sharedScorerChannel:
|
|
920
|
+
sharedScorerChannel: options.sharedScorerChannel
|
|
902
921
|
}) : void 0;
|
|
903
922
|
const powerSufficient = baselineScores.length >= minProductiveRuns && power !== void 0 && !power.underpowered;
|
|
904
923
|
const guardedDimensions = new Set(criticalDimensions);
|
|
@@ -909,20 +928,21 @@ function measuredComparisonFromCandidateExperiment(options) {
|
|
|
909
928
|
(objective) => objective.kind === "dimension" && guardedDimensions.has(objective.name) && objective.availability === "measured" && objective.confidenceInterval.lower < -regressionTolerance
|
|
910
929
|
);
|
|
911
930
|
const executionCostUsd = measurements.reduce(
|
|
912
|
-
(sum, measurement) => sum +
|
|
931
|
+
(sum, measurement) => sum + measurement.baseline.costUsd + measurement.candidate.costUsd,
|
|
932
|
+
0
|
|
933
|
+
);
|
|
934
|
+
const executionDurationMs = measurements.reduce(
|
|
935
|
+
(sum, measurement) => sum + measurement.baseline.latencyMs + measurement.candidate.latencyMs,
|
|
913
936
|
0
|
|
914
937
|
);
|
|
915
|
-
const searchCostUsd = options.searchCostUsd ?? 0;
|
|
916
|
-
const totalCostUsd = executionCostUsd + searchCostUsd;
|
|
917
|
-
const budgetPassed = budgetUsd === void 0 || totalCostUsd <= budgetUsd;
|
|
918
938
|
const completedRuns = measurements.flatMap((measurement) => [
|
|
919
939
|
measurement.baseline,
|
|
920
940
|
measurement.candidate
|
|
921
941
|
]);
|
|
922
|
-
const incompleteRuns = completedRuns.filter((
|
|
923
|
-
const failedCandidateResults = measurements.filter(
|
|
924
|
-
|
|
925
|
-
|
|
942
|
+
const incompleteRuns = completedRuns.filter((run) => !run.completed);
|
|
943
|
+
const failedCandidateResults = measurements.filter((measurement) => !measurement.candidate.passed);
|
|
944
|
+
const totalCostUsd = executionCostUsd + additionalCostUsd;
|
|
945
|
+
const budgetPassed = budgetUsd === void 0 || totalCostUsd <= budgetUsd;
|
|
926
946
|
const checks = [
|
|
927
947
|
{ name: "paired-significance", passed: significance.significant },
|
|
928
948
|
{ name: "statistical-power", passed: powerSufficient },
|
|
@@ -946,17 +966,7 @@ function measuredComparisonFromCandidateExperiment(options) {
|
|
|
946
966
|
...failedCandidateResults.length === 0 ? [] : [`candidate failed ${failedCandidateResults.length} benchmark tasks`],
|
|
947
967
|
...budgetPassed ? [] : [`total cost ${totalCostUsd} exceeded budget ${budgetUsd}`]
|
|
948
968
|
];
|
|
949
|
-
|
|
950
|
-
const executionDurationMs = measurements.reduce(
|
|
951
|
-
(sum, measurement) => sum + latencyFromEvidence(measurement.baseline) + latencyFromEvidence(measurement.candidate),
|
|
952
|
-
0
|
|
953
|
-
);
|
|
954
|
-
const searchDurationMs = options.searchDurationMs ?? 0;
|
|
955
|
-
const durationMs = executionDurationMs + searchDurationMs;
|
|
956
|
-
const provisional = agentImprovementMeasuredComparisonSchema.parse({
|
|
957
|
-
kind: "agent-improvement-measured-comparison",
|
|
958
|
-
experiment,
|
|
959
|
-
measurements,
|
|
969
|
+
return {
|
|
960
970
|
overall: {
|
|
961
971
|
name: "composite",
|
|
962
972
|
direction: "higher-is-better",
|
|
@@ -964,7 +974,6 @@ function measuredComparisonFromCandidateExperiment(options) {
|
|
|
964
974
|
...overall
|
|
965
975
|
},
|
|
966
976
|
objectives,
|
|
967
|
-
...options.candidate ? { candidate: options.candidate } : {},
|
|
968
977
|
decision: {
|
|
969
978
|
outcome: shipped ? "ship" : significance.fewRuns || !powerSufficient ? "need_more_work" : "hold",
|
|
970
979
|
reasons: reasons.length > 0 ? reasons : ["all measured checks passed"],
|
|
@@ -976,9 +985,51 @@ function measuredComparisonFromCandidateExperiment(options) {
|
|
|
976
985
|
minimumDetectableDelta: power?.mde ?? 1,
|
|
977
986
|
confidenceLevel: confidence,
|
|
978
987
|
scaleAssumed: power?.scaleAssumed ?? true,
|
|
979
|
-
sharedScorerChannel:
|
|
988
|
+
sharedScorerChannel: options.sharedScorerChannel,
|
|
980
989
|
reason: power?.recommendation ?? `need at least ${Math.max(3, minProductiveRuns)} paired runs`
|
|
981
990
|
},
|
|
991
|
+
executionCostUsd,
|
|
992
|
+
totalCostUsd,
|
|
993
|
+
executionDurationMs
|
|
994
|
+
};
|
|
995
|
+
}
|
|
996
|
+
function measuredComparisonFromCandidateExperiment(options) {
|
|
997
|
+
const experiment = verifyCandidateExperiment(options.experiment);
|
|
998
|
+
const measurements = options.measurements.map(
|
|
999
|
+
(measurement, index) => verifyMeasurement(experiment, measurement, index)
|
|
1000
|
+
);
|
|
1001
|
+
const expectedN = experiment.benchmark.suite.taskDigests.length * experiment.benchmark.suite.reps;
|
|
1002
|
+
if (measurements.length !== expectedN) {
|
|
1003
|
+
throw new Error(
|
|
1004
|
+
`candidate experiment is incomplete (${measurements.length}/${expectedN} paired cells)`
|
|
1005
|
+
);
|
|
1006
|
+
}
|
|
1007
|
+
verifyStableProfileMaterialization(measurements);
|
|
1008
|
+
if (!options.runId.trim()) throw new Error("candidate experiment runId is required");
|
|
1009
|
+
const searchCostUsd = options.searchCostUsd ?? 0;
|
|
1010
|
+
const evaluation = evaluatePairedMeasurements({
|
|
1011
|
+
measurements: measurements.map((measurement, index) => ({
|
|
1012
|
+
cellId: cellIds(experiment)[index],
|
|
1013
|
+
...measurement
|
|
1014
|
+
})),
|
|
1015
|
+
policy: experiment.policy,
|
|
1016
|
+
adapter: candidateExecutionEvidenceAdapter,
|
|
1017
|
+
sharedScorerChannel: true,
|
|
1018
|
+
additionalCostUsd: searchCostUsd
|
|
1019
|
+
});
|
|
1020
|
+
const diff = deriveCandidateBundleDiff(experiment);
|
|
1021
|
+
const searchDurationMs = options.searchDurationMs ?? 0;
|
|
1022
|
+
const totalCostUsd = evaluation.totalCostUsd;
|
|
1023
|
+
const durationMs = evaluation.executionDurationMs + searchDurationMs;
|
|
1024
|
+
const provisional = agentImprovementMeasuredComparisonSchema.parse({
|
|
1025
|
+
kind: "agent-improvement-measured-comparison",
|
|
1026
|
+
experiment,
|
|
1027
|
+
measurements,
|
|
1028
|
+
overall: evaluation.overall,
|
|
1029
|
+
objectives: evaluation.objectives,
|
|
1030
|
+
...options.candidate ? { candidate: options.candidate } : {},
|
|
1031
|
+
decision: evaluation.decision,
|
|
1032
|
+
power: evaluation.power,
|
|
982
1033
|
provenance: {
|
|
983
1034
|
kind: "agent-eval-loop",
|
|
984
1035
|
schema: "agent-candidate-experiment",
|
|
@@ -991,10 +1042,10 @@ function measuredComparisonFromCandidateExperiment(options) {
|
|
|
991
1042
|
evaluation: {
|
|
992
1043
|
generationsExplored: options.generationsExplored ?? 0,
|
|
993
1044
|
searchDurationMs,
|
|
994
|
-
executionDurationMs,
|
|
1045
|
+
executionDurationMs: evaluation.executionDurationMs,
|
|
995
1046
|
durationMs,
|
|
996
1047
|
searchCostUsd,
|
|
997
|
-
executionCostUsd,
|
|
1048
|
+
executionCostUsd: evaluation.executionCostUsd,
|
|
998
1049
|
totalCostUsd
|
|
999
1050
|
},
|
|
1000
1051
|
...options.metadata ? { metadata: options.metadata } : {}
|
|
@@ -1197,6 +1248,65 @@ function verifyMaterialAddressed(evidence, label) {
|
|
|
1197
1248
|
throw new Error(`${label} digest is invalid`);
|
|
1198
1249
|
}
|
|
1199
1250
|
}
|
|
1251
|
+
function projectPairedMeasurement(measurement, index, adapter) {
|
|
1252
|
+
if (typeof measurement.cellId !== "string" || !measurement.cellId.trim()) {
|
|
1253
|
+
throw new Error(`paired measurement ${index} requires a cell id`);
|
|
1254
|
+
}
|
|
1255
|
+
return {
|
|
1256
|
+
cellId: measurement.cellId,
|
|
1257
|
+
baseline: projectRun(measurement.baseline, adapter, `paired measurement ${index} baseline`),
|
|
1258
|
+
candidate: projectRun(measurement.candidate, adapter, `paired measurement ${index} candidate`)
|
|
1259
|
+
};
|
|
1260
|
+
}
|
|
1261
|
+
function projectRun(run, adapter, label) {
|
|
1262
|
+
const suppliedDimensions = adapter.dimensions(run);
|
|
1263
|
+
if (!Array.isArray(suppliedDimensions)) {
|
|
1264
|
+
throw new Error(`${label} dimensions must be an array`);
|
|
1265
|
+
}
|
|
1266
|
+
const dimensions = /* @__PURE__ */ new Map();
|
|
1267
|
+
for (const dimension of suppliedDimensions) {
|
|
1268
|
+
if (typeof dimension.name !== "string" || !dimension.name.trim()) {
|
|
1269
|
+
throw new Error(`${label} contains an unnamed dimension`);
|
|
1270
|
+
}
|
|
1271
|
+
if (dimensions.has(dimension.name)) {
|
|
1272
|
+
throw new Error(`${label} repeats dimension '${dimension.name}'`);
|
|
1273
|
+
}
|
|
1274
|
+
dimensions.set(dimension.name, finiteMeasurement(dimension.score, `${label} ${dimension.name}`));
|
|
1275
|
+
}
|
|
1276
|
+
const completed = adapter.completed(run);
|
|
1277
|
+
const passed = adapter.passed(run);
|
|
1278
|
+
if (typeof completed !== "boolean" || typeof passed !== "boolean") {
|
|
1279
|
+
throw new Error(`${label} completion and pass values must be booleans`);
|
|
1280
|
+
}
|
|
1281
|
+
return {
|
|
1282
|
+
score: finiteMeasurement(adapter.score(run), `${label} score`),
|
|
1283
|
+
dimensions,
|
|
1284
|
+
costUsd: nonNegativeMeasurement(adapter.costUsd(run), `${label} cost`),
|
|
1285
|
+
latencyMs: nonNegativeMeasurement(adapter.latencyMs(run), `${label} latency`),
|
|
1286
|
+
completed,
|
|
1287
|
+
passed
|
|
1288
|
+
};
|
|
1289
|
+
}
|
|
1290
|
+
function sharedProjectedDimensions(measurements) {
|
|
1291
|
+
const expected = [...measurements[0].baseline.dimensions.keys()];
|
|
1292
|
+
for (const [index, measurement] of measurements.entries()) {
|
|
1293
|
+
for (const [arm, run] of [
|
|
1294
|
+
["baseline", measurement.baseline],
|
|
1295
|
+
["candidate", measurement.candidate]
|
|
1296
|
+
]) {
|
|
1297
|
+
const actual = [...run.dimensions.keys()];
|
|
1298
|
+
if (JSON.stringify(actual) !== JSON.stringify(expected)) {
|
|
1299
|
+
throw new Error(`paired measurement ${index} ${arm} dimensions do not match the suite`);
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
return expected;
|
|
1304
|
+
}
|
|
1305
|
+
function dimensionScore(run, name) {
|
|
1306
|
+
const value = run.dimensions.get(name);
|
|
1307
|
+
if (value === void 0) throw new Error(`paired measurement is missing dimension '${name}'`);
|
|
1308
|
+
return value;
|
|
1309
|
+
}
|
|
1200
1310
|
function measuredEstimate(baseline, candidate, options) {
|
|
1201
1311
|
const bootstrap = pairedBootstrap(baseline, candidate, {
|
|
1202
1312
|
confidence: options.confidence,
|
|
@@ -1222,46 +1332,22 @@ function measuredEstimate(baseline, candidate, options) {
|
|
|
1222
1332
|
n: bootstrap.n
|
|
1223
1333
|
};
|
|
1224
1334
|
}
|
|
1225
|
-
function
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
for (const [arm, evidence] of [
|
|
1229
|
-
["baseline", measurement.baseline],
|
|
1230
|
-
["candidate", measurement.candidate]
|
|
1231
|
-
]) {
|
|
1232
|
-
const actual = dimensionNames(evidence);
|
|
1233
|
-
if (JSON.stringify(actual) !== JSON.stringify(expected)) {
|
|
1234
|
-
throw new Error(
|
|
1235
|
-
`candidate experiment measurement ${index} ${arm} dimensions do not match the suite`
|
|
1236
|
-
);
|
|
1237
|
-
}
|
|
1238
|
-
}
|
|
1239
|
-
}
|
|
1240
|
-
return expected;
|
|
1241
|
-
}
|
|
1242
|
-
function dimensionNames(evidence) {
|
|
1243
|
-
return (evidence?.receipt.benchmarkResult.material.dimensions ?? []).map(
|
|
1244
|
-
(dimension) => dimension.name
|
|
1245
|
-
);
|
|
1246
|
-
}
|
|
1247
|
-
function scoreOf(arm) {
|
|
1248
|
-
return (measurement) => measurement[arm].receipt.benchmarkResult.material.score;
|
|
1249
|
-
}
|
|
1250
|
-
function dimensionOf(arm, name) {
|
|
1251
|
-
return (measurement) => {
|
|
1252
|
-
const dimension = measurement[arm].receipt.benchmarkResult.material.dimensions.find(
|
|
1253
|
-
(entry) => entry.name === name
|
|
1254
|
-
);
|
|
1255
|
-
if (!dimension) throw new Error(`candidate experiment is missing dimension '${name}'`);
|
|
1256
|
-
return dimension.score;
|
|
1257
|
-
};
|
|
1258
|
-
}
|
|
1259
|
-
function costOf(arm) {
|
|
1260
|
-
return (measurement) => costFromEvidence(measurement[arm]);
|
|
1335
|
+
function finiteMeasurement(value, label) {
|
|
1336
|
+
if (!Number.isFinite(value)) throw new Error(`${label} must be finite`);
|
|
1337
|
+
return value;
|
|
1261
1338
|
}
|
|
1262
|
-
function
|
|
1263
|
-
|
|
1339
|
+
function nonNegativeMeasurement(value, label) {
|
|
1340
|
+
if (!Number.isFinite(value) || value < 0) throw new Error(`${label} must be non-negative`);
|
|
1341
|
+
return value;
|
|
1264
1342
|
}
|
|
1343
|
+
var candidateExecutionEvidenceAdapter = {
|
|
1344
|
+
score: (evidence) => evidence.receipt.benchmarkResult.material.score,
|
|
1345
|
+
dimensions: (evidence) => evidence.receipt.benchmarkResult.material.dimensions,
|
|
1346
|
+
costUsd: costFromEvidence,
|
|
1347
|
+
latencyMs: latencyFromEvidence,
|
|
1348
|
+
completed: completedSuccessfully,
|
|
1349
|
+
passed: (evidence) => evidence.receipt.benchmarkResult.material.passed
|
|
1350
|
+
};
|
|
1265
1351
|
function costFromEvidence(evidence) {
|
|
1266
1352
|
return combinedUsage(evidence).costUsdNanos / 1e9;
|
|
1267
1353
|
}
|
|
@@ -1822,6 +1908,7 @@ export {
|
|
|
1822
1908
|
diffRunBaselineToWinner,
|
|
1823
1909
|
diffRuns,
|
|
1824
1910
|
evalReportingSuite,
|
|
1911
|
+
evaluatePairedMeasurements,
|
|
1825
1912
|
externalTextOptimizationMethod,
|
|
1826
1913
|
fromClaudeCodeSession,
|
|
1827
1914
|
fromCodexSession,
|