agent-inspect 4.2.0 → 4.4.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 +12 -0
- package/docs/API.md +3 -0
- package/docs/CLI.md +36 -0
- package/docs/SCHEMA.md +27 -1
- package/package.json +1 -1
- package/packages/cli/dist/{chunk-5VSPJEZ7.mjs → chunk-ORHDQUT6.mjs} +385 -10
- package/packages/cli/dist/chunk-ORHDQUT6.mjs.map +1 -0
- package/packages/cli/dist/index.cjs +2548 -1567
- package/packages/cli/dist/index.cjs.map +1 -1
- package/packages/cli/dist/index.mjs +2028 -1495
- package/packages/cli/dist/index.mjs.map +1 -1
- package/packages/cli/dist/{src-VQT7QLGV.mjs → src-FJOHPC4X.mjs} +3 -3
- package/packages/cli/dist/{src-VQT7QLGV.mjs.map → src-FJOHPC4X.mjs.map} +1 -1
- package/packages/core/dist/advanced.cjs +397 -12
- package/packages/core/dist/advanced.cjs.map +1 -1
- package/packages/core/dist/advanced.d.cts +105 -9
- package/packages/core/dist/advanced.d.ts +105 -9
- package/packages/core/dist/advanced.mjs +219 -17
- package/packages/core/dist/advanced.mjs.map +1 -1
- package/packages/core/dist/checks.cjs +117 -18
- package/packages/core/dist/checks.cjs.map +1 -1
- package/packages/core/dist/checks.d.cts +11 -3
- package/packages/core/dist/checks.d.ts +11 -3
- package/packages/core/dist/checks.mjs +42 -1
- package/packages/core/dist/checks.mjs.map +1 -1
- package/packages/core/dist/{chunk-2ZXEMWGK.mjs → chunk-3USJVBLA.mjs} +3 -3
- package/packages/core/dist/{chunk-2ZXEMWGK.mjs.map → chunk-3USJVBLA.mjs.map} +1 -1
- package/packages/core/dist/{chunk-HY7H3CQM.mjs → chunk-CAWPF22J.mjs} +4 -3
- package/packages/core/dist/chunk-CAWPF22J.mjs.map +1 -0
- package/packages/core/dist/{chunk-XUNJMAPD.mjs → chunk-KNYL56KZ.mjs} +38 -3
- package/packages/core/dist/chunk-KNYL56KZ.mjs.map +1 -0
- package/packages/core/dist/{chunk-IZBJAZGF.mjs → chunk-P366CCL2.mjs} +34 -3
- package/packages/core/dist/chunk-P366CCL2.mjs.map +1 -0
- package/packages/core/dist/{chunk-4JVGFNQH.mjs → chunk-ULCGIRTC.mjs} +95 -8
- package/packages/core/dist/chunk-ULCGIRTC.mjs.map +1 -0
- package/packages/core/dist/chunk-VFO76UH3.mjs +228 -0
- package/packages/core/dist/chunk-VFO76UH3.mjs.map +1 -0
- package/packages/core/dist/{chunk-NQZPZ2FN.mjs → chunk-WRE4CNPF.mjs} +6 -3
- package/packages/core/dist/chunk-WRE4CNPF.mjs.map +1 -0
- package/packages/core/dist/{chunk-A4V2H3YU.mjs → chunk-ZWA5RWMV.mjs} +40 -4
- package/packages/core/dist/chunk-ZWA5RWMV.mjs.map +1 -0
- package/packages/core/dist/{context-DjY-jvQk.d.cts → context-BbfkMYjz.d.cts} +5 -3
- package/packages/core/dist/{context-BDZmi53V.d.ts → context-Cp8NRbBX.d.ts} +5 -3
- package/packages/core/dist/diff.cjs.map +1 -1
- package/packages/core/dist/diff.d.cts +3 -3
- package/packages/core/dist/diff.d.ts +3 -3
- package/packages/core/dist/diff.mjs +1 -1
- package/packages/core/dist/exporters.cjs +137 -1
- package/packages/core/dist/exporters.cjs.map +1 -1
- package/packages/core/dist/exporters.d.cts +6 -3
- package/packages/core/dist/exporters.d.ts +6 -3
- package/packages/core/dist/exporters.mjs +71 -6
- package/packages/core/dist/exporters.mjs.map +1 -1
- package/packages/core/dist/index.cjs +181 -6
- package/packages/core/dist/index.cjs.map +1 -1
- package/packages/core/dist/index.d.cts +14 -7
- package/packages/core/dist/index.d.ts +14 -7
- package/packages/core/dist/index.mjs +51 -7
- package/packages/core/dist/index.mjs.map +1 -1
- package/packages/core/dist/{inspect-event-CYAV7Hxm.d.cts → inspect-event-IqwOHbGo.d.cts} +1 -1
- package/packages/core/dist/{inspect-event-CYAV7Hxm.d.ts → inspect-event-IqwOHbGo.d.ts} +1 -1
- package/packages/core/dist/{log-config-BNQ9UTmP.d.cts → log-config-CW8w5YQ9.d.cts} +1 -1
- package/packages/core/dist/{log-config-D3Yp1SZN.d.ts → log-config-SRA4xTp8.d.ts} +1 -1
- package/packages/core/dist/logs.d.cts +3 -3
- package/packages/core/dist/logs.d.ts +3 -3
- package/packages/core/dist/{persisted-inspect-event-BLvb0jSX.d.ts → persisted-inspect-event-DruwqARZ.d.ts} +1 -1
- package/packages/core/dist/{persisted-inspect-event-D5SjBz9b.d.cts → persisted-inspect-event-Gd-W8vB7.d.cts} +1 -1
- package/packages/core/dist/persisted.cjs +67 -1
- package/packages/core/dist/persisted.cjs.map +1 -1
- package/packages/core/dist/persisted.d.cts +5 -5
- package/packages/core/dist/persisted.d.ts +5 -5
- package/packages/core/dist/persisted.mjs +3 -3
- package/packages/core/dist/readers.cjs +72 -3
- package/packages/core/dist/readers.cjs.map +1 -1
- package/packages/core/dist/readers.d.cts +2 -2
- package/packages/core/dist/readers.d.ts +2 -2
- package/packages/core/dist/readers.mjs +5 -5
- package/packages/core/dist/readers.mjs.map +1 -1
- package/packages/core/dist/{types-CQun9LW6.d.ts → types-B1X87dUW.d.cts} +16 -2
- package/packages/core/dist/{types-C-llnPH0.d.cts → types-BVkjSd0q.d.ts} +16 -2
- package/packages/core/dist/types-CvsKGweN.d.cts +12 -0
- package/packages/core/dist/types-CvsKGweN.d.ts +12 -0
- package/packages/core/dist/writers.cjs +2 -1
- package/packages/core/dist/writers.cjs.map +1 -1
- package/packages/core/dist/writers.d.cts +2 -2
- package/packages/core/dist/writers.d.ts +2 -2
- package/packages/core/dist/writers.mjs +3 -4
- package/packages/core/dist/writers.mjs.map +1 -1
- package/packages/cli/dist/chunk-5VSPJEZ7.mjs.map +0 -1
- package/packages/core/dist/chunk-4JVGFNQH.mjs.map +0 -1
- package/packages/core/dist/chunk-A4V2H3YU.mjs.map +0 -1
- package/packages/core/dist/chunk-EDTQHZPM.mjs +0 -88
- package/packages/core/dist/chunk-EDTQHZPM.mjs.map +0 -1
- package/packages/core/dist/chunk-HY7H3CQM.mjs.map +0 -1
- package/packages/core/dist/chunk-IZBJAZGF.mjs.map +0 -1
- package/packages/core/dist/chunk-NQZPZ2FN.mjs.map +0 -1
- package/packages/core/dist/chunk-XUNJMAPD.mjs.map +0 -1
|
@@ -275,6 +275,9 @@ function isTraceEvent(value) {
|
|
|
275
275
|
case "step_completed": {
|
|
276
276
|
return typeof value.runId === "string" && typeof value.stepId === "string" && (value.status === "success" || value.status === "error") && typeof value.endTime === "number" && typeof value.durationMs === "number";
|
|
277
277
|
}
|
|
278
|
+
case "outcome_observed": {
|
|
279
|
+
return typeof value.runId === "string" && typeof value.outcomeId === "string" && typeof value.name === "string" && typeof value.expectation === "string" && (value.status === "passed" || value.status === "failed" || value.status === "unknown" || value.status === "skipped") && typeof value.observedAt === "number";
|
|
280
|
+
}
|
|
278
281
|
default:
|
|
279
282
|
return false;
|
|
280
283
|
}
|
|
@@ -292,7 +295,8 @@ var INSPECT_KINDS = [
|
|
|
292
295
|
"RESULT",
|
|
293
296
|
"ERROR",
|
|
294
297
|
"LOGIC",
|
|
295
|
-
"LOG"
|
|
298
|
+
"LOG",
|
|
299
|
+
"OUTCOME"
|
|
296
300
|
];
|
|
297
301
|
var ATTRIBUTION_CONFIDENCES = [
|
|
298
302
|
"explicit",
|
|
@@ -584,6 +588,32 @@ function fromLegacyStepCompleted(event) {
|
|
|
584
588
|
if (error) out.error = error;
|
|
585
589
|
return out;
|
|
586
590
|
}
|
|
591
|
+
function fromLegacyOutcomeObserved(event) {
|
|
592
|
+
const attrs = event.attributes ?? {};
|
|
593
|
+
const observedAtRaw = attrs.observedAt;
|
|
594
|
+
const observedAt = typeof observedAtRaw === "string" ? Date.parse(observedAtRaw) : typeof observedAtRaw === "number" && Number.isFinite(observedAtRaw) ? observedAtRaw : resolveTimes(event).timestamp;
|
|
595
|
+
const status = attrs.outcomeStatus;
|
|
596
|
+
const out = {
|
|
597
|
+
schemaVersion: "0.1",
|
|
598
|
+
event: "outcome_observed",
|
|
599
|
+
timestamp: observedAt,
|
|
600
|
+
runId: event.runId,
|
|
601
|
+
outcomeId: typeof attrs.outcomeId === "string" ? attrs.outcomeId : event.eventId,
|
|
602
|
+
name: event.name,
|
|
603
|
+
expectation: typeof attrs.expectation === "string" ? attrs.expectation : event.name,
|
|
604
|
+
status: status === "passed" || status === "failed" || status === "unknown" || status === "skipped" ? status : "unknown",
|
|
605
|
+
observedAt
|
|
606
|
+
};
|
|
607
|
+
if (event.parentId !== void 0) out.parentId = event.parentId;
|
|
608
|
+
if (typeof attrs.method === "string") out.method = attrs.method;
|
|
609
|
+
if (attrs.actual !== void 0) out.actual = attrs.actual;
|
|
610
|
+
if (event.outputSummary !== void 0) out.actual = event.outputSummary;
|
|
611
|
+
if (attrs.evidence !== void 0) out.evidence = attrs.evidence;
|
|
612
|
+
return out;
|
|
613
|
+
}
|
|
614
|
+
function fromNativeOutcome(event) {
|
|
615
|
+
return [fromLegacyOutcomeObserved(event)];
|
|
616
|
+
}
|
|
587
617
|
function fromNativeRun(event) {
|
|
588
618
|
const { timestamp, startTime, endTime } = resolveTimes(event);
|
|
589
619
|
const runStatus = mapPersistedStatusToRunStatus(event.status);
|
|
@@ -671,9 +701,13 @@ function persistedInspectEventToTraceEvents(event) {
|
|
|
671
701
|
if (legacyEvent === "run_completed") return [fromLegacyRunCompleted(event)];
|
|
672
702
|
if (legacyEvent === "step_started") return [fromLegacyStepStarted(event)];
|
|
673
703
|
if (legacyEvent === "step_completed") return [fromLegacyStepCompleted(event)];
|
|
704
|
+
if (legacyEvent === "outcome_observed") return [fromLegacyOutcomeObserved(event)];
|
|
674
705
|
if (event.kind === "RUN") {
|
|
675
706
|
return fromNativeRun(event);
|
|
676
707
|
}
|
|
708
|
+
if (event.kind === "OUTCOME") {
|
|
709
|
+
return fromNativeOutcome(event);
|
|
710
|
+
}
|
|
677
711
|
return fromNativeStep(event);
|
|
678
712
|
}
|
|
679
713
|
|
|
@@ -1012,6 +1046,9 @@ function validateEvent(event) {
|
|
|
1012
1046
|
case "step_completed": {
|
|
1013
1047
|
return nonEmptyString(event.runId) && nonEmptyString(event.stepId) && (event.status === "success" || event.status === "error") && finiteNumber(event.endTime) && finiteNumber(event.durationMs) && optionalErrorInfo(event.error);
|
|
1014
1048
|
}
|
|
1049
|
+
case "outcome_observed": {
|
|
1050
|
+
return nonEmptyString(event.runId) && nonEmptyString(event.outcomeId) && nonEmptyString(event.name) && nonEmptyString(event.expectation) && (event.status === "passed" || event.status === "failed" || event.status === "unknown" || event.status === "skipped") && finiteNumber(event.observedAt);
|
|
1051
|
+
}
|
|
1015
1052
|
default:
|
|
1016
1053
|
return false;
|
|
1017
1054
|
}
|
|
@@ -1956,9 +1993,111 @@ function createInspectorRuntime(options = {}) {
|
|
|
1956
1993
|
return runtime;
|
|
1957
1994
|
}
|
|
1958
1995
|
|
|
1996
|
+
// packages/core/src/outcomes/types.ts
|
|
1997
|
+
var OBSERVED_OUTCOME_STATUSES = [
|
|
1998
|
+
"passed",
|
|
1999
|
+
"failed",
|
|
2000
|
+
"unknown",
|
|
2001
|
+
"skipped"
|
|
2002
|
+
];
|
|
2003
|
+
var OBSERVED_OUTCOME_METHODS = [
|
|
2004
|
+
"dom",
|
|
2005
|
+
"accessibility",
|
|
2006
|
+
"snapshot",
|
|
2007
|
+
"network",
|
|
2008
|
+
"storage",
|
|
2009
|
+
"filesystem",
|
|
2010
|
+
"database",
|
|
2011
|
+
"queue",
|
|
2012
|
+
"custom"
|
|
2013
|
+
];
|
|
2014
|
+
var OUTCOME_LEGACY_EVENT = "outcome_observed";
|
|
2015
|
+
|
|
2016
|
+
// packages/core/src/outcomes/validate.ts
|
|
2017
|
+
function normalizeName(name) {
|
|
2018
|
+
const trimmed = name.trim();
|
|
2019
|
+
if (trimmed === "") {
|
|
2020
|
+
throw new Error("observeOutcome requires a non-empty name.");
|
|
2021
|
+
}
|
|
2022
|
+
return trimmed.slice(0, 100);
|
|
2023
|
+
}
|
|
2024
|
+
function normalizeExpectation(value) {
|
|
2025
|
+
const trimmed = value.trim();
|
|
2026
|
+
if (trimmed === "") {
|
|
2027
|
+
throw new Error("observeOutcome requires a non-empty expectation.");
|
|
2028
|
+
}
|
|
2029
|
+
return trimmed.slice(0, 500);
|
|
2030
|
+
}
|
|
2031
|
+
function parseObservedOutcomeStatus(value) {
|
|
2032
|
+
const trimmed = value.trim().toLowerCase();
|
|
2033
|
+
if (OBSERVED_OUTCOME_STATUSES.includes(trimmed)) {
|
|
2034
|
+
return trimmed;
|
|
2035
|
+
}
|
|
2036
|
+
throw new Error(
|
|
2037
|
+
`Unsupported observation status "${value}". Use passed, failed, unknown, or skipped.`
|
|
2038
|
+
);
|
|
2039
|
+
}
|
|
2040
|
+
function parseMethod(value) {
|
|
2041
|
+
if (value === void 0 || value.trim() === "") return void 0;
|
|
2042
|
+
const trimmed = value.trim().toLowerCase();
|
|
2043
|
+
if (OBSERVED_OUTCOME_METHODS.includes(trimmed)) {
|
|
2044
|
+
return trimmed;
|
|
2045
|
+
}
|
|
2046
|
+
throw new Error(`Unsupported observation method "${value}".`);
|
|
2047
|
+
}
|
|
2048
|
+
function parseObservedAt(value, fallback) {
|
|
2049
|
+
if (value === void 0) return fallback;
|
|
2050
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
2051
|
+
if (typeof value === "string") {
|
|
2052
|
+
const parsed = Date.parse(value);
|
|
2053
|
+
if (Number.isFinite(parsed)) return parsed;
|
|
2054
|
+
}
|
|
2055
|
+
return fallback;
|
|
2056
|
+
}
|
|
2057
|
+
function normalizeObserveOutcomeInput(name, options, nowMs = Date.now()) {
|
|
2058
|
+
return {
|
|
2059
|
+
name: normalizeName(name),
|
|
2060
|
+
expectation: normalizeExpectation(options.expectation),
|
|
2061
|
+
status: options.status,
|
|
2062
|
+
...options.method !== void 0 ? { method: parseMethod(options.method) } : {},
|
|
2063
|
+
...options.actual !== void 0 ? { actual: options.actual } : {},
|
|
2064
|
+
...options.evidence !== void 0 ? { evidence: options.evidence } : {},
|
|
2065
|
+
observedAt: parseObservedAt(options.observedAt, nowMs)
|
|
2066
|
+
};
|
|
2067
|
+
}
|
|
2068
|
+
|
|
2069
|
+
// packages/core/src/outcomes/extract.ts
|
|
2070
|
+
function fromOutcomeObservedEvent(event) {
|
|
2071
|
+
return {
|
|
2072
|
+
outcomeId: event.outcomeId,
|
|
2073
|
+
runId: event.runId,
|
|
2074
|
+
...event.parentId !== void 0 ? { parentId: event.parentId } : {},
|
|
2075
|
+
name: event.name,
|
|
2076
|
+
expectation: event.expectation,
|
|
2077
|
+
status: event.status,
|
|
2078
|
+
...event.method !== void 0 ? { method: event.method } : {},
|
|
2079
|
+
...event.actual !== void 0 ? { actual: event.actual } : {},
|
|
2080
|
+
...event.evidence !== void 0 ? { evidence: event.evidence } : {},
|
|
2081
|
+
observedAt: event.observedAt
|
|
2082
|
+
};
|
|
2083
|
+
}
|
|
2084
|
+
function extractOutcomesFromTraceEvents(events) {
|
|
2085
|
+
const out = [];
|
|
2086
|
+
for (const event of events) {
|
|
2087
|
+
if (event.event === OUTCOME_LEGACY_EVENT) {
|
|
2088
|
+
out.push(fromOutcomeObservedEvent(event));
|
|
2089
|
+
}
|
|
2090
|
+
}
|
|
2091
|
+
return out.sort((a, b) => a.observedAt - b.observedAt || a.name.localeCompare(b.name));
|
|
2092
|
+
}
|
|
2093
|
+
function parseObservationFilter(value) {
|
|
2094
|
+
if (value === void 0 || value.trim() === "") return void 0;
|
|
2095
|
+
return parseObservedOutcomeStatus(value);
|
|
2096
|
+
}
|
|
2097
|
+
|
|
1959
2098
|
// packages/core/src/inspector.ts
|
|
1960
2099
|
var INSPECTOR_PERSISTED_SCHEMA_VERSION = "1.0";
|
|
1961
|
-
function
|
|
2100
|
+
function normalizeName2(name, fallback) {
|
|
1962
2101
|
if (typeof name !== "string" || name.trim() === "") return fallback;
|
|
1963
2102
|
return truncateName(name.trim(), 100);
|
|
1964
2103
|
}
|
|
@@ -2059,7 +2198,7 @@ function createInspector(options = {}) {
|
|
|
2059
2198
|
if (options.enabled === false) {
|
|
2060
2199
|
return Promise.resolve(fn());
|
|
2061
2200
|
}
|
|
2062
|
-
const runName =
|
|
2201
|
+
const runName = normalizeName2(name, "unnamed-run");
|
|
2063
2202
|
const runId = runOptions.runId ?? createRunId();
|
|
2064
2203
|
const traceDir = runOptions.traceDir ?? options.traceDir ?? getDefaultTraceDir();
|
|
2065
2204
|
const metadata = mergeMetadata(options.metadata, runOptions.metadata);
|
|
@@ -2139,7 +2278,7 @@ function createInspector(options = {}) {
|
|
|
2139
2278
|
return Promise.resolve(fn());
|
|
2140
2279
|
}
|
|
2141
2280
|
const context = runtime.getCurrentContext();
|
|
2142
|
-
const stepName =
|
|
2281
|
+
const stepName = normalizeName2(name, "unnamed-step");
|
|
2143
2282
|
const stepId = createStepId();
|
|
2144
2283
|
const parentId = runtime.getCurrentStepId();
|
|
2145
2284
|
const stepType = stepOptions.type ?? "logic";
|
|
@@ -2219,7 +2358,7 @@ function createInspector(options = {}) {
|
|
|
2219
2358
|
run,
|
|
2220
2359
|
step,
|
|
2221
2360
|
tool(name, fn, toolOptions) {
|
|
2222
|
-
const toolName =
|
|
2361
|
+
const toolName = normalizeName2(name, "unknown-tool");
|
|
2223
2362
|
return step(`tool:${toolName}`, fn, {
|
|
2224
2363
|
...toolOptions,
|
|
2225
2364
|
type: "tool",
|
|
@@ -2230,7 +2369,7 @@ function createInspector(options = {}) {
|
|
|
2230
2369
|
});
|
|
2231
2370
|
},
|
|
2232
2371
|
llm(name, fn, llmOptions) {
|
|
2233
|
-
const model =
|
|
2372
|
+
const model = normalizeName2(name, "unknown-model");
|
|
2234
2373
|
return step(`llm:${model}`, fn, {
|
|
2235
2374
|
...llmOptions,
|
|
2236
2375
|
type: "llm",
|
|
@@ -2243,6 +2382,41 @@ function createInspector(options = {}) {
|
|
|
2243
2382
|
observe(name, fn, observeOptions) {
|
|
2244
2383
|
return async (...args) => step(name, () => Promise.resolve(fn(...args)), observeOptions);
|
|
2245
2384
|
},
|
|
2385
|
+
async observeOutcome(name, outcomeOptions) {
|
|
2386
|
+
const ctx = runtime.getCurrentContext();
|
|
2387
|
+
if (!ctx) return;
|
|
2388
|
+
let normalized;
|
|
2389
|
+
try {
|
|
2390
|
+
normalized = normalizeObserveOutcomeInput(name, outcomeOptions);
|
|
2391
|
+
} catch {
|
|
2392
|
+
return;
|
|
2393
|
+
}
|
|
2394
|
+
const outcomeId = createStepId();
|
|
2395
|
+
const parentId = runtime.getCurrentStepId();
|
|
2396
|
+
await write({
|
|
2397
|
+
schemaVersion: INSPECTOR_PERSISTED_SCHEMA_VERSION,
|
|
2398
|
+
eventId: outcomeId,
|
|
2399
|
+
runId: ctx.runId,
|
|
2400
|
+
...parentId !== void 0 ? { parentId } : {},
|
|
2401
|
+
kind: "OUTCOME",
|
|
2402
|
+
name: normalized.name,
|
|
2403
|
+
status: normalized.status === "failed" ? "error" : "ok",
|
|
2404
|
+
timestamp: new Date(normalized.observedAt).toISOString(),
|
|
2405
|
+
confidence: "explicit",
|
|
2406
|
+
source: { type: "manual", name: "createInspector" },
|
|
2407
|
+
attributes: {
|
|
2408
|
+
legacyEvent: "outcome_observed",
|
|
2409
|
+
outcomeId,
|
|
2410
|
+
outcomeStatus: normalized.status,
|
|
2411
|
+
expectation: normalized.expectation,
|
|
2412
|
+
...normalized.method !== void 0 ? { method: normalized.method } : {},
|
|
2413
|
+
...normalized.actual !== void 0 ? { actual: normalized.actual } : {},
|
|
2414
|
+
...normalized.evidence !== void 0 ? { evidence: normalized.evidence } : {},
|
|
2415
|
+
observedAt: new Date(normalized.observedAt).toISOString()
|
|
2416
|
+
},
|
|
2417
|
+
...normalized.actual !== void 0 ? { outputSummary: normalized.actual } : {}
|
|
2418
|
+
});
|
|
2419
|
+
},
|
|
2246
2420
|
getDiagnostics() {
|
|
2247
2421
|
return runtime.getDiagnostics();
|
|
2248
2422
|
},
|
|
@@ -3867,8 +4041,9 @@ async function searchTraces(metas, options) {
|
|
|
3867
4041
|
}
|
|
3868
4042
|
const limit = options.limit ?? 50;
|
|
3869
4043
|
const sessionId = options.session?.trim();
|
|
4044
|
+
const observationStatus = parseObservationFilter(options.observation);
|
|
3870
4045
|
const hasContentFilter = Boolean(
|
|
3871
|
-
options.status || stepTypeFilter || nameQuery || toolQuery || durationFilter
|
|
4046
|
+
options.status || stepTypeFilter || nameQuery || toolQuery || durationFilter || observationStatus
|
|
3872
4047
|
);
|
|
3873
4048
|
const results = [];
|
|
3874
4049
|
const sessionLabel = sessionId && sessionId !== "" ? sessionId : void 0;
|
|
@@ -3913,6 +4088,22 @@ async function searchTraces(metas, options) {
|
|
|
3913
4088
|
statusFilter: options.status
|
|
3914
4089
|
});
|
|
3915
4090
|
results.push(...stepMatches);
|
|
4091
|
+
if (observationStatus) {
|
|
4092
|
+
const outcomes = extractOutcomesFromTraceEvents(events);
|
|
4093
|
+
const matched = outcomes.filter((outcome) => outcome.status === observationStatus);
|
|
4094
|
+
for (const outcome of matched) {
|
|
4095
|
+
results.push({
|
|
4096
|
+
runId: m.runId,
|
|
4097
|
+
runName: m.name,
|
|
4098
|
+
runStatus: m.status,
|
|
4099
|
+
stepName: outcome.name,
|
|
4100
|
+
timestamp: outcome.observedAt,
|
|
4101
|
+
matchReason: `observation status=${outcome.status}`,
|
|
4102
|
+
matchedFields: ["outcome.status", "outcome.name"],
|
|
4103
|
+
filePath: m.filePath
|
|
4104
|
+
});
|
|
4105
|
+
}
|
|
4106
|
+
}
|
|
3916
4107
|
}
|
|
3917
4108
|
results.sort((a, b) => {
|
|
3918
4109
|
const ta = a.timestamp ?? 0;
|
|
@@ -4301,9 +4492,10 @@ function buildActivitySummary(index, options = {}) {
|
|
|
4301
4492
|
entries
|
|
4302
4493
|
};
|
|
4303
4494
|
}
|
|
4304
|
-
function renderActivitySummaryHuman(summary) {
|
|
4495
|
+
function renderActivitySummaryHuman(summary, options) {
|
|
4305
4496
|
const lines = [];
|
|
4306
|
-
const
|
|
4497
|
+
const nowMs = options?.nowMs ?? Date.now();
|
|
4498
|
+
const todayStart = new Date(nowMs);
|
|
4307
4499
|
todayStart.setHours(0, 0, 0, 0);
|
|
4308
4500
|
const todayMs = todayStart.getTime();
|
|
4309
4501
|
const today = summary.entries.filter(
|
|
@@ -4734,12 +4926,12 @@ function buildCriticalPath(runs, handoffs) {
|
|
|
4734
4926
|
handoffs.filter((edge) => edge.confidence === "explicit").map((edge) => edge.from)
|
|
4735
4927
|
);
|
|
4736
4928
|
const ordered = [...runs].sort(compareRuns);
|
|
4737
|
-
const
|
|
4929
|
+
const path6 = [];
|
|
4738
4930
|
const visited = /* @__PURE__ */ new Set();
|
|
4739
4931
|
const pushRun = (run, confidence, source) => {
|
|
4740
4932
|
if (visited.has(run.runId)) return;
|
|
4741
4933
|
visited.add(run.runId);
|
|
4742
|
-
|
|
4934
|
+
path6.push({
|
|
4743
4935
|
runId: run.runId,
|
|
4744
4936
|
name: run.name,
|
|
4745
4937
|
startedAt: run.startedAt,
|
|
@@ -4764,7 +4956,7 @@ function buildCriticalPath(runs, handoffs) {
|
|
|
4764
4956
|
const confidence = explicitTargets.has(run.runId) || explicitSources.has(run.runId) ? "explicit" : "correlated";
|
|
4765
4957
|
pushRun(run, confidence, confidence === "explicit" ? "manual" : "inferred");
|
|
4766
4958
|
}
|
|
4767
|
-
return
|
|
4959
|
+
return path6;
|
|
4768
4960
|
}
|
|
4769
4961
|
function metaRunIdMatches(run, token, runById) {
|
|
4770
4962
|
const meta = extractSessionWorkflowMetadata(run.metadata);
|
|
@@ -4884,6 +5076,190 @@ async function isAgentInspectTrace(filePath) {
|
|
|
4884
5076
|
}
|
|
4885
5077
|
}
|
|
4886
5078
|
|
|
5079
|
+
// packages/core/src/bundle/resolve.ts
|
|
5080
|
+
function parseSinceCutoff(since) {
|
|
5081
|
+
const trimmed = since.trim();
|
|
5082
|
+
if (trimmed === "") {
|
|
5083
|
+
throw new Error("--since requires a non-empty duration (e.g. 24h, 7d).");
|
|
5084
|
+
}
|
|
5085
|
+
return Date.now() - parseDuration(trimmed);
|
|
5086
|
+
}
|
|
5087
|
+
function runActivityMs(run) {
|
|
5088
|
+
if (run.startedAt !== void 0 && Number.isFinite(run.startedAt)) return run.startedAt;
|
|
5089
|
+
if (run.endedAt !== void 0 && Number.isFinite(run.endedAt)) return run.endedAt;
|
|
5090
|
+
return void 0;
|
|
5091
|
+
}
|
|
5092
|
+
function runsInSinceWindow(runs, since) {
|
|
5093
|
+
const cutoff = parseSinceCutoff(since);
|
|
5094
|
+
const ids = [];
|
|
5095
|
+
for (const run of runs) {
|
|
5096
|
+
const activity = runActivityMs(run);
|
|
5097
|
+
if (activity !== void 0 && activity >= cutoff) {
|
|
5098
|
+
ids.push(run.runId);
|
|
5099
|
+
}
|
|
5100
|
+
}
|
|
5101
|
+
return ids.sort((a, b) => a.localeCompare(b));
|
|
5102
|
+
}
|
|
5103
|
+
function findSession(index, sessionId) {
|
|
5104
|
+
return index.sessions.find((session) => session.sessionId === sessionId);
|
|
5105
|
+
}
|
|
5106
|
+
function resolveBundleRunIds(index, runs, options) {
|
|
5107
|
+
const runId = options.runId?.trim();
|
|
5108
|
+
const sessionId = options.sessionId?.trim();
|
|
5109
|
+
const since = options.since?.trim();
|
|
5110
|
+
const modes = [runId ? 1 : 0, sessionId ? 1 : 0, since ? 1 : 0].reduce((a, b) => a + b, 0);
|
|
5111
|
+
if (modes === 0) {
|
|
5112
|
+
throw new Error(
|
|
5113
|
+
"bundle requires a run id, --session <sessionId>, or --since <duration>."
|
|
5114
|
+
);
|
|
5115
|
+
}
|
|
5116
|
+
if (modes > 1) {
|
|
5117
|
+
throw new Error(
|
|
5118
|
+
"bundle accepts only one target: a run id, --session, or --since (not combined)."
|
|
5119
|
+
);
|
|
5120
|
+
}
|
|
5121
|
+
if (runId) {
|
|
5122
|
+
const known = runs.some((run) => run.runId === runId);
|
|
5123
|
+
if (!known) {
|
|
5124
|
+
throw new Error(`Run "${runId}" was not found in the trace directory.`);
|
|
5125
|
+
}
|
|
5126
|
+
return { runIds: [runId] };
|
|
5127
|
+
}
|
|
5128
|
+
if (sessionId) {
|
|
5129
|
+
const session = findSession(index, sessionId);
|
|
5130
|
+
if (!session) {
|
|
5131
|
+
throw new Error(`Session "${sessionId}" was not found.`);
|
|
5132
|
+
}
|
|
5133
|
+
if (session.runIds.length === 0) {
|
|
5134
|
+
throw new Error(`Session "${sessionId}" has no runs to bundle.`);
|
|
5135
|
+
}
|
|
5136
|
+
return {
|
|
5137
|
+
runIds: [...session.runIds].sort((a, b) => a.localeCompare(b)),
|
|
5138
|
+
sessionId
|
|
5139
|
+
};
|
|
5140
|
+
}
|
|
5141
|
+
const runIds = runsInSinceWindow(runs, since);
|
|
5142
|
+
if (runIds.length === 0) {
|
|
5143
|
+
throw new Error(`No runs matched --since ${since}.`);
|
|
5144
|
+
}
|
|
5145
|
+
return { runIds, since };
|
|
5146
|
+
}
|
|
5147
|
+
|
|
5148
|
+
// packages/core/src/bundle/safety-status.ts
|
|
5149
|
+
function aggregateBundleSafeStatus(statuses) {
|
|
5150
|
+
if (statuses.length === 0) return "UNKNOWN";
|
|
5151
|
+
if (statuses.some((status) => status === "UNSAFE")) return "UNSAFE";
|
|
5152
|
+
if (statuses.some((status) => status === "UNKNOWN")) return "UNKNOWN";
|
|
5153
|
+
if (statuses.some((status) => status === "SAFE WITH WARNINGS")) return "SAFE WITH WARNINGS";
|
|
5154
|
+
return "SAFE";
|
|
5155
|
+
}
|
|
5156
|
+
function toMetadataSafeStatus(status) {
|
|
5157
|
+
if (status === "SAFE WITH WARNINGS") return "SAFE_WITH_WARNINGS";
|
|
5158
|
+
return status;
|
|
5159
|
+
}
|
|
5160
|
+
function bundleFailsOnSafety(status, allowUnsafe) {
|
|
5161
|
+
if (allowUnsafe) return false;
|
|
5162
|
+
return status === "UNSAFE" || status === "UNKNOWN";
|
|
5163
|
+
}
|
|
5164
|
+
|
|
5165
|
+
// packages/core/src/bundle/manifest.ts
|
|
5166
|
+
var BUNDLE_NOTE = "Generated locally by AgentInspect. Bundles are derived copies for review \u2014 not compliance or security certification. Review before sharing.";
|
|
5167
|
+
var PLACEHOLDER_NOTE = "No eval or performance artifacts were requested for this bundle.";
|
|
5168
|
+
function buildBundleMetadata(parts) {
|
|
5169
|
+
const aggregate = aggregateBundleSafeStatus(
|
|
5170
|
+
parts.checks.runs.map((run) => run.status)
|
|
5171
|
+
);
|
|
5172
|
+
return {
|
|
5173
|
+
createdAt: parts.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
5174
|
+
agentInspectVersion: parts.agentInspectVersion,
|
|
5175
|
+
redactionProfile: parts.profile,
|
|
5176
|
+
sourceTraceCount: parts.resolve.runIds.length,
|
|
5177
|
+
runIds: [...parts.resolve.runIds],
|
|
5178
|
+
safeStatus: toMetadataSafeStatus(aggregate),
|
|
5179
|
+
files: [...parts.files].sort((a, b) => a.localeCompare(b)),
|
|
5180
|
+
note: BUNDLE_NOTE,
|
|
5181
|
+
...parts.resolve.sessionId !== void 0 ? { sessionId: parts.resolve.sessionId } : {},
|
|
5182
|
+
...parts.resolve.since !== void 0 ? { since: parts.resolve.since } : {}
|
|
5183
|
+
};
|
|
5184
|
+
}
|
|
5185
|
+
function buildPlaceholderArtifact() {
|
|
5186
|
+
return {
|
|
5187
|
+
status: "not_requested",
|
|
5188
|
+
note: PLACEHOLDER_NOTE
|
|
5189
|
+
};
|
|
5190
|
+
}
|
|
5191
|
+
|
|
5192
|
+
// packages/core/src/bundle/summary.ts
|
|
5193
|
+
function markdownTable(rows) {
|
|
5194
|
+
const lines = ["| Field | Value |", "| --- | --- |"];
|
|
5195
|
+
for (const [key, value] of rows) {
|
|
5196
|
+
lines.push(`| ${key} | ${value ?? "unknown"} |`);
|
|
5197
|
+
}
|
|
5198
|
+
return lines.join("\n");
|
|
5199
|
+
}
|
|
5200
|
+
function buildBundleSummaryMarkdown(parts) {
|
|
5201
|
+
const { metadata, checks, redaction } = parts;
|
|
5202
|
+
const lines = [
|
|
5203
|
+
"# AgentInspect trace bundle",
|
|
5204
|
+
"",
|
|
5205
|
+
metadata.note,
|
|
5206
|
+
"",
|
|
5207
|
+
"## Overview",
|
|
5208
|
+
"",
|
|
5209
|
+
markdownTable([
|
|
5210
|
+
["Created", metadata.createdAt],
|
|
5211
|
+
["AgentInspect", metadata.agentInspectVersion],
|
|
5212
|
+
["Redaction profile", metadata.redactionProfile],
|
|
5213
|
+
["Safe status", metadata.safeStatus],
|
|
5214
|
+
["Source traces", metadata.sourceTraceCount],
|
|
5215
|
+
["Runs", metadata.runIds.join(", ")],
|
|
5216
|
+
...metadata.sessionId ? [["Session", metadata.sessionId]] : [],
|
|
5217
|
+
...metadata.since ? [["Since", metadata.since]] : []
|
|
5218
|
+
]),
|
|
5219
|
+
"",
|
|
5220
|
+
"## Safety checks",
|
|
5221
|
+
"",
|
|
5222
|
+
`Aggregate: **${checks.aggregateStatus}**`,
|
|
5223
|
+
""
|
|
5224
|
+
];
|
|
5225
|
+
for (const run of checks.runs) {
|
|
5226
|
+
lines.push(
|
|
5227
|
+
`- \`${run.runId}\`: ${run.status} (${run.findings} finding(s), ${run.errors} error(s), ${run.warnings} warning(s))`
|
|
5228
|
+
);
|
|
5229
|
+
}
|
|
5230
|
+
lines.push("", "## Redaction", "", `Total findings: ${redaction.totalFindings}`, "");
|
|
5231
|
+
for (const run of redaction.runs) {
|
|
5232
|
+
const detectors = run.detectors.length > 0 ? run.detectors.join(", ") : "none";
|
|
5233
|
+
lines.push(`- \`${run.runId}\`: ${run.findings} finding(s); detectors: ${detectors}`);
|
|
5234
|
+
}
|
|
5235
|
+
lines.push(
|
|
5236
|
+
"",
|
|
5237
|
+
"## Files",
|
|
5238
|
+
"",
|
|
5239
|
+
...metadata.files.map((file) => `- \`${file}\``),
|
|
5240
|
+
"",
|
|
5241
|
+
"_Review every generated artifact before sharing outside your team._",
|
|
5242
|
+
""
|
|
5243
|
+
);
|
|
5244
|
+
return lines.join("\n");
|
|
5245
|
+
}
|
|
5246
|
+
function normalizeBundleOutputPath(out) {
|
|
5247
|
+
const trimmed = out.trim();
|
|
5248
|
+
if (trimmed === "") {
|
|
5249
|
+
throw new Error("--out requires a non-empty path.");
|
|
5250
|
+
}
|
|
5251
|
+
const resolved = path__default.default.resolve(trimmed);
|
|
5252
|
+
if (resolved.toLowerCase().endsWith(".zip")) {
|
|
5253
|
+
return resolved.slice(0, -4);
|
|
5254
|
+
}
|
|
5255
|
+
return resolved;
|
|
5256
|
+
}
|
|
5257
|
+
function defaultBundleOutputPath(runIds) {
|
|
5258
|
+
const label = runIds.length === 1 ? runIds[0] : `multi-${runIds.length}`;
|
|
5259
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
5260
|
+
return path__default.default.resolve(`agent-inspect-bundle-${label}-${stamp}`);
|
|
5261
|
+
}
|
|
5262
|
+
|
|
4887
5263
|
// packages/core/src/inspect-run.ts
|
|
4888
5264
|
function normalizeRunName(name) {
|
|
4889
5265
|
if (typeof name !== "string" || name.trim() === "") {
|
|
@@ -5026,18 +5402,24 @@ exports.RUNS_DIR_NAME = RUNS_DIR_NAME;
|
|
|
5026
5402
|
exports.SESSION_WORKFLOW_KEYS = SESSION_WORKFLOW_KEYS;
|
|
5027
5403
|
exports.TERMINAL_INDENT = TERMINAL_INDENT;
|
|
5028
5404
|
exports.TraceDirectory = TraceDirectory;
|
|
5405
|
+
exports.aggregateBundleSafeStatus = aggregateBundleSafeStatus;
|
|
5029
5406
|
exports.aggregateSessionCheckResults = aggregateSessionCheckResults;
|
|
5030
5407
|
exports.buildActivitySummary = buildActivitySummary;
|
|
5408
|
+
exports.buildBundleMetadata = buildBundleMetadata;
|
|
5409
|
+
exports.buildBundleSummaryMarkdown = buildBundleSummaryMarkdown;
|
|
5031
5410
|
exports.buildLocalExplanation = buildLocalExplanation;
|
|
5411
|
+
exports.buildPlaceholderArtifact = buildPlaceholderArtifact;
|
|
5032
5412
|
exports.buildRunSummary = buildRunSummary;
|
|
5033
5413
|
exports.buildRunTimeline = buildRunTimeline;
|
|
5034
5414
|
exports.buildRunWhatSummary = buildRunWhatSummary;
|
|
5035
5415
|
exports.buildSessionIndex = buildSessionIndex;
|
|
5036
5416
|
exports.buildTraceStats = buildTraceStats;
|
|
5417
|
+
exports.bundleFailsOnSafety = bundleFailsOnSafety;
|
|
5037
5418
|
exports.createInspector = createInspector;
|
|
5038
5419
|
exports.createInspectorRuntime = createInspectorRuntime;
|
|
5039
5420
|
exports.createRunId = createRunId;
|
|
5040
5421
|
exports.createStepId = createStepId;
|
|
5422
|
+
exports.defaultBundleOutputPath = defaultBundleOutputPath;
|
|
5041
5423
|
exports.deriveSessionStatus = deriveSessionStatus;
|
|
5042
5424
|
exports.enrichSessionRunRecord = enrichSessionRunRecord;
|
|
5043
5425
|
exports.enrichSessionSummary = enrichSessionSummary;
|
|
@@ -5076,6 +5458,7 @@ exports.listTraceFiles = listTraceFiles;
|
|
|
5076
5458
|
exports.loadSessionRunRecords = loadSessionRunRecords;
|
|
5077
5459
|
exports.loadTraceMetadataList = loadTraceMetadataList;
|
|
5078
5460
|
exports.maybeInspectRun = maybeInspectRun;
|
|
5461
|
+
exports.normalizeBundleOutputPath = normalizeBundleOutputPath;
|
|
5079
5462
|
exports.parseDuration = parseDuration;
|
|
5080
5463
|
exports.parseDurationFilter = parseDurationFilter;
|
|
5081
5464
|
exports.parseTraceJsonl = parseTraceJsonl;
|
|
@@ -5096,6 +5479,7 @@ exports.renderRunWhat = renderRunWhat;
|
|
|
5096
5479
|
exports.renderStepLine = renderStepLine;
|
|
5097
5480
|
exports.renderTimeline = renderTimeline;
|
|
5098
5481
|
exports.renderTraceStats = renderTraceStats;
|
|
5482
|
+
exports.resolveBundleRunIds = resolveBundleRunIds;
|
|
5099
5483
|
exports.resolveRedactionProfile = resolveRedactionProfile;
|
|
5100
5484
|
exports.resolveTraceDir = resolveTraceDir;
|
|
5101
5485
|
exports.resolveTraceSafetyOptions = resolveTraceSafetyOptions;
|
|
@@ -5104,6 +5488,7 @@ exports.runWithStepContext = runWithStepContext;
|
|
|
5104
5488
|
exports.searchTraces = searchTraces;
|
|
5105
5489
|
exports.serializeEvent = serializeEvent;
|
|
5106
5490
|
exports.sessionKeyForRun = sessionKeyForRun;
|
|
5491
|
+
exports.toMetadataSafeStatus = toMetadataSafeStatus;
|
|
5107
5492
|
exports.traceMetasToSessionRunRecords = traceMetasToSessionRunRecords;
|
|
5108
5493
|
exports.truncateName = truncateName;
|
|
5109
5494
|
exports.unknownTraceFormatMessage = unknownTraceFormatMessage;
|