@agent-inspect/viewer 6.14.1 → 6.15.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/dist/index.cjs +267 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +267 -24
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -2223,6 +2223,81 @@ async function resolveSuiteCaseTrace(suiteCase, options) {
|
|
|
2223
2223
|
};
|
|
2224
2224
|
}
|
|
2225
2225
|
|
|
2226
|
+
// packages/core/src/diagnostics/programmatic.ts
|
|
2227
|
+
var PROGRAMMATIC_DIAGNOSTIC_SPECS = Object.freeze({
|
|
2228
|
+
AI_TRACE_INPUT_INVALID: {
|
|
2229
|
+
code: "AI_TRACE_INPUT_INVALID",
|
|
2230
|
+
summary: 'Expected { type: "file", path }, { type: "directory", path }, { type: "string", content }, { type: "buffer", content }, or { type: "stdin" }.',
|
|
2231
|
+
remediation: "For a file path, use openTraceFile(path).",
|
|
2232
|
+
relatedCodes: ["invalid_input"]
|
|
2233
|
+
},
|
|
2234
|
+
AI_TRACE_FORMAT_UNSUPPORTED: {
|
|
2235
|
+
code: "AI_TRACE_FORMAT_UNSUPPORTED",
|
|
2236
|
+
summary: "No trace reader could detect the input format.",
|
|
2237
|
+
remediation: "Pass an AgentInspect JSONL file via openTraceFile, or set options.format to a registered reader.",
|
|
2238
|
+
relatedCodes: ["unsupported_format"]
|
|
2239
|
+
},
|
|
2240
|
+
AI_TRACE_FORMAT_AMBIGUOUS: {
|
|
2241
|
+
code: "AI_TRACE_FORMAT_AMBIGUOUS",
|
|
2242
|
+
summary: "Multiple trace readers matched the input with equal confidence.",
|
|
2243
|
+
remediation: "Set options.format explicitly to disambiguate the reader.",
|
|
2244
|
+
relatedCodes: ["ambiguous_format"]
|
|
2245
|
+
},
|
|
2246
|
+
AI_TRACE_FACTS_INPUT_NOT_NORMALIZED: {
|
|
2247
|
+
code: "AI_TRACE_FACTS_INPUT_NOT_NORMALIZED",
|
|
2248
|
+
summary: "TraceFacts requires TraceReadResult or PersistedInspectEvent[].",
|
|
2249
|
+
remediation: "Use openTraceFile() to normalize a JSONL trace first."
|
|
2250
|
+
},
|
|
2251
|
+
AI_TRACE_CONTRACT_RUN_SELECTION_REQUIRED: {
|
|
2252
|
+
code: "AI_TRACE_CONTRACT_RUN_SELECTION_REQUIRED",
|
|
2253
|
+
summary: "Multiple runs are available; select a run before executing checks.",
|
|
2254
|
+
remediation: "Pass options.runId or TraceCheckInput.selectedRun.",
|
|
2255
|
+
relatedCodes: ["AI_CHECK_RUN_SELECTION_REQUIRED"]
|
|
2256
|
+
},
|
|
2257
|
+
AI_TRACE_RELATIONSHIP_SELF_PARENT: {
|
|
2258
|
+
code: "AI_TRACE_RELATIONSHIP_SELF_PARENT",
|
|
2259
|
+
summary: "A parentId equals its own event/step id.",
|
|
2260
|
+
remediation: "Reject at capture (AI_LANGGRAPH_SELF_PARENT_REJECTED) or drop via logical projection; do not invent replacement parents.",
|
|
2261
|
+
relatedCodes: [
|
|
2262
|
+
"AI_LANGGRAPH_SELF_PARENT_REJECTED",
|
|
2263
|
+
"AI_LOGICAL_SELF_PARENT_REMOVED"
|
|
2264
|
+
]
|
|
2265
|
+
},
|
|
2266
|
+
AI_TRACE_RELATIONSHIP_CYCLE: {
|
|
2267
|
+
code: "AI_TRACE_RELATIONSHIP_CYCLE",
|
|
2268
|
+
summary: "Trace contains a parentId cycle.",
|
|
2269
|
+
remediation: "Use visibility-first tree linking for legacy fixtures; prefer acyclic capture for new adapter output.",
|
|
2270
|
+
relatedCodes: ["structure.cycle"]
|
|
2271
|
+
}
|
|
2272
|
+
});
|
|
2273
|
+
function formatProgrammaticDiagnostic(code, detail) {
|
|
2274
|
+
const spec = PROGRAMMATIC_DIAGNOSTIC_SPECS[code];
|
|
2275
|
+
const summary = detail?.trim() ? detail.trim() : spec.summary;
|
|
2276
|
+
return `${code}: ${summary} Remediation: ${spec.remediation}`;
|
|
2277
|
+
}
|
|
2278
|
+
|
|
2279
|
+
// packages/core/src/safety/sensitive-key.ts
|
|
2280
|
+
function normalizeSensitiveKey(value) {
|
|
2281
|
+
return value.toLowerCase().replace(/[^a-z0-9_]/g, "");
|
|
2282
|
+
}
|
|
2283
|
+
new Set(
|
|
2284
|
+
[
|
|
2285
|
+
"tokens",
|
|
2286
|
+
"max_tokens",
|
|
2287
|
+
"min_tokens",
|
|
2288
|
+
"ls_max_tokens",
|
|
2289
|
+
"token_count",
|
|
2290
|
+
"token_limit",
|
|
2291
|
+
"token_budget",
|
|
2292
|
+
"input_tokens",
|
|
2293
|
+
"output_tokens",
|
|
2294
|
+
"total_tokens",
|
|
2295
|
+
"cached_tokens",
|
|
2296
|
+
"prompt_tokens",
|
|
2297
|
+
"completion_tokens"
|
|
2298
|
+
].map(normalizeSensitiveKey)
|
|
2299
|
+
);
|
|
2300
|
+
|
|
2226
2301
|
// packages/core/src/checks/logical-events.ts
|
|
2227
2302
|
function isRecord5(value) {
|
|
2228
2303
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -2418,6 +2493,26 @@ function projectLogicalEvents(events) {
|
|
|
2418
2493
|
}
|
|
2419
2494
|
}
|
|
2420
2495
|
if (!remapped) {
|
|
2496
|
+
if (originalParentId === event.eventId) {
|
|
2497
|
+
diagnostics.push({
|
|
2498
|
+
code: "AI_LOGICAL_SELF_PARENT_REMOVED",
|
|
2499
|
+
message: formatProgrammaticDiagnostic(
|
|
2500
|
+
"AI_TRACE_RELATIONSHIP_SELF_PARENT",
|
|
2501
|
+
`Removed self-parent edge on ${event.eventId}.`
|
|
2502
|
+
),
|
|
2503
|
+
eventIds: [event.eventId]
|
|
2504
|
+
});
|
|
2505
|
+
const { parentId: _drop, ...rest } = event;
|
|
2506
|
+
normalized.push({
|
|
2507
|
+
...rest,
|
|
2508
|
+
projection: {
|
|
2509
|
+
...event.projection,
|
|
2510
|
+
parentNormalized: true,
|
|
2511
|
+
originalParentId
|
|
2512
|
+
}
|
|
2513
|
+
});
|
|
2514
|
+
continue;
|
|
2515
|
+
}
|
|
2421
2516
|
if (!logicalById.has(originalParentId) && !logicalByRawId.has(originalParentId)) {
|
|
2422
2517
|
const mapping = event.attributes?.parentMapping;
|
|
2423
2518
|
const unresolved = mapping === "unresolved" || event.attributes?.parentUnresolved === true || event.attributes?.unresolvedParent === true || // LangGraph/framework scaffolding sentinel labels are not event ids.
|
|
@@ -2433,6 +2528,26 @@ function projectLogicalEvents(events) {
|
|
|
2433
2528
|
normalized.push(event);
|
|
2434
2529
|
continue;
|
|
2435
2530
|
}
|
|
2531
|
+
if (nextParent === event.eventId) {
|
|
2532
|
+
diagnostics.push({
|
|
2533
|
+
code: "AI_LOGICAL_SELF_PARENT_REMOVED",
|
|
2534
|
+
message: formatProgrammaticDiagnostic(
|
|
2535
|
+
"AI_TRACE_RELATIONSHIP_SELF_PARENT",
|
|
2536
|
+
`Removed self-parent edge on ${event.eventId} (was ${originalParentId}).`
|
|
2537
|
+
),
|
|
2538
|
+
eventIds: [event.eventId]
|
|
2539
|
+
});
|
|
2540
|
+
const { parentId: _drop, ...rest } = event;
|
|
2541
|
+
normalized.push({
|
|
2542
|
+
...rest,
|
|
2543
|
+
projection: {
|
|
2544
|
+
...event.projection,
|
|
2545
|
+
parentNormalized: true,
|
|
2546
|
+
originalParentId
|
|
2547
|
+
}
|
|
2548
|
+
});
|
|
2549
|
+
continue;
|
|
2550
|
+
}
|
|
2436
2551
|
diagnostics.push({
|
|
2437
2552
|
code: "AI_LOGICAL_PARENT_REMAPPED",
|
|
2438
2553
|
message: `Remapped parent ${originalParentId} \u2192 ${nextParent} for ${event.eventId}.`,
|
|
@@ -2482,6 +2597,11 @@ function pickString(record, keys) {
|
|
|
2482
2597
|
return void 0;
|
|
2483
2598
|
}
|
|
2484
2599
|
|
|
2600
|
+
// packages/core/src/checks/trace-facts.ts
|
|
2601
|
+
formatProgrammaticDiagnostic(
|
|
2602
|
+
"AI_TRACE_FACTS_INPUT_NOT_NORMALIZED"
|
|
2603
|
+
);
|
|
2604
|
+
|
|
2485
2605
|
// packages/core/src/checks/index.ts
|
|
2486
2606
|
var SEVERITY_RANK = {
|
|
2487
2607
|
error: 0,
|
|
@@ -2591,7 +2711,13 @@ function resolveSelectedRun(input, runId) {
|
|
|
2591
2711
|
if (input.read.runs.length === 0) {
|
|
2592
2712
|
return {
|
|
2593
2713
|
diagnostics: [
|
|
2594
|
-
diagnostic3(
|
|
2714
|
+
diagnostic3(
|
|
2715
|
+
"AI_CHECK_RUN_SELECTION_REQUIRED",
|
|
2716
|
+
formatProgrammaticDiagnostic(
|
|
2717
|
+
"AI_TRACE_CONTRACT_RUN_SELECTION_REQUIRED",
|
|
2718
|
+
"No runs are available for checks."
|
|
2719
|
+
)
|
|
2720
|
+
)
|
|
2595
2721
|
]
|
|
2596
2722
|
};
|
|
2597
2723
|
}
|
|
@@ -2599,7 +2725,7 @@ function resolveSelectedRun(input, runId) {
|
|
|
2599
2725
|
diagnostics: [
|
|
2600
2726
|
diagnostic3(
|
|
2601
2727
|
"AI_CHECK_RUN_SELECTION_REQUIRED",
|
|
2602
|
-
"
|
|
2728
|
+
formatProgrammaticDiagnostic("AI_TRACE_CONTRACT_RUN_SELECTION_REQUIRED")
|
|
2603
2729
|
)
|
|
2604
2730
|
]
|
|
2605
2731
|
};
|
|
@@ -2826,7 +2952,7 @@ function createToolUsageRule(options) {
|
|
|
2826
2952
|
}
|
|
2827
2953
|
}
|
|
2828
2954
|
const forbidden = new Set(options.forbidden ?? []);
|
|
2829
|
-
const allowed = options.allowed ? new Set(options.allowed) : void 0;
|
|
2955
|
+
const allowed = options.allowed?.length ? new Set(options.allowed) : void 0;
|
|
2830
2956
|
for (const event of tools) {
|
|
2831
2957
|
const name = toolName(event);
|
|
2832
2958
|
if (forbidden.has(name)) {
|
|
@@ -2862,9 +2988,9 @@ function createLlmUsageRule(options) {
|
|
|
2862
2988
|
evaluate(context) {
|
|
2863
2989
|
const llms = finishedEvents(context, "LLM");
|
|
2864
2990
|
const findings = [];
|
|
2865
|
-
const allowedModels = options.allowedModels ? new Set(options.allowedModels) : void 0;
|
|
2866
|
-
const allowedProviders = options.allowedProviders ? new Set(options.allowedProviders) : void 0;
|
|
2867
|
-
const finishReasons = options.finishReasons ? new Set(options.finishReasons) : void 0;
|
|
2991
|
+
const allowedModels = options.allowedModels?.length ? new Set(options.allowedModels) : void 0;
|
|
2992
|
+
const allowedProviders = options.allowedProviders?.length ? new Set(options.allowedProviders) : void 0;
|
|
2993
|
+
const finishReasons = options.finishReasons?.length ? new Set(options.finishReasons) : void 0;
|
|
2868
2994
|
if (options.maxCalls !== void 0 && llms.length > options.maxCalls) {
|
|
2869
2995
|
findings.push(
|
|
2870
2996
|
failFinding(
|
|
@@ -3279,6 +3405,20 @@ function traceEventsToPersistedInspectEvents(events, options) {
|
|
|
3279
3405
|
function inc(map, key) {
|
|
3280
3406
|
map[key] = (map[key] ?? 0) + 1;
|
|
3281
3407
|
}
|
|
3408
|
+
function confidenceRank(confidence) {
|
|
3409
|
+
switch (confidence) {
|
|
3410
|
+
case "unknown":
|
|
3411
|
+
return 0;
|
|
3412
|
+
case "heuristic":
|
|
3413
|
+
return 1;
|
|
3414
|
+
case "correlated":
|
|
3415
|
+
return 2;
|
|
3416
|
+
case "explicit":
|
|
3417
|
+
return 3;
|
|
3418
|
+
default:
|
|
3419
|
+
return 0;
|
|
3420
|
+
}
|
|
3421
|
+
}
|
|
3282
3422
|
function computeRunStatus(events) {
|
|
3283
3423
|
let runTerminal;
|
|
3284
3424
|
let sawRunEvent = false;
|
|
@@ -3299,6 +3439,84 @@ function computeRunStatus(events) {
|
|
|
3299
3439
|
}
|
|
3300
3440
|
return hasRunning ? "running" : "ok";
|
|
3301
3441
|
}
|
|
3442
|
+
function linkNodesVisibilityFirst(nodes) {
|
|
3443
|
+
let selfParentCount = 0;
|
|
3444
|
+
let unresolvedParentCount = 0;
|
|
3445
|
+
let normalizedEdgeCount = 0;
|
|
3446
|
+
let cycleCount = 0;
|
|
3447
|
+
const pending = [];
|
|
3448
|
+
for (const node of nodes.values()) {
|
|
3449
|
+
const parentId = node.event.parentId;
|
|
3450
|
+
if (!parentId) continue;
|
|
3451
|
+
if (parentId === node.event.eventId) {
|
|
3452
|
+
selfParentCount += 1;
|
|
3453
|
+
normalizedEdgeCount += 1;
|
|
3454
|
+
continue;
|
|
3455
|
+
}
|
|
3456
|
+
if (!nodes.has(parentId)) {
|
|
3457
|
+
unresolvedParentCount += 1;
|
|
3458
|
+
continue;
|
|
3459
|
+
}
|
|
3460
|
+
pending.push({
|
|
3461
|
+
childId: node.event.eventId,
|
|
3462
|
+
parentId,
|
|
3463
|
+
childTimestamp: node.event.timestamp,
|
|
3464
|
+
childConfidence: node.event.confidence
|
|
3465
|
+
});
|
|
3466
|
+
}
|
|
3467
|
+
pending.sort((a, b) => {
|
|
3468
|
+
const conf = confidenceRank(b.childConfidence) - confidenceRank(a.childConfidence);
|
|
3469
|
+
if (conf !== 0) return conf;
|
|
3470
|
+
return a.childTimestamp - b.childTimestamp;
|
|
3471
|
+
});
|
|
3472
|
+
const parentOf = /* @__PURE__ */ new Map();
|
|
3473
|
+
for (const edge of pending) {
|
|
3474
|
+
parentOf.set(edge.childId, edge.parentId);
|
|
3475
|
+
let cursor = edge.parentId;
|
|
3476
|
+
const seen = /* @__PURE__ */ new Set([edge.childId]);
|
|
3477
|
+
let cyclic = false;
|
|
3478
|
+
while (cursor) {
|
|
3479
|
+
if (seen.has(cursor)) {
|
|
3480
|
+
cyclic = true;
|
|
3481
|
+
break;
|
|
3482
|
+
}
|
|
3483
|
+
seen.add(cursor);
|
|
3484
|
+
cursor = parentOf.get(cursor);
|
|
3485
|
+
}
|
|
3486
|
+
if (cyclic) {
|
|
3487
|
+
parentOf.delete(edge.childId);
|
|
3488
|
+
cycleCount += 1;
|
|
3489
|
+
normalizedEdgeCount += 1;
|
|
3490
|
+
}
|
|
3491
|
+
}
|
|
3492
|
+
for (const [childId, parentId] of parentOf) {
|
|
3493
|
+
nodes.get(parentId).children.push(nodes.get(childId));
|
|
3494
|
+
}
|
|
3495
|
+
const roots = [];
|
|
3496
|
+
for (const node of nodes.values()) {
|
|
3497
|
+
if (!parentOf.has(node.event.eventId)) {
|
|
3498
|
+
roots.push(node);
|
|
3499
|
+
}
|
|
3500
|
+
}
|
|
3501
|
+
const assignDepth = (n, depth, stack) => {
|
|
3502
|
+
if (stack.has(n.event.eventId)) return;
|
|
3503
|
+
n.depth = depth;
|
|
3504
|
+
stack.add(n.event.eventId);
|
|
3505
|
+
for (const c of n.children) assignDepth(c, depth + 1, stack);
|
|
3506
|
+
stack.delete(n.event.eventId);
|
|
3507
|
+
};
|
|
3508
|
+
for (const r of roots) assignDepth(r, 0, /* @__PURE__ */ new Set());
|
|
3509
|
+
return {
|
|
3510
|
+
roots,
|
|
3511
|
+
summary: {
|
|
3512
|
+
rootCount: roots.length,
|
|
3513
|
+
selfParentCount,
|
|
3514
|
+
cycleCount,
|
|
3515
|
+
unresolvedParentCount,
|
|
3516
|
+
normalizedEdgeCount
|
|
3517
|
+
}
|
|
3518
|
+
};
|
|
3519
|
+
}
|
|
3302
3520
|
var TreeBuilder = class {
|
|
3303
3521
|
constructor(options) {
|
|
3304
3522
|
void options?.config;
|
|
@@ -3316,20 +3534,7 @@ var TreeBuilder = class {
|
|
|
3316
3534
|
for (const e of sorted) {
|
|
3317
3535
|
nodes.set(e.eventId, { event: e, children: [], depth: 0 });
|
|
3318
3536
|
}
|
|
3319
|
-
const roots =
|
|
3320
|
-
for (const node of nodes.values()) {
|
|
3321
|
-
const parentId = node.event.parentId;
|
|
3322
|
-
if (parentId && nodes.has(parentId)) {
|
|
3323
|
-
nodes.get(parentId).children.push(node);
|
|
3324
|
-
} else {
|
|
3325
|
-
roots.push(node);
|
|
3326
|
-
}
|
|
3327
|
-
}
|
|
3328
|
-
const assignDepth = (n, depth) => {
|
|
3329
|
-
n.depth = depth;
|
|
3330
|
-
for (const c of n.children) assignDepth(c, depth + 1);
|
|
3331
|
-
};
|
|
3332
|
-
for (const r of roots) assignDepth(r, 0);
|
|
3537
|
+
const { roots, summary } = linkNodesVisibilityFirst(nodes);
|
|
3333
3538
|
const confidenceBreakdown = {
|
|
3334
3539
|
explicit: 0,
|
|
3335
3540
|
correlated: 0,
|
|
@@ -3357,7 +3562,8 @@ var TreeBuilder = class {
|
|
|
3357
3562
|
metadata: {
|
|
3358
3563
|
totalEvents: sorted.length,
|
|
3359
3564
|
confidenceBreakdown,
|
|
3360
|
-
kinds
|
|
3565
|
+
kinds,
|
|
3566
|
+
relationshipSummary: summary
|
|
3361
3567
|
}
|
|
3362
3568
|
});
|
|
3363
3569
|
}
|
|
@@ -3586,6 +3792,38 @@ var TraceReadError = class extends Error {
|
|
|
3586
3792
|
this.warnings = warnings;
|
|
3587
3793
|
}
|
|
3588
3794
|
};
|
|
3795
|
+
var TRACE_INPUT_INVALID_MESSAGE = formatProgrammaticDiagnostic(
|
|
3796
|
+
"AI_TRACE_INPUT_INVALID"
|
|
3797
|
+
);
|
|
3798
|
+
function isTraceInput(input) {
|
|
3799
|
+
if (typeof input !== "object" || input === null || Array.isArray(input)) {
|
|
3800
|
+
return false;
|
|
3801
|
+
}
|
|
3802
|
+
const record = input;
|
|
3803
|
+
switch (record.type) {
|
|
3804
|
+
case "file":
|
|
3805
|
+
case "directory":
|
|
3806
|
+
return typeof record.path === "string";
|
|
3807
|
+
case "string":
|
|
3808
|
+
return typeof record.content === "string";
|
|
3809
|
+
case "buffer":
|
|
3810
|
+
return Buffer.isBuffer(record.content);
|
|
3811
|
+
case "stdin":
|
|
3812
|
+
return true;
|
|
3813
|
+
default:
|
|
3814
|
+
return false;
|
|
3815
|
+
}
|
|
3816
|
+
}
|
|
3817
|
+
function assertTraceInput(input) {
|
|
3818
|
+
if (isTraceInput(input)) return;
|
|
3819
|
+
throw new TraceReadError("invalid_input", TRACE_INPUT_INVALID_MESSAGE, [
|
|
3820
|
+
{
|
|
3821
|
+
code: "AI_TRACE_INPUT_INVALID",
|
|
3822
|
+
message: TRACE_INPUT_INVALID_MESSAGE,
|
|
3823
|
+
severity: "error"
|
|
3824
|
+
}
|
|
3825
|
+
]);
|
|
3826
|
+
}
|
|
3589
3827
|
function normalizeCandidate(reader, candidate) {
|
|
3590
3828
|
const confidence = Number.isFinite(candidate.confidence) ? Math.max(0, Math.min(1, candidate.confidence)) : 0;
|
|
3591
3829
|
return {
|
|
@@ -4940,6 +5178,7 @@ var DEFAULT_TRACE_READERS = [
|
|
|
4940
5178
|
otlpJsonReader
|
|
4941
5179
|
];
|
|
4942
5180
|
async function detectTraceFormat(input, options = {}) {
|
|
5181
|
+
assertTraceInput(input);
|
|
4943
5182
|
const readers = options.readers ?? DEFAULT_TRACE_READERS;
|
|
4944
5183
|
if (options.format !== void 0) {
|
|
4945
5184
|
const reader = findReaderByFormat(options.format, readers);
|
|
@@ -5036,19 +5275,20 @@ async function detectTraceFormat(input, options = {}) {
|
|
|
5036
5275
|
};
|
|
5037
5276
|
}
|
|
5038
5277
|
async function readTrace(input, options = {}) {
|
|
5278
|
+
assertTraceInput(input);
|
|
5039
5279
|
const readers = options.readers ?? DEFAULT_TRACE_READERS;
|
|
5040
5280
|
const detection = await detectTraceFormat(input, options);
|
|
5041
5281
|
if (detection.status === "unsupported" || detection.format === void 0) {
|
|
5042
5282
|
throw new TraceReadError(
|
|
5043
5283
|
"unsupported_format",
|
|
5044
|
-
"
|
|
5284
|
+
formatProgrammaticDiagnostic("AI_TRACE_FORMAT_UNSUPPORTED"),
|
|
5045
5285
|
detection.warnings
|
|
5046
5286
|
);
|
|
5047
5287
|
}
|
|
5048
5288
|
if (detection.status === "ambiguous") {
|
|
5049
5289
|
throw new TraceReadError(
|
|
5050
5290
|
"ambiguous_format",
|
|
5051
|
-
"
|
|
5291
|
+
formatProgrammaticDiagnostic("AI_TRACE_FORMAT_AMBIGUOUS"),
|
|
5052
5292
|
detection.warnings
|
|
5053
5293
|
);
|
|
5054
5294
|
}
|
|
@@ -5056,7 +5296,10 @@ async function readTrace(input, options = {}) {
|
|
|
5056
5296
|
if (!reader) {
|
|
5057
5297
|
throw new TraceReadError(
|
|
5058
5298
|
"unsupported_format",
|
|
5059
|
-
|
|
5299
|
+
formatProgrammaticDiagnostic(
|
|
5300
|
+
"AI_TRACE_FORMAT_UNSUPPORTED",
|
|
5301
|
+
`No trace reader is registered for format "${detection.format}".`
|
|
5302
|
+
),
|
|
5060
5303
|
detection.warnings
|
|
5061
5304
|
);
|
|
5062
5305
|
}
|