agent-inspect 6.31.32 → 6.31.33
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/TRACE-CONTRACTS.md +2 -0
- package/package.json +1 -1
- package/packages/cli/dist/{chunk-PEGM6T2X.mjs → chunk-AILSHDEF.mjs} +111 -24
- package/packages/cli/dist/chunk-AILSHDEF.mjs.map +1 -0
- package/packages/cli/dist/index.cjs +110 -23
- package/packages/cli/dist/index.cjs.map +1 -1
- package/packages/cli/dist/index.mjs +4 -4
- package/packages/cli/dist/index.mjs.map +1 -1
- package/packages/cli/dist/{src-CWUJTMRD.mjs → src-SP36M4VB.mjs} +3 -3
- package/packages/cli/dist/{src-CWUJTMRD.mjs.map → src-SP36M4VB.mjs.map} +1 -1
- package/packages/core/dist/advanced.cjs +76 -18
- package/packages/core/dist/advanced.cjs.map +1 -1
- package/packages/core/dist/advanced.mjs +2 -2
- package/packages/core/dist/checks.cjs +109 -22
- package/packages/core/dist/checks.cjs.map +1 -1
- package/packages/core/dist/checks.mjs +1 -1
- package/packages/core/dist/{chunk-6G67ZN72.mjs → chunk-EMDJLFRK.mjs} +111 -24
- package/packages/core/dist/chunk-EMDJLFRK.mjs.map +1 -0
- package/packages/cli/dist/chunk-PEGM6T2X.mjs.map +0 -1
- package/packages/core/dist/chunk-6G67ZN72.mjs.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 6.31.33
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- b2adf03: Fail requiredOrder when a before tool starts but never finishes while after runs (#521). Escape mixed-script lookalike tool names in tool.usage findings and sort allowlist causes first (#522).
|
|
8
|
+
|
|
3
9
|
## 6.31.32
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -213,7 +213,7 @@ The root package is enough for custom capture, the CLI, checks, and Evidence wor
|
|
|
213
213
|
|
|
214
214
|
## Status and documentation
|
|
215
215
|
|
|
216
|
-
**Current published baseline:** **6.31.
|
|
216
|
+
**Current published baseline:** **6.31.33** · persisted schema `1.0` · Node.js `>=20` · MIT.
|
|
217
217
|
|
|
218
218
|
Legacy v0.1 and v0.2 traces remain readable. Check the npm badge and [changelog](CHANGELOG.md) for the current published version.
|
|
219
219
|
|
package/docs/TRACE-CONTRACTS.md
CHANGED
|
@@ -45,6 +45,7 @@ Contracts compile to deterministic check rules for common cases:
|
|
|
45
45
|
- `all-occurrences` requires every `before` occurrence to finish before every `after` occurrence starts (`max(before.end) <= min(after.start)`);
|
|
46
46
|
- causal modes fail when a required interval boundary cannot be resolved instead of falling back to encounter order.
|
|
47
47
|
- when the boundary timestamps tie at millisecond resolution (for example scripted or mocked tools that start and finish inside one millisecond), causal modes decide by recorded event order: the before event must have been recorded as finished before the after event was recorded as started. Such findings carry `resolvedBy: "recorded-order"`.
|
|
48
|
+
- a `before` tool that starts but never finishes (`status: "running"`) while a later `after` tool finishes fails the order rule in every mode with `tool.order.interval-unresolved` (unfinished before), naming the abandoned tool — not only the generic incomplete-running `run.status` finding.
|
|
48
49
|
|
|
49
50
|
Examples for `requiredOrder: ["retrieve_policy", "send_email"]` (both TOOL-typed):
|
|
50
51
|
|
|
@@ -120,6 +121,7 @@ The evaluator expands each list into adjacent pairs and applies one `requiredOrd
|
|
|
120
121
|
- `requiredOrderMode: "all-occurrences"` requires every before to end before every after starts; any cross-boundary overlap or later before fails.
|
|
121
122
|
- Missing interval boundaries fail closed in the two causal modes.
|
|
122
123
|
- Millisecond timestamp ties are decided by recorded event order in the two causal modes.
|
|
124
|
+
- A started-but-never-finished `before` tool (running, no completion) fails order in every mode when `after` has finished, with `tool.order.interval-unresolved`.
|
|
123
125
|
|
|
124
126
|
### `alternatives.anyOf` (shipped)
|
|
125
127
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-inspect",
|
|
3
|
-
"version": "6.31.
|
|
3
|
+
"version": "6.31.33",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Local evidence debugger and trajectory-test toolkit for TypeScript AI agents — execution trees, TraceContract checks, Evidence v2, and read-only MCP",
|
|
@@ -7051,10 +7051,17 @@ function contractToRules(contract) {
|
|
|
7051
7051
|
(event) => event.status === "running"
|
|
7052
7052
|
);
|
|
7053
7053
|
if (running.length > 0) {
|
|
7054
|
+
const labels = running.map((event) => {
|
|
7055
|
+
if (event.kind === "TOOL") {
|
|
7056
|
+
return `tool ${resolveCanonicalToolName(event)}`;
|
|
7057
|
+
}
|
|
7058
|
+
return `${event.kind} ${event.name}`;
|
|
7059
|
+
});
|
|
7060
|
+
const message = labels.length === 1 ? `Run contains incomplete running events: ${labels[0]} never completed.` : `Run contains incomplete running events: ${labels.join("; ")}.`;
|
|
7054
7061
|
findings.push(
|
|
7055
7062
|
contractFailFinding(
|
|
7056
7063
|
"contract.run.allowedStatuses",
|
|
7057
|
-
|
|
7064
|
+
message,
|
|
7058
7065
|
running.map((event) => ({
|
|
7059
7066
|
runId: event.runId,
|
|
7060
7067
|
eventId: event.eventId,
|
|
@@ -7063,7 +7070,10 @@ function contractToRules(contract) {
|
|
|
7063
7070
|
status: event.status
|
|
7064
7071
|
})),
|
|
7065
7072
|
"no running events",
|
|
7066
|
-
|
|
7073
|
+
{
|
|
7074
|
+
count: running.length,
|
|
7075
|
+
unfinished: labels
|
|
7076
|
+
}
|
|
7067
7077
|
)
|
|
7068
7078
|
);
|
|
7069
7079
|
}
|
|
@@ -8009,6 +8019,11 @@ function compareFindings(eventById) {
|
|
|
8009
8019
|
if (STATUS_RANK[a.status] !== STATUS_RANK[b.status]) {
|
|
8010
8020
|
return STATUS_RANK[a.status] - STATUS_RANK[b.status];
|
|
8011
8021
|
}
|
|
8022
|
+
if (a.ruleId === "tool.usage") {
|
|
8023
|
+
const aHasEvent = a.evidence[0]?.eventId !== void 0;
|
|
8024
|
+
const bHasEvent = b.evidence[0]?.eventId !== void 0;
|
|
8025
|
+
if (aHasEvent !== bHasEvent) return aHasEvent ? -1 : 1;
|
|
8026
|
+
}
|
|
8012
8027
|
const byRun = compareStrings(a.evidence[0]?.runId, b.evidence[0]?.runId);
|
|
8013
8028
|
if (byRun !== 0) return byRun;
|
|
8014
8029
|
const byTime = eventTimestamp(a, eventById).localeCompare(eventTimestamp(b, eventById));
|
|
@@ -8134,6 +8149,37 @@ function failFinding(ruleId, message, evidence, expected, actual, meta) {
|
|
|
8134
8149
|
function toolName(event) {
|
|
8135
8150
|
return resolveCanonicalToolName(event);
|
|
8136
8151
|
}
|
|
8152
|
+
function formatToolNameForMessage(name) {
|
|
8153
|
+
const details = [];
|
|
8154
|
+
for (let index = 0; index < name.length; ) {
|
|
8155
|
+
const codePoint = name.codePointAt(index);
|
|
8156
|
+
const width = codePoint > 65535 ? 2 : 1;
|
|
8157
|
+
if (codePoint > 127) {
|
|
8158
|
+
details.push(
|
|
8159
|
+
`U+${codePoint.toString(16).toUpperCase().padStart(4, "0")} at index ${index}`
|
|
8160
|
+
);
|
|
8161
|
+
}
|
|
8162
|
+
index += width;
|
|
8163
|
+
}
|
|
8164
|
+
if (details.length === 0) return name;
|
|
8165
|
+
return `"${name}" (contains ${details.join("; ")})`;
|
|
8166
|
+
}
|
|
8167
|
+
function describeRunningEvent(event) {
|
|
8168
|
+
if (event.kind === "TOOL") {
|
|
8169
|
+
return `tool ${formatToolNameForMessage(resolveCanonicalToolName(event))}`;
|
|
8170
|
+
}
|
|
8171
|
+
if (event.kind === "LLM") {
|
|
8172
|
+
return `llm ${stepEndpointName(event, "LLM")}`;
|
|
8173
|
+
}
|
|
8174
|
+
return `${event.kind} ${event.name}`;
|
|
8175
|
+
}
|
|
8176
|
+
function incompleteRunningMessage(prefix, running) {
|
|
8177
|
+
const labels = running.map(describeRunningEvent);
|
|
8178
|
+
if (labels.length === 1) {
|
|
8179
|
+
return `${prefix}: ${labels[0]} never completed.`;
|
|
8180
|
+
}
|
|
8181
|
+
return `${prefix}: ${labels.join("; ")}.`;
|
|
8182
|
+
}
|
|
8137
8183
|
function stepEndpointName(event, kind) {
|
|
8138
8184
|
if (kind === "TOOL") return resolveCanonicalToolName(event);
|
|
8139
8185
|
for (const prefix of ["llm:", "generation:", "transcription:", "speech:"]) {
|
|
@@ -8475,10 +8521,13 @@ function createRunStatusRule(options = {}) {
|
|
|
8475
8521
|
findings.push(
|
|
8476
8522
|
failFinding(
|
|
8477
8523
|
"run.status",
|
|
8478
|
-
"Run contains incomplete running events
|
|
8524
|
+
incompleteRunningMessage("Run contains incomplete running events", running),
|
|
8479
8525
|
running.map((event) => eventEvidence3(event)),
|
|
8480
8526
|
"no running events",
|
|
8481
|
-
|
|
8527
|
+
{
|
|
8528
|
+
count: running.length,
|
|
8529
|
+
unfinished: running.map(describeRunningEvent)
|
|
8530
|
+
}
|
|
8482
8531
|
)
|
|
8483
8532
|
);
|
|
8484
8533
|
}
|
|
@@ -8648,6 +8697,34 @@ function createToolUsageRule(options) {
|
|
|
8648
8697
|
const names = tools.map(toolName);
|
|
8649
8698
|
const nameSet = new Set(names);
|
|
8650
8699
|
const findings = [];
|
|
8700
|
+
const forbidden = new Set(options.forbidden ?? []);
|
|
8701
|
+
const allowed = options.allowed?.length ? new Set(options.allowed) : void 0;
|
|
8702
|
+
for (const event of tools) {
|
|
8703
|
+
const name = toolName(event);
|
|
8704
|
+
const display = formatToolNameForMessage(name);
|
|
8705
|
+
if (forbidden.has(name)) {
|
|
8706
|
+
findings.push(
|
|
8707
|
+
failFinding(
|
|
8708
|
+
"tool.usage",
|
|
8709
|
+
`Forbidden tool ${display} appeared.`,
|
|
8710
|
+
[eventEvidence3(event)],
|
|
8711
|
+
"tool absent",
|
|
8712
|
+
name
|
|
8713
|
+
)
|
|
8714
|
+
);
|
|
8715
|
+
}
|
|
8716
|
+
if (allowed && !allowed.has(name)) {
|
|
8717
|
+
findings.push(
|
|
8718
|
+
failFinding(
|
|
8719
|
+
"tool.usage",
|
|
8720
|
+
`Tool ${display} is not in the allowed tool set.`,
|
|
8721
|
+
[eventEvidence3(event)],
|
|
8722
|
+
[...allowed].sort(),
|
|
8723
|
+
name
|
|
8724
|
+
)
|
|
8725
|
+
);
|
|
8726
|
+
}
|
|
8727
|
+
}
|
|
8651
8728
|
for (const required of options.required ?? []) {
|
|
8652
8729
|
if (!nameSet.has(required)) {
|
|
8653
8730
|
const otherKinds = [
|
|
@@ -8665,7 +8742,7 @@ function createToolUsageRule(options) {
|
|
|
8665
8742
|
findings.push(
|
|
8666
8743
|
failFinding(
|
|
8667
8744
|
"tool.usage",
|
|
8668
|
-
`Required tool ${required} did not appear.${hint}`,
|
|
8745
|
+
`Required tool ${formatToolNameForMessage(required)} did not appear.${hint}`,
|
|
8669
8746
|
runEvidence(context.selectedRun),
|
|
8670
8747
|
required,
|
|
8671
8748
|
names
|
|
@@ -8673,21 +8750,6 @@ function createToolUsageRule(options) {
|
|
|
8673
8750
|
);
|
|
8674
8751
|
}
|
|
8675
8752
|
}
|
|
8676
|
-
const forbidden = new Set(options.forbidden ?? []);
|
|
8677
|
-
const allowed = options.allowed?.length ? new Set(options.allowed) : void 0;
|
|
8678
|
-
for (const event of tools) {
|
|
8679
|
-
const name = toolName(event);
|
|
8680
|
-
if (forbidden.has(name)) {
|
|
8681
|
-
findings.push(
|
|
8682
|
-
failFinding("tool.usage", `Forbidden tool ${name} appeared.`, [eventEvidence3(event)], "tool absent", name)
|
|
8683
|
-
);
|
|
8684
|
-
}
|
|
8685
|
-
if (allowed && !allowed.has(name)) {
|
|
8686
|
-
findings.push(
|
|
8687
|
-
failFinding("tool.usage", `Tool ${name} is not in the allowed tool set.`, [eventEvidence3(event)], [...allowed].sort(), name)
|
|
8688
|
-
);
|
|
8689
|
-
}
|
|
8690
|
-
}
|
|
8691
8753
|
if (options.minCount !== void 0 && tools.length < options.minCount) {
|
|
8692
8754
|
findings.push(
|
|
8693
8755
|
failFinding("tool.usage", `Tool count ${tools.length} was below minimum ${options.minCount}.`, runEvidence(context.selectedRun), { minCount: options.minCount }, tools.length)
|
|
@@ -8721,6 +8783,28 @@ function createStepOrderingRule(options) {
|
|
|
8721
8783
|
const afterEvents = finishedEvents(context, options.after.kind).filter(
|
|
8722
8784
|
(event) => stepEndpointName(event, options.after.kind) === options.after.name
|
|
8723
8785
|
);
|
|
8786
|
+
const beforeRunning = semanticEvents(context).filter(
|
|
8787
|
+
(event) => event.kind === options.before.kind && event.status === "running" && stepEndpointName(event, options.before.kind) === options.before.name
|
|
8788
|
+
);
|
|
8789
|
+
if (beforeEvents.length === 0 && afterEvents.length > 0 && beforeRunning.length > 0) {
|
|
8790
|
+
const endpointExpected2 = bothTools ? { before: options.before.name, after: options.after.name } : { before: options.before, after: options.after };
|
|
8791
|
+
return [
|
|
8792
|
+
failFinding(
|
|
8793
|
+
ruleId,
|
|
8794
|
+
`${subject} ${beforeLabel} started but never finished before ${afterLabel} ran.`,
|
|
8795
|
+
[
|
|
8796
|
+
...beforeRunning.map((event) => eventEvidence3(event)),
|
|
8797
|
+
eventEvidence3(afterEvents[0])
|
|
8798
|
+
],
|
|
8799
|
+
{ ...endpointExpected2, mode },
|
|
8800
|
+
{
|
|
8801
|
+
code: bothTools ? "tool.order.interval-unresolved" : "step.order.interval-unresolved",
|
|
8802
|
+
unfinishedBefore: true,
|
|
8803
|
+
beforeStatus: "running"
|
|
8804
|
+
}
|
|
8805
|
+
)
|
|
8806
|
+
];
|
|
8807
|
+
}
|
|
8724
8808
|
if (beforeEvents.length === 0 || afterEvents.length === 0) {
|
|
8725
8809
|
if (!requireEndpoints) return [];
|
|
8726
8810
|
const findings = [];
|
|
@@ -9097,10 +9181,13 @@ function createStructureIncompleteRule(options = {}) {
|
|
|
9097
9181
|
findings.push(
|
|
9098
9182
|
failFinding(
|
|
9099
9183
|
"structure.incomplete",
|
|
9100
|
-
"Trace contains incomplete running events
|
|
9184
|
+
incompleteRunningMessage("Trace contains incomplete running events", running),
|
|
9101
9185
|
running.map((event) => eventEvidence3(event, "status")),
|
|
9102
9186
|
"no running events",
|
|
9103
|
-
|
|
9187
|
+
{
|
|
9188
|
+
count: running.length,
|
|
9189
|
+
unfinished: running.map(describeRunningEvent)
|
|
9190
|
+
}
|
|
9104
9191
|
)
|
|
9105
9192
|
);
|
|
9106
9193
|
}
|
|
@@ -16084,5 +16171,5 @@ function renderGateReport(result, options = {}) {
|
|
|
16084
16171
|
}
|
|
16085
16172
|
|
|
16086
16173
|
export { ATTRIBUTION_CONFIDENCES, COHORT_METRIC_IDS, DEFAULT_REDACT_KEYS, DEFAULT_SUITE_ARTIFACTS_DIR, DELIVERY_CONFLICT_ATTR, DELIVERY_EVENT_BASE_ATTR, EVIDENCE_FORMAT_VERSION, EVIDENCE_HTML_FILENAME, EVIDENCE_MANIFEST_FILENAME, IDENTITY_CONFLICT_ATTR, Redactor, TraceDirectory, TraceReadError, TreeBuilder, aggregateBundleSafeStatus, aggregateSessionCheckResults, analyzeCohort, applyProfileMetadataCaps, assertBundlePathContained, assertEvidenceRelativePath, buildActivitySummary, buildBundleMetadata, buildBundleSummaryMarkdown, buildEvidenceCausalFailureViewHtml, buildEvidenceCiPackage, buildEvidenceCircuitViewHtml, buildEvidenceContractsViewHtml, buildEvidenceDiffViewHtml, buildEvidenceHtmlShell, buildEvidenceManifest, buildEvidenceOutcomesViewHtml, buildEvidenceProvenanceViewHtml, buildEvidenceSafetyViewHtml, buildEvidenceTimelineViewHtml, buildEvidenceToolsLlmViewHtml, buildEvidenceTreeViewHtml, buildLocalExplanation, buildPlaceholderArtifact, buildRunSummary, buildRunTimeline, buildRunWhatSummary, buildSessionIndex, buildTraceStats, buildZipArchive, bundleFailsOnSafety, bundleRunAssetRelativePath, collectTraceSchemaVersions, compactAttributes, createBaselineRegressionRule, createLlmUsageRule, createMaxStepDurationRule, createObservedOutcomeRule, createRequireCompletedRule, createRunDepthRule, createRunDurationRule, createRunStatusRule, createSafetyOversizedAttributeRule, createSafetyRawContentRule, createSafetyRedactionRule, createSafetySecretPatternRule, createStallDetectionRule, createStructureCycleRule, createStructureOrphanRule, createStructureParallelWidthRule, createStructureRelationshipRule, createToolUsageRule, defaultBundleOutputPath, defaultSuiteConfigTemplate, defineTraceContract, diffRuns, diffTraceEvents, enrichSessionRunRecord, escapeHtml, escapeMarkdown, evaluateTraceContract, extractMetadata, extractOutcomesFromTraceEvents, filterMetasBySessionScope, filterTraces, flattenTree, formatDuration2 as formatDuration, formatStepLabel, formatTimestamp, gateHasThresholds, getIndent, getTraceFilePath, inferEvidenceFileRole, isAgentInspectTrace, isAttributionConfidence, isCredentialSensitiveKey, isPersistedInspectEvent, loadSessionRunRecords, loadSuiteConfig, loadTraceMetadataList, manualTraceEventsToComparableRun, nanoid, normalizeBundleOutputPath, openTrace, parseCohortMetricList, parseDuration, parseDurationFilter, parseGateList, parseTraceJsonl, persistedInspectEventsToRunTrees, persistedInspectEventsToTraceEvents, projectLogicalEvents, renderActivitySummaryHuman, renderCohortReport, renderErrorLine, renderGateReport, renderObservedOutcomesHtml, renderObservedOutcomesMarkdown, renderRunDiff, renderRunWhat, renderStepLine, renderSuiteReport, renderTimeline, renderTraceStats, resolveBundleRunIds, resolveRedactionProfile, resolveSuiteTemplate, resolveTraceDir, runGate, runSuite, runTraceChecks, safeString, sanitizeBundleRunId, searchTraces, serializeEvidenceManifest, sha256Hex, stableJson, stringContainsHighConfidenceCredential, summarizeObservedOutcomes, summarizeSemanticParity, traceEventToPersistedInspectEvent, truncateName, truncateStringForProfile, validateEvent, validateSuiteConfig, verifyEvidenceDirectory, zeroKinds };
|
|
16087
|
-
//# sourceMappingURL=chunk-
|
|
16088
|
-
//# sourceMappingURL=chunk-
|
|
16174
|
+
//# sourceMappingURL=chunk-AILSHDEF.mjs.map
|
|
16175
|
+
//# sourceMappingURL=chunk-AILSHDEF.mjs.map
|