agent-inspect 6.31.21 → 6.31.22

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 (47) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +1 -1
  3. package/package.json +1 -1
  4. package/packages/cli/dist/{chunk-N5JN26MW.mjs → chunk-EMWA5EKU.mjs} +300 -31
  5. package/packages/cli/dist/chunk-EMWA5EKU.mjs.map +1 -0
  6. package/packages/cli/dist/index.cjs +379 -56
  7. package/packages/cli/dist/index.cjs.map +1 -1
  8. package/packages/cli/dist/index.mjs +75 -31
  9. package/packages/cli/dist/index.mjs.map +1 -1
  10. package/packages/cli/dist/{src-VMGRSTG7.mjs → src-VZHGOLTO.mjs} +3 -3
  11. package/packages/cli/dist/{src-VMGRSTG7.mjs.map → src-VZHGOLTO.mjs.map} +1 -1
  12. package/packages/core/dist/advanced.cjs +247 -5
  13. package/packages/core/dist/advanced.cjs.map +1 -1
  14. package/packages/core/dist/advanced.mjs +6 -5
  15. package/packages/core/dist/advanced.mjs.map +1 -1
  16. package/packages/core/dist/checks.cjs +160 -27
  17. package/packages/core/dist/checks.cjs.map +1 -1
  18. package/packages/core/dist/checks.mjs +2 -1
  19. package/packages/core/dist/chunk-GCZUWY47.mjs +182 -0
  20. package/packages/core/dist/chunk-GCZUWY47.mjs.map +1 -0
  21. package/packages/core/dist/{chunk-JE3TUFAQ.mjs → chunk-RBXD7BNX.mjs} +3 -3
  22. package/packages/core/dist/{chunk-JE3TUFAQ.mjs.map → chunk-RBXD7BNX.mjs.map} +1 -1
  23. package/packages/core/dist/{chunk-YU6XT5A2.mjs → chunk-S4NU55LU.mjs} +45 -3
  24. package/packages/core/dist/chunk-S4NU55LU.mjs.map +1 -0
  25. package/packages/core/dist/{chunk-EIP5CNEL.mjs → chunk-UPGBMRL4.mjs} +49 -3
  26. package/packages/core/dist/chunk-UPGBMRL4.mjs.map +1 -0
  27. package/packages/core/dist/{chunk-4CDX5GDS.mjs → chunk-ZOF6ON65.mjs} +104 -99
  28. package/packages/core/dist/chunk-ZOF6ON65.mjs.map +1 -0
  29. package/packages/core/dist/exporters.cjs +82 -27
  30. package/packages/core/dist/exporters.cjs.map +1 -1
  31. package/packages/core/dist/exporters.mjs +72 -27
  32. package/packages/core/dist/exporters.mjs.map +1 -1
  33. package/packages/core/dist/logs.cjs +197 -1
  34. package/packages/core/dist/logs.cjs.map +1 -1
  35. package/packages/core/dist/logs.mjs +3 -2
  36. package/packages/core/dist/logs.mjs.map +1 -1
  37. package/packages/core/dist/persisted.cjs +197 -1
  38. package/packages/core/dist/persisted.cjs.map +1 -1
  39. package/packages/core/dist/persisted.mjs +4 -3
  40. package/packages/core/dist/persisted.mjs.map +1 -1
  41. package/packages/core/dist/readers.cjs +243 -1
  42. package/packages/core/dist/readers.cjs.map +1 -1
  43. package/packages/core/dist/readers.mjs +4 -3
  44. package/packages/cli/dist/chunk-N5JN26MW.mjs.map +0 -1
  45. package/packages/core/dist/chunk-4CDX5GDS.mjs.map +0 -1
  46. package/packages/core/dist/chunk-EIP5CNEL.mjs.map +0 -1
  47. package/packages/core/dist/chunk-YU6XT5A2.mjs.map +0 -1
@@ -1704,6 +1704,65 @@ function evaluateToolArgumentValue(value, check, evidencePresent) {
1704
1704
  };
1705
1705
  }
1706
1706
 
1707
+ // packages/core/src/persisted/delivery-identity.ts
1708
+ var DELIVERY_CONFLICT_ATTR = "agent_inspect.delivery_conflict";
1709
+ var SYNTHETIC_DELIVERY_ID = /^(?:manual|inspect):[A-Za-z0-9_-]+:[A-Za-z0-9_-]+:[A-Za-z0-9_-]+:\d+$/;
1710
+ function stripReaderDeliveryDiscriminator(eventId) {
1711
+ if (!SYNTHETIC_DELIVERY_ID.test(eventId)) return eventId;
1712
+ return eventId.replace(/:\d+$/, "");
1713
+ }
1714
+ function canonicalDigest(value) {
1715
+ if (value === void 0) return null;
1716
+ const encoded = encodeCanonicalStructured(value);
1717
+ return encoded.ok ? encoded.value : `unencodable:${encoded.code}`;
1718
+ }
1719
+ function capturedContentDigest(attributes) {
1720
+ if (!attributes || typeof attributes !== "object") {
1721
+ return { args: null, result: null };
1722
+ }
1723
+ const nested = attributes.metadata && typeof attributes.metadata === "object" ? attributes.metadata : void 0;
1724
+ const args = attributes.arguments ?? attributes.args ?? attributes.input ?? nested?.arguments ?? nested?.args ?? nested?.input;
1725
+ const result = attributes.result ?? attributes.output ?? attributes.response ?? nested?.result ?? nested?.output ?? nested?.response;
1726
+ return {
1727
+ args: args === void 0 ? null : canonicalDigest(args),
1728
+ result: result === void 0 ? null : canonicalDigest(result)
1729
+ };
1730
+ }
1731
+ function timeKey(fields) {
1732
+ if (typeof fields.startedAt === "string" && fields.startedAt.trim() !== "") {
1733
+ return fields.startedAt;
1734
+ }
1735
+ if (typeof fields.timestamp === "string" && fields.timestamp.trim() !== "") {
1736
+ return fields.timestamp;
1737
+ }
1738
+ if (typeof fields.timestamp === "number" && Number.isFinite(fields.timestamp)) {
1739
+ return String(fields.timestamp);
1740
+ }
1741
+ return null;
1742
+ }
1743
+ function deliverySemanticFingerprint(fields) {
1744
+ const content = capturedContentDigest(fields.attributes);
1745
+ return JSON.stringify({
1746
+ stableEventId: stripReaderDeliveryDiscriminator(fields.eventId),
1747
+ runId: fields.runId,
1748
+ kind: fields.kind,
1749
+ name: fields.name,
1750
+ status: fields.status ?? null,
1751
+ parentId: fields.parentId ?? null,
1752
+ sourceType: fields.sourceType ?? null,
1753
+ time: timeKey(fields),
1754
+ operationId: fields.operationId ?? null,
1755
+ attemptId: fields.attemptId ?? null,
1756
+ attemptNumber: fields.attemptNumber ?? null,
1757
+ retryOf: fields.retryOf ?? null,
1758
+ argsDigest: content.args,
1759
+ resultDigest: content.result
1760
+ });
1761
+ }
1762
+ function hasDeliveryConflictMarker(attributes) {
1763
+ return attributes?.[DELIVERY_CONFLICT_ATTR] === true;
1764
+ }
1765
+
1707
1766
  // packages/core/src/checks/retry-safety.ts
1708
1767
  function fail2(ruleId, message, evidence, expected, actual) {
1709
1768
  return {
@@ -1759,7 +1818,7 @@ function attemptIdOf(event) {
1759
1818
  }
1760
1819
  function countOperationAttempts(members) {
1761
1820
  const identified = /* @__PURE__ */ new Set();
1762
- let unidentified = 0;
1821
+ const unidentifiedFingerprints = /* @__PURE__ */ new Set();
1763
1822
  for (const event of members) {
1764
1823
  if (event.kind !== "TOOL" && event.kind !== "LLM") continue;
1765
1824
  const id = attemptIdOf(event);
@@ -1767,13 +1826,13 @@ function countOperationAttempts(members) {
1767
1826
  identified.add(id);
1768
1827
  continue;
1769
1828
  }
1770
- unidentified += 1;
1829
+ unidentifiedFingerprints.add(redeliveryFingerprint(event));
1771
1830
  }
1772
1831
  if (identified.size > 0) {
1773
- return identified.size + unidentified;
1832
+ return identified.size + unidentifiedFingerprints.size;
1774
1833
  }
1775
1834
  const numbered = /* @__PURE__ */ new Set();
1776
- let unnumbered = 0;
1835
+ const unnumberedFingerprints = /* @__PURE__ */ new Set();
1777
1836
  for (const event of members) {
1778
1837
  if (event.kind !== "TOOL" && event.kind !== "LLM") continue;
1779
1838
  const num = attemptNumberOf(event);
@@ -1781,12 +1840,12 @@ function countOperationAttempts(members) {
1781
1840
  numbered.add(num);
1782
1841
  continue;
1783
1842
  }
1784
- unnumbered += 1;
1843
+ unnumberedFingerprints.add(redeliveryFingerprint(event));
1785
1844
  }
1786
1845
  if (numbered.size > 0) {
1787
- return numbered.size + unnumbered;
1846
+ return numbered.size + unnumberedFingerprints.size;
1788
1847
  }
1789
- return unnumbered;
1848
+ return unnumberedFingerprints.size;
1790
1849
  }
1791
1850
  function classifyRetryAttempt(event, priorOrdered, allMembers) {
1792
1851
  const workflow = workflowFor(event);
@@ -1838,19 +1897,49 @@ function classifyRetryAttempt(event, priorOrdered, allMembers) {
1838
1897
  }
1839
1898
  function redeliveryFingerprint(event) {
1840
1899
  const workflow = workflowFor(event);
1841
- const stableEventId = (event.eventId ?? "").replace(/:\d+$/, "");
1842
- return JSON.stringify({
1843
- stableEventId,
1900
+ return deliverySemanticFingerprint({
1901
+ eventId: event.eventId ?? "",
1844
1902
  runId: event.runId,
1845
1903
  kind: event.kind,
1846
1904
  name: event.name,
1847
1905
  status: event.status,
1906
+ parentId: event.parentId,
1907
+ timestamp: event.timestamp,
1908
+ startedAt: event.startedAt,
1909
+ sourceType: event.source?.type,
1910
+ attributes: event.attributes && typeof event.attributes === "object" ? event.attributes : void 0,
1848
1911
  operationId: workflow.operationId ?? null,
1849
1912
  attemptId: workflow.attemptId ?? null,
1850
1913
  attemptNumber: workflow.attemptNumber ?? null,
1851
1914
  retryOf: workflow.retryOf ?? null
1852
1915
  });
1853
1916
  }
1917
+ var IDENTITY_KEYS = ["operationId", "attemptId", "retryOf", "attemptNumber"];
1918
+ function identityValuesEqual(a, b) {
1919
+ if (typeof a === "number" && typeof b === "number") {
1920
+ return Number.isFinite(a) && Number.isFinite(b) && a === b;
1921
+ }
1922
+ if (typeof a === "string" && typeof b === "string") {
1923
+ return a.trim() === b.trim();
1924
+ }
1925
+ return a === b;
1926
+ }
1927
+ function directNestedIdentityConflicts(event) {
1928
+ const attrs2 = event.attributes;
1929
+ if (!attrs2 || typeof attrs2 !== "object") return [];
1930
+ const nested = attrs2.metadata && typeof attrs2.metadata === "object" && !Array.isArray(attrs2.metadata) ? attrs2.metadata : void 0;
1931
+ if (!nested) return [];
1932
+ const conflicts = [];
1933
+ for (const key of IDENTITY_KEYS) {
1934
+ const direct = attrs2[key];
1935
+ const nestedValue = nested[key];
1936
+ if (direct === void 0 || nestedValue === void 0) continue;
1937
+ if (!identityValuesEqual(direct, nestedValue)) {
1938
+ conflicts.push(key);
1939
+ }
1940
+ }
1941
+ return conflicts;
1942
+ }
1854
1943
  function hasConflictingAttemptIdReuse(members) {
1855
1944
  const byAttempt = /* @__PURE__ */ new Map();
1856
1945
  for (const event of members) {
@@ -1866,6 +1955,31 @@ function hasConflictingAttemptIdReuse(members) {
1866
1955
  }
1867
1956
  return false;
1868
1957
  }
1958
+ function hasConflictingEventIdReuse(members) {
1959
+ const byEventId = /* @__PURE__ */ new Map();
1960
+ for (const event of members) {
1961
+ if (event.kind !== "TOOL" && event.kind !== "LLM") continue;
1962
+ const eventId = event.eventId;
1963
+ if (!eventId) continue;
1964
+ if (hasDeliveryConflictMarker(event.attributes)) {
1965
+ return true;
1966
+ }
1967
+ const fingerprints = byEventId.get(eventId) ?? /* @__PURE__ */ new Set();
1968
+ fingerprints.add(redeliveryFingerprint(event));
1969
+ byEventId.set(eventId, fingerprints);
1970
+ }
1971
+ for (const fingerprints of byEventId.values()) {
1972
+ if (fingerprints.size > 1) return true;
1973
+ }
1974
+ return false;
1975
+ }
1976
+ function hasIdentityRepresentationConflict(members) {
1977
+ for (const event of members) {
1978
+ if (event.kind !== "TOOL" && event.kind !== "LLM") continue;
1979
+ if (directNestedIdentityConflicts(event).length > 0) return true;
1980
+ }
1981
+ return false;
1982
+ }
1869
1983
  function evaluateRetrySafetyRules(events, rules, _runEvidence) {
1870
1984
  const findings = [];
1871
1985
  const byOperation = /* @__PURE__ */ new Map();
@@ -1873,13 +1987,14 @@ function evaluateRetrySafetyRules(events, rules, _runEvidence) {
1873
1987
  const workflow = workflowFor(event);
1874
1988
  const operationId = workflow.operationId;
1875
1989
  if (!operationId) continue;
1876
- const list = byOperation.get(operationId) ?? [];
1877
- list.push(event);
1878
- byOperation.set(operationId, list);
1990
+ const key = `${event.runId}\0${operationId}`;
1991
+ const group = byOperation.get(key) ?? { operationId, members: [] };
1992
+ group.members.push(event);
1993
+ byOperation.set(key, group);
1879
1994
  }
1880
1995
  if (rules.maxAttempts !== void 0) {
1881
- for (const [operationId, members] of byOperation) {
1882
- if (hasConflictingAttemptIdReuse(members)) {
1996
+ for (const { operationId, members } of byOperation.values()) {
1997
+ if (hasConflictingAttemptIdReuse(members) || hasConflictingEventIdReuse(members)) {
1883
1998
  findings.push(
1884
1999
  fail2(
1885
2000
  "contract.retry.duplicate-attempt-id",
@@ -1890,6 +2005,31 @@ function evaluateRetrySafetyRules(events, rules, _runEvidence) {
1890
2005
  )
1891
2006
  );
1892
2007
  }
2008
+ if (hasIdentityRepresentationConflict(members)) {
2009
+ findings.push(
2010
+ fail2(
2011
+ "contract.retry.ambiguous-identity",
2012
+ `Operation ${operationId} has conflicting direct vs nested identity fields; strict identity cannot pass.`,
2013
+ members.slice(0, 4).map(eventEvidence),
2014
+ "agreeing identity representation",
2015
+ "direct/nested conflict"
2016
+ )
2017
+ );
2018
+ }
2019
+ const toolish = members.filter((event) => event.kind === "TOOL" || event.kind === "LLM");
2020
+ const hasAttemptId = toolish.some((event) => attemptIdOf(event) !== void 0);
2021
+ const missingAttemptId = toolish.some((event) => attemptIdOf(event) === void 0);
2022
+ if (hasAttemptId && missingAttemptId) {
2023
+ findings.push(
2024
+ fail2(
2025
+ "contract.retry.ambiguous-identity",
2026
+ `Operation ${operationId} has partial attempt identity; strict identity conformance cannot pass.`,
2027
+ members.slice(0, 4).map(eventEvidence),
2028
+ "complete attempt identity",
2029
+ "partial attemptId coverage"
2030
+ )
2031
+ );
2032
+ }
1893
2033
  const count = countOperationAttempts(members);
1894
2034
  if (count > rules.maxAttempts) {
1895
2035
  findings.push(
@@ -1905,7 +2045,7 @@ function evaluateRetrySafetyRules(events, rules, _runEvidence) {
1905
2045
  }
1906
2046
  }
1907
2047
  if (rules.requireTerminalResult) {
1908
- for (const [operationId, members] of byOperation) {
2048
+ for (const { operationId, members } of byOperation.values()) {
1909
2049
  const hasTerminal = members.some((event) => event.status === "ok" || event.status === "error");
1910
2050
  if (!hasTerminal) {
1911
2051
  findings.push(
@@ -1925,7 +2065,7 @@ function evaluateRetrySafetyRules(events, rules, _runEvidence) {
1925
2065
  const workflow = workflowFor(event);
1926
2066
  const fallbackOf = workflow.fallbackOf;
1927
2067
  if (!fallbackOf) continue;
1928
- const prior = byOperation.get(fallbackOf) ?? [];
2068
+ const prior = byOperation.get(`${event.runId}\0${fallbackOf}`)?.members ?? [];
1929
2069
  const fallbackStart = eventTime(event);
1930
2070
  const earlierFailure = prior.some(
1931
2071
  (candidate) => candidate.status === "error" && eventTime(candidate) !== "" && fallbackStart !== "" && eventTime(candidate) < fallbackStart
@@ -1952,7 +2092,7 @@ function evaluateRetrySafetyRules(events, rules, _runEvidence) {
1952
2092
  for (const event of toolEvents) {
1953
2093
  const name = resolveCanonicalToolName(event);
1954
2094
  const workflow = workflowFor(event);
1955
- const key = `${workflow.operationId ?? name}::${name}`;
2095
+ const key = `${event.runId}::${workflow.operationId ?? name}::${name}`;
1956
2096
  const list = byToolOp.get(key) ?? [];
1957
2097
  list.push(event);
1958
2098
  byToolOp.set(key, list);
@@ -2010,7 +2150,7 @@ function evaluateRetrySafetyRules(events, rules, _runEvidence) {
2010
2150
  }
2011
2151
  }
2012
2152
  if (rules.requireRecoveredFailureVisible) {
2013
- for (const [operationId, members] of byOperation) {
2153
+ for (const { operationId, members } of byOperation.values()) {
2014
2154
  const ordered = sortByTime(members);
2015
2155
  const toolish = ordered.filter(
2016
2156
  (event) => (event.kind === "TOOL" || event.kind === "LLM") && (event.status === "ok" || event.status === "error")
@@ -2269,14 +2409,7 @@ function attemptIdOf2(event) {
2269
2409
  return typeof value === "string" && value.trim() !== "" ? value.trim() : void 0;
2270
2410
  }
2271
2411
  function hasDuplicateAttemptIds(members) {
2272
- const seen = /* @__PURE__ */ new Set();
2273
- for (const event of members) {
2274
- const id = attemptIdOf2(event);
2275
- if (!id) continue;
2276
- if (seen.has(id)) return true;
2277
- seen.add(id);
2278
- }
2279
- return false;
2412
+ return hasConflictingAttemptIdReuse(members) || hasConflictingEventIdReuse(members);
2280
2413
  }
2281
2414
  function findRetryTarget(members, retryOf) {
2282
2415
  return members.find(