"""Format context-free coach debug paste bundles for external AI review. Bundles include formulas, evidence, prompts, raw output, and checklist. """ from __future__ import annotations import json from typing import Any def render_paste_bundle(trace: dict[str, Any], *, app_name: str, shrink_k: float, match_alpha: float, min_n: int) -> str: """Render the exact markdown paste bundle from a stored trace.""" evidence = trace.get("evidence") or {} evidence_block = evidence.get("evidence_block") or json.dumps(evidence, indent=2) picks = json.dumps(trace.get("server_picks") or [], indent=2, ensure_ascii=False) current = json.dumps(trace.get("current") or {}, indent=2, ensure_ascii=False) history = json.dumps(trace.get("history_truncated") or [], indent=2, ensure_ascii=False) parsed = json.dumps(trace.get("parsed"), indent=2, ensure_ascii=False) return f"""# Coach Trace Paste Bundle (context-free) app: {app_name} | version: {trace.get('app_version')} | trace_id: {trace.get('trace_id')} | ts: {trace.get('ts')} ## How to help You have NO prior context about the user. Use ONLY this bundle. Do not ask for biography. Critique prompts, math, backup rules, and free-model fitness. Output: (1) findings (2) concrete patch list for backend prompts/rules/math weights. ## Math definitions (server authoritative) - pending excluded from denominators - p_worked(r) = N(worked,r) / N(r) - p_helped(r) = N(worked|partial,r) / N(r) - rank(r) = p_helped * n/(n+k) with k={shrink_k} - pick(r) = rank * (1 + alpha * match) with alpha={match_alpha} - min_n = {min_n} - DATA_THIN if n_scored < 10 ## Server evidence {evidence_block} ## Server picks {picks} ## Current situation {current} ## Recent history (truncated) {history} ## System prompt {trace.get('system_prompt') or ''} ## User prompt {trace.get('user_prompt') or ''} ## Model raw response {trace.get('raw_model_response') or ''} ## Parse / source / flags source: {trace.get('source')} backup_rule_id: {trace.get('backup_rule_id')} flags: {trace.get('flags')} parsed: {parsed} ## Final text shown to user {trace.get('final_text') or ''} ## Reviewer checklist 1. Invented numbers? 2. Ignored SERVER_PICKS? 3. Format broken (free model)? 4. Backup better? 5. Evidence too long/short? 6. Shrinkage k / alpha tweak? """