agent-inspect 6.30.0 → 6.31.1
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/README.md +1 -1
- package/docs/COMPARE.md +1 -1
- package/docs/FIRST-TRACE-IN-5-MINUTES.md +21 -17
- package/docs/GETTING-STARTED.md +1 -1
- package/docs/TRACE-CONTRACTS.md +25 -0
- package/package.json +4 -2
- package/packages/cli/dist/{chunk-BDRJENLM.mjs → chunk-SJ6FRNOE.mjs} +201 -49
- package/packages/cli/dist/chunk-SJ6FRNOE.mjs.map +1 -0
- package/packages/cli/dist/index.cjs +288 -50
- package/packages/cli/dist/index.cjs.map +1 -1
- package/packages/cli/dist/index.mjs +91 -5
- package/packages/cli/dist/index.mjs.map +1 -1
- package/packages/cli/dist/{src-ZUGAUXY6.mjs → src-YNEJOPRA.mjs} +3 -3
- package/packages/cli/dist/{src-ZUGAUXY6.mjs.map → src-YNEJOPRA.mjs.map} +1 -1
- package/packages/core/dist/advanced.cjs +39 -1
- package/packages/core/dist/advanced.cjs.map +1 -1
- package/packages/core/dist/advanced.d.cts +2 -2
- package/packages/core/dist/advanced.d.ts +2 -2
- package/packages/core/dist/advanced.mjs +2 -2
- package/packages/core/dist/checks.cjs +207 -47
- package/packages/core/dist/checks.cjs.map +1 -1
- package/packages/core/dist/checks.d.cts +2 -2
- package/packages/core/dist/checks.d.ts +2 -2
- package/packages/core/dist/checks.mjs +1 -1
- package/packages/core/dist/{chunk-OOX25GTH.mjs → chunk-CBPWLHNQ.mjs} +209 -50
- package/packages/core/dist/{chunk-OOX25GTH.mjs.map → chunk-CBPWLHNQ.mjs.map} +1 -1
- package/packages/core/dist/{index-7hG_qggp.d.ts → index-CgOAGuM5.d.ts} +111 -1
- package/packages/core/dist/{index-CQJUNPPe.d.cts → index-EQihlEei.d.cts} +111 -1
- package/packages/cli/dist/chunk-BDRJENLM.mjs.map +0 -1
|
@@ -5700,6 +5700,31 @@ function failFinding(ruleId, message, evidence, expected, actual, meta2) {
|
|
|
5700
5700
|
function toolName(event) {
|
|
5701
5701
|
return resolveCanonicalToolName(event);
|
|
5702
5702
|
}
|
|
5703
|
+
function stepEndpointName(event, kind) {
|
|
5704
|
+
if (kind === "TOOL") return resolveCanonicalToolName(event);
|
|
5705
|
+
for (const prefix of ["llm:", "generation:", "transcription:", "speech:"]) {
|
|
5706
|
+
if (event.name.startsWith(prefix)) return event.name.slice(prefix.length);
|
|
5707
|
+
}
|
|
5708
|
+
return event.name;
|
|
5709
|
+
}
|
|
5710
|
+
function formatStepEndpoint(endpoint) {
|
|
5711
|
+
return `${endpoint.kind} ${endpoint.name}`;
|
|
5712
|
+
}
|
|
5713
|
+
function otherKindsForStepName(context, expectedKind, name) {
|
|
5714
|
+
return [
|
|
5715
|
+
...new Set(
|
|
5716
|
+
semanticEvents(context).filter((event) => {
|
|
5717
|
+
const kind = typeof event.kind === "string" ? event.kind.toUpperCase() : "";
|
|
5718
|
+
if (kind === expectedKind) return false;
|
|
5719
|
+
if (kind === "TOOL") return resolveCanonicalToolName(event) === name;
|
|
5720
|
+
if (kind === "LLM") return stepEndpointName(event, "LLM") === name;
|
|
5721
|
+
return event.name === name || event.name === `tool:${name}` || event.name === `llm:${name}` || event.name.endsWith(`:${name}`);
|
|
5722
|
+
}).map(
|
|
5723
|
+
(event) => typeof event.kind === "string" ? event.kind.toUpperCase() : "UNKNOWN"
|
|
5724
|
+
)
|
|
5725
|
+
)
|
|
5726
|
+
].sort();
|
|
5727
|
+
}
|
|
5703
5728
|
function semanticEvents(context) {
|
|
5704
5729
|
return context.logicalEvents ?? context.events;
|
|
5705
5730
|
}
|
|
@@ -5726,14 +5751,6 @@ function finishedEvents(context, kind) {
|
|
|
5726
5751
|
function toolInvocationEvents(context) {
|
|
5727
5752
|
return semanticEvents(context).filter((event) => event.kind === "TOOL");
|
|
5728
5753
|
}
|
|
5729
|
-
function firstIndexByName(events) {
|
|
5730
|
-
const index = /* @__PURE__ */ new Map();
|
|
5731
|
-
for (const [position, event] of events.entries()) {
|
|
5732
|
-
const name = toolName(event);
|
|
5733
|
-
if (!index.has(name)) index.set(name, position);
|
|
5734
|
-
}
|
|
5735
|
-
return index;
|
|
5736
|
-
}
|
|
5737
5754
|
function isRecord9(value) {
|
|
5738
5755
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5739
5756
|
}
|
|
@@ -6204,18 +6221,85 @@ function createToolUsageRule(options) {
|
|
|
6204
6221
|
}
|
|
6205
6222
|
};
|
|
6206
6223
|
}
|
|
6207
|
-
function
|
|
6208
|
-
const
|
|
6224
|
+
function createStepOrderingRule(options) {
|
|
6225
|
+
const bothTools = options.before.kind === "TOOL" && options.after.kind === "TOOL";
|
|
6226
|
+
const ruleId = options.id ?? (bothTools ? "tool.order" : "step.order");
|
|
6209
6227
|
const mode = options.mode ?? "first-occurrence";
|
|
6228
|
+
const requireEndpoints = options.requireEndpoints === true;
|
|
6229
|
+
const beforeLabel = bothTools ? options.before.name : formatStepEndpoint(options.before);
|
|
6230
|
+
const afterLabel = bothTools ? options.after.name : formatStepEndpoint(options.after);
|
|
6231
|
+
const subject = bothTools ? "Tool" : "Step";
|
|
6210
6232
|
return {
|
|
6211
6233
|
id: ruleId,
|
|
6212
|
-
category: "tool",
|
|
6234
|
+
category: bothTools ? "tool" : "structure",
|
|
6213
6235
|
defaultSeverity: "error",
|
|
6214
6236
|
evaluate(context) {
|
|
6215
|
-
const
|
|
6216
|
-
|
|
6217
|
-
|
|
6218
|
-
const
|
|
6237
|
+
const beforeEvents = finishedEvents(context, options.before.kind).filter(
|
|
6238
|
+
(event) => stepEndpointName(event, options.before.kind) === options.before.name
|
|
6239
|
+
);
|
|
6240
|
+
const afterEvents = finishedEvents(context, options.after.kind).filter(
|
|
6241
|
+
(event) => stepEndpointName(event, options.after.kind) === options.after.name
|
|
6242
|
+
);
|
|
6243
|
+
if (beforeEvents.length === 0 || afterEvents.length === 0) {
|
|
6244
|
+
if (!requireEndpoints) return [];
|
|
6245
|
+
const findings = [];
|
|
6246
|
+
if (beforeEvents.length === 0) {
|
|
6247
|
+
const otherKinds = otherKindsForStepName(
|
|
6248
|
+
context,
|
|
6249
|
+
options.before.kind,
|
|
6250
|
+
options.before.name
|
|
6251
|
+
);
|
|
6252
|
+
const hint = otherKinds.length > 0 ? ` Required name appears under non-${options.before.kind} kind(s): ${otherKinds.join(", ")}.` : "";
|
|
6253
|
+
findings.push(
|
|
6254
|
+
failFinding(
|
|
6255
|
+
ruleId,
|
|
6256
|
+
`Required ${formatStepEndpoint(options.before)} did not appear.${hint}`,
|
|
6257
|
+
runEvidence(context.selectedRun),
|
|
6258
|
+
options.before,
|
|
6259
|
+
{
|
|
6260
|
+
code: bothTools ? "tool.order.missing-endpoint" : "step.order.missing-endpoint",
|
|
6261
|
+
endpoint: "before",
|
|
6262
|
+
otherKinds
|
|
6263
|
+
}
|
|
6264
|
+
)
|
|
6265
|
+
);
|
|
6266
|
+
}
|
|
6267
|
+
if (afterEvents.length === 0) {
|
|
6268
|
+
const otherKinds = otherKindsForStepName(
|
|
6269
|
+
context,
|
|
6270
|
+
options.after.kind,
|
|
6271
|
+
options.after.name
|
|
6272
|
+
);
|
|
6273
|
+
const hint = otherKinds.length > 0 ? ` Required name appears under non-${options.after.kind} kind(s): ${otherKinds.join(", ")}.` : "";
|
|
6274
|
+
findings.push(
|
|
6275
|
+
failFinding(
|
|
6276
|
+
ruleId,
|
|
6277
|
+
`Required ${formatStepEndpoint(options.after)} did not appear.${hint}`,
|
|
6278
|
+
runEvidence(context.selectedRun),
|
|
6279
|
+
options.after,
|
|
6280
|
+
{
|
|
6281
|
+
code: bothTools ? "tool.order.missing-endpoint" : "step.order.missing-endpoint",
|
|
6282
|
+
endpoint: "after",
|
|
6283
|
+
otherKinds
|
|
6284
|
+
}
|
|
6285
|
+
)
|
|
6286
|
+
);
|
|
6287
|
+
}
|
|
6288
|
+
return findings;
|
|
6289
|
+
}
|
|
6290
|
+
const encounter = finishedEvents(context).filter(
|
|
6291
|
+
(event) => event.kind === options.before.kind && stepEndpointName(event, options.before.kind) === options.before.name || event.kind === options.after.kind && stepEndpointName(event, options.after.kind) === options.after.name
|
|
6292
|
+
);
|
|
6293
|
+
let beforeIndex;
|
|
6294
|
+
let afterIndex;
|
|
6295
|
+
for (const [position, event] of encounter.entries()) {
|
|
6296
|
+
if (beforeIndex === void 0 && event.kind === options.before.kind && stepEndpointName(event, options.before.kind) === options.before.name) {
|
|
6297
|
+
beforeIndex = position;
|
|
6298
|
+
}
|
|
6299
|
+
if (afterIndex === void 0 && event.kind === options.after.kind && stepEndpointName(event, options.after.kind) === options.after.name) {
|
|
6300
|
+
afterIndex = position;
|
|
6301
|
+
}
|
|
6302
|
+
}
|
|
6219
6303
|
if (beforeIndex === void 0 || afterIndex === void 0) {
|
|
6220
6304
|
return [];
|
|
6221
6305
|
}
|
|
@@ -6223,32 +6307,37 @@ function createToolOrderingRule(options) {
|
|
|
6223
6307
|
return [
|
|
6224
6308
|
failFinding(
|
|
6225
6309
|
ruleId,
|
|
6226
|
-
|
|
6227
|
-
[
|
|
6228
|
-
|
|
6229
|
-
|
|
6310
|
+
`${subject} ${beforeLabel} must appear before ${afterLabel}.`,
|
|
6311
|
+
[
|
|
6312
|
+
eventEvidence(encounter[beforeIndex]),
|
|
6313
|
+
eventEvidence(encounter[afterIndex])
|
|
6314
|
+
],
|
|
6315
|
+
bothTools ? { before: options.before.name, after: options.after.name } : { before: options.before, after: options.after },
|
|
6316
|
+
bothTools ? finishedEvents(context, "TOOL").map(toolName) : encounter.map(
|
|
6317
|
+
(event) => event.kind === "TOOL" || event.kind === "LLM" ? `${event.kind}:${stepEndpointName(event, event.kind)}` : event.name
|
|
6318
|
+
)
|
|
6230
6319
|
)
|
|
6231
6320
|
];
|
|
6232
6321
|
}
|
|
6233
|
-
const beforeEvent =
|
|
6234
|
-
const afterEvent =
|
|
6322
|
+
const beforeEvent = beforeEvents[0];
|
|
6323
|
+
const afterEvent = afterEvents[0];
|
|
6235
6324
|
const beforeEnd = eventEndMs(beforeEvent);
|
|
6236
6325
|
const afterStart = eventStartMs(afterEvent);
|
|
6326
|
+
const endpointExpected = bothTools ? { before: options.before.name, after: options.after.name } : { before: options.before, after: options.after };
|
|
6237
6327
|
if (mode === "happens-before") {
|
|
6238
6328
|
const expected = {
|
|
6239
|
-
|
|
6240
|
-
after: options.after,
|
|
6329
|
+
...endpointExpected,
|
|
6241
6330
|
mode,
|
|
6242
6331
|
relation: "before.end <= after.start"
|
|
6243
6332
|
};
|
|
6244
|
-
if (options.before === options.after) {
|
|
6333
|
+
if (options.before.kind === options.after.kind && options.before.name === options.after.name) {
|
|
6245
6334
|
return [
|
|
6246
6335
|
failFinding(
|
|
6247
6336
|
ruleId,
|
|
6248
|
-
|
|
6337
|
+
`${subject} ${beforeLabel} cannot causally happen before itself.`,
|
|
6249
6338
|
[eventEvidence(beforeEvent)],
|
|
6250
6339
|
expected,
|
|
6251
|
-
{ code: "tool.order.same-tool" }
|
|
6340
|
+
{ code: bothTools ? "tool.order.same-tool" : "step.order.same-step" }
|
|
6252
6341
|
)
|
|
6253
6342
|
];
|
|
6254
6343
|
}
|
|
@@ -6256,11 +6345,11 @@ function createToolOrderingRule(options) {
|
|
|
6256
6345
|
return [
|
|
6257
6346
|
failFinding(
|
|
6258
6347
|
ruleId,
|
|
6259
|
-
|
|
6348
|
+
`${subject} order ${beforeLabel} before ${afterLabel} could not establish causal timing.`,
|
|
6260
6349
|
[eventEvidence(beforeEvent), eventEvidence(afterEvent)],
|
|
6261
6350
|
expected,
|
|
6262
6351
|
{
|
|
6263
|
-
code: "tool.order.interval-unresolved",
|
|
6352
|
+
code: bothTools ? "tool.order.interval-unresolved" : "step.order.interval-unresolved",
|
|
6264
6353
|
beforeEndResolved: beforeEnd !== void 0,
|
|
6265
6354
|
afterStartResolved: afterStart !== void 0
|
|
6266
6355
|
}
|
|
@@ -6271,7 +6360,7 @@ function createToolOrderingRule(options) {
|
|
|
6271
6360
|
return [
|
|
6272
6361
|
failFinding(
|
|
6273
6362
|
ruleId,
|
|
6274
|
-
|
|
6363
|
+
`${subject} ${beforeLabel} must finish before ${afterLabel} starts.`,
|
|
6275
6364
|
[eventEvidence(beforeEvent), eventEvidence(afterEvent)],
|
|
6276
6365
|
expected,
|
|
6277
6366
|
{
|
|
@@ -6284,22 +6373,19 @@ function createToolOrderingRule(options) {
|
|
|
6284
6373
|
return [];
|
|
6285
6374
|
}
|
|
6286
6375
|
if (mode === "all-occurrences") {
|
|
6287
|
-
const beforeEvents = tools.filter((event) => toolName(event) === options.before);
|
|
6288
|
-
const afterEvents = tools.filter((event) => toolName(event) === options.after);
|
|
6289
6376
|
const expected = {
|
|
6290
|
-
|
|
6291
|
-
after: options.after,
|
|
6377
|
+
...endpointExpected,
|
|
6292
6378
|
mode,
|
|
6293
6379
|
relation: "max(before.end) <= min(after.start)"
|
|
6294
6380
|
};
|
|
6295
|
-
if (options.before === options.after) {
|
|
6381
|
+
if (options.before.kind === options.after.kind && options.before.name === options.after.name) {
|
|
6296
6382
|
return [
|
|
6297
6383
|
failFinding(
|
|
6298
6384
|
ruleId,
|
|
6299
|
-
|
|
6385
|
+
`${subject} ${beforeLabel} cannot causally happen before itself.`,
|
|
6300
6386
|
[eventEvidence(beforeEvent)],
|
|
6301
6387
|
expected,
|
|
6302
|
-
{ code: "tool.order.same-tool" }
|
|
6388
|
+
{ code: bothTools ? "tool.order.same-tool" : "step.order.same-step" }
|
|
6303
6389
|
)
|
|
6304
6390
|
];
|
|
6305
6391
|
}
|
|
@@ -6331,11 +6417,11 @@ function createToolOrderingRule(options) {
|
|
|
6331
6417
|
return [
|
|
6332
6418
|
failFinding(
|
|
6333
6419
|
ruleId,
|
|
6334
|
-
|
|
6420
|
+
`${subject} order ${beforeLabel} before ${afterLabel} could not establish all causal intervals.`,
|
|
6335
6421
|
[firstMissingBefore, firstMissingAfter].filter((event) => event !== void 0).map((event) => eventEvidence(event)),
|
|
6336
6422
|
expected,
|
|
6337
6423
|
{
|
|
6338
|
-
code: "tool.order.interval-unresolved",
|
|
6424
|
+
code: bothTools ? "tool.order.interval-unresolved" : "step.order.interval-unresolved",
|
|
6339
6425
|
missingBeforeEnds,
|
|
6340
6426
|
missingAfterStarts
|
|
6341
6427
|
}
|
|
@@ -6346,7 +6432,7 @@ function createToolOrderingRule(options) {
|
|
|
6346
6432
|
return [
|
|
6347
6433
|
failFinding(
|
|
6348
6434
|
ruleId,
|
|
6349
|
-
`Every ${options.before} tool call must finish before any ${options.after} tool call starts.`,
|
|
6435
|
+
bothTools ? `Every ${options.before.name} tool call must finish before any ${options.after.name} tool call starts.` : `Every ${beforeLabel} must finish before any ${afterLabel} starts.`,
|
|
6350
6436
|
[eventEvidence(latestBefore.event), eventEvidence(earliestAfter.event)],
|
|
6351
6437
|
expected,
|
|
6352
6438
|
{
|
|
@@ -6364,10 +6450,13 @@ function createToolOrderingRule(options) {
|
|
|
6364
6450
|
ruleId,
|
|
6365
6451
|
severity: "warning",
|
|
6366
6452
|
status: "warning",
|
|
6367
|
-
message:
|
|
6368
|
-
expected: {
|
|
6453
|
+
message: `${subject} order ${beforeLabel} before ${afterLabel} satisfied start/encounter order, but intervals overlap so causal completion before the next ${bothTools ? "tool" : "step"} was not established.`,
|
|
6454
|
+
expected: {
|
|
6455
|
+
...endpointExpected,
|
|
6456
|
+
mode: "first-occurrence"
|
|
6457
|
+
},
|
|
6369
6458
|
actual: {
|
|
6370
|
-
code: "tool.order.overlap",
|
|
6459
|
+
code: bothTools ? "tool.order.overlap" : "step.order.overlap",
|
|
6371
6460
|
beforeEndedAt: beforeEvent.endedAt,
|
|
6372
6461
|
afterStartedAt: afterEvent.startedAt ?? afterEvent.timestamp
|
|
6373
6462
|
},
|
|
@@ -6379,6 +6468,15 @@ function createToolOrderingRule(options) {
|
|
|
6379
6468
|
}
|
|
6380
6469
|
};
|
|
6381
6470
|
}
|
|
6471
|
+
function createToolOrderingRule(options) {
|
|
6472
|
+
return createStepOrderingRule({
|
|
6473
|
+
before: { kind: "TOOL", name: options.before },
|
|
6474
|
+
after: { kind: "TOOL", name: options.after },
|
|
6475
|
+
...options.id !== void 0 ? { id: options.id } : {},
|
|
6476
|
+
...options.mode !== void 0 ? { mode: options.mode } : {},
|
|
6477
|
+
requireEndpoints: false
|
|
6478
|
+
});
|
|
6479
|
+
}
|
|
6382
6480
|
function createLlmUsageRule(options) {
|
|
6383
6481
|
return {
|
|
6384
6482
|
id: "llm.usage",
|
|
@@ -8640,11 +8738,33 @@ function contractFailFinding(ruleId, message, evidence, expected, actual) {
|
|
|
8640
8738
|
evidence: [...evidence]
|
|
8641
8739
|
};
|
|
8642
8740
|
}
|
|
8741
|
+
function parseAllowedStatus(status) {
|
|
8742
|
+
return ALLOWED_STATUS_ALIASES[status];
|
|
8743
|
+
}
|
|
8643
8744
|
function normalizeStatus(status) {
|
|
8644
|
-
|
|
8645
|
-
if (
|
|
8646
|
-
|
|
8647
|
-
|
|
8745
|
+
const parsed = parseAllowedStatus(status);
|
|
8746
|
+
if (parsed === void 0) {
|
|
8747
|
+
throw new TypeError(
|
|
8748
|
+
`Unknown run status ${JSON.stringify(status)}. Allowed: ok, error, running (aliases: success, failed).`
|
|
8749
|
+
);
|
|
8750
|
+
}
|
|
8751
|
+
return parsed;
|
|
8752
|
+
}
|
|
8753
|
+
function validateAllowedStatusesShape(allowedStatuses, pathPrefix = "run.allowedStatuses") {
|
|
8754
|
+
if (!allowedStatuses?.length) return [];
|
|
8755
|
+
const out = [];
|
|
8756
|
+
for (let i = 0; i < allowedStatuses.length; i++) {
|
|
8757
|
+
const status = allowedStatuses[i];
|
|
8758
|
+
if (parseAllowedStatus(status) === void 0) {
|
|
8759
|
+
out.push({
|
|
8760
|
+
code: "contract.run.allowedStatuses.unknown",
|
|
8761
|
+
severity: "error",
|
|
8762
|
+
message: `${pathPrefix}[${i}] has unknown status ${JSON.stringify(status)}. Allowed: ok, error, running (aliases: success, failed).`,
|
|
8763
|
+
path: `${pathPrefix}[${i}]`
|
|
8764
|
+
});
|
|
8765
|
+
}
|
|
8766
|
+
}
|
|
8767
|
+
return out;
|
|
8648
8768
|
}
|
|
8649
8769
|
function cloneBody(body) {
|
|
8650
8770
|
return {
|
|
@@ -8657,6 +8777,17 @@ function cloneBody(body) {
|
|
|
8657
8777
|
}
|
|
8658
8778
|
} : {},
|
|
8659
8779
|
...body.llm ? { llm: { ...body.llm } } : {},
|
|
8780
|
+
...body.steps ? {
|
|
8781
|
+
steps: {
|
|
8782
|
+
...body.steps.orderRelations ? {
|
|
8783
|
+
orderRelations: body.steps.orderRelations.map((item) => ({
|
|
8784
|
+
...item,
|
|
8785
|
+
before: { ...item.before },
|
|
8786
|
+
after: { ...item.after }
|
|
8787
|
+
}))
|
|
8788
|
+
} : {}
|
|
8789
|
+
}
|
|
8790
|
+
} : {},
|
|
8660
8791
|
...body.observations ? {
|
|
8661
8792
|
observations: {
|
|
8662
8793
|
...body.observations,
|
|
@@ -8696,7 +8827,7 @@ function cloneBody(body) {
|
|
|
8696
8827
|
};
|
|
8697
8828
|
}
|
|
8698
8829
|
function bodyHasRules(body) {
|
|
8699
|
-
return body.run !== void 0 || body.tools !== void 0 || body.llm !== void 0 || body.observations !== void 0 || body.controls !== void 0 || body.retry !== void 0;
|
|
8830
|
+
return body.run !== void 0 || body.tools !== void 0 || body.llm !== void 0 || body.steps !== void 0 || body.observations !== void 0 || body.controls !== void 0 || body.retry !== void 0;
|
|
8700
8831
|
}
|
|
8701
8832
|
function parseEvidenceEventIds(evidence) {
|
|
8702
8833
|
if (evidence === void 0 || evidence === null) {
|
|
@@ -9037,6 +9168,18 @@ function contractToRules(contract) {
|
|
|
9037
9168
|
})
|
|
9038
9169
|
);
|
|
9039
9170
|
}
|
|
9171
|
+
const orderRelations = contract.steps?.orderRelations ?? [];
|
|
9172
|
+
for (const [index, relation] of orderRelations.entries()) {
|
|
9173
|
+
rules.push(
|
|
9174
|
+
createStepOrderingRule({
|
|
9175
|
+
before: { kind: relation.before.kind, name: relation.before.name },
|
|
9176
|
+
after: { kind: relation.after.kind, name: relation.after.name },
|
|
9177
|
+
id: `contract.step.orderRelation.${index}`,
|
|
9178
|
+
mode: relation.mode ?? "first-occurrence",
|
|
9179
|
+
requireEndpoints: relation.requireEndpoints !== false
|
|
9180
|
+
})
|
|
9181
|
+
);
|
|
9182
|
+
}
|
|
9040
9183
|
if (contract.observations) {
|
|
9041
9184
|
const required = contract.observations.required ?? [];
|
|
9042
9185
|
if (required.length > 0) {
|
|
@@ -9286,6 +9429,7 @@ function evaluateBody(input3, body, options = {}) {
|
|
|
9286
9429
|
}
|
|
9287
9430
|
function defineTraceContract(input3) {
|
|
9288
9431
|
const shapeErrors = [
|
|
9432
|
+
...validateAllowedStatusesShape(input3.run?.allowedStatuses),
|
|
9289
9433
|
...validateAlternativesShape(input3.alternatives),
|
|
9290
9434
|
...validateScopeShape(input3.scope),
|
|
9291
9435
|
...validateProvenanceShape(input3.observations)
|
|
@@ -9316,6 +9460,7 @@ function defineTraceContract(input3) {
|
|
|
9316
9460
|
}
|
|
9317
9461
|
function evaluateTraceContract(input3, contract, options = {}) {
|
|
9318
9462
|
const shapeErrors = [
|
|
9463
|
+
...validateAllowedStatusesShape(contract.run?.allowedStatuses),
|
|
9319
9464
|
...validateAlternativesShape(contract.alternatives),
|
|
9320
9465
|
...validateScopeShape(contract.scope),
|
|
9321
9466
|
...validateProvenanceShape(contract.observations)
|
|
@@ -9451,7 +9596,7 @@ function evaluateTraceContract(input3, contract, options = {}) {
|
|
|
9451
9596
|
[...scopeFinding ? [scopeFinding] : [], noneFinding, ...prefixedBranchFindings]
|
|
9452
9597
|
);
|
|
9453
9598
|
}
|
|
9454
|
-
var MAX_EVIDENCE_EVENT_IDS, METHOD_VOCABULARY;
|
|
9599
|
+
var ALLOWED_STATUS_ALIASES, MAX_EVIDENCE_EVENT_IDS, METHOD_VOCABULARY;
|
|
9455
9600
|
var init_contract = __esm({
|
|
9456
9601
|
"packages/core/src/checks/contract.ts"() {
|
|
9457
9602
|
init_checks2();
|
|
@@ -9464,6 +9609,13 @@ var init_contract = __esm({
|
|
|
9464
9609
|
init_outcomes();
|
|
9465
9610
|
init_contract_scope();
|
|
9466
9611
|
init_tool_arguments();
|
|
9612
|
+
ALLOWED_STATUS_ALIASES = {
|
|
9613
|
+
ok: "ok",
|
|
9614
|
+
error: "error",
|
|
9615
|
+
running: "running",
|
|
9616
|
+
success: "ok",
|
|
9617
|
+
failed: "error"
|
|
9618
|
+
};
|
|
9467
9619
|
MAX_EVIDENCE_EVENT_IDS = 16;
|
|
9468
9620
|
METHOD_VOCABULARY = new Set(OBSERVED_OUTCOME_METHODS);
|
|
9469
9621
|
}
|
|
@@ -16001,7 +16153,7 @@ var init_src = __esm({
|
|
|
16001
16153
|
});
|
|
16002
16154
|
|
|
16003
16155
|
// package.json
|
|
16004
|
-
var version = "6.
|
|
16156
|
+
var version = "6.31.1";
|
|
16005
16157
|
|
|
16006
16158
|
// packages/cli/src/list.ts
|
|
16007
16159
|
init_advanced();
|
|
@@ -22925,6 +23077,7 @@ var CONTRACT_KEYS = /* @__PURE__ */ new Set([
|
|
|
22925
23077
|
"run",
|
|
22926
23078
|
"tools",
|
|
22927
23079
|
"llm",
|
|
23080
|
+
"steps",
|
|
22928
23081
|
"observations",
|
|
22929
23082
|
"scope",
|
|
22930
23083
|
"alternatives",
|
|
@@ -22935,6 +23088,7 @@ var CONTRACT_BODY_KEYS = /* @__PURE__ */ new Set([
|
|
|
22935
23088
|
"run",
|
|
22936
23089
|
"tools",
|
|
22937
23090
|
"llm",
|
|
23091
|
+
"steps",
|
|
22938
23092
|
"observations",
|
|
22939
23093
|
"controls",
|
|
22940
23094
|
"retry"
|
|
@@ -23012,6 +23166,15 @@ var CONTRACT_ORDER_RULE_KEYS = /* @__PURE__ */ new Set([
|
|
|
23012
23166
|
"occurrenceMode",
|
|
23013
23167
|
"requireEndpoints"
|
|
23014
23168
|
]);
|
|
23169
|
+
var CONTRACT_STEPS_KEYS = /* @__PURE__ */ new Set(["orderRelations"]);
|
|
23170
|
+
var CONTRACT_STEP_ORDER_RELATION_KEYS = /* @__PURE__ */ new Set([
|
|
23171
|
+
"before",
|
|
23172
|
+
"after",
|
|
23173
|
+
"mode",
|
|
23174
|
+
"requireEndpoints"
|
|
23175
|
+
]);
|
|
23176
|
+
var CONTRACT_STEP_REF_KEYS = /* @__PURE__ */ new Set(["kind", "name"]);
|
|
23177
|
+
var CONTRACT_STEP_KINDS = /* @__PURE__ */ new Set(["TOOL", "LLM"]);
|
|
23015
23178
|
var CONTRACT_ARGUMENT_KEYS = /* @__PURE__ */ new Set([
|
|
23016
23179
|
"tool",
|
|
23017
23180
|
"path",
|
|
@@ -23342,6 +23505,7 @@ function contractConfigHasEffect(contract) {
|
|
|
23342
23505
|
if (sectionHasEffect(contract.run)) return true;
|
|
23343
23506
|
if (sectionHasEffect(contract.tools)) return true;
|
|
23344
23507
|
if (sectionHasEffect(contract.llm)) return true;
|
|
23508
|
+
if (sectionHasEffect(contract.steps)) return true;
|
|
23345
23509
|
if (sectionHasEffect(contract.observations)) {
|
|
23346
23510
|
return true;
|
|
23347
23511
|
}
|
|
@@ -23361,10 +23525,21 @@ function parseContractRunSection(value, pathPrefix = "contract.run") {
|
|
|
23361
23525
|
);
|
|
23362
23526
|
}
|
|
23363
23527
|
if (record.allowedStatuses !== void 0) {
|
|
23364
|
-
|
|
23528
|
+
const statuses = requireBoundedStringArray(
|
|
23365
23529
|
record.allowedStatuses,
|
|
23366
23530
|
`${pathPrefix}.allowedStatuses`
|
|
23367
23531
|
);
|
|
23532
|
+
const allowed = /* @__PURE__ */ new Set(["ok", "error", "running", "success", "failed"]);
|
|
23533
|
+
for (let i = 0; i < statuses.length; i++) {
|
|
23534
|
+
const status = statuses[i];
|
|
23535
|
+
if (!allowed.has(status)) {
|
|
23536
|
+
throw new CheckConfigError(
|
|
23537
|
+
"AI_CHECK_CONFIG_INVALID_VALUE",
|
|
23538
|
+
`${pathPrefix}.allowedStatuses[${i}] must be one of: ok, error, running (aliases: success, failed); got ${JSON.stringify(status)}.`
|
|
23539
|
+
);
|
|
23540
|
+
}
|
|
23541
|
+
}
|
|
23542
|
+
out.allowedStatuses = statuses;
|
|
23368
23543
|
}
|
|
23369
23544
|
if (record.maxDurationMs !== void 0) {
|
|
23370
23545
|
out.maxDurationMs = requireNonNegativeNumber(
|
|
@@ -23526,6 +23701,66 @@ function parseContractLlmSection(value, pathPrefix = "contract.llm") {
|
|
|
23526
23701
|
}
|
|
23527
23702
|
return out;
|
|
23528
23703
|
}
|
|
23704
|
+
function parseStepRef(value, pathPrefix) {
|
|
23705
|
+
const record = requireObject(value, pathPrefix);
|
|
23706
|
+
rejectUnknownKeys(record, CONTRACT_STEP_REF_KEYS, pathPrefix);
|
|
23707
|
+
if (typeof record.kind !== "string" || !CONTRACT_STEP_KINDS.has(record.kind)) {
|
|
23708
|
+
throw new CheckConfigError(
|
|
23709
|
+
"AI_CHECK_CONFIG_INVALID_VALUE",
|
|
23710
|
+
`${pathPrefix}.kind must be "TOOL" or "LLM".`
|
|
23711
|
+
);
|
|
23712
|
+
}
|
|
23713
|
+
return {
|
|
23714
|
+
kind: record.kind,
|
|
23715
|
+
name: requireNonEmptyString(record.name, `${pathPrefix}.name`)
|
|
23716
|
+
};
|
|
23717
|
+
}
|
|
23718
|
+
function parseStepOrderRelation(value, pathPrefix) {
|
|
23719
|
+
const record = requireObject(value, pathPrefix);
|
|
23720
|
+
rejectUnknownKeys(record, CONTRACT_STEP_ORDER_RELATION_KEYS, pathPrefix);
|
|
23721
|
+
if (record.before === void 0) {
|
|
23722
|
+
throw new CheckConfigError(
|
|
23723
|
+
"AI_CHECK_CONFIG_INVALID_VALUE",
|
|
23724
|
+
`${pathPrefix}.before is required.`
|
|
23725
|
+
);
|
|
23726
|
+
}
|
|
23727
|
+
if (record.after === void 0) {
|
|
23728
|
+
throw new CheckConfigError(
|
|
23729
|
+
"AI_CHECK_CONFIG_INVALID_VALUE",
|
|
23730
|
+
`${pathPrefix}.after is required.`
|
|
23731
|
+
);
|
|
23732
|
+
}
|
|
23733
|
+
const out = {
|
|
23734
|
+
before: parseStepRef(record.before, `${pathPrefix}.before`),
|
|
23735
|
+
after: parseStepRef(record.after, `${pathPrefix}.after`)
|
|
23736
|
+
};
|
|
23737
|
+
if (record.mode !== void 0) {
|
|
23738
|
+
out.mode = requireOrderMode(record.mode, `${pathPrefix}.mode`);
|
|
23739
|
+
}
|
|
23740
|
+
if (record.requireEndpoints !== void 0) {
|
|
23741
|
+
out.requireEndpoints = requireBoolean(
|
|
23742
|
+
record.requireEndpoints,
|
|
23743
|
+
`${pathPrefix}.requireEndpoints`
|
|
23744
|
+
);
|
|
23745
|
+
}
|
|
23746
|
+
return out;
|
|
23747
|
+
}
|
|
23748
|
+
function parseContractStepsSection(value, pathPrefix = "contract.steps") {
|
|
23749
|
+
const record = requireObject(value, pathPrefix);
|
|
23750
|
+
rejectUnknownKeys(record, CONTRACT_STEPS_KEYS, pathPrefix);
|
|
23751
|
+
const out = {};
|
|
23752
|
+
if (record.orderRelations !== void 0) {
|
|
23753
|
+
const items = requireBoundedArray(
|
|
23754
|
+
record.orderRelations,
|
|
23755
|
+
`${pathPrefix}.orderRelations`,
|
|
23756
|
+
CONTRACT_MAX_ORDER_RULES
|
|
23757
|
+
);
|
|
23758
|
+
out.orderRelations = items.map(
|
|
23759
|
+
(item, index) => parseStepOrderRelation(item, `${pathPrefix}.orderRelations[${index}]`)
|
|
23760
|
+
);
|
|
23761
|
+
}
|
|
23762
|
+
return out;
|
|
23763
|
+
}
|
|
23529
23764
|
function parseRequireProvenance(value, pathPrefix) {
|
|
23530
23765
|
const record = requireObject(value, pathPrefix);
|
|
23531
23766
|
rejectUnknownKeys(record, CONTRACT_PROVENANCE_KEYS, pathPrefix);
|
|
@@ -23811,6 +24046,9 @@ function parseContractBodySection(value, pathPrefix) {
|
|
|
23811
24046
|
out.tools = parseContractToolsSection(record.tools, `${pathPrefix}.tools`);
|
|
23812
24047
|
}
|
|
23813
24048
|
if (record.llm !== void 0) out.llm = parseContractLlmSection(record.llm, `${pathPrefix}.llm`);
|
|
24049
|
+
if (record.steps !== void 0) {
|
|
24050
|
+
out.steps = parseContractStepsSection(record.steps, `${pathPrefix}.steps`);
|
|
24051
|
+
}
|
|
23814
24052
|
if (record.observations !== void 0) {
|
|
23815
24053
|
out.observations = parseContractObservationsSection(
|
|
23816
24054
|
record.observations,
|