agent-inspect 6.31.21 → 6.31.23
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 +12 -0
- package/README.md +1 -1
- package/package.json +1 -1
- package/packages/cli/dist/{chunk-N5JN26MW.mjs → chunk-P27XTK5U.mjs} +347 -36
- package/packages/cli/dist/chunk-P27XTK5U.mjs.map +1 -0
- package/packages/cli/dist/index.cjs +434 -63
- package/packages/cli/dist/index.cjs.map +1 -1
- package/packages/cli/dist/index.mjs +81 -33
- package/packages/cli/dist/index.mjs.map +1 -1
- package/packages/cli/dist/{src-VMGRSTG7.mjs → src-EWZYLDST.mjs} +3 -3
- package/packages/cli/dist/{src-VMGRSTG7.mjs.map → src-EWZYLDST.mjs.map} +1 -1
- package/packages/core/dist/advanced.cjs +280 -10
- package/packages/core/dist/advanced.cjs.map +1 -1
- package/packages/core/dist/advanced.mjs +6 -5
- package/packages/core/dist/advanced.mjs.map +1 -1
- package/packages/core/dist/checks.cjs +185 -27
- package/packages/core/dist/checks.cjs.map +1 -1
- package/packages/core/dist/checks.mjs +2 -1
- package/packages/core/dist/{chunk-JE3TUFAQ.mjs → chunk-77PUPLPG.mjs} +14 -8
- package/packages/core/dist/chunk-77PUPLPG.mjs.map +1 -0
- package/packages/core/dist/chunk-AN5MOADW.mjs +204 -0
- package/packages/core/dist/chunk-AN5MOADW.mjs.map +1 -0
- package/packages/core/dist/{chunk-4CDX5GDS.mjs → chunk-IMCM42W6.mjs} +110 -99
- package/packages/core/dist/chunk-IMCM42W6.mjs.map +1 -0
- package/packages/core/dist/{chunk-YU6XT5A2.mjs → chunk-J2ST4VCX.mjs} +45 -3
- package/packages/core/dist/chunk-J2ST4VCX.mjs.map +1 -0
- package/packages/core/dist/{chunk-EIP5CNEL.mjs → chunk-JJSL346L.mjs} +58 -3
- package/packages/core/dist/chunk-JJSL346L.mjs.map +1 -0
- package/packages/core/dist/exporters.cjs +91 -29
- package/packages/core/dist/exporters.cjs.map +1 -1
- package/packages/core/dist/exporters.mjs +78 -29
- package/packages/core/dist/exporters.mjs.map +1 -1
- package/packages/core/dist/logs.cjs +206 -1
- package/packages/core/dist/logs.cjs.map +1 -1
- package/packages/core/dist/logs.mjs +3 -2
- package/packages/core/dist/logs.mjs.map +1 -1
- package/packages/core/dist/persisted.cjs +226 -8
- package/packages/core/dist/persisted.cjs.map +1 -1
- package/packages/core/dist/persisted.mjs +9 -5
- package/packages/core/dist/persisted.mjs.map +1 -1
- package/packages/core/dist/readers.cjs +276 -6
- package/packages/core/dist/readers.cjs.map +1 -1
- package/packages/core/dist/readers.mjs +4 -3
- package/packages/cli/dist/chunk-N5JN26MW.mjs.map +0 -1
- package/packages/core/dist/chunk-4CDX5GDS.mjs.map +0 -1
- package/packages/core/dist/chunk-EIP5CNEL.mjs.map +0 -1
- package/packages/core/dist/chunk-JE3TUFAQ.mjs.map +0 -1
- package/packages/core/dist/chunk-YU6XT5A2.mjs.map +0 -1
|
@@ -708,6 +708,171 @@ var EventNormalizer = class {
|
|
|
708
708
|
}
|
|
709
709
|
};
|
|
710
710
|
|
|
711
|
+
// packages/core/src/checks/canonical-equality.ts
|
|
712
|
+
var DEFAULT_MAX_DEPTH = 8;
|
|
713
|
+
var DEFAULT_MAX_BYTES = 16384;
|
|
714
|
+
function sortKeysDeep(input, depth, maxDepth) {
|
|
715
|
+
if (depth > maxDepth) {
|
|
716
|
+
throw new Error("AI_CHECK_CANONICAL_DEPTH_EXCEEDED");
|
|
717
|
+
}
|
|
718
|
+
if (input === null || typeof input !== "object") return input;
|
|
719
|
+
if (Array.isArray(input)) {
|
|
720
|
+
return input.map((item) => sortKeysDeep(item, depth + 1, maxDepth));
|
|
721
|
+
}
|
|
722
|
+
const record = input;
|
|
723
|
+
const out = {};
|
|
724
|
+
for (const key of Object.keys(record).sort()) {
|
|
725
|
+
out[key] = sortKeysDeep(record[key], depth + 1, maxDepth);
|
|
726
|
+
}
|
|
727
|
+
return out;
|
|
728
|
+
}
|
|
729
|
+
function encodeCanonicalStructured(value, limits) {
|
|
730
|
+
const maxDepth = DEFAULT_MAX_DEPTH;
|
|
731
|
+
const maxBytes = DEFAULT_MAX_BYTES;
|
|
732
|
+
try {
|
|
733
|
+
const sorted = sortKeysDeep(value, 0, maxDepth);
|
|
734
|
+
const encoded = JSON.stringify(sorted);
|
|
735
|
+
if (encoded === void 0) {
|
|
736
|
+
return {
|
|
737
|
+
ok: false,
|
|
738
|
+
reason: "Value is not JSON-serializable for canonical comparison.",
|
|
739
|
+
code: "AI_CHECK_CANONICAL_UNSERIALIZABLE"
|
|
740
|
+
};
|
|
741
|
+
}
|
|
742
|
+
if (Buffer.byteLength(encoded, "utf8") > maxBytes) {
|
|
743
|
+
return {
|
|
744
|
+
ok: false,
|
|
745
|
+
reason: "Canonical structured value exceeds bounded size limit.",
|
|
746
|
+
code: "AI_CHECK_CANONICAL_SIZE_EXCEEDED"
|
|
747
|
+
};
|
|
748
|
+
}
|
|
749
|
+
return { ok: true, value: encoded };
|
|
750
|
+
} catch (error) {
|
|
751
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
752
|
+
if (message === "AI_CHECK_CANONICAL_DEPTH_EXCEEDED") {
|
|
753
|
+
return {
|
|
754
|
+
ok: false,
|
|
755
|
+
reason: "Canonical structured value exceeds bounded depth limit.",
|
|
756
|
+
code: "AI_CHECK_CANONICAL_DEPTH_EXCEEDED"
|
|
757
|
+
};
|
|
758
|
+
}
|
|
759
|
+
return {
|
|
760
|
+
ok: false,
|
|
761
|
+
reason: "Canonical structured encoding failed.",
|
|
762
|
+
code: "AI_CHECK_CANONICAL_UNSERIALIZABLE"
|
|
763
|
+
};
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
// packages/core/src/persisted/delivery-identity.ts
|
|
768
|
+
var DELIVERY_CONFLICT_ATTR = "agent_inspect.delivery_conflict";
|
|
769
|
+
var DELIVERY_EVENT_BASE_ATTR = "agent_inspect.delivery_event_base";
|
|
770
|
+
var MAX_DELIVERY_BASE_LEN = 500;
|
|
771
|
+
function stripReaderDeliveryDiscriminator(eventId, attributes) {
|
|
772
|
+
if (!eventId) return eventId;
|
|
773
|
+
const rawBase = attributes?.[DELIVERY_EVENT_BASE_ATTR];
|
|
774
|
+
if (typeof rawBase !== "string" || rawBase.trim() === "") return eventId;
|
|
775
|
+
const base = rawBase.trim().slice(0, MAX_DELIVERY_BASE_LEN);
|
|
776
|
+
if (eventId === base) return base;
|
|
777
|
+
const prefix = `${base}:`;
|
|
778
|
+
if (!eventId.startsWith(prefix)) return eventId;
|
|
779
|
+
const suffix = eventId.slice(prefix.length);
|
|
780
|
+
if (/^\d+$/.test(suffix)) return base;
|
|
781
|
+
return eventId;
|
|
782
|
+
}
|
|
783
|
+
function canonicalDigest(value) {
|
|
784
|
+
if (value === void 0) return null;
|
|
785
|
+
const encoded = encodeCanonicalStructured(value);
|
|
786
|
+
return encoded.ok ? encoded.value : `unencodable:${encoded.code}`;
|
|
787
|
+
}
|
|
788
|
+
function capturedContentDigest(attributes) {
|
|
789
|
+
if (!attributes || typeof attributes !== "object") {
|
|
790
|
+
return { args: null, result: null };
|
|
791
|
+
}
|
|
792
|
+
const nested = attributes.metadata && typeof attributes.metadata === "object" ? attributes.metadata : void 0;
|
|
793
|
+
const args = attributes.arguments ?? attributes.args ?? attributes.input ?? nested?.arguments ?? nested?.args ?? nested?.input;
|
|
794
|
+
const result = attributes.result ?? attributes.output ?? attributes.response ?? nested?.result ?? nested?.output ?? nested?.response;
|
|
795
|
+
return {
|
|
796
|
+
args: args === void 0 ? null : canonicalDigest(args),
|
|
797
|
+
result: result === void 0 ? null : canonicalDigest(result)
|
|
798
|
+
};
|
|
799
|
+
}
|
|
800
|
+
function timeKey(fields) {
|
|
801
|
+
if (typeof fields.startedAt === "string" && fields.startedAt.trim() !== "") {
|
|
802
|
+
return fields.startedAt;
|
|
803
|
+
}
|
|
804
|
+
if (typeof fields.timestamp === "string" && fields.timestamp.trim() !== "") {
|
|
805
|
+
return fields.timestamp;
|
|
806
|
+
}
|
|
807
|
+
if (typeof fields.timestamp === "number" && Number.isFinite(fields.timestamp)) {
|
|
808
|
+
return String(fields.timestamp);
|
|
809
|
+
}
|
|
810
|
+
return null;
|
|
811
|
+
}
|
|
812
|
+
function deliverySemanticFingerprint(fields) {
|
|
813
|
+
const content = capturedContentDigest(fields.attributes);
|
|
814
|
+
return JSON.stringify({
|
|
815
|
+
stableEventId: stripReaderDeliveryDiscriminator(fields.eventId, fields.attributes),
|
|
816
|
+
runId: fields.runId,
|
|
817
|
+
kind: fields.kind,
|
|
818
|
+
name: fields.name,
|
|
819
|
+
status: fields.status ?? null,
|
|
820
|
+
parentId: fields.parentId ?? null,
|
|
821
|
+
sourceType: fields.sourceType ?? null,
|
|
822
|
+
time: timeKey(fields),
|
|
823
|
+
operationId: fields.operationId ?? null,
|
|
824
|
+
attemptId: fields.attemptId ?? null,
|
|
825
|
+
attemptNumber: fields.attemptNumber ?? null,
|
|
826
|
+
retryOf: fields.retryOf ?? null,
|
|
827
|
+
argsDigest: content.args,
|
|
828
|
+
resultDigest: content.result
|
|
829
|
+
});
|
|
830
|
+
}
|
|
831
|
+
function identityFieldsFromAttributes(attributes) {
|
|
832
|
+
if (!attributes || typeof attributes !== "object") {
|
|
833
|
+
return {
|
|
834
|
+
operationId: null,
|
|
835
|
+
attemptId: null,
|
|
836
|
+
attemptNumber: null,
|
|
837
|
+
retryOf: null
|
|
838
|
+
};
|
|
839
|
+
}
|
|
840
|
+
const nested = attributes.metadata && typeof attributes.metadata === "object" && !Array.isArray(attributes.metadata) ? attributes.metadata : void 0;
|
|
841
|
+
const pickString = (key) => {
|
|
842
|
+
const direct = attributes[key];
|
|
843
|
+
if (typeof direct === "string" && direct.trim() !== "") return direct.trim();
|
|
844
|
+
const nestedValue = nested?.[key];
|
|
845
|
+
if (typeof nestedValue === "string" && nestedValue.trim() !== "") {
|
|
846
|
+
return nestedValue.trim();
|
|
847
|
+
}
|
|
848
|
+
return null;
|
|
849
|
+
};
|
|
850
|
+
const pickNumber = () => {
|
|
851
|
+
const direct = attributes.attemptNumber ?? attributes.attempt;
|
|
852
|
+
if (typeof direct === "number" && Number.isFinite(direct)) return direct;
|
|
853
|
+
const nestedValue = nested?.attemptNumber ?? nested?.attempt;
|
|
854
|
+
if (typeof nestedValue === "number" && Number.isFinite(nestedValue)) {
|
|
855
|
+
return nestedValue;
|
|
856
|
+
}
|
|
857
|
+
return null;
|
|
858
|
+
};
|
|
859
|
+
return {
|
|
860
|
+
operationId: pickString("operationId"),
|
|
861
|
+
attemptId: pickString("attemptId"),
|
|
862
|
+
retryOf: pickString("retryOf"),
|
|
863
|
+
attemptNumber: pickNumber()
|
|
864
|
+
};
|
|
865
|
+
}
|
|
866
|
+
function stampDeliveryConflict(event) {
|
|
867
|
+
return {
|
|
868
|
+
...event,
|
|
869
|
+
attributes: {
|
|
870
|
+
...event.attributes ?? {},
|
|
871
|
+
[DELIVERY_CONFLICT_ATTR]: true
|
|
872
|
+
}
|
|
873
|
+
};
|
|
874
|
+
}
|
|
875
|
+
|
|
711
876
|
// packages/core/src/logs/tree-builder.ts
|
|
712
877
|
function inc(map, key) {
|
|
713
878
|
map[key] = (map[key] ?? 0) + 1;
|
|
@@ -839,7 +1004,47 @@ var TreeBuilder = class {
|
|
|
839
1004
|
const sorted = [...runEvents].sort((a, b) => a.timestamp - b.timestamp);
|
|
840
1005
|
const nodes = /* @__PURE__ */ new Map();
|
|
841
1006
|
for (const e of sorted) {
|
|
842
|
-
nodes.
|
|
1007
|
+
const existing = nodes.get(e.eventId);
|
|
1008
|
+
if (!existing) {
|
|
1009
|
+
nodes.set(e.eventId, { event: e, children: [], depth: 0 });
|
|
1010
|
+
continue;
|
|
1011
|
+
}
|
|
1012
|
+
const existingAttrs = existing.event.attributes && typeof existing.event.attributes === "object" ? existing.event.attributes : void 0;
|
|
1013
|
+
const nextAttrs = e.attributes && typeof e.attributes === "object" ? e.attributes : void 0;
|
|
1014
|
+
const existingIdentity = identityFieldsFromAttributes(existingAttrs);
|
|
1015
|
+
const nextIdentity = identityFieldsFromAttributes(nextAttrs);
|
|
1016
|
+
const existingFp = deliverySemanticFingerprint({
|
|
1017
|
+
eventId: existing.event.eventId,
|
|
1018
|
+
runId: existing.event.runId,
|
|
1019
|
+
kind: existing.event.kind,
|
|
1020
|
+
name: existing.event.name,
|
|
1021
|
+
status: existing.event.status,
|
|
1022
|
+
parentId: existing.event.parentId,
|
|
1023
|
+
timestamp: existing.event.timestamp,
|
|
1024
|
+
sourceType: existing.event.source?.type,
|
|
1025
|
+
attributes: existingAttrs,
|
|
1026
|
+
...existingIdentity
|
|
1027
|
+
});
|
|
1028
|
+
const nextFp = deliverySemanticFingerprint({
|
|
1029
|
+
eventId: e.eventId,
|
|
1030
|
+
runId: e.runId,
|
|
1031
|
+
kind: e.kind,
|
|
1032
|
+
name: e.name,
|
|
1033
|
+
status: e.status,
|
|
1034
|
+
parentId: e.parentId,
|
|
1035
|
+
timestamp: e.timestamp,
|
|
1036
|
+
sourceType: e.source?.type,
|
|
1037
|
+
attributes: nextAttrs,
|
|
1038
|
+
...nextIdentity
|
|
1039
|
+
});
|
|
1040
|
+
if (existingFp === nextFp) {
|
|
1041
|
+
continue;
|
|
1042
|
+
}
|
|
1043
|
+
nodes.set(e.eventId, {
|
|
1044
|
+
event: stampDeliveryConflict(e),
|
|
1045
|
+
children: [],
|
|
1046
|
+
depth: 0
|
|
1047
|
+
});
|
|
843
1048
|
}
|
|
844
1049
|
const { roots, summary } = linkNodesVisibilityFirst(nodes);
|
|
845
1050
|
const confidenceBreakdown = {
|