Spaces:
Sleeping
Sleeping
Add compact activity log for Analyzer reference values
Browse files- Log metric reference values in compact format for manual verification
- Format: revenue=$394.3B, net_margin=25.3%, pe_trailing=32.5, beta=1.23
- Shortens large numbers (B/M) and removes dates for readability
- Creates audit trail: MCP data → Analyzer reference → SWOT output
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- src/nodes/analyzer.py +30 -0
src/nodes/analyzer.py
CHANGED
|
@@ -895,6 +895,32 @@ def _verify_reference_integrity(metric_lookup: dict, stored_hash: str) -> bool:
|
|
| 895 |
return _compute_reference_hash(metric_lookup) == stored_hash
|
| 896 |
|
| 897 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 898 |
# New institutional-grade prompt
|
| 899 |
ANALYZER_SYSTEM_PROMPT = """You are a senior financial analyst producing institutional-grade SWOT analyses.
|
| 900 |
|
|
@@ -1215,6 +1241,10 @@ def analyzer_node(state, workflow_id=None, progress_store=None):
|
|
| 1215 |
# Store metric reference for validation (Layer 1 hallucination prevention)
|
| 1216 |
state["metric_reference"] = metric_lookup
|
| 1217 |
state["metric_reference_hash"] = ref_hash
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1218 |
current_revision = 0
|
| 1219 |
|
| 1220 |
# In revision mode, add delay before LLM call to avoid rate limits
|
|
|
|
| 895 |
return _compute_reference_hash(metric_lookup) == stored_hash
|
| 896 |
|
| 897 |
|
| 898 |
+
def _format_reference_log(metric_lookup: dict) -> str:
|
| 899 |
+
"""Format metric reference as compact single-line log for activity display."""
|
| 900 |
+
if not metric_lookup:
|
| 901 |
+
return "No metrics extracted"
|
| 902 |
+
|
| 903 |
+
parts = []
|
| 904 |
+
for ref_id in sorted(metric_lookup.keys()):
|
| 905 |
+
entry = metric_lookup[ref_id]
|
| 906 |
+
key = entry.get("key", "unknown")
|
| 907 |
+
formatted = entry.get("formatted", "N/A")
|
| 908 |
+
# Shorten large numbers for compact display
|
| 909 |
+
if "$" in formatted and len(formatted) > 15:
|
| 910 |
+
# Convert $394,328,000,000 to $394.3B
|
| 911 |
+
raw = entry.get("raw_value", 0)
|
| 912 |
+
if isinstance(raw, (int, float)) and abs(raw) >= 1e9:
|
| 913 |
+
formatted = f"${raw/1e9:.1f}B"
|
| 914 |
+
elif isinstance(raw, (int, float)) and abs(raw) >= 1e6:
|
| 915 |
+
formatted = f"${raw/1e6:.0f}M"
|
| 916 |
+
# Remove "as of" date for compact display
|
| 917 |
+
if " (as of " in formatted:
|
| 918 |
+
formatted = formatted.split(" (as of ")[0]
|
| 919 |
+
parts.append(f"{key}={formatted}")
|
| 920 |
+
|
| 921 |
+
return ", ".join(parts)
|
| 922 |
+
|
| 923 |
+
|
| 924 |
# New institutional-grade prompt
|
| 925 |
ANALYZER_SYSTEM_PROMPT = """You are a senior financial analyst producing institutional-grade SWOT analyses.
|
| 926 |
|
|
|
|
| 1241 |
# Store metric reference for validation (Layer 1 hallucination prevention)
|
| 1242 |
state["metric_reference"] = metric_lookup
|
| 1243 |
state["metric_reference_hash"] = ref_hash
|
| 1244 |
+
# Log reference values for manual verification
|
| 1245 |
+
ref_log = _format_reference_log(metric_lookup)
|
| 1246 |
+
_add_activity_log(workflow_id, progress_store, "analyzer",
|
| 1247 |
+
f"Reference values: {ref_log}")
|
| 1248 |
current_revision = 0
|
| 1249 |
|
| 1250 |
# In revision mode, add delay before LLM call to avoid rate limits
|