agent-inspect 6.31.11 → 6.31.13

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.
Files changed (36) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +1 -1
  3. package/package.json +1 -1
  4. package/packages/cli/dist/{chunk-MQYHJL3W.mjs → chunk-ZAYVAHIH.mjs} +206 -34
  5. package/packages/cli/dist/chunk-ZAYVAHIH.mjs.map +1 -0
  6. package/packages/cli/dist/index.cjs +413 -67
  7. package/packages/cli/dist/index.cjs.map +1 -1
  8. package/packages/cli/dist/index.mjs +209 -36
  9. package/packages/cli/dist/index.mjs.map +1 -1
  10. package/packages/cli/dist/{src-76R6E2LQ.mjs → src-KP4UIFK5.mjs} +3 -3
  11. package/packages/cli/dist/{src-76R6E2LQ.mjs.map → src-KP4UIFK5.mjs.map} +1 -1
  12. package/packages/core/dist/advanced.cjs +204 -32
  13. package/packages/core/dist/advanced.cjs.map +1 -1
  14. package/packages/core/dist/advanced.mjs +151 -28
  15. package/packages/core/dist/advanced.mjs.map +1 -1
  16. package/packages/core/dist/{chunk-OAUNS5CS.mjs → chunk-JE3TUFAQ.mjs} +3 -3
  17. package/packages/core/dist/{chunk-OAUNS5CS.mjs.map → chunk-JE3TUFAQ.mjs.map} +1 -1
  18. package/packages/core/dist/{chunk-QOC3PJO3.mjs → chunk-NJUSSJX3.mjs} +3 -3
  19. package/packages/core/dist/{chunk-QOC3PJO3.mjs.map → chunk-NJUSSJX3.mjs.map} +1 -1
  20. package/packages/core/dist/{chunk-AK5EN4U2.mjs → chunk-YU6XT5A2.mjs} +58 -9
  21. package/packages/core/dist/chunk-YU6XT5A2.mjs.map +1 -0
  22. package/packages/core/dist/exporters.cjs +205 -32
  23. package/packages/core/dist/exporters.cjs.map +1 -1
  24. package/packages/core/dist/exporters.mjs +205 -32
  25. package/packages/core/dist/exporters.mjs.map +1 -1
  26. package/packages/core/dist/logs.cjs +56 -7
  27. package/packages/core/dist/logs.cjs.map +1 -1
  28. package/packages/core/dist/logs.mjs +2 -2
  29. package/packages/core/dist/persisted.cjs +56 -7
  30. package/packages/core/dist/persisted.cjs.map +1 -1
  31. package/packages/core/dist/persisted.mjs +3 -3
  32. package/packages/core/dist/readers.cjs +56 -7
  33. package/packages/core/dist/readers.cjs.map +1 -1
  34. package/packages/core/dist/readers.mjs +3 -3
  35. package/packages/cli/dist/chunk-MQYHJL3W.mjs.map +0 -1
  36. package/packages/core/dist/chunk-AK5EN4U2.mjs.map +0 -1
@@ -3411,12 +3411,14 @@ function topKinds(run) {
3411
3411
  function countErrorNodes(nodes) {
3412
3412
  return nodes.filter((entry) => entry.node.event.status === "error").length;
3413
3413
  }
3414
+ function isExecutionStepKind(kind) {
3415
+ return kind !== "RUN" && kind !== "OUTCOME";
3416
+ }
3414
3417
  function slowestNode(nodes) {
3415
3418
  return nodes.filter(
3416
3419
  (entry) => entry.node.event.durationMs !== void 0 && // The RUN boundary spans the whole run, so its duration always dominates
3417
- // and shadows every real step. Rank actual work nodes only, matching the
3418
- // stats slowest-step ranking, which never counts the run envelope.
3419
- entry.node.event.kind !== "RUN"
3420
+ // and shadows every real step. OUTCOME is a linked result, not execution.
3421
+ isExecutionStepKind(entry.node.event.kind)
3420
3422
  ).sort((a, b) => {
3421
3423
  const delta = (b.node.event.durationMs ?? 0) - (a.node.event.durationMs ?? 0);
3422
3424
  return delta !== 0 ? delta : a.index - b.index;
@@ -3469,6 +3471,12 @@ function buildFacts(run, redactor, events) {
3469
3471
  const scoped = events.filter((event) => event.runId === run.runId);
3470
3472
  const { logicalEvents: logical } = projectLogicalEvents(scoped);
3471
3473
  const logicalSteps = logical.filter((event) => event.kind !== "RUN");
3474
+ const executionSteps = logical.filter((event) => isExecutionStepKind(event.kind));
3475
+ const executionByKind = {
3476
+ LLM: executionSteps.filter((event) => event.kind === "LLM").length,
3477
+ TOOL: executionSteps.filter((event) => event.kind === "TOOL").length,
3478
+ LOGIC: executionSteps.filter((event) => event.kind === "LOGIC").length
3479
+ };
3472
3480
  facts.push(
3473
3481
  fact("run.rawEventCount", "Raw persisted event count", scoped.length, redactor),
3474
3482
  fact(
@@ -3482,9 +3490,21 @@ function buildFacts(run, redactor, events) {
3482
3490
  "Logical lifecycle event count (including RUN)",
3483
3491
  logical.length,
3484
3492
  redactor
3493
+ ),
3494
+ fact(
3495
+ "run.executionStepCount",
3496
+ "Execution step count (excludes RUN and OUTCOME)",
3497
+ executionSteps.length,
3498
+ redactor
3499
+ ),
3500
+ fact(
3501
+ "run.executionStepKinds",
3502
+ "Execution step kind counts",
3503
+ executionByKind,
3504
+ redactor
3485
3505
  )
3486
3506
  );
3487
- const slowestLogical = [...logicalSteps].filter((event) => typeof event.durationMs === "number").sort((a, b) => {
3507
+ const slowestLogical = [...executionSteps].filter((event) => typeof event.durationMs === "number").sort((a, b) => {
3488
3508
  const delta = (b.durationMs ?? 0) - (a.durationMs ?? 0);
3489
3509
  return delta !== 0 ? delta : a.eventId.localeCompare(b.eventId);
3490
3510
  })[0];
@@ -11918,25 +11938,45 @@ function asStringArray(value, label) {
11918
11938
  function asPositiveNumber(value, label) {
11919
11939
  if (value === void 0) return void 0;
11920
11940
  if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
11921
- throw new Error(`${label} must be a non-negative number.`);
11941
+ throw new Error(`${label} must be a non-negative finite number.`);
11922
11942
  }
11923
11943
  return value;
11924
11944
  }
11925
- function asExpectConfig(value, label) {
11945
+ function asBoolean(value, label) {
11926
11946
  if (value === void 0) return void 0;
11947
+ if (typeof value !== "boolean") {
11948
+ throw new Error(`${label} must be a boolean (not a string or other type).`);
11949
+ }
11950
+ return value;
11951
+ }
11952
+ function assertObject(value, label) {
11927
11953
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
11928
11954
  throw new Error(`${label} must be an object.`);
11929
11955
  }
11930
- const raw = value;
11956
+ return value;
11957
+ }
11958
+ function assertKnownKeys(raw, allowed, label) {
11959
+ const allowedSet = new Set(allowed);
11960
+ for (const key of Object.keys(raw)) {
11961
+ if (!allowedSet.has(key)) {
11962
+ throw new Error(`${label} has unknown key "${key}".`);
11963
+ }
11964
+ }
11965
+ }
11966
+ function asExpectConfig(value, label) {
11967
+ if (value === void 0) return void 0;
11968
+ const raw = assertObject(value, label);
11969
+ assertKnownKeys(raw, EXPECT_KEYS, label);
11931
11970
  const checkStatus = raw.checkStatus;
11932
11971
  if (checkStatus !== "pass" && checkStatus !== "fail" && checkStatus !== "error") {
11933
11972
  throw new Error(`${label}.checkStatus must be "pass", "fail", or "error".`);
11934
11973
  }
11935
11974
  const findingRuleIds = asStringArray(raw.findingRuleIds, `${label}.findingRuleIds`);
11936
11975
  const minAssertions = asPositiveNumber(raw.minAssertions, `${label}.minAssertions`);
11937
- const rejectUnexpectedFindings = raw.rejectUnexpectedFindings === void 0 ? void 0 : typeof raw.rejectUnexpectedFindings === "boolean" ? raw.rejectUnexpectedFindings : (() => {
11938
- throw new Error(`${label}.rejectUnexpectedFindings must be a boolean.`);
11939
- })();
11976
+ const rejectUnexpectedFindings = asBoolean(
11977
+ raw.rejectUnexpectedFindings,
11978
+ `${label}.rejectUnexpectedFindings`
11979
+ );
11940
11980
  return {
11941
11981
  checkStatus,
11942
11982
  ...findingRuleIds !== void 0 ? { findingRuleIds } : {},
@@ -11944,6 +11984,56 @@ function asExpectConfig(value, label) {
11944
11984
  ...minAssertions !== void 0 ? { minAssertions } : {}
11945
11985
  };
11946
11986
  }
11987
+ function asChecksConfig(value, label) {
11988
+ const raw = assertObject(value, label);
11989
+ assertKnownKeys(raw, CHECKS_KEYS, label);
11990
+ const checks2 = {};
11991
+ const select = asStringArray(raw.select, `${label}.select`);
11992
+ if (select !== void 0) checks2.select = select;
11993
+ if (raw.run !== void 0) {
11994
+ const run = assertObject(raw.run, `${label}.run`);
11995
+ assertKnownKeys(run, CHECKS_RUN_KEYS, `${label}.run`);
11996
+ checks2.run = {
11997
+ ...asPositiveNumber(run.maxDurationMs, `${label}.run.maxDurationMs`) !== void 0 ? { maxDurationMs: asPositiveNumber(run.maxDurationMs, `${label}.run.maxDurationMs`) } : {},
11998
+ ...asPositiveNumber(run.maxDepth, `${label}.run.maxDepth`) !== void 0 ? { maxDepth: asPositiveNumber(run.maxDepth, `${label}.run.maxDepth`) } : {}
11999
+ };
12000
+ }
12001
+ if (raw.tool !== void 0) {
12002
+ const tool = assertObject(raw.tool, `${label}.tool`);
12003
+ assertKnownKeys(tool, CHECKS_TOOL_KEYS, `${label}.tool`);
12004
+ checks2.tool = {
12005
+ ...asStringArray(tool.required, `${label}.tool.required`) !== void 0 ? { required: asStringArray(tool.required, `${label}.tool.required`) } : {},
12006
+ ...asStringArray(tool.forbidden, `${label}.tool.forbidden`) !== void 0 ? { forbidden: asStringArray(tool.forbidden, `${label}.tool.forbidden`) } : {}
12007
+ };
12008
+ }
12009
+ if (raw.llm !== void 0) {
12010
+ const llm = assertObject(raw.llm, `${label}.llm`);
12011
+ assertKnownKeys(llm, CHECKS_LLM_KEYS, `${label}.llm`);
12012
+ checks2.llm = {
12013
+ ...asStringArray(llm.allowedModels, `${label}.llm.allowedModels`) !== void 0 ? { allowedModels: asStringArray(llm.allowedModels, `${label}.llm.allowedModels`) } : {},
12014
+ ...asPositiveNumber(llm.maxTotalTokens, `${label}.llm.maxTotalTokens`) !== void 0 ? {
12015
+ maxTotalTokens: asPositiveNumber(
12016
+ llm.maxTotalTokens,
12017
+ `${label}.llm.maxTotalTokens`
12018
+ )
12019
+ } : {}
12020
+ };
12021
+ }
12022
+ return checks2;
12023
+ }
12024
+ function asEvalConfig(value, label) {
12025
+ const raw = assertObject(value, label);
12026
+ assertKnownKeys(raw, EVAL_KEYS, label);
12027
+ return {
12028
+ ...asBoolean(raw.requireSuccess, `${label}.requireSuccess`) !== void 0 ? { requireSuccess: asBoolean(raw.requireSuccess, `${label}.requireSuccess`) } : {},
12029
+ ...asStringArray(raw.requiredTools, `${label}.requiredTools`) !== void 0 ? { requiredTools: asStringArray(raw.requiredTools, `${label}.requiredTools`) } : {},
12030
+ ...asStringArray(raw.forbiddenTools, `${label}.forbiddenTools`) !== void 0 ? { forbiddenTools: asStringArray(raw.forbiddenTools, `${label}.forbiddenTools`) } : {},
12031
+ ...asPositiveNumber(raw.maxDurationMs, `${label}.maxDurationMs`) !== void 0 ? { maxDurationMs: asPositiveNumber(raw.maxDurationMs, `${label}.maxDurationMs`) } : {},
12032
+ ...asPositiveNumber(raw.maxDepth, `${label}.maxDepth`) !== void 0 ? { maxDepth: asPositiveNumber(raw.maxDepth, `${label}.maxDepth`) } : {},
12033
+ ...asPositiveNumber(raw.maxRetries, `${label}.maxRetries`) !== void 0 ? { maxRetries: asPositiveNumber(raw.maxRetries, `${label}.maxRetries`) } : {},
12034
+ ...asPositiveNumber(raw.maxTotalTokens, `${label}.maxTotalTokens`) !== void 0 ? { maxTotalTokens: asPositiveNumber(raw.maxTotalTokens, `${label}.maxTotalTokens`) } : {}
12035
+ };
12036
+ }
11947
12037
  function validateCaseConfig(value, index) {
11948
12038
  const diagnostics = [];
11949
12039
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
@@ -11954,6 +12044,7 @@ function validateCaseConfig(value, index) {
11954
12044
  }
11955
12045
  const raw = value;
11956
12046
  try {
12047
+ assertKnownKeys(raw, CASE_KEYS, `cases[${index}]`);
11957
12048
  const id = asString(raw.id, `cases[${index}].id`);
11958
12049
  if (id === void 0) {
11959
12050
  diagnostics.push(
@@ -12002,6 +12093,7 @@ function normalizeSuiteConfig(value) {
12002
12093
  throw new Error("Suite config must export an object.");
12003
12094
  }
12004
12095
  const raw = value;
12096
+ assertKnownKeys(raw, ROOT_KEYS, "suite config");
12005
12097
  const name = asString(raw.name, "name");
12006
12098
  const traces = asString(raw.traces, "traces");
12007
12099
  if (name === void 0) throw new Error("name is required.");
@@ -12030,25 +12122,15 @@ function normalizeSuiteConfig(value) {
12030
12122
  }
12031
12123
  const config = { name, traces, cases };
12032
12124
  if (raw.checks !== void 0) {
12033
- if (typeof raw.checks !== "object" || Array.isArray(raw.checks)) {
12034
- throw new Error("checks must be an object.");
12035
- }
12036
- config.checks = raw.checks;
12125
+ config.checks = asChecksConfig(raw.checks, "checks");
12037
12126
  }
12038
12127
  if (raw.eval !== void 0) {
12039
- if (typeof raw.eval !== "object" || Array.isArray(raw.eval)) {
12040
- throw new Error("eval must be an object.");
12041
- }
12042
- config.eval = raw.eval;
12128
+ config.eval = asEvalConfig(raw.eval, "eval");
12043
12129
  }
12044
12130
  if (raw.artifacts !== void 0) {
12045
- if (typeof raw.artifacts !== "object" || Array.isArray(raw.artifacts)) {
12046
- throw new Error("artifacts must be an object.");
12047
- }
12048
- const outputDir = asString(
12049
- raw.artifacts.outputDir,
12050
- "artifacts.outputDir"
12051
- );
12131
+ const artifacts = assertObject(raw.artifacts, "artifacts");
12132
+ assertKnownKeys(artifacts, ["outputDir"], "artifacts");
12133
+ const outputDir = asString(artifacts.outputDir, "artifacts.outputDir");
12052
12134
  config.artifacts = outputDir !== void 0 ? { outputDir } : {};
12053
12135
  }
12054
12136
  if (raw.baseline !== void 0) {
@@ -12091,8 +12173,50 @@ async function validateSuiteConfig(config, options) {
12091
12173
  }
12092
12174
  return { ok: diagnostics.every((item) => item.severity !== "error"), diagnostics };
12093
12175
  }
12176
+ var CASE_KEYS, EXPECT_KEYS, CHECKS_KEYS, CHECKS_RUN_KEYS, CHECKS_TOOL_KEYS, CHECKS_LLM_KEYS, EVAL_KEYS, ROOT_KEYS;
12094
12177
  var init_validate2 = __esm({
12095
12178
  "packages/core/src/suite/validate.ts"() {
12179
+ CASE_KEYS = [
12180
+ "id",
12181
+ "trace",
12182
+ "runId",
12183
+ "input",
12184
+ "requireTools",
12185
+ "forbidTools",
12186
+ "maxDurationMs",
12187
+ "expectedObservations",
12188
+ "expect"
12189
+ ];
12190
+ EXPECT_KEYS = [
12191
+ "checkStatus",
12192
+ "findingRuleIds",
12193
+ "rejectUnexpectedFindings",
12194
+ "minAssertions"
12195
+ ];
12196
+ CHECKS_KEYS = ["select", "run", "tool", "llm"];
12197
+ CHECKS_RUN_KEYS = ["maxDurationMs", "maxDepth"];
12198
+ CHECKS_TOOL_KEYS = ["required", "forbidden"];
12199
+ CHECKS_LLM_KEYS = ["allowedModels", "maxTotalTokens"];
12200
+ EVAL_KEYS = [
12201
+ "requireSuccess",
12202
+ "requiredTools",
12203
+ "forbiddenTools",
12204
+ "maxDurationMs",
12205
+ "maxDepth",
12206
+ "maxRetries",
12207
+ "maxTotalTokens"
12208
+ ];
12209
+ ROOT_KEYS = [
12210
+ "name",
12211
+ "traces",
12212
+ "cases",
12213
+ "checks",
12214
+ "eval",
12215
+ "redactionProfile",
12216
+ "artifacts",
12217
+ "baseline",
12218
+ "candidate"
12219
+ ];
12096
12220
  }
12097
12221
  });
12098
12222
  function diagnostic4(code, message) {
@@ -12635,6 +12759,57 @@ function linkNodesVisibilityFirst(nodes) {
12635
12759
  }
12636
12760
  };
12637
12761
  }
12762
+ function resolveRunTiming(sorted, status) {
12763
+ let startedAtMs;
12764
+ let endedAtMs;
12765
+ let explicitDurationMs;
12766
+ for (const event of sorted) {
12767
+ if (event.kind !== "RUN") continue;
12768
+ const attrs = event.attributes ?? {};
12769
+ if (typeof attrs.startedAtMs === "number" && Number.isFinite(attrs.startedAtMs)) {
12770
+ startedAtMs = startedAtMs === void 0 ? attrs.startedAtMs : Math.min(startedAtMs, attrs.startedAtMs);
12771
+ }
12772
+ if (typeof attrs.endedAtMs === "number" && Number.isFinite(attrs.endedAtMs)) {
12773
+ endedAtMs = endedAtMs === void 0 ? attrs.endedAtMs : Math.max(endedAtMs, attrs.endedAtMs);
12774
+ }
12775
+ if ((event.status === "ok" || event.status === "error") && typeof event.durationMs === "number" && Number.isFinite(event.durationMs) && event.durationMs >= 0) {
12776
+ explicitDurationMs = event.durationMs;
12777
+ if (endedAtMs === void 0 && startedAtMs !== void 0) {
12778
+ endedAtMs = startedAtMs + event.durationMs;
12779
+ } else if (endedAtMs === void 0 && Number.isFinite(event.timestamp)) {
12780
+ endedAtMs = event.timestamp + event.durationMs;
12781
+ if (startedAtMs === void 0) {
12782
+ startedAtMs = event.timestamp;
12783
+ }
12784
+ }
12785
+ }
12786
+ if (startedAtMs === void 0 && event.status === "running" && Number.isFinite(event.timestamp)) {
12787
+ startedAtMs = event.timestamp;
12788
+ }
12789
+ }
12790
+ if (startedAtMs !== void 0 && endedAtMs !== void 0 && Number.isFinite(startedAtMs) && Number.isFinite(endedAtMs) && endedAtMs >= startedAtMs && status !== "running") {
12791
+ return {
12792
+ startedAt: startedAtMs,
12793
+ endedAt: endedAtMs,
12794
+ durationMs: endedAtMs - startedAtMs
12795
+ };
12796
+ }
12797
+ if (startedAtMs !== void 0 && explicitDurationMs !== void 0 && status !== "running") {
12798
+ return {
12799
+ startedAt: startedAtMs,
12800
+ endedAt: startedAtMs + explicitDurationMs,
12801
+ durationMs: explicitDurationMs
12802
+ };
12803
+ }
12804
+ const startedAt = sorted.length > 0 ? sorted[0].timestamp : void 0;
12805
+ const endedAt = sorted.length > 0 ? sorted[sorted.length - 1].timestamp : void 0;
12806
+ const durationMs2 = startedAt !== void 0 && endedAt !== void 0 && Number.isFinite(startedAt) && Number.isFinite(endedAt) && endedAt >= startedAt && status !== "running" ? endedAt - startedAt : void 0;
12807
+ return {
12808
+ startedAt,
12809
+ endedAt: status === "running" ? void 0 : endedAt,
12810
+ durationMs: durationMs2
12811
+ };
12812
+ }
12638
12813
  var TreeBuilder;
12639
12814
  var init_tree_builder = __esm({
12640
12815
  "packages/core/src/logs/tree-builder.ts"() {
@@ -12667,18 +12842,16 @@ var init_tree_builder = __esm({
12667
12842
  inc(confidenceBreakdown, e.confidence);
12668
12843
  kinds[e.kind] = (kinds[e.kind] ?? 0) + 1;
12669
12844
  }
12670
- const startedAt = sorted.length > 0 ? sorted[0].timestamp : void 0;
12671
- const endedAt = sorted.length > 0 ? sorted[sorted.length - 1].timestamp : void 0;
12672
- const status = computeRunStatus(sorted);
12673
- const durationMs2 = startedAt !== void 0 && endedAt !== void 0 && Number.isFinite(startedAt) && Number.isFinite(endedAt) && endedAt >= startedAt && status !== "running" ? endedAt - startedAt : void 0;
12674
12845
  const name = sorted.find((e) => e.kind === "RUN")?.name;
12846
+ const status = computeRunStatus(sorted);
12847
+ const timing = resolveRunTiming(sorted, status);
12675
12848
  out.push({
12676
12849
  runId,
12677
12850
  name,
12678
12851
  status,
12679
- startedAt,
12680
- endedAt: status === "running" ? void 0 : endedAt,
12681
- durationMs: durationMs2,
12852
+ startedAt: timing.startedAt,
12853
+ endedAt: timing.endedAt,
12854
+ durationMs: timing.durationMs,
12682
12855
  children: roots,
12683
12856
  metadata: {
12684
12857
  totalEvents: sorted.length,
@@ -16656,7 +16829,7 @@ var init_src = __esm({
16656
16829
  });
16657
16830
 
16658
16831
  // package.json
16659
- var version = "6.31.11";
16832
+ var version = "6.31.13";
16660
16833
 
16661
16834
  // packages/cli/src/list.ts
16662
16835
  init_advanced();
@@ -19450,7 +19623,14 @@ function exportOtlpJson(tree, options) {
19450
19623
 
19451
19624
  // packages/core/src/exporters/validation.ts
19452
19625
  var EXPERIMENTAL = "Experimental compatibility export \u2014 verify against your target tooling before relying on it.";
19626
+ var UINT64_MAX = 18446744073709551615n;
19627
+ var INT64_MIN = -9223372036854775808n;
19628
+ var INT64_MAX = 9223372036854775807n;
19629
+ var MAX_ANYVALUE_DEPTH = 8;
19630
+ var MAX_ANYVALUE_ELEMENTS = 256;
19631
+ var MAX_DIAGNOSTIC_ERRORS = 64;
19453
19632
  function pushPath(errors, path44, message) {
19633
+ if (errors.length >= MAX_DIAGNOSTIC_ERRORS) return;
19454
19634
  errors.push(`${path44}: ${message}`);
19455
19635
  }
19456
19636
  function isRecord16(value) {
@@ -19459,7 +19639,59 @@ function isRecord16(value) {
19459
19639
  function isHexId(value, byteLen) {
19460
19640
  return typeof value === "string" && new RegExp(`^[0-9a-fA-F]{${byteLen * 2}}$`).test(value);
19461
19641
  }
19462
- function validateAnyValue(errors, path44, value) {
19642
+ function parseDecimalIntegerString(value) {
19643
+ if (typeof value !== "string" || !/^-?\d+$/.test(value)) {
19644
+ return { ok: false, reason: "must be a decimal integer string" };
19645
+ }
19646
+ try {
19647
+ return { ok: true, n: BigInt(value) };
19648
+ } catch {
19649
+ return { ok: false, reason: "out of integer range" };
19650
+ }
19651
+ }
19652
+ function validateUint64String(errors, path44, value, label) {
19653
+ const parsed = parseDecimalIntegerString(value);
19654
+ if (!parsed.ok) {
19655
+ pushPath(errors, path44, `${label} ${parsed.reason}`);
19656
+ return;
19657
+ }
19658
+ if (parsed.n < 0n || parsed.n > UINT64_MAX) {
19659
+ pushPath(
19660
+ errors,
19661
+ path44,
19662
+ `${label} must be an unsigned 64-bit integer (0..${UINT64_MAX.toString()})`
19663
+ );
19664
+ }
19665
+ }
19666
+ function validateInt64String(errors, path44, value) {
19667
+ const parsed = parseDecimalIntegerString(value);
19668
+ if (!parsed.ok) {
19669
+ pushPath(errors, path44, parsed.reason);
19670
+ return;
19671
+ }
19672
+ if (parsed.n < INT64_MIN || parsed.n > INT64_MAX) {
19673
+ pushPath(
19674
+ errors,
19675
+ path44,
19676
+ `must be a signed 64-bit integer (${INT64_MIN.toString()}..${INT64_MAX.toString()})`
19677
+ );
19678
+ }
19679
+ }
19680
+ function validateAnyValue(errors, path44, value, depth = 0, counters = { elements: 0 }) {
19681
+ if (errors.length >= MAX_DIAGNOSTIC_ERRORS) return;
19682
+ if (depth > MAX_ANYVALUE_DEPTH) {
19683
+ pushPath(errors, path44, `AnyValue nesting exceeds depth ${MAX_ANYVALUE_DEPTH}`);
19684
+ return;
19685
+ }
19686
+ counters.elements += 1;
19687
+ if (counters.elements > MAX_ANYVALUE_ELEMENTS) {
19688
+ pushPath(
19689
+ errors,
19690
+ path44,
19691
+ `AnyValue element count exceeds ${MAX_ANYVALUE_ELEMENTS}`
19692
+ );
19693
+ return;
19694
+ }
19463
19695
  if (!isRecord16(value)) {
19464
19696
  pushPath(errors, path44, "must be an AnyValue object");
19465
19697
  return;
@@ -19479,13 +19711,99 @@ function validateAnyValue(errors, path44, value) {
19479
19711
  path44,
19480
19712
  `AnyValue must set exactly one variant (found ${variants.length}: ${variants.join(",")})`
19481
19713
  );
19714
+ return;
19482
19715
  }
19483
- if (value.intValue !== void 0) {
19484
- if (typeof value.intValue !== "string" || !/^-?\d+$/.test(value.intValue)) {
19485
- pushPath(errors, `${path44}.intValue`, "must be a decimal integer string");
19716
+ const arm = variants[0];
19717
+ switch (arm) {
19718
+ case "stringValue":
19719
+ if (typeof value.stringValue !== "string") {
19720
+ pushPath(errors, `${path44}.stringValue`, "must be a string");
19721
+ }
19722
+ break;
19723
+ case "boolValue":
19724
+ if (typeof value.boolValue !== "boolean") {
19725
+ pushPath(errors, `${path44}.boolValue`, "must be a boolean");
19726
+ }
19727
+ break;
19728
+ case "intValue":
19729
+ validateInt64String(errors, `${path44}.intValue`, value.intValue);
19730
+ break;
19731
+ case "doubleValue":
19732
+ if (typeof value.doubleValue !== "number" || !Number.isFinite(value.doubleValue)) {
19733
+ pushPath(errors, `${path44}.doubleValue`, "must be a finite number");
19734
+ }
19735
+ break;
19736
+ case "bytesValue":
19737
+ if (typeof value.bytesValue !== "string") {
19738
+ pushPath(errors, `${path44}.bytesValue`, "must be a base64 string");
19739
+ }
19740
+ break;
19741
+ case "arrayValue": {
19742
+ if (!isRecord16(value.arrayValue)) {
19743
+ pushPath(errors, `${path44}.arrayValue`, "must be an object");
19744
+ break;
19745
+ }
19746
+ const values = value.arrayValue.values;
19747
+ if (values === void 0) break;
19748
+ if (!Array.isArray(values)) {
19749
+ pushPath(errors, `${path44}.arrayValue.values`, "must be an array");
19750
+ break;
19751
+ }
19752
+ values.forEach((item, i) => {
19753
+ validateAnyValue(
19754
+ errors,
19755
+ `${path44}.arrayValue.values[${i}]`,
19756
+ item,
19757
+ depth + 1,
19758
+ counters
19759
+ );
19760
+ });
19761
+ break;
19762
+ }
19763
+ case "kvlistValue": {
19764
+ if (!isRecord16(value.kvlistValue)) {
19765
+ pushPath(errors, `${path44}.kvlistValue`, "must be an object");
19766
+ break;
19767
+ }
19768
+ const values = value.kvlistValue.values;
19769
+ if (values === void 0) break;
19770
+ if (!Array.isArray(values)) {
19771
+ pushPath(errors, `${path44}.kvlistValue.values`, "must be an array");
19772
+ break;
19773
+ }
19774
+ values.forEach((item, i) => {
19775
+ const itemPath = `${path44}.kvlistValue.values[${i}]`;
19776
+ if (!isRecord16(item)) {
19777
+ pushPath(errors, itemPath, "must be a KeyValue object");
19778
+ return;
19779
+ }
19780
+ if (typeof item.key !== "string") {
19781
+ pushPath(errors, `${itemPath}.key`, "must be a string");
19782
+ }
19783
+ validateAnyValue(errors, `${itemPath}.value`, item.value, depth + 1, counters);
19784
+ });
19785
+ break;
19486
19786
  }
19487
19787
  }
19488
19788
  }
19789
+ function validateKeyValueList(errors, path44, attrs) {
19790
+ if (attrs === void 0) return;
19791
+ if (!Array.isArray(attrs)) {
19792
+ pushPath(errors, path44, "must be an array");
19793
+ return;
19794
+ }
19795
+ attrs.forEach((attr, ai) => {
19796
+ const attrPath = `${path44}[${ai}]`;
19797
+ if (!isRecord16(attr)) {
19798
+ pushPath(errors, attrPath, "must be an object");
19799
+ return;
19800
+ }
19801
+ if (typeof attr.key !== "string") {
19802
+ pushPath(errors, `${attrPath}.key`, "must be a string");
19803
+ }
19804
+ validateAnyValue(errors, `${attrPath}.value`, attr.value);
19805
+ });
19806
+ }
19489
19807
  function validateOtlpJson(content) {
19490
19808
  const errors = [];
19491
19809
  const warnings = [
@@ -19514,6 +19832,13 @@ function validateOtlpJson(content) {
19514
19832
  pushPath(errors, rsPath, "must be an object");
19515
19833
  return;
19516
19834
  }
19835
+ if (isRecord16(resourceSpan.resource)) {
19836
+ validateKeyValueList(
19837
+ errors,
19838
+ `${rsPath}.resource.attributes`,
19839
+ resourceSpan.resource.attributes
19840
+ );
19841
+ }
19517
19842
  if (!Array.isArray(resourceSpan.scopeSpans)) {
19518
19843
  pushPath(errors, `${rsPath}.scopeSpans`, "must be an array");
19519
19844
  return;
@@ -19524,6 +19849,13 @@ function validateOtlpJson(content) {
19524
19849
  pushPath(errors, ssPath, "must be an object");
19525
19850
  return;
19526
19851
  }
19852
+ if (isRecord16(scopeSpan.scope)) {
19853
+ validateKeyValueList(
19854
+ errors,
19855
+ `${ssPath}.scope.attributes`,
19856
+ scopeSpan.scope.attributes
19857
+ );
19858
+ }
19527
19859
  if (!Array.isArray(scopeSpan.spans)) {
19528
19860
  pushPath(errors, `${ssPath}.spans`, "must be an array");
19529
19861
  return;
@@ -19558,44 +19890,58 @@ function validateOtlpJson(content) {
19558
19890
  if (typeof span.name !== "string") {
19559
19891
  pushPath(errors, `${spanPath}.name`, "must be a string");
19560
19892
  }
19561
- if (typeof span.startTimeUnixNano !== "string" || !/^\d+$/.test(span.startTimeUnixNano)) {
19562
- pushPath(
19563
- errors,
19564
- `${spanPath}.startTimeUnixNano`,
19565
- "must be a decimal-string 64-bit integer"
19566
- );
19567
- }
19568
- if (span.endTimeUnixNano !== void 0 && (typeof span.endTimeUnixNano !== "string" || !/^\d+$/.test(span.endTimeUnixNano))) {
19569
- pushPath(
19893
+ validateUint64String(
19894
+ errors,
19895
+ `${spanPath}.startTimeUnixNano`,
19896
+ span.startTimeUnixNano,
19897
+ "startTimeUnixNano"
19898
+ );
19899
+ if (span.endTimeUnixNano !== void 0) {
19900
+ validateUint64String(
19570
19901
  errors,
19571
19902
  `${spanPath}.endTimeUnixNano`,
19572
- "must be a decimal-string 64-bit integer when present"
19903
+ span.endTimeUnixNano,
19904
+ "endTimeUnixNano"
19573
19905
  );
19574
19906
  }
19575
- if (typeof span.startTimeUnixNano === "string" && /^\d+$/.test(span.startTimeUnixNano) && typeof span.endTimeUnixNano === "string" && /^\d+$/.test(span.endTimeUnixNano)) {
19576
- try {
19577
- if (BigInt(span.endTimeUnixNano) < BigInt(span.startTimeUnixNano)) {
19578
- pushPath(
19907
+ if (typeof span.startTimeUnixNano === "string" && typeof span.endTimeUnixNano === "string") {
19908
+ const start = parseDecimalIntegerString(span.startTimeUnixNano);
19909
+ const end = parseDecimalIntegerString(span.endTimeUnixNano);
19910
+ if (start.ok && end.ok && end.n < start.n) {
19911
+ pushPath(
19912
+ errors,
19913
+ `${spanPath}.endTimeUnixNano`,
19914
+ "must be >= startTimeUnixNano"
19915
+ );
19916
+ }
19917
+ }
19918
+ validateKeyValueList(errors, `${spanPath}.attributes`, span.attributes);
19919
+ if (Array.isArray(span.events)) {
19920
+ span.events.forEach((event, ei) => {
19921
+ const eventPath = `${spanPath}.events[${ei}]`;
19922
+ if (!isRecord16(event)) {
19923
+ pushPath(errors, eventPath, "must be an object");
19924
+ return;
19925
+ }
19926
+ if (event.timeUnixNano !== void 0) {
19927
+ validateUint64String(
19579
19928
  errors,
19580
- `${spanPath}.endTimeUnixNano`,
19581
- "must be >= startTimeUnixNano"
19929
+ `${eventPath}.timeUnixNano`,
19930
+ event.timeUnixNano,
19931
+ "timeUnixNano"
19582
19932
  );
19583
19933
  }
19584
- } catch {
19585
- pushPath(errors, `${spanPath}.endTimeUnixNano`, "out of integer range");
19586
- }
19934
+ validateKeyValueList(errors, `${eventPath}.attributes`, event.attributes);
19935
+ });
19587
19936
  }
19588
- if (Array.isArray(span.attributes)) {
19589
- span.attributes.forEach((attr, ai) => {
19590
- const attrPath = `${spanPath}.attributes[${ai}]`;
19591
- if (!isRecord16(attr)) {
19592
- pushPath(errors, attrPath, "must be an object");
19937
+ if (Array.isArray(span.links)) {
19938
+ span.links.forEach((link, li) => {
19939
+ const linkPath = `${spanPath}.links[${li}]`;
19940
+ if (!isRecord16(link)) {
19941
+ pushPath(errors, linkPath, "must be an object");
19593
19942
  return;
19594
19943
  }
19595
- if (typeof attr.key !== "string") {
19596
- pushPath(errors, `${attrPath}.key`, "must be a string");
19597
- }
19598
- validateAnyValue(errors, `${attrPath}.value`, attr.value);
19944
+ validateKeyValueList(errors, `${linkPath}.attributes`, link.attributes);
19599
19945
  });
19600
19946
  }
19601
19947
  if (typeof span.kind === "number") {
@@ -24209,7 +24555,7 @@ function asStringArray2(value) {
24209
24555
  }
24210
24556
  return value;
24211
24557
  }
24212
- var CHECKS_KEYS = /* @__PURE__ */ new Set(["select", "run", "tool", "llm", "structure", "safety"]);
24558
+ var CHECKS_KEYS2 = /* @__PURE__ */ new Set(["select", "run", "tool", "llm", "structure", "safety"]);
24213
24559
  var ROOT_CONFIG_KEYS = /* @__PURE__ */ new Set(["checks", "contract"]);
24214
24560
  var CONTRACT_KEYS = /* @__PURE__ */ new Set([
24215
24561
  "run",
@@ -25270,7 +25616,7 @@ function parseCheckConfig(value) {
25270
25616
  const out = {};
25271
25617
  if ("checks" in root) {
25272
25618
  const checksRecord = requireObject(root.checks, "checks");
25273
- rejectUnknownKeys(checksRecord, CHECKS_KEYS, "checks");
25619
+ rejectUnknownKeys(checksRecord, CHECKS_KEYS2, "checks");
25274
25620
  const checks2 = {};
25275
25621
  if (checksRecord.select !== void 0) {
25276
25622
  checks2.select = requireStringArray(checksRecord.select, "checks.select");