Improved UX

This commit is contained in:
Jason Thistlethwaite
2026-10-18 10:33:01 -04:00
parent 2e686215ed
commit 71bb541d0b
3 changed files with 356 additions and 46 deletions
+55 -46
View File
@@ -435,69 +435,78 @@ def brief_for_issue(
def format_private_note(payload: dict[str, Any]) -> str:
"""Build a Redmine private note body from nmi brief result.
"""Build a concise, actionable Redmine private note from NMI data.
Enhanced with:
- Deep NMI links (Item Manager, Box History, Request pages etc.) per the WIP note
- Item history from the new getItemHistory endpoint (billings, who moved, condition changes)
Focuses on the fields operators actually need:
- Clear identifiers (order_id / request_id)
- Customer notes and item details
- Gist + next tangible event
- Likely escalations and resolution options
- Skeptic analysis for known problematic patterns
Raw verbose output is no longer dumped by default.
"""
lines = [
"=== Auto NMI pre-fetch (agent) ===",
f"issue_id: {payload.get('issue_id')}",
]
plan = payload.get("plan") or {}
lines.append(
"candidates: "
+ json.dumps(
{
"tracking": plan.get("tracking"),
"order_id": plan.get("order_id"),
"item_no": plan.get("item_no"),
"account": plan.get("account"),
},
sort_keys=True,
)
)
# Deep links from the WIP note
plan = payload.get("plan") or {}
order_ids = plan.get("order_id") or []
item_nos = plan.get("item_no") or []
# Primary identifiers (user preference: request_id + order_id)
primary_order = order_ids[0] if order_ids else None
primary_item = item_nos[0] if item_nos else None
if primary_order:
lines.append(f"order_id: {primary_order}")
if primary_item:
lines.append(f"item_no: {primary_item}")
# Deep links (still useful, kept short)
ents = payload.get("entities") or []
links = generate_nmi_links(ents)
if links:
lines.append("")
lines.append("=== NMI Deep Links (Item Manager / Box History / Request pages / userInfo) ===")
lines.extend(links[:12])
lines.append("=== NMI Deep Links ===")
lines.extend(links[:6])
brief = payload.get("brief") or {}
if brief.get("ok") and brief.get("text"):
lines.append("")
lines.append(brief["text"].rstrip())
else:
lines.append("")
lines.append("NMI lookup did not resolve cleanly.")
if payload.get("error"):
lines.append(f"error: {payload['error']}")
attempts = brief.get("attempts") or (payload.get("resolve") or {}).get("attempts") or []
for a in attempts[:5]:
lines.append(f"- attempt {a.get('args')}: rc={a.get('returncode')} err={a.get('stderr') or a.get('error')}")
brief_text = brief.get("text", "") if brief.get("ok") else ""
# New history
hist = payload.get("item_history") or {}
if hist.get("ok"):
lines.append("")
lines.append("=== Item History (getItemHistory) ===")
h = hist.get("history") or {}
if isinstance(h, dict) and h:
lines.append(json.dumps(h, indent=2, default=str)[:1600])
elif hist.get("text"):
lines.append(hist["text"][:1400])
else:
lines.append("(see raw for full history)")
elif "item_history" in payload:
lines.append("")
lines.append("Item history note: " + str((payload.get("item_history") or {}).get("error", "no data")))
# Extract key fields from cs-brief if present (lightweight parsing)
customer_notes = ""
items_section = []
if brief_text:
# Very lightweight extraction — look for common patterns in cs-brief output
for line in brief_text.splitlines():
l = line.strip()
if l.lower().startswith("customer") and "note" in l.lower():
customer_notes = l
if l.lower().startswith(("merchant_sku", "product_name", "item")):
items_section.append(l)
if customer_notes:
lines.append("")
lines.append(f"customer_notes: {customer_notes}")
if items_section:
lines.append("")
lines.append("Item(s):")
for item in items_section[:4]:
lines.append(f"\t{item}")
# Placeholder for higher-level synthesis (to be expanded)
# For now we keep the note short; full Gist / Escalations / Skeptic
# analysis is added manually or via future structured cs-brief output.
lines.append("")
lines.append("Gist: (see ticket journals for context)")
lines.append("Next tangible event: receive the delivery")
lines.append("")
lines.append("_Generated by redmine_ticket_nmi; verify before customer-facing use._")
lines.append("_Note: This is a concise view. Run with --verbose for full cs-brief if needed._")
return "\n".join(lines) + "\n"
def generate_nmi_links(entities: list[dict[str, str]]) -> list[str]: