@tangle-network/agent-eval 0.121.0 → 0.122.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.
@@ -1208,6 +1208,7 @@ interface SemanticConceptJudgeOptions {
1208
1208
  llm?: LlmClientOptions;
1209
1209
  costLedger?: CostLedgerHandle;
1210
1210
  costPhase?: string;
1211
+ costTags?: Record<string, string>;
1211
1212
  signal?: AbortSignal;
1212
1213
  /**
1213
1214
  * Score aggregation strategy. Default `mean` — uniform average across
@@ -9,7 +9,7 @@ import {
9
9
  diffFindings,
10
10
  emitSkillUsageFindings,
11
11
  runSemanticConceptJudge
12
- } from "../chunk-JM2SKQMS.js";
12
+ } from "../chunk-P62I523A.js";
13
13
  import {
14
14
  behavioralAnalyst,
15
15
  buildDefaultAnalystRegistry,
@@ -794,6 +794,37 @@ interface RunRecord {
794
794
  }
795
795
 
796
796
  type CodeAgentSessionSource = 'codex' | 'claude-code' | 'opencode' | 'kimi-code' | 'pi';
797
+ type CodeAgentSessionTerminalStatus = 'completed' | 'failed' | 'unknown';
798
+ type CodeAgentSessionActionKind = 'tool' | 'patch' | 'terminal' | 'graph-completion';
799
+ type CodeAgentSessionActionSurface = 'tool' | 'mcp' | 'subagent' | 'skill' | 'hook' | 'web' | 'code';
800
+ type CodeAgentSessionActionStatus = 'started' | 'completed' | 'failed' | 'unknown';
801
+ interface CodeAgentSessionExecutionReceipt {
802
+ exitCode: number;
803
+ startedAtMs?: number;
804
+ completedAtMs?: number;
805
+ }
806
+ interface CodeAgentSessionAction {
807
+ id: string;
808
+ stepIndex: number;
809
+ kind: CodeAgentSessionActionKind;
810
+ surface: CodeAgentSessionActionSurface;
811
+ name: string;
812
+ status: CodeAgentSessionActionStatus;
813
+ timestampMs?: number;
814
+ costUsd?: number;
815
+ metadata: Record<string, unknown>;
816
+ }
817
+ interface CodeAgentSessionObservation {
818
+ source: CodeAgentSessionSource;
819
+ sessionId: string;
820
+ finalText: string | null;
821
+ terminal: {
822
+ status: CodeAgentSessionTerminalStatus;
823
+ explicit: boolean;
824
+ };
825
+ actions: CodeAgentSessionAction[];
826
+ }
827
+
797
828
  interface CodeAgentSessionMetrics {
798
829
  entries: number;
799
830
  userMessages: number;
@@ -809,6 +840,12 @@ interface CodeAgentSessionMetrics {
809
840
  turnsCompleted: number;
810
841
  turnsAborted: number;
811
842
  contextCompactions: number;
843
+ mcpCalls: number;
844
+ subagentCalls: number;
845
+ skillCalls: number;
846
+ hookCalls: number;
847
+ webCalls: number;
848
+ codeActions: number;
812
849
  prLinks: number;
813
850
  fileSnapshots: number;
814
851
  graphNodes: number;
@@ -836,6 +873,7 @@ interface CodeAgentSessionDiagnostic {
836
873
  malformedLines: number;
837
874
  inferredScore: boolean;
838
875
  hasExplicitTerminalSignal: boolean;
876
+ hasFinalOutput: boolean;
839
877
  hasQualityLabel: boolean;
840
878
  hasTokenUsage: boolean;
841
879
  hasCost: boolean;
@@ -861,6 +899,9 @@ interface CodeAgentSessionIntakeOptions {
861
899
  * sentinel as observed. When omitted, source-reported cost wins, then a
862
900
  * token-priced estimate, then uncaptured. */
863
901
  costProvenance?: RunCostProvenance;
902
+ /** Exact executor-owned process result. This is required when a provider's
903
+ * JSON stream has no terminal event, as with `opencode run --format json`. */
904
+ execution?: CodeAgentSessionExecutionReceipt;
864
905
  }
865
906
 
866
907
  interface BeliefOpeOptions extends OffPolicyOptions {
@@ -909,6 +950,8 @@ type CodeAgentBeliefDecisionTargetId = 'failure-recovery' | 'tool-selection' | '
909
950
  interface ExtractCodeAgentBeliefDecisionPointsOptions {
910
951
  source: CodeAgentSessionSource;
911
952
  entries: unknown[];
953
+ /** Reuse intake's provider-neutral projection when available. */
954
+ observation?: CodeAgentSessionObservation;
912
955
  run: Pick<RunRecord, 'runId' | 'scenarioId' | 'outcome' | 'costUsd'>;
913
956
  sourcePath?: string;
914
957
  }
@@ -3,8 +3,9 @@ import {
3
3
  fromCodexSession,
4
4
  fromKimiCodeSession,
5
5
  fromOpenCodeSession,
6
- fromPiSession
7
- } from "../chunk-HKUCJ437.js";
6
+ fromPiSession,
7
+ observeCodeAgentSession
8
+ } from "../chunk-7VYEGHWF.js";
8
9
  import {
9
10
  calibrationFromPairs
10
11
  } from "../chunk-NPCTHQIO.js";
@@ -479,275 +480,24 @@ function analyzeBeliefDecisionCorpus(options) {
479
480
  return { inventory, target, policy, evaluation, diagnostics };
480
481
  }
481
482
  function observedActionsFor(source, entries, options) {
482
- switch (source) {
483
- case "codex":
484
- return codexObservedActions(entries, options);
485
- case "claude-code":
486
- return claudeObservedActions(entries, options);
487
- case "opencode":
488
- return openCodeObservedActions(entries, options);
489
- case "kimi-code":
490
- return kimiObservedActions(entries, options);
491
- case "pi":
492
- return piObservedActions(entries, options);
483
+ const observation = options.observation ?? observeCodeAgentSession({ source, entries, sourcePath: options.sourcePath });
484
+ if (observation.source !== source) {
485
+ throw new Error("code-agent observation source does not match extraction source");
493
486
  }
487
+ return observation.actions.map((action) => observedActionFromSession(action, options));
494
488
  }
495
- function codexObservedActions(entries, options) {
496
- const actions = [];
497
- const calls = /* @__PURE__ */ new Map();
498
- for (const entry of entries) {
499
- const payload = record(entry.payload) ?? {};
500
- const entryType = stringField(entry, "type");
501
- const payloadType = stringField(payload, "type");
502
- const timestamp = timestampMs(entry.timestamp);
503
- if (entryType === "response_item") {
504
- if (payloadType === "function_call" || payloadType === "custom_tool_call") {
505
- const callId = stringField(payload, "call_id") ?? stringField(payload, "id") ?? `${actions.length}`;
506
- const action = observedAction({
507
- options,
508
- localId: callId,
509
- stepIndex: actions.length,
510
- kind: "tool",
511
- action: stringField(payload, "name") ?? payloadType,
512
- timestamp,
513
- metadata: { sourceEventType: entryType, payloadType }
514
- });
515
- calls.set(callId, action);
516
- actions.push(action);
517
- }
518
- if (payloadType === "function_call_output" || payloadType === "custom_tool_call_output") {
519
- const callId = stringField(payload, "call_id") ?? stringField(payload, "id");
520
- const action = callId ? calls.get(callId) : void 0;
521
- if (action) action.success = !looksLikeError(payload.output);
522
- }
523
- }
524
- if (entryType === "event_msg") {
525
- if (payloadType === "patch_apply_end") {
526
- actions.push(
527
- observedAction({
528
- options,
529
- localId: stringField(payload, "call_id") ?? `patch-${actions.length}`,
530
- stepIndex: actions.length,
531
- kind: "patch",
532
- action: "patch",
533
- timestamp,
534
- success: typeof payload.success === "boolean" ? payload.success : void 0,
535
- metadata: { sourceEventType: entryType, payloadType }
536
- })
537
- );
538
- }
539
- if (payloadType === "task_complete" || payloadType === "turn_aborted") {
540
- actions.push(
541
- observedAction({
542
- options,
543
- localId: `${payloadType}-${actions.length}`,
544
- stepIndex: actions.length,
545
- kind: "terminal",
546
- action: payloadType === "task_complete" ? "stop" : "abort",
547
- timestamp,
548
- success: payloadType === "task_complete",
549
- metadata: { sourceEventType: entryType, payloadType }
550
- })
551
- );
552
- }
553
- }
554
- }
555
- return actions;
556
- }
557
- function claudeObservedActions(entries, options) {
558
- const actions = [];
559
- const calls = /* @__PURE__ */ new Map();
560
- for (const entry of entries) {
561
- const timestamp = timestampMs(entry.timestamp);
562
- const message = record(entry.message);
563
- const content = Array.isArray(message?.content) ? message.content : [];
564
- for (const item of content) {
565
- const part = record(item);
566
- if (!part) continue;
567
- const partType = stringField(part, "type");
568
- if (partType === "tool_use") {
569
- const id = stringField(part, "id") ?? `tool-${actions.length}`;
570
- const action = observedAction({
571
- options,
572
- localId: id,
573
- stepIndex: actions.length,
574
- kind: "tool",
575
- action: stringField(part, "name") ?? "tool",
576
- timestamp,
577
- metadata: { sourceEventType: stringField(entry, "type"), partType }
578
- });
579
- calls.set(id, action);
580
- actions.push(action);
581
- }
582
- if (partType === "tool_result") {
583
- const id = stringField(part, "tool_use_id");
584
- const action = id ? calls.get(id) : void 0;
585
- if (action) action.success = part.is_error !== true;
586
- }
587
- }
588
- if (stringField(entry, "type") === "pr-link") {
589
- actions.push(
590
- observedAction({
591
- options,
592
- localId: `pr-link-${actions.length}`,
593
- stepIndex: actions.length,
594
- kind: "terminal",
595
- action: "stop",
596
- timestamp,
597
- success: true,
598
- metadata: { sourceEventType: "pr-link" }
599
- })
600
- );
601
- }
602
- }
603
- return actions;
604
- }
605
- function openCodeObservedActions(entries, options) {
606
- const actions = [];
607
- for (const entry of entries) {
608
- const type = stringField(entry, "type");
609
- const role = stringField(entry, "role");
610
- const time = record(entry.time);
611
- const timestamp = timestampMs(time?.created);
612
- if (type === "tool") {
613
- const state = record(entry.state);
614
- const status = stringField(state ?? {}, "status");
615
- actions.push(
616
- observedAction({
617
- options,
618
- localId: stringField(entry, "id") ?? `tool-${actions.length}`,
619
- stepIndex: actions.length,
620
- kind: "tool",
621
- action: stringField(entry, "tool") ?? "tool",
622
- timestamp,
623
- success: status === "completed" ? true : status === "error" ? false : void 0,
624
- metadata: { sourceEventType: type, status }
625
- })
626
- );
627
- }
628
- if (type === "patch") {
629
- actions.push(
630
- observedAction({
631
- options,
632
- localId: stringField(entry, "id") ?? `patch-${actions.length}`,
633
- stepIndex: actions.length,
634
- kind: "patch",
635
- action: "patch",
636
- timestamp,
637
- success: true,
638
- metadata: { sourceEventType: type }
639
- })
640
- );
641
- }
642
- if (role === "assistant") {
643
- const finish = stringField(entry, "finish");
644
- if (finish === "stop" || finish === "error") {
645
- actions.push(
646
- observedAction({
647
- options,
648
- localId: stringField(entry, "id") ?? `terminal-${actions.length}`,
649
- stepIndex: actions.length,
650
- kind: "terminal",
651
- action: finish === "stop" ? "stop" : "abort",
652
- timestamp: timestampMs(time?.completed) ?? timestamp,
653
- success: finish === "stop",
654
- costUsd: numberField(entry, "cost"),
655
- metadata: { sourceEventType: "assistant", finish }
656
- })
657
- );
658
- }
659
- }
660
- }
661
- return actions;
662
- }
663
- function kimiObservedActions(entries, options) {
664
- const actions = [];
665
- const calls = /* @__PURE__ */ new Map();
666
- for (const entry of entries) {
667
- const timestamp = timestampMs(entry.timestamp);
668
- const message = record(entry.message);
669
- const messageType = stringField(message ?? {}, "type");
670
- const payload = record(message?.payload) ?? {};
671
- if (messageType === "ToolCall") {
672
- const call = record(payload.function);
673
- const id = stringField(payload, "id") ?? `tool-${actions.length}`;
674
- const action = observedAction({
675
- options,
676
- localId: id,
677
- stepIndex: actions.length,
678
- kind: "tool",
679
- action: stringField(call ?? {}, "name") ?? "tool",
680
- timestamp,
681
- metadata: { sourceEventType: messageType }
682
- });
683
- calls.set(id, action);
684
- actions.push(action);
685
- }
686
- if (messageType === "ToolResult") {
687
- const id = stringField(payload, "tool_call_id");
688
- const action = id ? calls.get(id) : void 0;
689
- if (action) action.success = record(payload.return_value)?.is_error !== true;
690
- }
691
- if (messageType === "TurnEnd" || messageType === "StepInterrupted") {
692
- actions.push(
693
- observedAction({
694
- options,
695
- localId: `${messageType}-${actions.length}`,
696
- stepIndex: actions.length,
697
- kind: "terminal",
698
- action: messageType === "TurnEnd" ? "stop" : "abort",
699
- timestamp,
700
- success: messageType === "TurnEnd",
701
- metadata: { sourceEventType: messageType }
702
- })
703
- );
704
- }
705
- }
706
- return actions;
707
- }
708
- function piObservedActions(entries, options) {
709
- const actions = [];
710
- for (const entry of entries) {
711
- const nodes = Array.isArray(entry.nodes) ? entry.nodes : [];
712
- for (const node of nodes) {
713
- const obj = record(node);
714
- const ir = record(obj?.ir) ?? obj;
715
- const kind = stringField(ir ?? {}, "kind");
716
- if (kind === "ToolInvocation") {
717
- actions.push(
718
- observedAction({
719
- options,
720
- localId: stringField(ir ?? {}, "id") ?? stringField(obj ?? {}, "id") ?? `tool-${actions.length}`,
721
- stepIndex: actions.length,
722
- kind: "tool",
723
- action: "graph-tool",
724
- timestamp: timestampMs(ir?.createdAt),
725
- success: void 0,
726
- metadata: { sourceEventType: "graph-node", graphKind: kind }
727
- })
728
- );
729
- }
730
- if (kind === "ToolResult") {
731
- const prior = [...actions].reverse().find((action) => action.kind === "tool");
732
- if (prior) prior.success = true;
733
- }
734
- if (kind === "CompletionDecision") {
735
- actions.push(
736
- observedAction({
737
- options,
738
- localId: stringField(ir ?? {}, "id") ?? stringField(obj ?? {}, "id") ?? `completion-${actions.length}`,
739
- stepIndex: actions.length,
740
- kind: "graph-completion",
741
- action: "complete",
742
- timestamp: timestampMs(ir?.createdAt),
743
- success: true,
744
- metadata: { sourceEventType: "graph-node", graphKind: kind }
745
- })
746
- );
747
- }
748
- }
749
- }
750
- return actions;
489
+ function observedActionFromSession(action, options) {
490
+ return observedAction({
491
+ options,
492
+ localId: action.id,
493
+ stepIndex: action.stepIndex,
494
+ kind: action.kind,
495
+ action: action.name,
496
+ timestamp: action.timestampMs,
497
+ success: action.status === "completed" ? true : action.status === "failed" ? false : void 0,
498
+ costUsd: action.costUsd,
499
+ metadata: { surface: action.surface, status: action.status, ...action.metadata }
500
+ });
751
501
  }
752
502
  function toolSelectionDecision(action, options) {
753
503
  return {
@@ -946,35 +696,6 @@ function groupBy(values, keyOf) {
946
696
  function mean2(values) {
947
697
  return values.reduce((sum, value) => sum + value, 0) / values.length;
948
698
  }
949
- function looksLikeError(value) {
950
- if (isRecord(value)) {
951
- if (value.is_error === true || value.error === true) return true;
952
- if ("Err" in value) return true;
953
- }
954
- if (typeof value !== "string") return false;
955
- return /\b(error|failed|exception|traceback)\b/i.test(value);
956
- }
957
- function timestampMs(value) {
958
- if (typeof value === "number" && Number.isFinite(value)) {
959
- return value > 1e12 ? value : value * 1e3;
960
- }
961
- if (typeof value === "string" && value.length > 0) {
962
- const parsed = Date.parse(value);
963
- return Number.isFinite(parsed) ? parsed : void 0;
964
- }
965
- return void 0;
966
- }
967
- function stringField(obj, key) {
968
- const value = obj[key];
969
- return typeof value === "string" && value.length > 0 ? value : void 0;
970
- }
971
- function numberField(obj, key) {
972
- const value = obj[key];
973
- return typeof value === "number" && Number.isFinite(value) ? value : void 0;
974
- }
975
- function record(value) {
976
- return isRecord(value) ? value : null;
977
- }
978
699
  function isRecord(value) {
979
700
  return value !== null && typeof value === "object" && !Array.isArray(value);
980
701
  }
@@ -1068,10 +789,11 @@ function buildCodeAgentBeliefEvidenceCorpus(options) {
1068
789
  runs.push(...intake.runs);
1069
790
  metrics.push(...intake.metrics);
1070
791
  intakeDiagnostics.push(...intake.diagnostics);
1071
- for (const run of intake.runs) {
792
+ for (const [index, run] of intake.runs.entries()) {
1072
793
  const extraction = extractCodeAgentBeliefDecisionPoints({
1073
794
  source: session.source,
1074
795
  entries: session.entries,
796
+ observation: intake.observations[index],
1075
797
  run,
1076
798
  sourcePath: session.sourcePath
1077
799
  });
@@ -1265,9 +987,9 @@ async function extractBeliefDecisionPoints(store, options = {}) {
1265
987
  }
1266
988
  function parseDecisionEvent(event, context) {
1267
989
  const payload = event.payload;
1268
- const marker = stringField2(payload, "kind") ?? stringField2(payload, "type");
990
+ const marker = stringField(payload, "kind") ?? stringField(payload, "type");
1269
991
  if (!marker || !DECISION_MARKERS.has(marker)) return null;
1270
- const decisionKind = stringField2(payload, "decisionKind");
992
+ const decisionKind = stringField(payload, "decisionKind");
1271
993
  if (!isBeliefDecisionKind(decisionKind)) {
1272
994
  return {
1273
995
  diagnostic: {
@@ -1278,7 +1000,7 @@ function parseDecisionEvent(event, context) {
1278
1000
  }
1279
1001
  };
1280
1002
  }
1281
- const chosenAction = stringField2(payload, "chosenAction");
1003
+ const chosenAction = stringField(payload, "chosenAction");
1282
1004
  if (!chosenAction) {
1283
1005
  return {
1284
1006
  diagnostic: {
@@ -1309,16 +1031,16 @@ function parseDecisionEvent(event, context) {
1309
1031
  }
1310
1032
  return {
1311
1033
  decision: {
1312
- id: stringField2(payload, "id") ?? event.eventId,
1034
+ id: stringField(payload, "id") ?? event.eventId,
1313
1035
  runId: event.runId,
1314
- scenarioId: stringField2(payload, "scenarioId") ?? context.scenarioId,
1315
- stepIndex: numberField2(payload, "stepIndex") ?? context.stepIndex,
1036
+ scenarioId: stringField(payload, "scenarioId") ?? context.scenarioId,
1037
+ stepIndex: numberField(payload, "stepIndex") ?? context.stepIndex,
1316
1038
  kind: decisionKind,
1317
1039
  chosenAction,
1318
1040
  candidateActions: stringArrayField(payload, "candidateActions"),
1319
1041
  confidence: finiteUnitField(payload, "confidence"),
1320
- behaviorProb: numberField2(payload, "behaviorProb"),
1321
- targetProb: numberField2(payload, "targetProb"),
1042
+ behaviorProb: numberField(payload, "behaviorProb"),
1043
+ targetProb: numberField(payload, "targetProb"),
1322
1044
  qHat: finiteUnitField(payload, "qHat"),
1323
1045
  costUsd: nonNegativeNumberField(payload, "costUsd"),
1324
1046
  evidence,
@@ -1335,24 +1057,24 @@ function parseOutcome(payload) {
1335
1057
  score: finiteUnitField(value, "score"),
1336
1058
  reward: finiteUnitField(value, "reward"),
1337
1059
  costUsd: nonNegativeNumberField(value, "costUsd"),
1338
- observedAt: stringField2(value, "observedAt"),
1060
+ observedAt: stringField(value, "observedAt"),
1339
1061
  metadata: recordField(value, "metadata")
1340
1062
  };
1341
1063
  }
1342
- function stringField2(obj, key) {
1064
+ function stringField(obj, key) {
1343
1065
  const value = obj[key];
1344
1066
  return typeof value === "string" && value.length > 0 ? value : void 0;
1345
1067
  }
1346
- function numberField2(obj, key) {
1068
+ function numberField(obj, key) {
1347
1069
  const value = obj[key];
1348
1070
  return typeof value === "number" && Number.isFinite(value) ? value : void 0;
1349
1071
  }
1350
1072
  function finiteUnitField(obj, key) {
1351
- const value = numberField2(obj, key);
1073
+ const value = numberField(obj, key);
1352
1074
  return value === void 0 ? void 0 : Math.max(0, Math.min(1, value));
1353
1075
  }
1354
1076
  function nonNegativeNumberField(obj, key) {
1355
- const value = numberField2(obj, key);
1077
+ const value = numberField(obj, key);
1356
1078
  return value === void 0 ? void 0 : Math.max(0, value);
1357
1079
  }
1358
1080
  function stringArrayField(obj, key) {
@@ -1776,24 +1498,24 @@ function buildRuntimeBenchmarkBeliefPhase0Measurement(options) {
1776
1498
  diagnostics: [...trajectory.diagnostics, ...diagnostics, ...measurement.diagnostics]
1777
1499
  };
1778
1500
  }
1779
- function runtimeBenchmarkRecordId(record2) {
1501
+ function runtimeBenchmarkRecordId(record) {
1780
1502
  const parts = [
1781
- nonEmptyString(record2.benchmark),
1782
- nonEmptyString(record2.instanceId),
1783
- nonEmptyString(record2.condition)
1503
+ nonEmptyString(record.benchmark),
1504
+ nonEmptyString(record.instanceId),
1505
+ nonEmptyString(record.condition)
1784
1506
  ].filter((part) => part !== void 0);
1785
1507
  return parts.length > 0 ? parts.join(":") : void 0;
1786
1508
  }
1787
- function runtimeBenchmarkScenarioId(record2) {
1788
- return nonEmptyString(record2.instanceId);
1509
+ function runtimeBenchmarkScenarioId(record) {
1510
+ return nonEmptyString(record.instanceId);
1789
1511
  }
1790
1512
  function runtimeBenchmarkDecisionPoints(records, diagnostics) {
1791
1513
  const decisions = [];
1792
1514
  for (let recordIndex = 0; recordIndex < records.length; recordIndex += 1) {
1793
- const record2 = records[recordIndex];
1794
- const raw = record2.runtimeDecisionPoints;
1515
+ const record = records[recordIndex];
1516
+ const raw = record.runtimeDecisionPoints;
1795
1517
  if (raw === void 0) continue;
1796
- const recordId = runtimeBenchmarkRecordId(record2) ?? `record[${recordIndex}]`;
1518
+ const recordId = runtimeBenchmarkRecordId(record) ?? `record[${recordIndex}]`;
1797
1519
  if (!Array.isArray(raw)) {
1798
1520
  diagnostics.push(`${recordId}: runtimeDecisionPoints is not an array`);
1799
1521
  continue;
@@ -1930,7 +1652,7 @@ async function runBeliefShadowProbe(options) {
1930
1652
  }
1931
1653
  }
1932
1654
  await Promise.all(Array.from({ length: Math.min(concurrency, options.points.length) }, worker));
1933
- const completed = records.filter((record2) => !!record2);
1655
+ const completed = records.filter((record) => !!record);
1934
1656
  return {
1935
1657
  probeId: options.probeId,
1936
1658
  records: completed,
@@ -2081,14 +1803,14 @@ function normalizeProbeResponse(response, options) {
2081
1803
  };
2082
1804
  }
2083
1805
  function summarizeShadowProbe(attempted, records) {
2084
- const confidences = records.map((record2) => record2.confidence);
2085
- const agreements = records.filter((record2) => record2.agreesWithObservedAction).length;
1806
+ const confidences = records.map((record) => record.confidence);
1807
+ const agreements = records.filter((record) => record.agreesWithObservedAction).length;
2086
1808
  return {
2087
1809
  attempted,
2088
1810
  completed: records.length,
2089
1811
  dropped: attempted - records.length,
2090
- withOutcome: records.filter((record2) => record2.outcome !== void 0).length,
2091
- withTargetProb: records.filter((record2) => record2.targetProb !== void 0).length,
1812
+ withOutcome: records.filter((record) => record.outcome !== void 0).length,
1813
+ withTargetProb: records.filter((record) => record.targetProb !== void 0).length,
2092
1814
  meanConfidence: confidences.length > 0 ? mean3(confidences) : null,
2093
1815
  observedAgreementRate: records.length > 0 ? agreements / records.length : null
2094
1816
  };