@tangle-network/agent-eval 0.123.0 → 0.123.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 +4 -0
- package/dist/belief-state/index.d.ts +45 -5
- package/dist/belief-state/index.js +41 -3
- package/dist/belief-state/index.js.map +1 -1
- package/dist/{chunk-DTJ6QUQB.js → chunk-VGRCHJON.js} +39 -7
- package/dist/chunk-VGRCHJON.js.map +1 -0
- package/dist/openapi.json +1 -1
- package/dist/rl.d.ts +39 -11
- package/dist/rl.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-DTJ6QUQB.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -18,6 +18,10 @@ All notable changes to `@tangle-network/agent-eval` and its sibling `agent-eval-
|
|
|
18
18
|
- Pass track identity, operation, vision, ancestry, and proposer choice to candidate generation so independent tracks can pursue distinct strategies.
|
|
19
19
|
- Route named tracks to caller-supplied proposers, with the default proposer as fallback, and make heuristic branches inherit their parent track's proposer.
|
|
20
20
|
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
- Compute contextual-bandit doubly robust estimates with separate logged-action and target-policy value terms, expose how many rows use DR versus IPS or the deprecated scalar path, and carry both values through belief-state records.
|
|
24
|
+
|
|
21
25
|
## [0.122.2] — 2026-07-17 — premeasured optimization continuation
|
|
22
26
|
|
|
23
27
|
### Added
|
|
@@ -281,9 +281,10 @@ interface CalibrationReport {
|
|
|
281
281
|
* - For LLM agents, propensity scores must be supplied by the caller
|
|
282
282
|
* (logged in the trace, recovered from token log-probs, or estimated
|
|
283
283
|
* via a learned propensity model). We do NOT estimate propensity here.
|
|
284
|
-
* - Doubly-robust requires a Q-function
|
|
285
|
-
*
|
|
286
|
-
* a regression fit, or
|
|
284
|
+
* - Doubly-robust requires two outputs from a Q-function: its prediction
|
|
285
|
+
* for the logged action and its expectation under the target policy.
|
|
286
|
+
* Consumers compute these with a tabular estimate, regression fit, or
|
|
287
|
+
* learned reward model before constructing the trajectories.
|
|
287
288
|
*
|
|
288
289
|
* Bias / variance tradeoffs:
|
|
289
290
|
* - IPS: unbiased; high variance for small overlap, infinite variance
|
|
@@ -316,11 +317,33 @@ interface OffPolicyTrajectory {
|
|
|
316
317
|
*/
|
|
317
318
|
targetProb: number;
|
|
318
319
|
/**
|
|
319
|
-
*
|
|
320
|
-
* `
|
|
320
|
+
* Model-based reward prediction for the action selected by the behavior
|
|
321
|
+
* policy: `Q_hat(context, loggedAction)`. Supply this together with
|
|
322
|
+
* `vHatTarget` for contextual-bandit doubly-robust estimation.
|
|
323
|
+
*/
|
|
324
|
+
qHatChosen?: number | null;
|
|
325
|
+
/**
|
|
326
|
+
* Expected model-based reward under the target policy:
|
|
327
|
+
* `sum_action targetPolicy(action | context) * Q_hat(context, action)`.
|
|
328
|
+
* Supply this together with `qHatChosen`. For an honest evaluation, both
|
|
329
|
+
* values must come from a model cross-fitted or trained outside this row.
|
|
330
|
+
*/
|
|
331
|
+
vHatTarget?: number | null;
|
|
332
|
+
/**
|
|
333
|
+
* @deprecated Use `qHatChosen` and `vHatTarget` together. When the new pair
|
|
334
|
+
* is absent, this scalar is used as both terms to preserve existing results.
|
|
335
|
+
* When the new pair is present, this field is ignored.
|
|
321
336
|
*/
|
|
322
337
|
qHat?: number | null;
|
|
323
338
|
}
|
|
339
|
+
interface OffPolicyContributionCounts {
|
|
340
|
+
/** Contributions using the contextual-bandit doubly-robust formula. */
|
|
341
|
+
dr: number;
|
|
342
|
+
/** Contributions using exact IPS because no reward-model estimate was supplied. */
|
|
343
|
+
ipsFallback: number;
|
|
344
|
+
/** Contributions using the deprecated single-scalar formula. */
|
|
345
|
+
legacyScalar: number;
|
|
346
|
+
}
|
|
324
347
|
interface OffPolicyEstimate {
|
|
325
348
|
/** Estimated value of the target policy. */
|
|
326
349
|
value: number;
|
|
@@ -335,6 +358,8 @@ interface OffPolicyEstimate {
|
|
|
335
358
|
* mean) are a red flag — variance is dominated by a few outliers.
|
|
336
359
|
*/
|
|
337
360
|
maxImportanceWeight: number;
|
|
361
|
+
/** Populated by `doublyRobust` to expose which formula each row used. */
|
|
362
|
+
contributionCounts?: OffPolicyContributionCounts;
|
|
338
363
|
}
|
|
339
364
|
interface OffPolicyOptions {
|
|
340
365
|
/**
|
|
@@ -446,6 +471,9 @@ interface BeliefDecisionPoint {
|
|
|
446
471
|
confidence?: number;
|
|
447
472
|
behaviorProb?: number;
|
|
448
473
|
targetProb?: number;
|
|
474
|
+
qHatChosen?: number | null;
|
|
475
|
+
vHatTarget?: number | null;
|
|
476
|
+
/** @deprecated Use `qHatChosen` and `vHatTarget` together. */
|
|
449
477
|
qHat?: number | null;
|
|
450
478
|
costUsd?: number;
|
|
451
479
|
evidence: BeliefEvidenceRef[];
|
|
@@ -468,6 +496,9 @@ interface BeliefPolicyDecision {
|
|
|
468
496
|
action: BeliefPolicyAction;
|
|
469
497
|
confidence?: number;
|
|
470
498
|
targetProb?: number;
|
|
499
|
+
qHatChosen?: number | null;
|
|
500
|
+
vHatTarget?: number | null;
|
|
501
|
+
/** @deprecated Use `qHatChosen` and `vHatTarget` together. */
|
|
471
502
|
qHat?: number | null;
|
|
472
503
|
reason?: string;
|
|
473
504
|
reasons?: BeliefDecisionReason[];
|
|
@@ -479,6 +510,9 @@ interface BeliefSelectivePolicy {
|
|
|
479
510
|
interface BeliefOpeTargetPolicy {
|
|
480
511
|
id: string;
|
|
481
512
|
targetProbOf(point: BeliefDecisionPoint): number | null | undefined;
|
|
513
|
+
qHatChosenOf?(point: BeliefDecisionPoint): number | null | undefined;
|
|
514
|
+
vHatTargetOf?(point: BeliefDecisionPoint): number | null | undefined;
|
|
515
|
+
/** @deprecated Use `qHatChosenOf` and `vHatTargetOf` together. */
|
|
482
516
|
qHatOf?(point: BeliefDecisionPoint): number | null | undefined;
|
|
483
517
|
}
|
|
484
518
|
interface BeliefUtilityOptions {
|
|
@@ -1189,6 +1223,9 @@ interface RuntimeBeliefDecisionPointOptions {
|
|
|
1189
1223
|
confidence?: number;
|
|
1190
1224
|
behaviorProb?: number;
|
|
1191
1225
|
targetProb?: number;
|
|
1226
|
+
qHatChosen?: number | null;
|
|
1227
|
+
vHatTarget?: number | null;
|
|
1228
|
+
/** @deprecated Use `qHatChosen` and `vHatTarget` together. */
|
|
1192
1229
|
qHat?: number | null;
|
|
1193
1230
|
costUsd?: number;
|
|
1194
1231
|
outcome?: BeliefDecisionOutcome;
|
|
@@ -1230,6 +1267,9 @@ interface RuntimeBeliefDecisionLabel {
|
|
|
1230
1267
|
confidence?: number;
|
|
1231
1268
|
behaviorProb?: number;
|
|
1232
1269
|
targetProb?: number;
|
|
1270
|
+
qHatChosen?: number | null;
|
|
1271
|
+
vHatTarget?: number | null;
|
|
1272
|
+
/** @deprecated Use `qHatChosen` and `vHatTarget` together. */
|
|
1233
1273
|
qHat?: number | null;
|
|
1234
1274
|
costUsd?: number;
|
|
1235
1275
|
splitTag?: RunSplitTag;
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
} from "../chunk-T4SQEITX.js";
|
|
15
15
|
import {
|
|
16
16
|
offPolicyEstimateAll
|
|
17
|
-
} from "../chunk-
|
|
17
|
+
} from "../chunk-VGRCHJON.js";
|
|
18
18
|
import {
|
|
19
19
|
confidenceInterval
|
|
20
20
|
} from "../chunk-PJQFMIOX.js";
|
|
@@ -68,6 +68,12 @@ function embeddedBeliefOpeTargetPolicy(id = "embedded-target-prob") {
|
|
|
68
68
|
targetProbOf(point) {
|
|
69
69
|
return point.targetProb;
|
|
70
70
|
},
|
|
71
|
+
qHatChosenOf(point) {
|
|
72
|
+
return point.qHatChosen;
|
|
73
|
+
},
|
|
74
|
+
vHatTargetOf(point) {
|
|
75
|
+
return point.vHatTarget;
|
|
76
|
+
},
|
|
71
77
|
qHatOf(point) {
|
|
72
78
|
return point.qHat;
|
|
73
79
|
}
|
|
@@ -86,9 +92,13 @@ function beliefDecisionsToOffPolicyTrajectories(points, targetPolicy, options =
|
|
|
86
92
|
continue;
|
|
87
93
|
}
|
|
88
94
|
let targetProb;
|
|
95
|
+
let qHatChosen;
|
|
96
|
+
let vHatTarget;
|
|
89
97
|
let qHat;
|
|
90
98
|
try {
|
|
91
99
|
targetProb = targetPolicy.targetProbOf(point);
|
|
100
|
+
qHatChosen = targetPolicy.qHatChosenOf?.(point);
|
|
101
|
+
vHatTarget = targetPolicy.vHatTargetOf?.(point);
|
|
92
102
|
qHat = targetPolicy.qHatOf?.(point);
|
|
93
103
|
} catch (error) {
|
|
94
104
|
diagnostics.push(
|
|
@@ -100,7 +110,19 @@ function beliefDecisionsToOffPolicyTrajectories(points, targetPolicy, options =
|
|
|
100
110
|
diagnostics.push(`${point.id}: invalid targetProb ${formatProbability(targetProb)}`);
|
|
101
111
|
continue;
|
|
102
112
|
}
|
|
103
|
-
|
|
113
|
+
const hasQHatChosen = qHatChosen !== null && qHatChosen !== void 0;
|
|
114
|
+
const hasVHatTarget = vHatTarget !== null && vHatTarget !== void 0;
|
|
115
|
+
if (hasQHatChosen !== hasVHatTarget) {
|
|
116
|
+
diagnostics.push(`${point.id}: qHatChosen and vHatTarget must be supplied together`);
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
if (hasQHatChosen && hasVHatTarget && (!isTargetProbability(qHatChosen) || !isTargetProbability(vHatTarget))) {
|
|
120
|
+
diagnostics.push(
|
|
121
|
+
`${point.id}: invalid contextual Q pair qHatChosen=${formatProbability(qHatChosen)} vHatTarget=${formatProbability(vHatTarget)}`
|
|
122
|
+
);
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
if (!hasQHatChosen && !hasVHatTarget && qHat !== null && qHat !== void 0 && !isTargetProbability(qHat)) {
|
|
104
126
|
diagnostics.push(`${point.id}: invalid qHat ${formatProbability(qHat)}; ignoring qHat`);
|
|
105
127
|
qHat = null;
|
|
106
128
|
}
|
|
@@ -109,6 +131,8 @@ function beliefDecisionsToOffPolicyTrajectories(points, targetPolicy, options =
|
|
|
109
131
|
reward: rewardOf(point),
|
|
110
132
|
behaviorProb: point.behaviorProb,
|
|
111
133
|
targetProb,
|
|
134
|
+
...qHatChosen !== void 0 ? { qHatChosen } : {},
|
|
135
|
+
...vHatTarget !== void 0 ? { vHatTarget } : {},
|
|
112
136
|
qHat
|
|
113
137
|
});
|
|
114
138
|
}
|
|
@@ -127,7 +151,8 @@ function evaluateBeliefOffPolicy(points, targetPolicy, options = {}) {
|
|
|
127
151
|
minEffectiveSampleSize: options.minEffectiveSampleSize ?? 30,
|
|
128
152
|
minEffectiveSampleRatio: options.minEffectiveSampleRatio ?? 0.25,
|
|
129
153
|
dropped: trajectoryReport.dropped,
|
|
130
|
-
diagnostics: trajectoryReport.diagnostics
|
|
154
|
+
diagnostics: trajectoryReport.diagnostics,
|
|
155
|
+
legacyScalarContributions: estimates.dr.contributionCounts?.legacyScalar ?? 0
|
|
131
156
|
});
|
|
132
157
|
return { targetPolicyId: targetPolicy.id, ...estimates, support };
|
|
133
158
|
}
|
|
@@ -140,6 +165,11 @@ function supportDiagnostics(estimate, options) {
|
|
|
140
165
|
if (options.dropped > 0) {
|
|
141
166
|
reasons.push(`dropped ${options.dropped} unsupported decision(s)`);
|
|
142
167
|
}
|
|
168
|
+
if (options.legacyScalarContributions > 0) {
|
|
169
|
+
reasons.push(
|
|
170
|
+
`${options.legacyScalarContributions} decision(s) used deprecated scalar qHat; supply qHatChosen and vHatTarget for contextual doubly robust estimation`
|
|
171
|
+
);
|
|
172
|
+
}
|
|
143
173
|
if (estimate.effectiveSampleSize < options.minEffectiveSampleSize) {
|
|
144
174
|
reasons.push(
|
|
145
175
|
`effective sample size ${estimate.effectiveSampleSize.toFixed(2)} below ${options.minEffectiveSampleSize}`
|
|
@@ -216,6 +246,8 @@ function thresholdSelectivePolicy(options) {
|
|
|
216
246
|
action: confidence >= threshold ? "accept" : belowThresholdAction,
|
|
217
247
|
confidence,
|
|
218
248
|
targetProb: point.targetProb,
|
|
249
|
+
qHatChosen: point.qHatChosen,
|
|
250
|
+
vHatTarget: point.vHatTarget,
|
|
219
251
|
qHat: point.qHat,
|
|
220
252
|
reason: confidence >= threshold ? "confidence threshold passed" : "confidence threshold failed"
|
|
221
253
|
};
|
|
@@ -1041,6 +1073,8 @@ function parseDecisionEvent(event, context) {
|
|
|
1041
1073
|
confidence: finiteUnitField(payload, "confidence"),
|
|
1042
1074
|
behaviorProb: numberField(payload, "behaviorProb"),
|
|
1043
1075
|
targetProb: numberField(payload, "targetProb"),
|
|
1076
|
+
qHatChosen: finiteUnitField(payload, "qHatChosen"),
|
|
1077
|
+
vHatTarget: finiteUnitField(payload, "vHatTarget"),
|
|
1044
1078
|
qHat: finiteUnitField(payload, "qHat"),
|
|
1045
1079
|
costUsd: nonNegativeNumberField(payload, "costUsd"),
|
|
1046
1080
|
evidence,
|
|
@@ -1155,6 +1189,8 @@ function runtimeDecisionPointToBeliefDecisionPoint(point, options) {
|
|
|
1155
1189
|
confidence: unitProbabilityOrUndefined(options.confidence),
|
|
1156
1190
|
behaviorProb: finiteNumberOrUndefined(options.behaviorProb),
|
|
1157
1191
|
targetProb: finiteNumberOrUndefined(options.targetProb),
|
|
1192
|
+
qHatChosen: options.qHatChosen === null ? null : unitProbabilityOrUndefined(options.qHatChosen),
|
|
1193
|
+
vHatTarget: options.vHatTarget === null ? null : unitProbabilityOrUndefined(options.vHatTarget),
|
|
1158
1194
|
qHat: options.qHat === null ? null : unitProbabilityOrUndefined(options.qHat),
|
|
1159
1195
|
costUsd: nonNegativeNumberOrUndefined(options.costUsd),
|
|
1160
1196
|
evidence: evidence.map((ref) => runtimeEvidenceToBeliefEvidence(ref, point)),
|
|
@@ -1384,6 +1420,8 @@ function buildRuntimeBeliefPhase0Measurement(options) {
|
|
|
1384
1420
|
confidence: label.confidence,
|
|
1385
1421
|
behaviorProb: label.behaviorProb,
|
|
1386
1422
|
targetProb: label.targetProb,
|
|
1423
|
+
qHatChosen: label.qHatChosen,
|
|
1424
|
+
vHatTarget: label.vHatTarget,
|
|
1387
1425
|
qHat: label.qHat,
|
|
1388
1426
|
costUsd: label.costUsd,
|
|
1389
1427
|
outcome: label.outcome,
|