agent-inspect 6.31.6 → 6.31.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 +7 -0
- package/README.md +1 -1
- package/docs/AI-SDK-ADOPTION.md +62 -34
- package/package.json +1 -1
- package/packages/cli/dist/{chunk-YXDNWHNJ.mjs → chunk-QV73NM25.mjs} +97 -25
- package/packages/cli/dist/chunk-QV73NM25.mjs.map +1 -0
- package/packages/cli/dist/index.cjs +414 -81
- package/packages/cli/dist/index.cjs.map +1 -1
- package/packages/cli/dist/index.mjs +322 -62
- package/packages/cli/dist/index.mjs.map +1 -1
- package/packages/cli/dist/{src-H22KNWAZ.mjs → src-KFOBXFPN.mjs} +3 -3
- package/packages/cli/dist/{src-H22KNWAZ.mjs.map → src-KFOBXFPN.mjs.map} +1 -1
- package/packages/core/dist/advanced.cjs +94 -22
- package/packages/core/dist/advanced.cjs.map +1 -1
- package/packages/core/dist/advanced.mjs +4 -4
- package/packages/core/dist/{chunk-OSGNGRHF.mjs → chunk-3RV3JILQ.mjs} +34 -16
- package/packages/core/dist/chunk-3RV3JILQ.mjs.map +1 -0
- package/packages/core/dist/{chunk-EXGQLMVB.mjs → chunk-7YYS742B.mjs} +49 -12
- package/packages/core/dist/chunk-7YYS742B.mjs.map +1 -0
- package/packages/core/dist/{chunk-Q5SLKV2Y.mjs → chunk-QLYUWKK7.mjs} +19 -2
- package/packages/core/dist/chunk-QLYUWKK7.mjs.map +1 -0
- package/packages/core/dist/exporters.cjs +224 -47
- package/packages/core/dist/exporters.cjs.map +1 -1
- package/packages/core/dist/exporters.mjs +178 -38
- package/packages/core/dist/exporters.mjs.map +1 -1
- package/packages/core/dist/persisted.cjs +17 -0
- package/packages/core/dist/persisted.cjs.map +1 -1
- package/packages/core/dist/persisted.mjs +2 -2
- package/packages/core/dist/readers.cjs +48 -13
- package/packages/core/dist/readers.cjs.map +1 -1
- package/packages/core/dist/readers.mjs +2 -2
- package/packages/cli/dist/chunk-YXDNWHNJ.mjs.map +0 -1
- package/packages/core/dist/chunk-EXGQLMVB.mjs.map +0 -1
- package/packages/core/dist/chunk-OSGNGRHF.mjs.map +0 -1
- package/packages/core/dist/chunk-Q5SLKV2Y.mjs.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { buildRunWhatSummary, renderRunWhat, renderTimeline, buildRunTimeline } from './chunk-
|
|
1
|
+
import { buildRunWhatSummary, renderRunWhat, renderTimeline, buildRunTimeline } from './chunk-7YYS742B.mjs';
|
|
2
2
|
import { summarizeObservedOutcomes, extractOutcomesFromTraceEvents, renderObservedOutcomesMarkdown, renderObservedOutcomesHtml } from './chunk-N5PZAI6Q.mjs';
|
|
3
3
|
import { escapeHtml, flattenTree, safeString, compactAttributes, stableJson, escapeMarkdown, zeroKinds } from './chunk-CAWPF22J.mjs';
|
|
4
4
|
export { compactAttributes, escapeHtml, escapeMarkdown, flattenTree, safeString, stableJson, summarizeTree } from './chunk-CAWPF22J.mjs';
|
|
@@ -808,6 +808,10 @@ function exportOpenInference(tree, options) {
|
|
|
808
808
|
warnings
|
|
809
809
|
};
|
|
810
810
|
}
|
|
811
|
+
var OTLP_STATUS_CODE_UNSET = 0;
|
|
812
|
+
var OTLP_STATUS_CODE_OK = 1;
|
|
813
|
+
var OTLP_STATUS_CODE_ERROR = 2;
|
|
814
|
+
var OTLP_SPAN_KIND_INTERNAL = 1;
|
|
811
815
|
function hexFrom2(seed, byteLen) {
|
|
812
816
|
return crypto.createHash("sha256").update(seed, "utf8").digest("hex").slice(0, byteLen * 2);
|
|
813
817
|
}
|
|
@@ -820,7 +824,19 @@ function stringAttr(key, value) {
|
|
|
820
824
|
return { key, value: { stringValue: value } };
|
|
821
825
|
}
|
|
822
826
|
function intAttr(key, value) {
|
|
823
|
-
return { key, value: { intValue: String(value) } };
|
|
827
|
+
return { key, value: { intValue: String(Math.trunc(value)) } };
|
|
828
|
+
}
|
|
829
|
+
function doubleAttr(key, value) {
|
|
830
|
+
return { key, value: { doubleValue: value } };
|
|
831
|
+
}
|
|
832
|
+
function boolAttr(key, value) {
|
|
833
|
+
return { key, value: { boolValue: value } };
|
|
834
|
+
}
|
|
835
|
+
function numberAttr(key, value) {
|
|
836
|
+
if (Number.isFinite(value) && !Number.isInteger(value)) {
|
|
837
|
+
return doubleAttr(key, value);
|
|
838
|
+
}
|
|
839
|
+
return intAttr(key, value);
|
|
824
840
|
}
|
|
825
841
|
function genAiOperationName(kind) {
|
|
826
842
|
switch (kind) {
|
|
@@ -834,10 +850,27 @@ function genAiOperationName(kind) {
|
|
|
834
850
|
return void 0;
|
|
835
851
|
}
|
|
836
852
|
}
|
|
853
|
+
function resolveSpanTimes(ev) {
|
|
854
|
+
const startedAtMs = typeof ev.attributes?.startedAtMs === "number" && Number.isFinite(ev.attributes.startedAtMs) ? ev.attributes.startedAtMs : void 0;
|
|
855
|
+
const endedAtMs = typeof ev.attributes?.endedAtMs === "number" && Number.isFinite(ev.attributes.endedAtMs) ? ev.attributes.endedAtMs : void 0;
|
|
856
|
+
const startMs = startedAtMs ?? ev.timestamp;
|
|
857
|
+
const startNs = String(unixNano2(startMs));
|
|
858
|
+
if (endedAtMs !== void 0) {
|
|
859
|
+
return { startNs, endNs: String(unixNano2(endedAtMs)) };
|
|
860
|
+
}
|
|
861
|
+
if (ev.durationMs !== void 0 && Number.isFinite(ev.durationMs)) {
|
|
862
|
+
return {
|
|
863
|
+
startNs,
|
|
864
|
+
endNs: String(unixNano2(startMs) + unixNano2(ev.durationMs))
|
|
865
|
+
};
|
|
866
|
+
}
|
|
867
|
+
return { startNs };
|
|
868
|
+
}
|
|
837
869
|
function exportOtlpJson(tree, options) {
|
|
838
870
|
const warnings = [
|
|
839
871
|
"OTLP JSON export uses OTel GenAI-aligned attributes where applicable; experimental until verified against specific collectors.",
|
|
840
|
-
"Not OTLP gRPC/protobuf \u2014 JSON mapping only. Generated locally; no network upload."
|
|
872
|
+
"Not OTLP gRPC/protobuf \u2014 JSON mapping only. Generated locally; no network upload.",
|
|
873
|
+
"Status and span kind use OTLP numeric enums (StatusCode 0/1/2, SpanKind INTERNAL=1)."
|
|
841
874
|
];
|
|
842
875
|
const traceId = hexFrom2(`trace:${tree.runId}`, 16);
|
|
843
876
|
const includeAttributes = options?.includeAttributes ?? false;
|
|
@@ -849,11 +882,7 @@ function exportOtlpJson(tree, options) {
|
|
|
849
882
|
const ev = n.event;
|
|
850
883
|
const spanId = hexFrom2(`${tree.runId}:${ev.eventId}`, 8);
|
|
851
884
|
const parentSpanId = ev.parentId ? hexFrom2(`${tree.runId}:${ev.parentId}`, 8) : void 0;
|
|
852
|
-
const startNs =
|
|
853
|
-
let endNs;
|
|
854
|
-
if (ev.durationMs !== void 0 && Number.isFinite(ev.durationMs)) {
|
|
855
|
-
endNs = String(unixNano2(ev.timestamp) + unixNano2(ev.durationMs));
|
|
856
|
-
}
|
|
885
|
+
const { startNs, endNs } = resolveSpanTimes(ev);
|
|
857
886
|
const attrs = [
|
|
858
887
|
stringAttr("agent_inspect.kind", ev.kind),
|
|
859
888
|
stringAttr("agent_inspect.confidence", ev.confidence),
|
|
@@ -883,29 +912,28 @@ function exportOtlpJson(tree, options) {
|
|
|
883
912
|
if (includeAttributes && meta && typeof meta === "object") {
|
|
884
913
|
for (const [k, v] of Object.entries(meta)) {
|
|
885
914
|
if (k === "tokens" || k === "model") continue;
|
|
886
|
-
if (typeof v === "string"
|
|
887
|
-
attrs.push(
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
);
|
|
915
|
+
if (typeof v === "string") {
|
|
916
|
+
attrs.push(stringAttr(`agent_inspect.preview.${k}`, v.slice(0, maxLen)));
|
|
917
|
+
} else if (typeof v === "number" && Number.isFinite(v)) {
|
|
918
|
+
attrs.push(numberAttr(`agent_inspect.preview.${k}`, v));
|
|
919
|
+
} else if (typeof v === "boolean") {
|
|
920
|
+
attrs.push(boolAttr(`agent_inspect.preview.${k}`, v));
|
|
893
921
|
}
|
|
894
922
|
}
|
|
895
923
|
}
|
|
896
|
-
let statusCode =
|
|
924
|
+
let statusCode = OTLP_STATUS_CODE_UNSET;
|
|
897
925
|
let statusMessage;
|
|
898
926
|
if (ev.status === "error") {
|
|
899
|
-
statusCode =
|
|
927
|
+
statusCode = OTLP_STATUS_CODE_ERROR;
|
|
900
928
|
statusMessage = meta && typeof meta.error === "object" && meta.error !== null ? String(meta.error.message ?? "error").slice(0, maxLen) : "error";
|
|
901
929
|
} else if (ev.status === "ok") {
|
|
902
|
-
statusCode =
|
|
930
|
+
statusCode = OTLP_STATUS_CODE_OK;
|
|
903
931
|
}
|
|
904
932
|
const spanJson = {
|
|
905
933
|
traceId,
|
|
906
934
|
spanId,
|
|
907
935
|
name: ev.name,
|
|
908
|
-
kind:
|
|
936
|
+
kind: OTLP_SPAN_KIND_INTERNAL,
|
|
909
937
|
startTimeUnixNano: startNs,
|
|
910
938
|
attributes: attrs,
|
|
911
939
|
status: {
|
|
@@ -947,6 +975,136 @@ function exportOtlpJson(tree, options) {
|
|
|
947
975
|
|
|
948
976
|
// packages/core/src/exporters/validation.ts
|
|
949
977
|
var EXPERIMENTAL = "Experimental compatibility export \u2014 verify against your target tooling before relying on it.";
|
|
978
|
+
function pushPath(errors, path, message) {
|
|
979
|
+
errors.push(`${path}: ${message}`);
|
|
980
|
+
}
|
|
981
|
+
function isRecord2(value) {
|
|
982
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
983
|
+
}
|
|
984
|
+
function validateOtlpJson(content) {
|
|
985
|
+
const errors = [];
|
|
986
|
+
const warnings = [
|
|
987
|
+
EXPERIMENTAL,
|
|
988
|
+
"OTLP JSON mapping uses OTel GenAI-aligned attributes where applicable; collectors may require transformation.",
|
|
989
|
+
"protocol-valid \u2260 profile-complete \u2260 fixture-complete \u2014 nested path diagnostics report protocol shape only."
|
|
990
|
+
];
|
|
991
|
+
let parsed;
|
|
992
|
+
try {
|
|
993
|
+
parsed = JSON.parse(content);
|
|
994
|
+
} catch {
|
|
995
|
+
pushPath(errors, "$", "OTLP JSON export is not valid JSON");
|
|
996
|
+
return { ok: false, format: "otlp-json", errors, warnings };
|
|
997
|
+
}
|
|
998
|
+
if (!isRecord2(parsed)) {
|
|
999
|
+
pushPath(errors, "$", "OTLP JSON export must be an object");
|
|
1000
|
+
return { ok: false, format: "otlp-json", errors, warnings };
|
|
1001
|
+
}
|
|
1002
|
+
if (!Array.isArray(parsed.resourceSpans)) {
|
|
1003
|
+
pushPath(errors, "$.resourceSpans", "must be an array");
|
|
1004
|
+
return { ok: false, format: "otlp-json", errors, warnings };
|
|
1005
|
+
}
|
|
1006
|
+
parsed.resourceSpans.forEach((resourceSpan, rsi) => {
|
|
1007
|
+
const rsPath = `$.resourceSpans[${rsi}]`;
|
|
1008
|
+
if (!isRecord2(resourceSpan)) {
|
|
1009
|
+
pushPath(errors, rsPath, "must be an object");
|
|
1010
|
+
return;
|
|
1011
|
+
}
|
|
1012
|
+
if (!Array.isArray(resourceSpan.scopeSpans)) {
|
|
1013
|
+
pushPath(errors, `${rsPath}.scopeSpans`, "must be an array");
|
|
1014
|
+
return;
|
|
1015
|
+
}
|
|
1016
|
+
resourceSpan.scopeSpans.forEach((scopeSpan, ssi) => {
|
|
1017
|
+
const ssPath = `${rsPath}.scopeSpans[${ssi}]`;
|
|
1018
|
+
if (!isRecord2(scopeSpan)) {
|
|
1019
|
+
pushPath(errors, ssPath, "must be an object");
|
|
1020
|
+
return;
|
|
1021
|
+
}
|
|
1022
|
+
if (!Array.isArray(scopeSpan.spans)) {
|
|
1023
|
+
pushPath(errors, `${ssPath}.spans`, "must be an array");
|
|
1024
|
+
return;
|
|
1025
|
+
}
|
|
1026
|
+
scopeSpan.spans.forEach((span, spi) => {
|
|
1027
|
+
const spanPath = `${ssPath}.spans[${spi}]`;
|
|
1028
|
+
if (!isRecord2(span)) {
|
|
1029
|
+
pushPath(errors, spanPath, "must be an object");
|
|
1030
|
+
return;
|
|
1031
|
+
}
|
|
1032
|
+
if (typeof span.traceId !== "string" || span.traceId.length === 0) {
|
|
1033
|
+
pushPath(errors, `${spanPath}.traceId`, "must be a non-empty string");
|
|
1034
|
+
}
|
|
1035
|
+
if (typeof span.spanId !== "string" || span.spanId.length === 0) {
|
|
1036
|
+
pushPath(errors, `${spanPath}.spanId`, "must be a non-empty string");
|
|
1037
|
+
}
|
|
1038
|
+
if (typeof span.name !== "string") {
|
|
1039
|
+
pushPath(errors, `${spanPath}.name`, "must be a string");
|
|
1040
|
+
}
|
|
1041
|
+
if (typeof span.startTimeUnixNano !== "string" || !/^\d+$/.test(span.startTimeUnixNano)) {
|
|
1042
|
+
pushPath(
|
|
1043
|
+
errors,
|
|
1044
|
+
`${spanPath}.startTimeUnixNano`,
|
|
1045
|
+
"must be a decimal-string 64-bit integer"
|
|
1046
|
+
);
|
|
1047
|
+
}
|
|
1048
|
+
if (span.endTimeUnixNano !== void 0 && (typeof span.endTimeUnixNano !== "string" || !/^\d+$/.test(span.endTimeUnixNano))) {
|
|
1049
|
+
pushPath(
|
|
1050
|
+
errors,
|
|
1051
|
+
`${spanPath}.endTimeUnixNano`,
|
|
1052
|
+
"must be a decimal-string 64-bit integer when present"
|
|
1053
|
+
);
|
|
1054
|
+
}
|
|
1055
|
+
if (typeof span.kind === "number") {
|
|
1056
|
+
if (!Number.isInteger(span.kind)) {
|
|
1057
|
+
pushPath(errors, `${spanPath}.kind`, "must be an integer SpanKind enum");
|
|
1058
|
+
}
|
|
1059
|
+
} else if (typeof span.kind === "string") {
|
|
1060
|
+
warnings.push(
|
|
1061
|
+
`${spanPath}.kind: string SpanKind enum is legacy; prefer numeric (INTERNAL=1)`
|
|
1062
|
+
);
|
|
1063
|
+
} else if (span.kind !== void 0) {
|
|
1064
|
+
pushPath(
|
|
1065
|
+
errors,
|
|
1066
|
+
`${spanPath}.kind`,
|
|
1067
|
+
"must be numeric SpanKind or historical string enum"
|
|
1068
|
+
);
|
|
1069
|
+
}
|
|
1070
|
+
if (!isRecord2(span.status)) {
|
|
1071
|
+
pushPath(errors, `${spanPath}.status`, "must be an object");
|
|
1072
|
+
} else {
|
|
1073
|
+
const code = span.status.code;
|
|
1074
|
+
if (typeof code === "number") {
|
|
1075
|
+
if (![0, 1, 2].includes(code)) {
|
|
1076
|
+
pushPath(
|
|
1077
|
+
errors,
|
|
1078
|
+
`${spanPath}.status.code`,
|
|
1079
|
+
"must be numeric StatusCode 0 (UNSET), 1 (OK), or 2 (ERROR)"
|
|
1080
|
+
);
|
|
1081
|
+
}
|
|
1082
|
+
} else if (typeof code === "string") {
|
|
1083
|
+
const upper = code.toUpperCase();
|
|
1084
|
+
if (upper !== "STATUS_CODE_UNSET" && upper !== "STATUS_CODE_OK" && upper !== "STATUS_CODE_ERROR" && upper !== "UNSET" && upper !== "OK" && upper !== "ERROR" && !/^[012]$/.test(code.trim())) {
|
|
1085
|
+
pushPath(
|
|
1086
|
+
errors,
|
|
1087
|
+
`${spanPath}.status.code`,
|
|
1088
|
+
"unrecognized StatusCode string"
|
|
1089
|
+
);
|
|
1090
|
+
} else {
|
|
1091
|
+
warnings.push(
|
|
1092
|
+
`${spanPath}.status.code: string StatusCode is legacy; prefer numeric 0/1/2`
|
|
1093
|
+
);
|
|
1094
|
+
}
|
|
1095
|
+
} else {
|
|
1096
|
+
pushPath(
|
|
1097
|
+
errors,
|
|
1098
|
+
`${spanPath}.status.code`,
|
|
1099
|
+
"must be numeric StatusCode 0/1/2 or historical string enum"
|
|
1100
|
+
);
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
});
|
|
1104
|
+
});
|
|
1105
|
+
});
|
|
1106
|
+
return { ok: errors.length === 0, format: "otlp-json", errors, warnings };
|
|
1107
|
+
}
|
|
950
1108
|
function validateExportContent(format, content) {
|
|
951
1109
|
const errors = [];
|
|
952
1110
|
const warnings = [EXPERIMENTAL];
|
|
@@ -992,25 +1150,7 @@ function validateExportContent(format, content) {
|
|
|
992
1150
|
return { ok: errors.length === 0, format, errors, warnings };
|
|
993
1151
|
}
|
|
994
1152
|
if (format === "otlp-json") {
|
|
995
|
-
|
|
996
|
-
try {
|
|
997
|
-
parsed = JSON.parse(content);
|
|
998
|
-
} catch {
|
|
999
|
-
errors.push("OTLP JSON export is not valid JSON");
|
|
1000
|
-
return { ok: false, format, errors, warnings };
|
|
1001
|
-
}
|
|
1002
|
-
if (!parsed || typeof parsed !== "object") {
|
|
1003
|
-
errors.push("OTLP JSON export must be an object");
|
|
1004
|
-
return { ok: false, format, errors, warnings };
|
|
1005
|
-
}
|
|
1006
|
-
const o = parsed;
|
|
1007
|
-
if (!Array.isArray(o.resourceSpans)) {
|
|
1008
|
-
errors.push("OTLP JSON export must include resourceSpans array");
|
|
1009
|
-
}
|
|
1010
|
-
warnings.push(
|
|
1011
|
-
"OTLP JSON mapping uses OTel GenAI-aligned attributes where applicable; collectors may require transformation."
|
|
1012
|
-
);
|
|
1013
|
-
return { ok: errors.length === 0, format, errors, warnings };
|
|
1153
|
+
return validateOtlpJson(content);
|
|
1014
1154
|
}
|
|
1015
1155
|
errors.push(`Unsupported export format`);
|
|
1016
1156
|
return { ok: false, format, errors, warnings };
|