agent-inspect 6.31.28 → 6.31.30
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 +14 -0
- package/README.md +1 -1
- package/docs/CLI.md +26 -1
- package/package.json +1 -1
- package/packages/cli/dist/index.cjs +142 -36
- package/packages/cli/dist/index.cjs.map +1 -1
- package/packages/cli/dist/index.mjs +141 -37
- package/packages/cli/dist/index.mjs.map +1 -1
- package/packages/core/dist/exporters.cjs +120 -28
- package/packages/core/dist/exporters.cjs.map +1 -1
- package/packages/core/dist/exporters.mjs +120 -28
- package/packages/core/dist/exporters.mjs.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 6.31.30
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 35923dd: Join sibling start/complete lifecycle rows in HTML/Markdown presentation and coalesce bundle HTML trees so completed steps are not shown as still running.
|
|
8
|
+
- f1c1752: Nest tenant recipe now executes real SupportService/PolicyService seams and scores consumption from reopened saved outcomes (N01–N08), not in-memory joinOk.
|
|
9
|
+
- f664b85: Om browser recipe records injected-clock wait/readiness diagnostics (document, in-flight, obstruction, elapsed/budget/remaining, stop reason) without inventing overlay from LocatorNotFound.
|
|
10
|
+
|
|
11
|
+
## 6.31.29
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- dcd714d: Tighten saved-evidence recipe controls: timeout-ledger same-run/marker/claim coverage, comparable-cohort one-pass reopen verification, and Nest opaque tenant/operation refs.
|
|
16
|
+
|
|
3
17
|
## 6.31.28
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -213,7 +213,7 @@ The root package is enough for custom capture, the CLI, checks, and Evidence wor
|
|
|
213
213
|
|
|
214
214
|
## Status and documentation
|
|
215
215
|
|
|
216
|
-
**Current published baseline:** **6.31.
|
|
216
|
+
**Current published baseline:** **6.31.30** · persisted schema `1.0` · Node.js `>=20` · MIT.
|
|
217
217
|
|
|
218
218
|
Legacy v0.1 and v0.2 traces remain readable. Check the npm badge and [changelog](CHANGELOG.md) for the current published version.
|
|
219
219
|
|
package/docs/CLI.md
CHANGED
|
@@ -382,12 +382,37 @@ Rich TraceContract JSON (6.30+):
|
|
|
382
382
|
}
|
|
383
383
|
```
|
|
384
384
|
|
|
385
|
-
Supported `contract` fields: `run`, `tools` (including `arguments`, `orderRules
|
|
385
|
+
Supported `contract` fields: `run`, `tools` (including `arguments`, `orderRules`,
|
|
386
|
+
`requiredOrder`, `requiredOrderMode`), `steps` (including `orderRelations`),
|
|
386
387
|
`llm`, `observations` (including `requireProvenance`), `scope`, `alternatives.anyOf`,
|
|
387
388
|
`controls`, and `retry`. Unknown keys fail closed (exit 2). With `--evidence-on`,
|
|
388
389
|
contract mode writes `contract.resolved.json` and binds digests into check-results.
|
|
389
390
|
YAML is not supported. TypeScript config files (`.ts`, `.mts`, `.cts`) fail clearly unless a future explicit loader strategy is added; use precompiled JavaScript config instead.
|
|
390
391
|
|
|
392
|
+
`steps.orderRelations` (6.31+) declares typed cross-kind ordering (for example TOOL
|
|
393
|
+
before LLM). Each relation has `before` / `after` step refs (`kind` + `name`), optional
|
|
394
|
+
`mode` (`first-occurrence` | `happens-before` | `all-occurrences`; default
|
|
395
|
+
`first-occurrence`), and optional `requireEndpoints` (default `true`). This is separate
|
|
396
|
+
from TOOL-only `tools.requiredOrder` / `orderRules`. Invalid shapes and unknown keys
|
|
397
|
+
fail closed.
|
|
398
|
+
|
|
399
|
+
```json
|
|
400
|
+
{
|
|
401
|
+
"contract": {
|
|
402
|
+
"tools": { "required": ["retrieve_policy"] },
|
|
403
|
+
"steps": {
|
|
404
|
+
"orderRelations": [
|
|
405
|
+
{
|
|
406
|
+
"before": { "kind": "TOOL", "name": "retrieve_policy" },
|
|
407
|
+
"after": { "kind": "LLM", "name": "answer" },
|
|
408
|
+
"mode": "first-occurrence"
|
|
409
|
+
}
|
|
410
|
+
]
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
```
|
|
415
|
+
|
|
391
416
|
Examples:
|
|
392
417
|
|
|
393
418
|
```bash
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-inspect",
|
|
3
|
-
"version": "6.31.
|
|
3
|
+
"version": "6.31.30",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Local evidence debugger and trajectory-test toolkit for TypeScript AI agents — execution trees, TraceContract checks, Evidence v2, and read-only MCP",
|
|
@@ -17304,7 +17304,7 @@ var init_src = __esm({
|
|
|
17304
17304
|
});
|
|
17305
17305
|
|
|
17306
17306
|
// package.json
|
|
17307
|
-
var version = "6.31.
|
|
17307
|
+
var version = "6.31.30";
|
|
17308
17308
|
|
|
17309
17309
|
// packages/cli/src/list.ts
|
|
17310
17310
|
init_advanced();
|
|
@@ -19516,6 +19516,98 @@ function redactRunTreeForExport(tree, options) {
|
|
|
19516
19516
|
|
|
19517
19517
|
// packages/core/src/exporters/html-exporter.ts
|
|
19518
19518
|
init_helpers();
|
|
19519
|
+
|
|
19520
|
+
// packages/core/src/exporters/presentation-lifecycle.ts
|
|
19521
|
+
function stepIdOf2(event) {
|
|
19522
|
+
const value = event.attributes?.stepId;
|
|
19523
|
+
return typeof value === "string" && value.trim() !== "" ? value : void 0;
|
|
19524
|
+
}
|
|
19525
|
+
function lifecycleKey(event) {
|
|
19526
|
+
if (event.kind === "RUN") return `run:${event.runId}`;
|
|
19527
|
+
const stepId = stepIdOf2(event);
|
|
19528
|
+
if (stepId !== void 0) return `step:${stepId}`;
|
|
19529
|
+
return `event:${event.eventId}`;
|
|
19530
|
+
}
|
|
19531
|
+
function isTerminal(status) {
|
|
19532
|
+
return status === "ok" || status === "error";
|
|
19533
|
+
}
|
|
19534
|
+
function cloneNode(node) {
|
|
19535
|
+
return {
|
|
19536
|
+
event: {
|
|
19537
|
+
...node.event,
|
|
19538
|
+
...node.event.attributes !== void 0 ? { attributes: { ...node.event.attributes } } : {}
|
|
19539
|
+
},
|
|
19540
|
+
children: node.children.map(cloneNode),
|
|
19541
|
+
depth: node.depth
|
|
19542
|
+
};
|
|
19543
|
+
}
|
|
19544
|
+
function joinSiblingGroup(group) {
|
|
19545
|
+
if (group.length <= 1) return group;
|
|
19546
|
+
const terminals = group.filter((n) => isTerminal(n.event.status));
|
|
19547
|
+
const runnings = group.filter((n) => n.event.status === "running");
|
|
19548
|
+
const terminalStatuses = new Set(terminals.map((n) => n.event.status));
|
|
19549
|
+
if (terminalStatuses.size > 1) {
|
|
19550
|
+
return group;
|
|
19551
|
+
}
|
|
19552
|
+
if (terminals.length >= 1) {
|
|
19553
|
+
const terminal = terminals[terminals.length - 1];
|
|
19554
|
+
const start = runnings[0];
|
|
19555
|
+
const childMap = /* @__PURE__ */ new Map();
|
|
19556
|
+
for (const n of group) {
|
|
19557
|
+
for (const child of n.children) {
|
|
19558
|
+
childMap.set(child.event.eventId, child);
|
|
19559
|
+
}
|
|
19560
|
+
}
|
|
19561
|
+
return [
|
|
19562
|
+
{
|
|
19563
|
+
event: {
|
|
19564
|
+
...terminal.event,
|
|
19565
|
+
name: start?.event.name ?? terminal.event.name,
|
|
19566
|
+
kind: start?.event.kind ?? terminal.event.kind,
|
|
19567
|
+
...start?.event.timestamp !== void 0 && terminal.event.durationMs === void 0 ? {} : {}
|
|
19568
|
+
},
|
|
19569
|
+
children: presentSiblingNodes([...childMap.values()]),
|
|
19570
|
+
depth: terminal.depth
|
|
19571
|
+
}
|
|
19572
|
+
];
|
|
19573
|
+
}
|
|
19574
|
+
return group;
|
|
19575
|
+
}
|
|
19576
|
+
function presentSiblingNodes(nodes) {
|
|
19577
|
+
const prepared = nodes.map((n) => ({
|
|
19578
|
+
...cloneNode(n),
|
|
19579
|
+
children: presentSiblingNodes(n.children)
|
|
19580
|
+
}));
|
|
19581
|
+
const order = [];
|
|
19582
|
+
const groups = /* @__PURE__ */ new Map();
|
|
19583
|
+
for (const node of prepared) {
|
|
19584
|
+
const key = lifecycleKey(node.event);
|
|
19585
|
+
if (!groups.has(key)) {
|
|
19586
|
+
groups.set(key, []);
|
|
19587
|
+
order.push(key);
|
|
19588
|
+
}
|
|
19589
|
+
groups.get(key).push(node);
|
|
19590
|
+
}
|
|
19591
|
+
const out = [];
|
|
19592
|
+
for (const key of order) {
|
|
19593
|
+
out.push(...joinSiblingGroup(groups.get(key)));
|
|
19594
|
+
}
|
|
19595
|
+
return out;
|
|
19596
|
+
}
|
|
19597
|
+
function presentLifecycleJoinedTree(tree) {
|
|
19598
|
+
return {
|
|
19599
|
+
...tree,
|
|
19600
|
+
children: presentSiblingNodes(tree.children),
|
|
19601
|
+
metadata: {
|
|
19602
|
+
...tree.metadata,
|
|
19603
|
+
confidenceBreakdown: { ...tree.metadata.confidenceBreakdown },
|
|
19604
|
+
kinds: { ...tree.metadata.kinds },
|
|
19605
|
+
...tree.metadata.relationshipSummary !== void 0 ? { relationshipSummary: { ...tree.metadata.relationshipSummary } } : {}
|
|
19606
|
+
}
|
|
19607
|
+
};
|
|
19608
|
+
}
|
|
19609
|
+
|
|
19610
|
+
// packages/core/src/exporters/html-exporter.ts
|
|
19519
19611
|
function renderTreeHtml2(nodes, ulClass = "tree") {
|
|
19520
19612
|
if (nodes.length === 0) return "";
|
|
19521
19613
|
const parts = [`<ul class="${ulClass}">`];
|
|
@@ -19542,32 +19634,33 @@ function exportHtml(tree, options) {
|
|
|
19542
19634
|
const includeErrors = options?.includeErrors ?? true;
|
|
19543
19635
|
const maxLen = options?.maxAttributeLength ?? 500;
|
|
19544
19636
|
const redacted = options?.redacted ?? true;
|
|
19545
|
-
const
|
|
19637
|
+
const view2 = presentLifecycleJoinedTree(tree);
|
|
19638
|
+
const titleName = escapeHtml(view2.name ?? view2.runId);
|
|
19546
19639
|
const summaryRows = [];
|
|
19547
19640
|
summaryRows.push(
|
|
19548
|
-
`<tr><th scope="row">runId</th><td><code>${escapeHtml(
|
|
19641
|
+
`<tr><th scope="row">runId</th><td><code>${escapeHtml(view2.runId)}</code></td></tr>`
|
|
19549
19642
|
);
|
|
19550
|
-
if (
|
|
19551
|
-
summaryRows.push(`<tr><th scope="row">name</th><td>${escapeHtml(
|
|
19643
|
+
if (view2.name !== void 0) {
|
|
19644
|
+
summaryRows.push(`<tr><th scope="row">name</th><td>${escapeHtml(view2.name)}</td></tr>`);
|
|
19552
19645
|
}
|
|
19553
19646
|
summaryRows.push(
|
|
19554
|
-
`<tr><th scope="row">status</th><td>${escapeHtml(String(
|
|
19647
|
+
`<tr><th scope="row">status</th><td>${escapeHtml(String(view2.status ?? "unknown"))}</td></tr>`
|
|
19555
19648
|
);
|
|
19556
19649
|
summaryRows.push(
|
|
19557
|
-
`<tr><th scope="row">durationMs</th><td>${
|
|
19650
|
+
`<tr><th scope="row">durationMs</th><td>${view2.durationMs !== void 0 ? escapeHtml(String(view2.durationMs)) : "\u2014"}</td></tr>`
|
|
19558
19651
|
);
|
|
19559
19652
|
summaryRows.push(
|
|
19560
|
-
`<tr><th scope="row">startedAt</th><td>${
|
|
19653
|
+
`<tr><th scope="row">startedAt</th><td>${view2.startedAt !== void 0 ? escapeHtml(String(view2.startedAt)) : "\u2014"}</td></tr>`
|
|
19561
19654
|
);
|
|
19562
19655
|
summaryRows.push(
|
|
19563
|
-
`<tr><th scope="row">endedAt</th><td>${
|
|
19656
|
+
`<tr><th scope="row">endedAt</th><td>${view2.endedAt !== void 0 ? escapeHtml(String(view2.endedAt)) : "\u2014"}</td></tr>`
|
|
19564
19657
|
);
|
|
19565
19658
|
summaryRows.push(
|
|
19566
|
-
`<tr><th scope="row">totalEvents</th><td>${escapeHtml(String(
|
|
19659
|
+
`<tr><th scope="row">totalEvents</th><td>${escapeHtml(String(view2.metadata.totalEvents))}</td></tr>`
|
|
19567
19660
|
);
|
|
19568
19661
|
let confidenceHtml = "";
|
|
19569
19662
|
if (includeMetadata) {
|
|
19570
|
-
const cb =
|
|
19663
|
+
const cb = view2.metadata.confidenceBreakdown;
|
|
19571
19664
|
confidenceHtml += "<h3>Confidence breakdown</h3><table><thead><tr><th>bucket</th><th>count</th></tr></thead><tbody>";
|
|
19572
19665
|
for (const k of Object.keys(cb).sort()) {
|
|
19573
19666
|
const key = k;
|
|
@@ -19575,14 +19668,14 @@ function exportHtml(tree, options) {
|
|
|
19575
19668
|
}
|
|
19576
19669
|
confidenceHtml += "</tbody></table>";
|
|
19577
19670
|
confidenceHtml += "<h3>Kind breakdown</h3><table><thead><tr><th>kind</th><th>count</th></tr></thead><tbody>";
|
|
19578
|
-
for (const k of Object.keys(
|
|
19671
|
+
for (const k of Object.keys(view2.metadata.kinds).sort()) {
|
|
19579
19672
|
const key = k;
|
|
19580
|
-
const c =
|
|
19673
|
+
const c = view2.metadata.kinds[key];
|
|
19581
19674
|
if (c > 0) confidenceHtml += `<tr><td>${escapeHtml(key)}</td><td>${c}</td></tr>`;
|
|
19582
19675
|
}
|
|
19583
19676
|
confidenceHtml += "</tbody></table>";
|
|
19584
19677
|
}
|
|
19585
|
-
const flat = flattenTree(
|
|
19678
|
+
const flat = flattenTree(view2);
|
|
19586
19679
|
const errors = flat.filter((n) => n.event.status === "error");
|
|
19587
19680
|
let errorsHtml = "";
|
|
19588
19681
|
if (includeErrors && errors.length > 0) {
|
|
@@ -19637,7 +19730,7 @@ footer{margin-top:2rem;font-size:0.85rem;color:#555}
|
|
|
19637
19730
|
<header><h1>AgentInspect Run: ${titleName}</h1></header>
|
|
19638
19731
|
<p class="note">Generated locally by AgentInspect.</p>
|
|
19639
19732
|
${includeMetadata ? `<section class="summary"><h2>Summary</h2><table>${summaryRows.join("")}</table>${confidenceHtml}</section>` : ""}
|
|
19640
|
-
<section class="tree"><h2>Execution tree</h2>${
|
|
19733
|
+
<section class="tree"><h2>Execution tree</h2>${view2.children.length > 0 ? renderTreeHtml2(view2.children) : "<p>No steps recorded.</p>"}</section>
|
|
19641
19734
|
${errorsHtml}
|
|
19642
19735
|
${attrsHtml}
|
|
19643
19736
|
<footer>Generated locally by AgentInspect. Review for sensitive data before sharing.</footer>
|
|
@@ -19679,7 +19772,8 @@ function exportMarkdown(tree, options) {
|
|
|
19679
19772
|
const includeErrors = options?.includeErrors ?? true;
|
|
19680
19773
|
const maxLen = options?.maxAttributeLength ?? 500;
|
|
19681
19774
|
const redacted = options?.redacted ?? true;
|
|
19682
|
-
const
|
|
19775
|
+
const view2 = presentLifecycleJoinedTree(tree);
|
|
19776
|
+
const titleName = view2.name ?? view2.runId;
|
|
19683
19777
|
const lines = [];
|
|
19684
19778
|
lines.push(`# AgentInspect Run: ${escapeMarkdown(titleName)}`);
|
|
19685
19779
|
lines.push("");
|
|
@@ -19688,28 +19782,28 @@ function exportMarkdown(tree, options) {
|
|
|
19688
19782
|
if (includeMetadata) {
|
|
19689
19783
|
lines.push("## Summary");
|
|
19690
19784
|
lines.push("");
|
|
19691
|
-
lines.push(`- **runId**: ${escapeMarkdown(
|
|
19692
|
-
if (
|
|
19693
|
-
lines.push(`- **status**: ${escapeMarkdown(String(
|
|
19785
|
+
lines.push(`- **runId**: ${escapeMarkdown(view2.runId)}`);
|
|
19786
|
+
if (view2.name !== void 0) lines.push(`- **name**: ${escapeMarkdown(view2.name)}`);
|
|
19787
|
+
lines.push(`- **status**: ${escapeMarkdown(String(view2.status ?? "unknown"))}`);
|
|
19694
19788
|
lines.push(
|
|
19695
|
-
`- **durationMs**: ${
|
|
19789
|
+
`- **durationMs**: ${view2.durationMs !== void 0 ? escapeMarkdown(String(view2.durationMs)) : "-"}`
|
|
19696
19790
|
);
|
|
19697
19791
|
lines.push(
|
|
19698
|
-
`- **startedAt**: ${
|
|
19792
|
+
`- **startedAt**: ${view2.startedAt !== void 0 ? escapeMarkdown(String(view2.startedAt)) : "-"}`
|
|
19699
19793
|
);
|
|
19700
19794
|
lines.push(
|
|
19701
|
-
`- **endedAt**: ${
|
|
19795
|
+
`- **endedAt**: ${view2.endedAt !== void 0 ? escapeMarkdown(String(view2.endedAt)) : "-"}`
|
|
19702
19796
|
);
|
|
19703
|
-
lines.push(`- **totalEvents**: ${
|
|
19797
|
+
lines.push(`- **totalEvents**: ${view2.metadata.totalEvents}`);
|
|
19704
19798
|
lines.push("");
|
|
19705
19799
|
lines.push("### Confidence breakdown");
|
|
19706
19800
|
lines.push("");
|
|
19707
19801
|
lines.push("| bucket | count |");
|
|
19708
19802
|
lines.push("| --- | --- |");
|
|
19709
|
-
for (const k of Object.keys(
|
|
19803
|
+
for (const k of Object.keys(view2.metadata.confidenceBreakdown).sort()) {
|
|
19710
19804
|
const key = k;
|
|
19711
19805
|
lines.push(
|
|
19712
|
-
`| ${escapeMarkdown(key)} | ${
|
|
19806
|
+
`| ${escapeMarkdown(key)} | ${view2.metadata.confidenceBreakdown[key]} |`
|
|
19713
19807
|
);
|
|
19714
19808
|
}
|
|
19715
19809
|
lines.push("");
|
|
@@ -19717,9 +19811,9 @@ function exportMarkdown(tree, options) {
|
|
|
19717
19811
|
lines.push("");
|
|
19718
19812
|
lines.push("| kind | count |");
|
|
19719
19813
|
lines.push("| --- | --- |");
|
|
19720
|
-
for (const k of Object.keys(
|
|
19814
|
+
for (const k of Object.keys(view2.metadata.kinds).sort()) {
|
|
19721
19815
|
const key = k;
|
|
19722
|
-
const c =
|
|
19816
|
+
const c = view2.metadata.kinds[key];
|
|
19723
19817
|
if (c > 0) lines.push(`| ${escapeMarkdown(key)} | ${c} |`);
|
|
19724
19818
|
}
|
|
19725
19819
|
lines.push("");
|
|
@@ -19728,11 +19822,11 @@ function exportMarkdown(tree, options) {
|
|
|
19728
19822
|
lines.push("");
|
|
19729
19823
|
lines.push("```text");
|
|
19730
19824
|
lines.push(
|
|
19731
|
-
|
|
19825
|
+
view2.children.length > 0 ? renderTreeAscii(view2.children) : "(no steps)"
|
|
19732
19826
|
);
|
|
19733
19827
|
lines.push("```");
|
|
19734
19828
|
lines.push("");
|
|
19735
|
-
const flat = flattenTree(
|
|
19829
|
+
const flat = flattenTree(view2);
|
|
19736
19830
|
const errors = flat.filter((n) => n.event.status === "error");
|
|
19737
19831
|
if (includeErrors && errors.length > 0) {
|
|
19738
19832
|
lines.push("## Errors");
|
|
@@ -29434,11 +29528,14 @@ async function bundleCommand(runIdArg, options = {}) {
|
|
|
29434
29528
|
...finding.action !== void 0 ? { action: finding.action } : {}
|
|
29435
29529
|
});
|
|
29436
29530
|
}
|
|
29437
|
-
|
|
29438
|
-
|
|
29439
|
-
|
|
29440
|
-
|
|
29441
|
-
|
|
29531
|
+
const persistedForRun = artifactEventsByRun.get(runId) ?? read.events.filter((event) => event.runId === runId);
|
|
29532
|
+
const presentationTrees = persistedInspectEventsToRunTrees(persistedForRun, {
|
|
29533
|
+
coalesceLifecycle: true,
|
|
29534
|
+
skipInvalid: true
|
|
29535
|
+
});
|
|
29536
|
+
const presentationTree = presentationTrees.find((candidate) => candidate.runId === runId) ?? presentationTrees[0] ?? artifactTree ?? read.runs.find((run) => run.runId === runId);
|
|
29537
|
+
if (presentationTree) {
|
|
29538
|
+
artifactTrees.push(presentationTree);
|
|
29442
29539
|
}
|
|
29443
29540
|
const status = safetyStatusFromAssess(artifactSafety.status);
|
|
29444
29541
|
checkRuns.push({
|
|
@@ -29449,8 +29546,17 @@ async function bundleCommand(runIdArg, options = {}) {
|
|
|
29449
29546
|
warnings: artifactSafety.summary.warnings,
|
|
29450
29547
|
findings: artifactSafety.summary.findings
|
|
29451
29548
|
});
|
|
29452
|
-
|
|
29453
|
-
|
|
29549
|
+
if (!presentationTree) {
|
|
29550
|
+
const message = `No run tree could be built for HTML presentation: ${runId}`;
|
|
29551
|
+
if (options.json) {
|
|
29552
|
+
console.log(writeJson4({ ok: false, error: message }).trimEnd());
|
|
29553
|
+
} else {
|
|
29554
|
+
console.error(`[AgentInspect] bundle failed: ${message}`);
|
|
29555
|
+
}
|
|
29556
|
+
process.exitCode = 1;
|
|
29557
|
+
return;
|
|
29558
|
+
}
|
|
29559
|
+
const runReport = exportRunTree(presentationTree, {
|
|
29454
29560
|
format: "html",
|
|
29455
29561
|
redacted: true,
|
|
29456
29562
|
redactionProfile: toReportProfile(profile)
|