agent-inspect 6.18.0 → 6.19.0
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/README.md +1 -1
- package/docs/API.md +2 -1
- package/package.json +1 -1
- package/packages/cli/dist/{chunk-S4TLTLXN.mjs → chunk-R7Y5SGH5.mjs} +348 -27
- package/packages/cli/dist/chunk-R7Y5SGH5.mjs.map +1 -0
- package/packages/cli/dist/index.cjs +375 -46
- package/packages/cli/dist/index.cjs.map +1 -1
- package/packages/cli/dist/index.mjs +6 -5
- package/packages/cli/dist/index.mjs.map +1 -1
- package/packages/cli/dist/{src-R6V5EZZH.mjs → src-T4EZERCX.mjs} +3 -3
- package/packages/cli/dist/{src-R6V5EZZH.mjs.map → src-T4EZERCX.mjs.map} +1 -1
- package/packages/core/dist/advanced.cjs.map +1 -1
- package/packages/core/dist/advanced.d.cts +13 -2
- package/packages/core/dist/advanced.d.ts +13 -2
- package/packages/core/dist/advanced.mjs +1 -1
- package/packages/core/dist/advanced.mjs.map +1 -1
- package/packages/core/dist/checks.cjs +334 -5
- package/packages/core/dist/checks.cjs.map +1 -1
- package/packages/core/dist/checks.d.cts +81 -4
- package/packages/core/dist/checks.d.ts +81 -4
- package/packages/core/dist/checks.mjs +1 -1
- package/packages/core/dist/{chunk-LQC7IED3.mjs → chunk-NABMW5DX.mjs} +336 -8
- package/packages/core/dist/chunk-NABMW5DX.mjs.map +1 -0
- package/packages/core/dist/{index-B9ZGvUVL.d.ts → index-AMAGuO_i.d.ts} +1 -1
- package/packages/core/dist/{index-DWu54Y28.d.cts → index-DCR816Yt.d.cts} +2 -2
- package/packages/core/dist/{index-DlwbVqEs.d.ts → index-DKwuGSe-.d.ts} +2 -2
- package/packages/core/dist/{index-B259NKkH.d.cts → index-vqr-g6ev.d.cts} +1 -1
- package/packages/core/dist/readers.d.cts +1 -1
- package/packages/core/dist/readers.d.ts +1 -1
- package/packages/cli/dist/chunk-S4TLTLXN.mjs.map +0 -1
- package/packages/core/dist/chunk-LQC7IED3.mjs.map +0 -1
|
@@ -488,6 +488,325 @@ function pickString(record, keys) {
|
|
|
488
488
|
return void 0;
|
|
489
489
|
}
|
|
490
490
|
|
|
491
|
+
// packages/core/src/checks/derived-failure.ts
|
|
492
|
+
function isRecord2(value) {
|
|
493
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
494
|
+
}
|
|
495
|
+
function pickString2(record, keys) {
|
|
496
|
+
if (!record) return void 0;
|
|
497
|
+
for (const key of keys) {
|
|
498
|
+
const value = record[key];
|
|
499
|
+
if (typeof value === "string" && value.trim() !== "") return value;
|
|
500
|
+
}
|
|
501
|
+
return void 0;
|
|
502
|
+
}
|
|
503
|
+
function pickNumber(record, keys) {
|
|
504
|
+
if (!record) return void 0;
|
|
505
|
+
for (const key of keys) {
|
|
506
|
+
const value = record[key];
|
|
507
|
+
if (typeof value === "number" && Number.isFinite(value) && value > 0) {
|
|
508
|
+
return value;
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
return void 0;
|
|
512
|
+
}
|
|
513
|
+
function eventMetadata(event) {
|
|
514
|
+
const attrs = isRecord2(event.attributes) ? event.attributes : void 0;
|
|
515
|
+
const nested = attrs !== void 0 && isRecord2(attrs.metadata) ? attrs.metadata : void 0;
|
|
516
|
+
return {
|
|
517
|
+
...attrs ?? {},
|
|
518
|
+
...nested ?? {}
|
|
519
|
+
};
|
|
520
|
+
}
|
|
521
|
+
function canonicalName(event) {
|
|
522
|
+
if (event.kind === "TOOL") return resolveCanonicalToolName(event);
|
|
523
|
+
return event.name;
|
|
524
|
+
}
|
|
525
|
+
function linkKeys(event) {
|
|
526
|
+
const meta = eventMetadata(event);
|
|
527
|
+
const keys = [];
|
|
528
|
+
for (const key of ["linkedStepId", "toolCallId", "mcpToolCallId"]) {
|
|
529
|
+
const value = pickString2(meta, [key]);
|
|
530
|
+
if (value !== void 0) keys.push(`${key}:${value}`);
|
|
531
|
+
}
|
|
532
|
+
const stepId = pickString2(meta, ["stepId"]);
|
|
533
|
+
if (stepId !== void 0) keys.push(`stepId:${stepId}`);
|
|
534
|
+
return keys;
|
|
535
|
+
}
|
|
536
|
+
function buildRunContexts(logicalEvents) {
|
|
537
|
+
const byRun = /* @__PURE__ */ new Map();
|
|
538
|
+
for (const event of logicalEvents) {
|
|
539
|
+
const existing = byRun.get(event.runId) ?? {
|
|
540
|
+
runId: event.runId,
|
|
541
|
+
name: event.name
|
|
542
|
+
};
|
|
543
|
+
const meta = eventMetadata(event);
|
|
544
|
+
if (event.kind === "RUN" || existing.name === event.runId) {
|
|
545
|
+
existing.name = event.name || existing.name;
|
|
546
|
+
}
|
|
547
|
+
if (event.kind === "RUN" && event.status !== void 0 && event.status !== "running") {
|
|
548
|
+
existing.status = event.status;
|
|
549
|
+
}
|
|
550
|
+
existing.retryOf ??= pickString2(meta, ["retryOf"]);
|
|
551
|
+
existing.attempt ??= pickNumber(meta, ["attempt", "retryAttempt", "retryCount"]);
|
|
552
|
+
existing.sessionId ??= pickString2(meta, ["sessionId", "conversationId"]);
|
|
553
|
+
existing.groupId ??= pickString2(meta, ["groupId"]);
|
|
554
|
+
existing.parentGroupId ??= pickString2(meta, ["parentGroupId"]);
|
|
555
|
+
existing.fallbackOf ??= pickString2(meta, ["fallbackOf", "fallbackFrom"]);
|
|
556
|
+
byRun.set(event.runId, existing);
|
|
557
|
+
}
|
|
558
|
+
return byRun;
|
|
559
|
+
}
|
|
560
|
+
function sameCorrelationScope(a, b) {
|
|
561
|
+
if (a.sessionId && b.sessionId && a.sessionId === b.sessionId) return true;
|
|
562
|
+
if (a.groupId && b.groupId && a.groupId === b.groupId) return true;
|
|
563
|
+
if (a.parentGroupId && b.parentGroupId && a.parentGroupId === b.parentGroupId) {
|
|
564
|
+
return true;
|
|
565
|
+
}
|
|
566
|
+
return false;
|
|
567
|
+
}
|
|
568
|
+
function isSuccessful(event) {
|
|
569
|
+
return event.status === "ok";
|
|
570
|
+
}
|
|
571
|
+
function isFailure(event) {
|
|
572
|
+
return event.status === "error";
|
|
573
|
+
}
|
|
574
|
+
function compareEventOrder(a, b) {
|
|
575
|
+
const byTime = a.timestamp.localeCompare(b.timestamp);
|
|
576
|
+
if (byTime !== 0) return byTime;
|
|
577
|
+
return a.eventId.localeCompare(b.eventId);
|
|
578
|
+
}
|
|
579
|
+
function collectCandidates(failure, logicalEvents, runs) {
|
|
580
|
+
const failureRun = runs.get(failure.runId);
|
|
581
|
+
const failureLinks = new Set(linkKeys(failure));
|
|
582
|
+
const failureName = canonicalName(failure);
|
|
583
|
+
const failureAttempt = pickNumber(eventMetadata(failure), ["attempt", "retryAttempt", "retryCount"]) ?? failureRun?.attempt;
|
|
584
|
+
const candidates = [];
|
|
585
|
+
for (const event of logicalEvents) {
|
|
586
|
+
if (event.eventId === failure.eventId) continue;
|
|
587
|
+
if (event.status === "running") continue;
|
|
588
|
+
const eventRun = runs.get(event.runId);
|
|
589
|
+
const eventMeta = eventMetadata(event);
|
|
590
|
+
const sameRun = event.runId === failure.runId;
|
|
591
|
+
if (eventRun?.retryOf === failure.runId) {
|
|
592
|
+
candidates.push({
|
|
593
|
+
event,
|
|
594
|
+
basis: "retryOf",
|
|
595
|
+
confidence: "explicit",
|
|
596
|
+
viaRunId: event.runId
|
|
597
|
+
});
|
|
598
|
+
continue;
|
|
599
|
+
}
|
|
600
|
+
if (eventRun?.fallbackOf === failure.runId || pickString2(eventMeta, ["fallbackOf", "fallbackFrom"]) === failure.runId) {
|
|
601
|
+
candidates.push({
|
|
602
|
+
event,
|
|
603
|
+
basis: "fallbackOf",
|
|
604
|
+
confidence: "explicit",
|
|
605
|
+
viaRunId: event.runId
|
|
606
|
+
});
|
|
607
|
+
continue;
|
|
608
|
+
}
|
|
609
|
+
if (sameRun && compareEventOrder(failure, event) >= 0) continue;
|
|
610
|
+
const eventLinks = linkKeys(event);
|
|
611
|
+
const sharedLink = eventLinks.find((key) => failureLinks.has(key));
|
|
612
|
+
if (sharedLink !== void 0) {
|
|
613
|
+
candidates.push({
|
|
614
|
+
event,
|
|
615
|
+
basis: sharedLink.split(":")[0] ?? "linkedId",
|
|
616
|
+
confidence: "explicit"
|
|
617
|
+
});
|
|
618
|
+
continue;
|
|
619
|
+
}
|
|
620
|
+
const eventAttempt = pickNumber(eventMeta, ["attempt", "retryAttempt", "retryCount"]) ?? eventRun?.attempt;
|
|
621
|
+
const sameParent = failure.parentId !== void 0 && event.parentId !== void 0 && failure.parentId === event.parentId;
|
|
622
|
+
const differentParent = failure.parentId !== void 0 && event.parentId !== void 0 && failure.parentId !== event.parentId;
|
|
623
|
+
const sessionScoped = failureRun !== void 0 && eventRun !== void 0 && sameCorrelationScope(failureRun, eventRun);
|
|
624
|
+
if (canonicalName(event) === failureName && failureAttempt !== void 0 && eventAttempt !== void 0 && eventAttempt > failureAttempt && !differentParent && (sameParent || sessionScoped || sameRun)) {
|
|
625
|
+
candidates.push({
|
|
626
|
+
event,
|
|
627
|
+
basis: "attempt-progression",
|
|
628
|
+
confidence: "correlated",
|
|
629
|
+
...event.runId !== failure.runId ? { viaRunId: event.runId } : {}
|
|
630
|
+
});
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
const byId = /* @__PURE__ */ new Map();
|
|
634
|
+
for (const candidate of candidates) {
|
|
635
|
+
const prev = byId.get(candidate.event.eventId);
|
|
636
|
+
if (!prev || prev.confidence !== "explicit" && candidate.confidence === "explicit") {
|
|
637
|
+
byId.set(candidate.event.eventId, candidate);
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
return [...byId.values()].sort((a, b) => compareEventOrder(a.event, b.event));
|
|
641
|
+
}
|
|
642
|
+
function classifyFailure(failure, candidates, runs, logicalEvents) {
|
|
643
|
+
const successful = candidates.filter((c) => isSuccessful(c.event));
|
|
644
|
+
const unsuccessful = candidates.filter((c) => !isSuccessful(c.event));
|
|
645
|
+
const retryRunIds = Object.freeze(
|
|
646
|
+
[...new Set(candidates.map((c) => c.viaRunId).filter((id) => id !== void 0))].sort(
|
|
647
|
+
(a, b) => a.localeCompare(b)
|
|
648
|
+
)
|
|
649
|
+
);
|
|
650
|
+
if (successful.length > 1) {
|
|
651
|
+
const distinctRuns = new Set(successful.map((c) => c.event.runId));
|
|
652
|
+
const distinctParents = new Set(
|
|
653
|
+
successful.map((c) => c.event.parentId ?? "").filter((id) => id !== "")
|
|
654
|
+
);
|
|
655
|
+
if (distinctRuns.size > 1 || distinctParents.size > 1) {
|
|
656
|
+
return {
|
|
657
|
+
eventId: failure.eventId,
|
|
658
|
+
runId: failure.runId,
|
|
659
|
+
name: failure.name,
|
|
660
|
+
kind: failure.kind,
|
|
661
|
+
role: "unknown",
|
|
662
|
+
confidence: "unknown",
|
|
663
|
+
basis: Object.freeze(["ambiguous-recovery-candidates"]),
|
|
664
|
+
recoveryEventIds: Object.freeze(
|
|
665
|
+
successful.map((c) => c.event.eventId).sort((a, b) => a.localeCompare(b))
|
|
666
|
+
),
|
|
667
|
+
retryRunIds
|
|
668
|
+
};
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
if (successful.length >= 1) {
|
|
672
|
+
const best = successful[0];
|
|
673
|
+
return {
|
|
674
|
+
eventId: failure.eventId,
|
|
675
|
+
runId: failure.runId,
|
|
676
|
+
name: failure.name,
|
|
677
|
+
kind: failure.kind,
|
|
678
|
+
role: "recovered",
|
|
679
|
+
confidence: best.confidence,
|
|
680
|
+
basis: Object.freeze([best.basis]),
|
|
681
|
+
recoveryEventIds: Object.freeze(
|
|
682
|
+
successful.map((c) => c.event.eventId).sort((a, b) => a.localeCompare(b))
|
|
683
|
+
),
|
|
684
|
+
retryRunIds
|
|
685
|
+
};
|
|
686
|
+
}
|
|
687
|
+
if (candidates.length > 0) {
|
|
688
|
+
const best = candidates[0];
|
|
689
|
+
return {
|
|
690
|
+
eventId: failure.eventId,
|
|
691
|
+
runId: failure.runId,
|
|
692
|
+
name: failure.name,
|
|
693
|
+
kind: failure.kind,
|
|
694
|
+
role: "transient",
|
|
695
|
+
confidence: best.confidence,
|
|
696
|
+
basis: Object.freeze([
|
|
697
|
+
best.basis,
|
|
698
|
+
unsuccessful.some((c) => c.event.status === void 0) ? "retry-incomplete" : "retry-without-success"
|
|
699
|
+
]),
|
|
700
|
+
recoveryEventIds: Object.freeze([]),
|
|
701
|
+
retryRunIds
|
|
702
|
+
};
|
|
703
|
+
}
|
|
704
|
+
const failureMeta = eventMetadata(failure);
|
|
705
|
+
const declaredSuccessor = pickString2(failureMeta, [
|
|
706
|
+
"retriedBy",
|
|
707
|
+
"nextRetryRunId",
|
|
708
|
+
"retryRunId"
|
|
709
|
+
]);
|
|
710
|
+
if (declaredSuccessor !== void 0 && !runs.has(declaredSuccessor)) {
|
|
711
|
+
return {
|
|
712
|
+
eventId: failure.eventId,
|
|
713
|
+
runId: failure.runId,
|
|
714
|
+
name: failure.name,
|
|
715
|
+
kind: failure.kind,
|
|
716
|
+
role: "transient",
|
|
717
|
+
confidence: "explicit",
|
|
718
|
+
basis: Object.freeze(["retry-declared", "retry-run-missing"]),
|
|
719
|
+
recoveryEventIds: Object.freeze([]),
|
|
720
|
+
retryRunIds: Object.freeze([declaredSuccessor])
|
|
721
|
+
};
|
|
722
|
+
}
|
|
723
|
+
for (const run of runs.values()) {
|
|
724
|
+
if (run.retryOf === failure.runId) {
|
|
725
|
+
return {
|
|
726
|
+
eventId: failure.eventId,
|
|
727
|
+
runId: failure.runId,
|
|
728
|
+
name: failure.name,
|
|
729
|
+
kind: failure.kind,
|
|
730
|
+
role: "transient",
|
|
731
|
+
confidence: "explicit",
|
|
732
|
+
basis: Object.freeze(["retryOf", "retry-run-missing-or-empty"]),
|
|
733
|
+
recoveryEventIds: Object.freeze([]),
|
|
734
|
+
retryRunIds: Object.freeze([run.runId])
|
|
735
|
+
};
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
const failureRun = runs.get(failure.runId);
|
|
739
|
+
const hasSuccessorDeclared = [...runs.values()].some((run) => run.retryOf === failure.runId);
|
|
740
|
+
const isFinalInChain = failureRun !== void 0 && !hasSuccessorDeclared && (failureRun.retryOf !== void 0 || failureRun.attempt !== void 0 && failureRun.attempt > 1 || pickNumber(eventMetadata(failure), ["attempt"]) !== void 0);
|
|
741
|
+
if (isFinalInChain && failureRun?.status === "error" && !logicalEvents.some(
|
|
742
|
+
(event) => event.runId === failure.runId && event.eventId !== failure.eventId && isSuccessful(event) && canonicalName(event) === canonicalName(failure)
|
|
743
|
+
)) {
|
|
744
|
+
return {
|
|
745
|
+
eventId: failure.eventId,
|
|
746
|
+
runId: failure.runId,
|
|
747
|
+
name: failure.name,
|
|
748
|
+
kind: failure.kind,
|
|
749
|
+
role: "terminal",
|
|
750
|
+
confidence: failureRun.retryOf !== void 0 ? "explicit" : "correlated",
|
|
751
|
+
basis: Object.freeze(["final-retry-chain-member", "enclosing-run-error"]),
|
|
752
|
+
recoveryEventIds: Object.freeze([]),
|
|
753
|
+
retryRunIds: Object.freeze(
|
|
754
|
+
failureRun.retryOf !== void 0 ? [failureRun.retryOf] : []
|
|
755
|
+
)
|
|
756
|
+
};
|
|
757
|
+
}
|
|
758
|
+
return {
|
|
759
|
+
eventId: failure.eventId,
|
|
760
|
+
runId: failure.runId,
|
|
761
|
+
name: failure.name,
|
|
762
|
+
kind: failure.kind,
|
|
763
|
+
role: "unknown",
|
|
764
|
+
confidence: "unknown",
|
|
765
|
+
basis: Object.freeze(["no-explicit-or-correlated-recovery"]),
|
|
766
|
+
recoveryEventIds: Object.freeze([]),
|
|
767
|
+
retryRunIds: Object.freeze([])
|
|
768
|
+
};
|
|
769
|
+
}
|
|
770
|
+
function deriveFailureFacts(logicalEvents) {
|
|
771
|
+
const runs = buildRunContexts(logicalEvents);
|
|
772
|
+
const failures = logicalEvents.filter((event) => isFailure(event)).sort(compareEventOrder);
|
|
773
|
+
const failureFacts = failures.map(
|
|
774
|
+
(failure) => classifyFailure(failure, collectCandidates(failure, logicalEvents, runs), runs, logicalEvents)
|
|
775
|
+
);
|
|
776
|
+
const byRole = /* @__PURE__ */ new Map([
|
|
777
|
+
["transient", []],
|
|
778
|
+
["recovered", []],
|
|
779
|
+
["terminal", []],
|
|
780
|
+
["unknown", []]
|
|
781
|
+
]);
|
|
782
|
+
for (const fact of failureFacts) {
|
|
783
|
+
byRole.get(fact.role).push(fact);
|
|
784
|
+
}
|
|
785
|
+
for (const [role, list] of byRole) {
|
|
786
|
+
byRole.set(
|
|
787
|
+
role,
|
|
788
|
+
Object.freeze(
|
|
789
|
+
[...list].sort((a, b) => {
|
|
790
|
+
const byRun = a.runId.localeCompare(b.runId);
|
|
791
|
+
if (byRun !== 0) return byRun;
|
|
792
|
+
return a.eventId.localeCompare(b.eventId);
|
|
793
|
+
})
|
|
794
|
+
)
|
|
795
|
+
);
|
|
796
|
+
}
|
|
797
|
+
const failureRoleCounts = {
|
|
798
|
+
transient: byRole.get("transient").length,
|
|
799
|
+
recovered: byRole.get("recovered").length,
|
|
800
|
+
terminal: byRole.get("terminal").length,
|
|
801
|
+
unknown: byRole.get("unknown").length
|
|
802
|
+
};
|
|
803
|
+
return {
|
|
804
|
+
failureFacts: Object.freeze(failureFacts),
|
|
805
|
+
failuresByRole: byRole,
|
|
806
|
+
failureRoleCounts
|
|
807
|
+
};
|
|
808
|
+
}
|
|
809
|
+
|
|
491
810
|
// packages/core/src/checks/trace-facts.ts
|
|
492
811
|
function summarizeSemanticParity(events) {
|
|
493
812
|
const projection = projectLogicalEvents(events);
|
|
@@ -498,6 +817,7 @@ function summarizeSemanticParity(events) {
|
|
|
498
817
|
const finishedToolNames = Object.freeze(
|
|
499
818
|
finishedTools.map((event) => resolveCanonicalToolName(event)).sort((a, b) => a.localeCompare(b))
|
|
500
819
|
);
|
|
820
|
+
const derived = deriveFailureFacts(logical);
|
|
501
821
|
return {
|
|
502
822
|
rawEventCount: events.length,
|
|
503
823
|
logicalEventCount: logical.length,
|
|
@@ -508,7 +828,8 @@ function summarizeSemanticParity(events) {
|
|
|
508
828
|
parentRemapCount: projection.diagnostics.filter(
|
|
509
829
|
(item) => item.code === "AI_LOGICAL_PARENT_REMAPPED"
|
|
510
830
|
).length,
|
|
511
|
-
diagnostics: projection.diagnostics
|
|
831
|
+
diagnostics: projection.diagnostics,
|
|
832
|
+
failureRoleCounts: derived.failureRoleCounts
|
|
512
833
|
};
|
|
513
834
|
}
|
|
514
835
|
var TRACE_FACTS_INPUT_NOT_NORMALIZED = formatProgrammaticDiagnostic(
|
|
@@ -571,6 +892,8 @@ function buildTraceFacts(input) {
|
|
|
571
892
|
for (const [name, list] of [...toolsByName.entries()]) {
|
|
572
893
|
toolsByName.set(name, Object.freeze([...list]));
|
|
573
894
|
}
|
|
895
|
+
const derived = deriveFailureFacts(projection.logicalEvents);
|
|
896
|
+
const summary = summarizeSemanticParity(events);
|
|
574
897
|
return {
|
|
575
898
|
rawEvents: Object.freeze([...events]),
|
|
576
899
|
logicalEvents: projection.logicalEvents,
|
|
@@ -578,7 +901,12 @@ function buildTraceFacts(input) {
|
|
|
578
901
|
toolsByName,
|
|
579
902
|
llmEvents: Object.freeze(llmEvents),
|
|
580
903
|
outcomeEvents: Object.freeze(outcomeEvents),
|
|
581
|
-
summary:
|
|
904
|
+
summary: {
|
|
905
|
+
...summary,
|
|
906
|
+
failureRoleCounts: derived.failureRoleCounts
|
|
907
|
+
},
|
|
908
|
+
failureFacts: derived.failureFacts,
|
|
909
|
+
failuresByRole: derived.failuresByRole
|
|
582
910
|
};
|
|
583
911
|
}
|
|
584
912
|
|
|
@@ -1168,7 +1496,7 @@ function firstIndexByName(events) {
|
|
|
1168
1496
|
}
|
|
1169
1497
|
return index;
|
|
1170
1498
|
}
|
|
1171
|
-
function
|
|
1499
|
+
function isRecord3(value) {
|
|
1172
1500
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1173
1501
|
}
|
|
1174
1502
|
function eventMap(events) {
|
|
@@ -1222,7 +1550,7 @@ function pushValueEntries(entries, event, value, path3, key, depth = 0) {
|
|
|
1222
1550
|
}
|
|
1223
1551
|
return;
|
|
1224
1552
|
}
|
|
1225
|
-
if (!
|
|
1553
|
+
if (!isRecord3(value)) return;
|
|
1226
1554
|
for (const nestedKey of Object.keys(value).sort((a, b) => a.localeCompare(b))) {
|
|
1227
1555
|
pushValueEntries(
|
|
1228
1556
|
entries,
|
|
@@ -2317,7 +2645,7 @@ function createSafetyOversizedAttributeRule(options) {
|
|
|
2317
2645
|
)
|
|
2318
2646
|
);
|
|
2319
2647
|
}
|
|
2320
|
-
if (
|
|
2648
|
+
if (isRecord3(entry.value) && options.maxObjectKeys !== void 0 && Object.keys(entry.value).length > options.maxObjectKeys) {
|
|
2321
2649
|
findings.push(
|
|
2322
2650
|
failFinding(
|
|
2323
2651
|
"safety.oversizedAttribute",
|
|
@@ -2636,6 +2964,7 @@ exports.createToolFailureRule = createToolFailureRule;
|
|
|
2636
2964
|
exports.createToolOrderingRule = createToolOrderingRule;
|
|
2637
2965
|
exports.createToolUsageRule = createToolUsageRule;
|
|
2638
2966
|
exports.defineTraceContract = defineTraceContract;
|
|
2967
|
+
exports.deriveFailureFacts = deriveFailureFacts;
|
|
2639
2968
|
exports.evaluateTraceContract = evaluateTraceContract;
|
|
2640
2969
|
exports.evaluateTraceContractRead = evaluateTraceContractRead;
|
|
2641
2970
|
exports.formatProgrammaticDiagnostic = formatProgrammaticDiagnostic;
|