Commit Β·
6a3b169
1
Parent(s): 61ab293
[KM-680] feat(report): markdown section separators + inline emphasis in summary
Browse files- Render a horizontal rule (---) between the header and each report section so it reads as a formal, sectioned document.
- Relax report_summary.md: the executive summary MAY use inline **bold**/*italic* for emphasis (kept no-headings/no-bullets so it doesn't duplicate the section structure or Key Findings).
- Tables / bold (method labels) / italic (meta + citations) were already emitted. Closes DEV_PLAN #23.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- DEV_PLAN.md +1 -1
- src/agents/report/generator.py +4 -3
- src/config/prompts/report_summary.md +2 -1
DEV_PLAN.md
CHANGED
|
@@ -132,7 +132,7 @@ Status legend: β¬ not started Β· π in progress Β· β
done Β· β blocked Β·
|
|
| 132 |
| 20 | **Help handoff:** update `handlers/help.py` + `help.md` β drop the `problem_validated` tier + `define_problem_statement` action (the skill it points at is gone as of #1) | Sofhia | β
| Done 2026-06-25. `help.py`: actions = `ask_analysis_question` (always) + `generate_report` (if ready); renders objective/business_questions (getattr-tolerant). `help.md` v1βv2: 3 tiers, no `/problem_statement`, `/generate report`β`/report`. Local test_help updated β 11 pass |
|
| 133 |
| 21 | Rename `analysis_records` β **`agent_observability`** (model, `slow_path/store.py`, readers, `init_db`) | Rifqi | β¬ new | Checkpoint: no "record" in the name (clashes w/ Go `analysis_message`). Confirm write scope: every agent call vs slow-path-only |
|
| 134 |
| 22 | Finalize `agent_observability` schema β hand to Harry for the dedorch migration/startup | Rifqi β Harry | β¬ new | Resolves #16 (table created post-cutover). Python still creates it locally until then |
|
| 135 |
-
| 23 | Report markdown formatting: tables, **bold**, *italic*, horizontal separators | Sofhia |
|
| 136 |
| 24 | Clarify report input contract: records table (+ `last_report` for edit mode?) | Rifqi/Sofhia β Harry | β¬ new | Edit-mode input left open at the checkpoint |
|
| 137 |
| 25 | Confirm Python history source = Go `analysis_message` | Rifqi β Harry | β¬ new | New chat-room table (Q + A); replaces `chat_messages` for analyses |
|
| 138 |
| 26 | **Charts (DEFERRED):** store Plotly JSON in a future `chart` table (not matplotlib PNG) | β | βΈοΈ | After the markdown path is done end-to-end |
|
|
|
|
| 132 |
| 20 | **Help handoff:** update `handlers/help.py` + `help.md` β drop the `problem_validated` tier + `define_problem_statement` action (the skill it points at is gone as of #1) | Sofhia | β
| Done 2026-06-25. `help.py`: actions = `ask_analysis_question` (always) + `generate_report` (if ready); renders objective/business_questions (getattr-tolerant). `help.md` v1βv2: 3 tiers, no `/problem_statement`, `/generate report`β`/report`. Local test_help updated β 11 pass |
|
| 133 |
| 21 | Rename `analysis_records` β **`agent_observability`** (model, `slow_path/store.py`, readers, `init_db`) | Rifqi | β¬ new | Checkpoint: no "record" in the name (clashes w/ Go `analysis_message`). Confirm write scope: every agent call vs slow-path-only |
|
| 134 |
| 22 | Finalize `agent_observability` schema β hand to Harry for the dedorch migration/startup | Rifqi β Harry | β¬ new | Resolves #16 (table created post-cutover). Python still creates it locally until then |
|
| 135 |
+
| 23 | Report markdown formatting: tables, **bold**, *italic*, horizontal separators | Sofhia | β
| Done 2026-06-25. Added `---` separators between header + each section in `_render_markdown`. Tables (EDA) / bold (method labels) / italic (meta + citations) already emitted. Relaxed `report_summary.md` to allow inline `**bold**`/`*italic*` for emphasis (kept no-headings/no-bullets so it doesn't duplicate the section structure / Key Findings). Compile + ruff clean |
|
| 136 |
| 24 | Clarify report input contract: records table (+ `last_report` for edit mode?) | Rifqi/Sofhia β Harry | β¬ new | Edit-mode input left open at the checkpoint |
|
| 137 |
| 25 | Confirm Python history source = Go `analysis_message` | Rifqi β Harry | β¬ new | New chat-room table (Q + A); replaces `chat_messages` for analyses |
|
| 138 |
| 26 | **Charts (DEFERRED):** store Plotly JSON in a future `chart` table (not matplotlib PNG) | β | βΈοΈ | After the markdown path is done end-to-end |
|
src/agents/report/generator.py
CHANGED
|
@@ -185,13 +185,14 @@ def _build_human_content(
|
|
| 185 |
def _render_markdown(report: AnalysisReport) -> str:
|
| 186 |
# Version is deliberately NOT in the markdown β it is assigned by the store
|
| 187 |
# after rendering and lives in the structured `version` field / API metadata.
|
| 188 |
-
parts: list[str] = ["# Analysis Report"]
|
| 189 |
meta = f"*Generated {report.generated_at:%Y-%m-%d}"
|
| 190 |
author = report.user_name or report.user_id
|
| 191 |
if author:
|
| 192 |
meta += f" by {author}"
|
| 193 |
meta += f" Β· {len(report.record_ids)} analyses Β· {len(report.data_sources)} source(s)*"
|
| 194 |
-
|
|
|
|
|
|
|
| 195 |
|
| 196 |
ps = report.problem_statement
|
| 197 |
if ps.objective:
|
|
@@ -248,7 +249,7 @@ def _render_markdown(report: AnalysisReport) -> str:
|
|
| 248 |
lines.append(f"**{label}** β {rendered}")
|
| 249 |
parts.append("\n".join(lines))
|
| 250 |
|
| 251 |
-
return "\n\n".join(parts)
|
| 252 |
|
| 253 |
|
| 254 |
# --------------------------------------------------------------------------- #
|
|
|
|
| 185 |
def _render_markdown(report: AnalysisReport) -> str:
|
| 186 |
# Version is deliberately NOT in the markdown β it is assigned by the store
|
| 187 |
# after rendering and lives in the structured `version` field / API metadata.
|
|
|
|
| 188 |
meta = f"*Generated {report.generated_at:%Y-%m-%d}"
|
| 189 |
author = report.user_name or report.user_id
|
| 190 |
if author:
|
| 191 |
meta += f" by {author}"
|
| 192 |
meta += f" Β· {len(report.record_ids)} analyses Β· {len(report.data_sources)} source(s)*"
|
| 193 |
+
# Title + meta form the header block; each subsequent section is divided by a
|
| 194 |
+
# horizontal rule (`---`) so the report reads as a formal, sectioned document.
|
| 195 |
+
parts: list[str] = ["# Analysis Report\n" + meta]
|
| 196 |
|
| 197 |
ps = report.problem_statement
|
| 198 |
if ps.objective:
|
|
|
|
| 249 |
lines.append(f"**{label}** β {rendered}")
|
| 250 |
parts.append("\n".join(lines))
|
| 251 |
|
| 252 |
+
return "\n\n---\n\n".join(parts)
|
| 253 |
|
| 254 |
|
| 255 |
# --------------------------------------------------------------------------- #
|
src/config/prompts/report_summary.md
CHANGED
|
@@ -7,4 +7,5 @@ Rules:
|
|
| 7 |
- Do NOT introduce any number, fact, or claim that is not present in the findings. You are summarizing, not analyzing.
|
| 8 |
- Do NOT simply restate every finding; connect them into a narrative and say what they mean for the objective.
|
| 9 |
- If the findings are thin or inconclusive, say so plainly rather than overstating.
|
| 10 |
-
- Plain business language
|
|
|
|
|
|
| 7 |
- Do NOT introduce any number, fact, or claim that is not present in the findings. You are summarizing, not analyzing.
|
| 8 |
- Do NOT simply restate every finding; connect them into a narrative and say what they mean for the objective.
|
| 9 |
- If the findings are thin or inconclusive, say so plainly rather than overstating.
|
| 10 |
+
- Plain business language. Write **prose only β no headings, no bullet lists** (the report already supplies the section structure and a Key Findings list below this summary; do not duplicate them).
|
| 11 |
+
- You MAY use light inline markdown for emphasis within the prose β `**bold**` for the most decision-relevant figure or term, `*italic*` sparingly. Keep it subtle; do not bold whole sentences.
|