Skip to content

Commit a78f3f3

Browse files
authored
Fix security cookbook comparison table layout (#3038)
1 parent 41ce358 commit a78f3f3

3 files changed

Lines changed: 230 additions & 60 deletions

File tree

examples/agents_sdk/security_review_helpers.py

Lines changed: 56 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1165,37 +1165,66 @@ def _text(value: Any, limit: int | None = 170) -> str:
11651165
# Model text stays literal; it cannot create Markdown links or images.
11661166
return "".join("\\" + char if char in "\\`*_{}[]()#+-.!|~$" else char for char in value)
11671167

1168-
def show_table(title: str, rows: Sequence[Mapping[str, Any]], columns: Sequence[str]):
1168+
def show_table(title: str, rows: Sequence[Mapping[str, Any]], columns: Sequence[str], *,
1169+
scrollable: bool = False):
11691170
rows = list(rows)
11701171
lines = [f"**{_text(title)}**", "",
11711172
"| " + " | ".join(map(_text, columns)) + " |",
11721173
"| " + " | ".join("---" for _ in columns) + " |"]
11731174
body = ["| " + " | ".join(_text(row.get(column, "")) for column in columns)
11741175
+ " |" for row in rows]
1175-
display(Markdown("\n".join((*lines, *body))))
1176-
1177-
def show_review_details(reviews: Mapping[str, Any]):
1178-
pending = [
1179-
(target, finding)
1180-
for target, bundle in reviews.items()
1181-
for finding in (bundle.provenance.findings if bundle.provenance else ())
1182-
if finding.disposition == "needs_review"
1183-
]
1184-
if not pending:
1185-
return
1186-
lines = ["**Findings that need more evidence**", ""]
1187-
for target, finding in pending:
1188-
location = f"{finding.source_path}:{finding.line}"
1189-
lines.extend([
1190-
f"**{_text(target)}{_text(location, None)}**", "",
1191-
f"Candidate: {_text(finding.candidate_id, None)}", "",
1192-
_text(finding.reason, None), "",
1193-
*(f"- Proof gap: {_text(gap, None)}" for gap in finding.proof_gaps), "",
1194-
])
1176+
if scrollable:
1177+
label = html.escape(f"{title} review results", quote=True)
1178+
opening = (f'<div role="region" aria-label="{label}" tabindex="0" '
1179+
'style="overflow-x: auto;">')
1180+
lines = [*lines[:2], opening, "", *lines[2:], *body, "", "</div>"]
1181+
else:
1182+
lines.extend(body)
11951183
display(Markdown("\n".join(lines)))
11961184

1197-
def result_rows(target: str, bundle: Any):
1198-
label = f"{target} / {', '.join(bundle.selected_scanners) or 'none'}"
1185+
def _finding_label(finding: Any) -> str:
1186+
words = finding.category.split("_")
1187+
category = " ".join(word.upper() if word in {"sql", "jwt", "tls"} else word for word in words)
1188+
return f"{finding.priority} / {category}"
1189+
1190+
def _source_link(snapshot: SourceSnapshot, finding: Any) -> Markdown:
1191+
path = _safe_path(finding.source_path)
1192+
source = snapshot.file(path)
1193+
repository = snapshot.source_url.rstrip("/")
1194+
revision = snapshot.source_revision
1195+
if (not re.fullmatch(r"https://github\.com/[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+", repository)
1196+
or not re.fullmatch(r"[0-9a-f]{40}", revision)
1197+
or finding.source_revision != revision or finding.source_sha256 != source.sha256
1198+
or type(finding.line) is not int or finding.line < 1):
1199+
raise EvidenceError("Display link does not match a pinned GitHub source record.")
1200+
file = PurePosixPath(path)
1201+
label = "/".join(file.parts[-2:])
1202+
if len(label) > 28:
1203+
label = file.name
1204+
if len(label) > 28:
1205+
label = f"{file.stem[:27 - len(file.suffix)]}{file.suffix}"
1206+
url = f"{repository}/blob/{revision}/{quote(path, safe='/')}#L{finding.line}"
1207+
return Markdown(f"[{_text(label, None)}:{finding.line}]({url})")
1208+
1209+
def show_review_details(reviews: Mapping[str, Any]):
1210+
lines = ["**Decision notes**", ""]
1211+
for target, bundle in reviews.items():
1212+
repository = bundle.snapshot.source_url.rstrip("/").rsplit("/", 1)[-1] if bundle.snapshot else target
1213+
for finding in (bundle.provenance.findings if bundle.provenance else ()):
1214+
location = _source_link(bundle.snapshot, finding).data
1215+
lines.extend([
1216+
f"**{_text(repository)} / {_text(_finding_label(finding))}{location}**", "",
1217+
f"Candidate: {_text(finding.candidate_id, None)} · {_text(finding.disposition)}", "",
1218+
_text(finding.reason, None), "",
1219+
*(f"- Proof gap: {_text(gap, None)}" for gap in finding.proof_gaps), "",
1220+
])
1221+
if not bundle.provenance and bundle.error:
1222+
lines.extend([f"**{_text(target)}{_text(bundle.status)}**", "",
1223+
_text(bundle.error, None), ""])
1224+
if len(lines) > 2:
1225+
display(Markdown("\n".join(lines)))
1226+
1227+
def result_rows(bundle: Any):
11991228
role_by_candidate = {
12001229
assessment.candidate_id: review.role
12011230
for review in bundle.specialist_reviews
@@ -1209,20 +1238,15 @@ def result_rows(target: str, bundle: Any):
12091238
for candidate in bundle.candidates:
12101239
model_finding = proposed.get(candidate.candidate_id)
12111240
final_finding = final.get(candidate.candidate_id)
1212-
reason = getattr(final_finding, "reason", None) or getattr(model_finding, "reason", "not reviewed")
1213-
gaps = getattr(final_finding, "proof_gaps", ()) or getattr(model_finding, "proof_gaps", ())
12141241
rows.append({
1215-
"target / scanners": label,
1216-
"signal": f"{candidate.priority} / {candidate.category}",
1217-
"source": f"{candidate.source_path}:{candidate.line}",
1242+
"finding": _finding_label(candidate),
1243+
"source": _source_link(bundle.snapshot, candidate),
12181244
"specialist": role_by_candidate.get(candidate.candidate_id, "not run"),
12191245
"validator": getattr(model_finding, "disposition", "not run"),
12201246
"final": getattr(final_finding, "disposition", "not adjudicated"),
1221-
"reason or gap": f"{reason} Proof gap: {', '.join(gaps)}" if gaps else reason,
12221247
})
12231248
if not rows:
1224-
rows.append({"target / scanners": label, "signal": bundle.status,
1249+
rows.append({"finding": bundle.status,
12251250
"source": "none", "specialist": "not run", "validator": "not run",
1226-
"final": "not adjudicated",
1227-
"reason or gap": bundle.error or "No candidates were reviewed."})
1251+
"final": "not adjudicated"})
12281252
return rows

0 commit comments

Comments
 (0)