agent-inspect 5.1.0 → 5.2.0
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/docs/CLI.md +32 -0
- package/package.json +1 -1
- package/packages/cli/dist/{chunk-TSIQUIPF.mjs → chunk-SJ5R2XBE.mjs} +416 -28
- package/packages/cli/dist/chunk-SJ5R2XBE.mjs.map +1 -0
- package/packages/cli/dist/index.cjs +753 -194
- package/packages/cli/dist/index.cjs.map +1 -1
- package/packages/cli/dist/index.mjs +184 -49
- package/packages/cli/dist/index.mjs.map +1 -1
- package/packages/cli/dist/{src-2SZWGKMM.mjs → src-PK22BBMH.mjs} +3 -3
- package/packages/cli/dist/{src-2SZWGKMM.mjs.map → src-PK22BBMH.mjs.map} +1 -1
- package/packages/core/dist/advanced.cjs +413 -9
- package/packages/core/dist/advanced.cjs.map +1 -1
- package/packages/core/dist/advanced.d.cts +47 -1
- package/packages/core/dist/advanced.d.ts +47 -1
- package/packages/core/dist/advanced.mjs +404 -8
- package/packages/core/dist/advanced.mjs.map +1 -1
- package/packages/cli/dist/chunk-TSIQUIPF.mjs.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { createSafetyRawContentRule, createSafetyRedactionRule, createSafetySecretPatternRule, createSafetyOversizedAttributeRule, resolveTraceDir, parseDuration, buildSessionIndex, enrichSessionRunRecord, TraceDirectory, loadTraceMetadataList, loadSessionRunRecords, extractMetadata, filterTraces, truncateName, getTraceFilePath, buildRunSummary, formatDuration, formatTimestamp, isAgentInspectTrace, openTrace, TraceReadError, filterMetasBySessionScope, runTraceChecks, aggregateSessionCheckResults, createBaselineRegressionRule, resolveBundleRunIds, aggregateBundleSafeStatus, bundleFailsOnSafety, buildPlaceholderArtifact, buildBundleMetadata, buildBundleSummaryMarkdown, buildRunTimeline, renderTimeline, buildTraceStats, renderTraceStats, parseDurationFilter, searchTraces, buildActivitySummary, renderActivitySummaryHuman, buildRunWhatSummary, renderRunWhat, buildLocalExplanation, defaultSuiteConfigTemplate, loadSuiteConfig, validateSuiteConfig, runSuite, renderSuiteReport, analyzeCohort, renderCohortReport, persistedInspectEventsToTraceEvents, renderStepLine, renderErrorLine, getIndent, Redactor, TreeBuilder, zeroKinds, validateEvent, traceEventToPersistedInspectEvent, isPersistedInspectEvent, createRunStatusRule, createStructureOrphanRule, createStructureCycleRule, createRunDurationRule, createMaxStepDurationRule, createRequireCompletedRule, createStallDetectionRule, createObservedOutcomeRule, createRunDepthRule, createToolUsageRule, createLlmUsageRule, createStructureRelationshipRule, createStructureParallelWidthRule, normalizeBundleOutputPath, defaultBundleOutputPath, summarizeObservedOutcomes, extractOutcomesFromTraceEvents, renderObservedOutcomesMarkdown, renderObservedOutcomesHtml, escapeMarkdown, escapeHtml, DEFAULT_SUITE_ARTIFACTS_DIR, parseCohortMetricList, COHORT_METRIC_IDS, nanoid, resolveRedactionProfile, applyProfileMetadataCaps, flattenTree, safeString, compactAttributes, stableJson, truncateStringForProfile } from './chunk-
|
|
2
|
+
import { createSafetyRawContentRule, createSafetyRedactionRule, createSafetySecretPatternRule, createSafetyOversizedAttributeRule, resolveTraceDir, parseDuration, buildSessionIndex, enrichSessionRunRecord, TraceDirectory, loadTraceMetadataList, loadSessionRunRecords, extractMetadata, filterTraces, truncateName, getTraceFilePath, buildRunSummary, formatDuration, formatTimestamp, isAgentInspectTrace, openTrace, TraceReadError, filterMetasBySessionScope, runTraceChecks, aggregateSessionCheckResults, createBaselineRegressionRule, resolveBundleRunIds, aggregateBundleSafeStatus, bundleFailsOnSafety, buildPlaceholderArtifact, buildBundleMetadata, buildBundleSummaryMarkdown, buildRunTimeline, renderTimeline, buildTraceStats, renderTraceStats, parseDurationFilter, searchTraces, buildActivitySummary, renderActivitySummaryHuman, buildRunWhatSummary, renderRunWhat, buildLocalExplanation, defaultSuiteConfigTemplate, loadSuiteConfig, validateSuiteConfig, runSuite, renderSuiteReport, analyzeCohort, renderCohortReport, gateHasThresholds, runGate, renderGateReport, persistedInspectEventsToTraceEvents, renderStepLine, renderErrorLine, getIndent, Redactor, TreeBuilder, zeroKinds, validateEvent, traceEventToPersistedInspectEvent, isPersistedInspectEvent, createRunStatusRule, createStructureOrphanRule, createStructureCycleRule, createRunDurationRule, createMaxStepDurationRule, createRequireCompletedRule, createStallDetectionRule, createObservedOutcomeRule, createRunDepthRule, createToolUsageRule, createLlmUsageRule, createStructureRelationshipRule, createStructureParallelWidthRule, normalizeBundleOutputPath, defaultBundleOutputPath, summarizeObservedOutcomes, extractOutcomesFromTraceEvents, renderObservedOutcomesMarkdown, renderObservedOutcomesHtml, escapeMarkdown, escapeHtml, DEFAULT_SUITE_ARTIFACTS_DIR, parseCohortMetricList, COHORT_METRIC_IDS, parseGateList, nanoid, resolveRedactionProfile, applyProfileMetadataCaps, flattenTree, safeString, compactAttributes, stableJson, truncateStringForProfile } from './chunk-SJ5R2XBE.mjs';
|
|
3
3
|
import { realpathSync, constants as constants$1 } from 'fs';
|
|
4
4
|
import path12 from 'path';
|
|
5
5
|
import { fileURLToPath, pathToFileURL } from 'url';
|
|
@@ -11,7 +11,7 @@ import { createServer } from 'http';
|
|
|
11
11
|
import { createRequire } from 'module';
|
|
12
12
|
|
|
13
13
|
// package.json
|
|
14
|
-
var version = "5.
|
|
14
|
+
var version = "5.2.0";
|
|
15
15
|
|
|
16
16
|
// packages/cli/src/trace-dir-scale.ts
|
|
17
17
|
var TRACE_COUNT_WARN = 1e3;
|
|
@@ -3129,13 +3129,13 @@ function pairSteps(left, right) {
|
|
|
3129
3129
|
return pairs;
|
|
3130
3130
|
}
|
|
3131
3131
|
function compareLeafSteps(L, R, segments, opts, out) {
|
|
3132
|
-
const
|
|
3132
|
+
const path21 = buildPath(segments);
|
|
3133
3133
|
if (L.name !== R.name) {
|
|
3134
3134
|
out.push({
|
|
3135
3135
|
kind: "structure",
|
|
3136
3136
|
severity: "warning",
|
|
3137
3137
|
message: "Step name differs",
|
|
3138
|
-
path:
|
|
3138
|
+
path: path21,
|
|
3139
3139
|
left: L.name,
|
|
3140
3140
|
right: R.name
|
|
3141
3141
|
});
|
|
@@ -3145,7 +3145,7 @@ function compareLeafSteps(L, R, segments, opts, out) {
|
|
|
3145
3145
|
kind: "step-type",
|
|
3146
3146
|
severity: "warning",
|
|
3147
3147
|
message: "Step type differs",
|
|
3148
|
-
path:
|
|
3148
|
+
path: path21,
|
|
3149
3149
|
left: L.type,
|
|
3150
3150
|
right: R.type
|
|
3151
3151
|
});
|
|
@@ -3155,7 +3155,7 @@ function compareLeafSteps(L, R, segments, opts, out) {
|
|
|
3155
3155
|
kind: "step-status",
|
|
3156
3156
|
severity: "warning",
|
|
3157
3157
|
message: "Step status differs",
|
|
3158
|
-
path:
|
|
3158
|
+
path: path21,
|
|
3159
3159
|
left: L.status,
|
|
3160
3160
|
right: R.status
|
|
3161
3161
|
});
|
|
@@ -3167,7 +3167,7 @@ function compareLeafSteps(L, R, segments, opts, out) {
|
|
|
3167
3167
|
kind: "error",
|
|
3168
3168
|
severity: "error",
|
|
3169
3169
|
message: "Step error message differs",
|
|
3170
|
-
path:
|
|
3170
|
+
path: path21,
|
|
3171
3171
|
left: le || void 0,
|
|
3172
3172
|
right: re || void 0
|
|
3173
3173
|
});
|
|
@@ -3185,7 +3185,7 @@ function compareLeafSteps(L, R, segments, opts, out) {
|
|
|
3185
3185
|
kind: "duration",
|
|
3186
3186
|
severity: "info",
|
|
3187
3187
|
message: "Step duration differs",
|
|
3188
|
-
path:
|
|
3188
|
+
path: path21,
|
|
3189
3189
|
left: ld,
|
|
3190
3190
|
right: rd
|
|
3191
3191
|
});
|
|
@@ -3198,7 +3198,7 @@ function compareLeafSteps(L, R, segments, opts, out) {
|
|
|
3198
3198
|
kind: "metadata",
|
|
3199
3199
|
severity: "info",
|
|
3200
3200
|
message: "Step metadata differs",
|
|
3201
|
-
path:
|
|
3201
|
+
path: path21,
|
|
3202
3202
|
left: L.metadata,
|
|
3203
3203
|
right: R.metadata
|
|
3204
3204
|
});
|
|
@@ -3210,7 +3210,7 @@ function compareLeafSteps(L, R, segments, opts, out) {
|
|
|
3210
3210
|
kind: "output",
|
|
3211
3211
|
severity: "info",
|
|
3212
3212
|
message: "Output preview differs",
|
|
3213
|
-
path:
|
|
3213
|
+
path: path21,
|
|
3214
3214
|
left: L.outputPreview,
|
|
3215
3215
|
right: R.outputPreview
|
|
3216
3216
|
});
|
|
@@ -3370,11 +3370,11 @@ function diffRuns(left, right, options) {
|
|
|
3370
3370
|
}
|
|
3371
3371
|
|
|
3372
3372
|
// packages/core/src/diff/renderer.ts
|
|
3373
|
-
function formatPath(
|
|
3374
|
-
if (
|
|
3373
|
+
function formatPath(path21) {
|
|
3374
|
+
if (path21 === void 0 || path21.path.length === 0) {
|
|
3375
3375
|
return "(run)";
|
|
3376
3376
|
}
|
|
3377
|
-
return
|
|
3377
|
+
return path21.path.map((s) => s.name).join(" > ");
|
|
3378
3378
|
}
|
|
3379
3379
|
function formatValue(v, verbose) {
|
|
3380
3380
|
if (v === void 0) return "(undefined)";
|
|
@@ -3782,7 +3782,7 @@ async function newestTraceMtimeMs(traceDir) {
|
|
|
3782
3782
|
}
|
|
3783
3783
|
async function loadSessionRuns(traceDir) {
|
|
3784
3784
|
try {
|
|
3785
|
-
const mod = await import('./src-
|
|
3785
|
+
const mod = await import('./src-PK22BBMH.mjs');
|
|
3786
3786
|
const dbPath = mod.resolveIndexDbPath(traceDir);
|
|
3787
3787
|
const status = mod.indexStatus(dbPath);
|
|
3788
3788
|
if (!status.healthy) {
|
|
@@ -4479,17 +4479,17 @@ function applyRule(rule, value, replacement) {
|
|
|
4479
4479
|
}
|
|
4480
4480
|
return value;
|
|
4481
4481
|
}
|
|
4482
|
-
function childPath(
|
|
4482
|
+
function childPath(path21, key) {
|
|
4483
4483
|
if (/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key)) {
|
|
4484
|
-
return
|
|
4484
|
+
return path21 ? `${path21}.${key}` : key;
|
|
4485
4485
|
}
|
|
4486
|
-
return `${
|
|
4486
|
+
return `${path21 || "$"}[${JSON.stringify(key)}]`;
|
|
4487
4487
|
}
|
|
4488
|
-
function indexPath(
|
|
4489
|
-
return `${
|
|
4488
|
+
function indexPath(path21, index) {
|
|
4489
|
+
return `${path21 || "$"}[${index}]`;
|
|
4490
4490
|
}
|
|
4491
|
-
function makeFinding(
|
|
4492
|
-
return preview === void 0 ? { path:
|
|
4491
|
+
function makeFinding(path21, detector, action, matchKind, severity = "warning", preview) {
|
|
4492
|
+
return preview === void 0 ? { path: path21, detector, action, severity, matchKind } : { path: path21, detector, action, severity, matchKind, preview };
|
|
4493
4493
|
}
|
|
4494
4494
|
function createRedactionProfile(profile = "local") {
|
|
4495
4495
|
switch (profile) {
|
|
@@ -4558,11 +4558,11 @@ var Redactor2 = class {
|
|
|
4558
4558
|
#recordFinding(state, finding) {
|
|
4559
4559
|
if (this.#collectFindings) state.findings.push(finding);
|
|
4560
4560
|
}
|
|
4561
|
-
#redactValue(value, key,
|
|
4561
|
+
#redactValue(value, key, path21, depth, state) {
|
|
4562
4562
|
if (depth > this.#maxDepth) {
|
|
4563
4563
|
this.#recordFinding(
|
|
4564
4564
|
state,
|
|
4565
|
-
makeFinding(
|
|
4565
|
+
makeFinding(path21, "structure.maxDepth", "truncate", "value", "warning")
|
|
4566
4566
|
);
|
|
4567
4567
|
return "[Truncated]";
|
|
4568
4568
|
}
|
|
@@ -4571,19 +4571,19 @@ var Redactor2 = class {
|
|
|
4571
4571
|
if (rule) {
|
|
4572
4572
|
this.#recordFinding(
|
|
4573
4573
|
state,
|
|
4574
|
-
makeFinding(
|
|
4574
|
+
makeFinding(path21, `key.${rule.key}`, actionForRule(rule), "key", "warning")
|
|
4575
4575
|
);
|
|
4576
4576
|
return applyRule(rule, value, this.#replacement);
|
|
4577
4577
|
}
|
|
4578
4578
|
}
|
|
4579
4579
|
for (const detector of this.#detectors) {
|
|
4580
|
-
const detections = detector.detect({ path:
|
|
4580
|
+
const detections = detector.detect({ path: path21, key, value });
|
|
4581
4581
|
for (const detection of detections) {
|
|
4582
4582
|
const action = detection.action ?? "replace";
|
|
4583
4583
|
this.#recordFinding(
|
|
4584
4584
|
state,
|
|
4585
4585
|
makeFinding(
|
|
4586
|
-
|
|
4586
|
+
path21,
|
|
4587
4587
|
detector.id,
|
|
4588
4588
|
action,
|
|
4589
4589
|
detection.matchKind ?? detector.matchKind ?? "custom",
|
|
@@ -4601,7 +4601,7 @@ var Redactor2 = class {
|
|
|
4601
4601
|
const out = [];
|
|
4602
4602
|
state.seen.set(value, out);
|
|
4603
4603
|
value.forEach((item, index) => {
|
|
4604
|
-
out[index] = this.#redactValue(item, void 0, indexPath(
|
|
4604
|
+
out[index] = this.#redactValue(item, void 0, indexPath(path21, index), depth + 1, state);
|
|
4605
4605
|
});
|
|
4606
4606
|
return out;
|
|
4607
4607
|
}
|
|
@@ -4613,7 +4613,7 @@ var Redactor2 = class {
|
|
|
4613
4613
|
out[entryKey] = this.#redactValue(
|
|
4614
4614
|
entryValue,
|
|
4615
4615
|
entryKey,
|
|
4616
|
-
childPath(
|
|
4616
|
+
childPath(path21 === "$" ? "" : path21, entryKey),
|
|
4617
4617
|
depth + 1,
|
|
4618
4618
|
state
|
|
4619
4619
|
);
|
|
@@ -5540,23 +5540,23 @@ function evaluatePromptInjection(text, options = {}) {
|
|
|
5540
5540
|
}
|
|
5541
5541
|
return fail(ruleId, `Matched ${evidence.length} injection pattern(s).`, evidence, "warning");
|
|
5542
5542
|
}
|
|
5543
|
-
function validateSchemaField(value, field,
|
|
5543
|
+
function validateSchemaField(value, field, path21, evidence) {
|
|
5544
5544
|
const ruleId = "guardrail.structured-output";
|
|
5545
5545
|
if (field.type) {
|
|
5546
5546
|
const actual = value === null ? "null" : Array.isArray(value) ? "array" : typeof value;
|
|
5547
5547
|
if (actual !== field.type) {
|
|
5548
|
-
evidence.push({ ruleId, path:
|
|
5548
|
+
evidence.push({ ruleId, path: path21, preview: `expected ${field.type}, got ${actual}` });
|
|
5549
5549
|
return;
|
|
5550
5550
|
}
|
|
5551
5551
|
}
|
|
5552
5552
|
if (field.enum && !field.enum.some((item) => Object.is(item, value))) {
|
|
5553
|
-
evidence.push({ ruleId, path:
|
|
5553
|
+
evidence.push({ ruleId, path: path21, preview: "value not in enum" });
|
|
5554
5554
|
}
|
|
5555
5555
|
if (field.type === "object" && field.required && value && typeof value === "object" && !Array.isArray(value)) {
|
|
5556
5556
|
const record = value;
|
|
5557
5557
|
for (const key of field.required) {
|
|
5558
5558
|
if (!(key in record)) {
|
|
5559
|
-
evidence.push({ ruleId, path: `${
|
|
5559
|
+
evidence.push({ ruleId, path: `${path21}.${key}`, preview: "missing required key" });
|
|
5560
5560
|
}
|
|
5561
5561
|
}
|
|
5562
5562
|
}
|
|
@@ -6057,10 +6057,10 @@ function printHuman(result) {
|
|
|
6057
6057
|
console.log(`- ${diagnostic3.code}: ${diagnostic3.message}`);
|
|
6058
6058
|
}
|
|
6059
6059
|
for (const finding of result.findings) {
|
|
6060
|
-
const
|
|
6060
|
+
const path21 = finding.evidence[0]?.path;
|
|
6061
6061
|
const run = finding.evidence[0]?.runId;
|
|
6062
6062
|
const runPrefix = run ? `[${run}] ` : "";
|
|
6063
|
-
console.log(`- ${runPrefix}${finding.ruleId}: ${finding.message}${
|
|
6063
|
+
console.log(`- ${runPrefix}${finding.ruleId}: ${finding.message}${path21 ? ` (${path21})` : ""}`);
|
|
6064
6064
|
}
|
|
6065
6065
|
}
|
|
6066
6066
|
function readErrorResult(error) {
|
|
@@ -6598,10 +6598,10 @@ async function evalRun(input3, options = {}) {
|
|
|
6598
6598
|
diagnostics: []
|
|
6599
6599
|
};
|
|
6600
6600
|
}
|
|
6601
|
-
function evidenceForRun(run,
|
|
6602
|
-
return [{ runId: run.runId, ...
|
|
6601
|
+
function evidenceForRun(run, path21) {
|
|
6602
|
+
return [{ runId: run.runId, ...path21 !== void 0 ? { path: path21 } : {} }];
|
|
6603
6603
|
}
|
|
6604
|
-
function evidenceForEvent(event,
|
|
6604
|
+
function evidenceForEvent(event, path21) {
|
|
6605
6605
|
return [
|
|
6606
6606
|
{
|
|
6607
6607
|
runId: event.runId,
|
|
@@ -6609,7 +6609,7 @@ function evidenceForEvent(event, path20) {
|
|
|
6609
6609
|
...event.parentId !== void 0 ? { parentId: event.parentId } : {},
|
|
6610
6610
|
kind: event.kind,
|
|
6611
6611
|
name: event.name,
|
|
6612
|
-
...
|
|
6612
|
+
...path21 !== void 0 ? { path: path21 } : {}
|
|
6613
6613
|
}
|
|
6614
6614
|
];
|
|
6615
6615
|
}
|
|
@@ -6767,9 +6767,9 @@ function collectTextFields(nodes, keys, preferredKinds = []) {
|
|
|
6767
6767
|
function tokenize(text) {
|
|
6768
6768
|
return [...text.toLowerCase().matchAll(/[a-z0-9][a-z0-9'-]{2,}/g)].map((match) => match[0].replace(/^['-]+|['-]+$/g, "")).filter((token) => token.length > 2 && !STOP_WORDS.has(token));
|
|
6769
6769
|
}
|
|
6770
|
-
function firstEvidence(fields, run,
|
|
6770
|
+
function firstEvidence(fields, run, path21) {
|
|
6771
6771
|
const first = fields[0];
|
|
6772
|
-
return first === void 0 ? evidenceForRun(run,
|
|
6772
|
+
return first === void 0 ? evidenceForRun(run, path21) : evidenceForEvent(first.node.event, first.path);
|
|
6773
6773
|
}
|
|
6774
6774
|
function collectSourceIds(nodes, keys) {
|
|
6775
6775
|
const wanted = keySet(keys);
|
|
@@ -7146,8 +7146,8 @@ function renderEvalMarkdown(result) {
|
|
|
7146
7146
|
if (result.findings.length > 0) {
|
|
7147
7147
|
lines.push("", "## Findings");
|
|
7148
7148
|
for (const finding of result.findings) {
|
|
7149
|
-
const
|
|
7150
|
-
lines.push(`- ${finding.ruleId}: ${finding.message}${
|
|
7149
|
+
const path21 = finding.evidence[0]?.path;
|
|
7150
|
+
lines.push(`- ${finding.ruleId}: ${finding.message}${path21 ? ` (${path21})` : ""}`);
|
|
7151
7151
|
}
|
|
7152
7152
|
}
|
|
7153
7153
|
return `${lines.join("\n")}
|
|
@@ -7340,8 +7340,8 @@ function printHuman2(result) {
|
|
|
7340
7340
|
console.log(`- ${diagnostic3.code}: ${diagnostic3.message}`);
|
|
7341
7341
|
}
|
|
7342
7342
|
for (const finding of result.findings) {
|
|
7343
|
-
const
|
|
7344
|
-
console.log(`- ${finding.ruleId}: ${finding.message}${
|
|
7343
|
+
const path21 = finding.evidence[0]?.path;
|
|
7344
|
+
console.log(`- ${finding.ruleId}: ${finding.message}${path21 ? ` (${path21})` : ""}`);
|
|
7345
7345
|
}
|
|
7346
7346
|
}
|
|
7347
7347
|
function readErrorResult2(error) {
|
|
@@ -7579,8 +7579,8 @@ function printHuman3(result) {
|
|
|
7579
7579
|
console.log(`- ${diagnostic3.code}: ${diagnostic3.message}`);
|
|
7580
7580
|
}
|
|
7581
7581
|
for (const finding of result.findings) {
|
|
7582
|
-
const
|
|
7583
|
-
console.log(`- ${finding.ruleId}: ${finding.message}${
|
|
7582
|
+
const path21 = finding.evidence[0]?.path;
|
|
7583
|
+
console.log(`- ${finding.ruleId}: ${finding.message}${path21 ? ` (${path21})` : ""}`);
|
|
7584
7584
|
}
|
|
7585
7585
|
console.log(`Note: ${result.note}`);
|
|
7586
7586
|
}
|
|
@@ -7731,8 +7731,8 @@ function renderCheckSection(result) {
|
|
|
7731
7731
|
`Diagnostics: ${result.diagnostics.length}`
|
|
7732
7732
|
];
|
|
7733
7733
|
for (const finding of result.findings.slice(0, 10)) {
|
|
7734
|
-
const
|
|
7735
|
-
lines.push(`- ${finding.ruleId}: ${finding.message} (${
|
|
7734
|
+
const path21 = finding.evidence[0]?.path ?? "(run)";
|
|
7735
|
+
lines.push(`- ${finding.ruleId}: ${finding.message} (${path21})`);
|
|
7736
7736
|
}
|
|
7737
7737
|
for (const diagnostic3 of result.diagnostics.slice(0, 10)) {
|
|
7738
7738
|
lines.push(`- ${diagnostic3.code}: ${diagnostic3.message}`);
|
|
@@ -9686,7 +9686,7 @@ function isModuleNotFound3(e) {
|
|
|
9686
9686
|
}
|
|
9687
9687
|
async function loadIndexSqlite() {
|
|
9688
9688
|
try {
|
|
9689
|
-
return await import('./src-
|
|
9689
|
+
return await import('./src-PK22BBMH.mjs');
|
|
9690
9690
|
} catch (e) {
|
|
9691
9691
|
if (isModuleNotFound3(e)) {
|
|
9692
9692
|
console.error(
|
|
@@ -10249,6 +10249,132 @@ async function cohortCommand(options = {}) {
|
|
|
10249
10249
|
process.exitCode = 1;
|
|
10250
10250
|
}
|
|
10251
10251
|
}
|
|
10252
|
+
var SUPPORTED_FORMATS = /* @__PURE__ */ new Set(["markdown", "json", "html", "junit", "github"]);
|
|
10253
|
+
function collectList(value) {
|
|
10254
|
+
if (value === void 0) return [];
|
|
10255
|
+
const items = Array.isArray(value) ? value : [value];
|
|
10256
|
+
return items.flatMap((item) => parseGateList(item));
|
|
10257
|
+
}
|
|
10258
|
+
function parseRate(value) {
|
|
10259
|
+
if (value === void 0 || value.trim() === "") return void 0;
|
|
10260
|
+
const parsed = Number(value);
|
|
10261
|
+
if (!Number.isFinite(parsed)) {
|
|
10262
|
+
throw new Error(`Invalid --max-error-rate: ${value}`);
|
|
10263
|
+
}
|
|
10264
|
+
return parsed;
|
|
10265
|
+
}
|
|
10266
|
+
function parseDuration2(value) {
|
|
10267
|
+
if (value === void 0 || value.trim() === "") return void 0;
|
|
10268
|
+
const parsed = Number(value);
|
|
10269
|
+
if (!Number.isFinite(parsed)) {
|
|
10270
|
+
throw new Error(`Invalid --max-p95-duration: ${value}`);
|
|
10271
|
+
}
|
|
10272
|
+
return parsed;
|
|
10273
|
+
}
|
|
10274
|
+
async function writeArtifacts2(result, outputDir) {
|
|
10275
|
+
await mkdir(outputDir, { recursive: true });
|
|
10276
|
+
const paths = {
|
|
10277
|
+
jsonPath: path12.join(outputDir, "gate-results.json"),
|
|
10278
|
+
markdownPath: path12.join(outputDir, "gate-summary.md"),
|
|
10279
|
+
htmlPath: path12.join(outputDir, "gate-report.html"),
|
|
10280
|
+
junitPath: path12.join(outputDir, "junit.xml"),
|
|
10281
|
+
githubPath: path12.join(outputDir, "github-step-summary.md")
|
|
10282
|
+
};
|
|
10283
|
+
await writeFile(
|
|
10284
|
+
paths.jsonPath,
|
|
10285
|
+
`${renderGateReport(result, { format: "json" })}
|
|
10286
|
+
`,
|
|
10287
|
+
"utf-8"
|
|
10288
|
+
);
|
|
10289
|
+
await writeFile(
|
|
10290
|
+
paths.markdownPath,
|
|
10291
|
+
`${renderGateReport(result, { format: "markdown" })}
|
|
10292
|
+
`,
|
|
10293
|
+
"utf-8"
|
|
10294
|
+
);
|
|
10295
|
+
await writeFile(
|
|
10296
|
+
paths.htmlPath,
|
|
10297
|
+
`${renderGateReport(result, { format: "html" })}
|
|
10298
|
+
`,
|
|
10299
|
+
"utf-8"
|
|
10300
|
+
);
|
|
10301
|
+
await writeFile(
|
|
10302
|
+
paths.junitPath,
|
|
10303
|
+
`${renderGateReport(result, { format: "junit" })}
|
|
10304
|
+
`,
|
|
10305
|
+
"utf-8"
|
|
10306
|
+
);
|
|
10307
|
+
await writeFile(
|
|
10308
|
+
paths.githubPath,
|
|
10309
|
+
`${renderGateReport(result, { format: "github" })}
|
|
10310
|
+
`,
|
|
10311
|
+
"utf-8"
|
|
10312
|
+
);
|
|
10313
|
+
return paths;
|
|
10314
|
+
}
|
|
10315
|
+
async function gateCommand(options = {}) {
|
|
10316
|
+
try {
|
|
10317
|
+
const format = options.format ?? (options.json ? "json" : "markdown");
|
|
10318
|
+
if (!SUPPORTED_FORMATS.has(format)) {
|
|
10319
|
+
if (options.json) {
|
|
10320
|
+
console.log(
|
|
10321
|
+
JSON.stringify({ ok: false, exitCode: 4, error: `Unsupported format: ${format}` }, null, 2)
|
|
10322
|
+
);
|
|
10323
|
+
} else {
|
|
10324
|
+
console.error(`[AgentInspect] Unsupported format: ${format}`);
|
|
10325
|
+
}
|
|
10326
|
+
process.exitCode = 4;
|
|
10327
|
+
return;
|
|
10328
|
+
}
|
|
10329
|
+
const gateOptions = {
|
|
10330
|
+
...options.dir !== void 0 ? { traceDir: resolveTraceDir({ dir: options.dir }) } : {},
|
|
10331
|
+
...options.suite !== void 0 ? { suitePath: options.suite } : {},
|
|
10332
|
+
...options.cwd !== void 0 ? { cwd: options.cwd } : {},
|
|
10333
|
+
...parseRate(options.maxErrorRate) !== void 0 ? { maxErrorRate: parseRate(options.maxErrorRate) } : {},
|
|
10334
|
+
...parseDuration2(options.maxP95Duration) !== void 0 ? { maxP95DurationMs: parseDuration2(options.maxP95Duration) } : {},
|
|
10335
|
+
forbidTools: collectList(options.forbidTool),
|
|
10336
|
+
requireObservations: collectList(options.requireObservation)
|
|
10337
|
+
};
|
|
10338
|
+
let runs = [];
|
|
10339
|
+
const needsRuns = gateHasThresholds(gateOptions) || gateOptions.traceDir !== void 0 && gateOptions.suitePath === void 0;
|
|
10340
|
+
if (needsRuns) {
|
|
10341
|
+
const traceDir = gateOptions.traceDir ?? resolveTraceDir({ dir: options.dir });
|
|
10342
|
+
const loaded = await loadSessionRuns(traceDir);
|
|
10343
|
+
runs = loaded.runs;
|
|
10344
|
+
gateOptions.traceDir = traceDir;
|
|
10345
|
+
}
|
|
10346
|
+
const result = await runGate(runs, gateOptions);
|
|
10347
|
+
let artifacts;
|
|
10348
|
+
if (options.output !== void 0 && options.output.trim() !== "") {
|
|
10349
|
+
artifacts = await writeArtifacts2(result, path12.resolve(options.output.trim()));
|
|
10350
|
+
}
|
|
10351
|
+
if (options.json || format === "json") {
|
|
10352
|
+
console.log(JSON.stringify({ ...result, artifacts: artifacts ?? null }, null, 2));
|
|
10353
|
+
} else if (format === "html") {
|
|
10354
|
+
console.log(renderGateReport(result, { format: "html" }));
|
|
10355
|
+
} else if (format === "junit") {
|
|
10356
|
+
console.log(renderGateReport(result, { format: "junit" }));
|
|
10357
|
+
} else if (format === "github") {
|
|
10358
|
+
console.log(renderGateReport(result, { format: "github" }));
|
|
10359
|
+
} else {
|
|
10360
|
+
console.log(renderGateReport(result, { format: "markdown" }));
|
|
10361
|
+
if (artifacts !== void 0) {
|
|
10362
|
+
console.log("");
|
|
10363
|
+
console.log("Artifacts:");
|
|
10364
|
+
for (const value of Object.values(artifacts)) console.log(`- ${value}`);
|
|
10365
|
+
}
|
|
10366
|
+
}
|
|
10367
|
+
process.exitCode = result.exitCode;
|
|
10368
|
+
} catch (error) {
|
|
10369
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
10370
|
+
if (options.json) {
|
|
10371
|
+
console.log(JSON.stringify({ ok: false, exitCode: 2, error: message }, null, 2));
|
|
10372
|
+
} else {
|
|
10373
|
+
console.error(`[AgentInspect] gate failed: ${message}`);
|
|
10374
|
+
}
|
|
10375
|
+
process.exitCode = 2;
|
|
10376
|
+
}
|
|
10377
|
+
}
|
|
10252
10378
|
|
|
10253
10379
|
// packages/cli/src/index.ts
|
|
10254
10380
|
function runCommand(action) {
|
|
@@ -10689,6 +10815,15 @@ function createCliProgram() {
|
|
|
10689
10815
|
).option("--format <format>", "markdown, json, or html", "markdown").option("-o, --output <dir>", "write cohort-results.json, cohort-summary.md, cohort-report.html").option("--json", "print deterministic JSON result").action((opts) => {
|
|
10690
10816
|
runCommand(() => cohortCommand(opts));
|
|
10691
10817
|
});
|
|
10818
|
+
program.command("gate").description("Run deterministic CI quality gates over traces or suites (v5.2+)").option("--dir <path>", "trace directory for threshold checks").option("--suite <path>", "suite config path").option("--max-error-rate <percent>", "maximum allowed error rate percentage").option("--max-p95-duration <ms>", "maximum allowed p95 run duration in ms").option("--forbid-tool <name>", "forbidden tool name (repeatable or comma-separated)").option(
|
|
10819
|
+
"--require-observation <name>",
|
|
10820
|
+
"required passed observation (repeatable or comma-separated)"
|
|
10821
|
+
).option("--format <format>", "markdown, json, html, junit, or github", "markdown").option(
|
|
10822
|
+
"-o, --output <dir>",
|
|
10823
|
+
"write gate-results.json, gate-summary.md, gate-report.html, junit.xml, github-step-summary.md"
|
|
10824
|
+
).option("--json", "print deterministic JSON result").action((opts) => {
|
|
10825
|
+
runCommand(() => gateCommand(opts));
|
|
10826
|
+
});
|
|
10692
10827
|
return program;
|
|
10693
10828
|
}
|
|
10694
10829
|
function isPrimaryModule() {
|