Jeremy Live
commited on
Commit
·
e7eb58c
1
Parent(s):
9f4148c
Revert "mhv2"
Browse filesThis reverts commit 9f4148c1d41eacbcd8b54880d9d0544b04dafa0f.
app.py
CHANGED
@@ -482,30 +482,6 @@ def is_db_intent(question: str) -> bool:
|
|
482 |
except Exception:
|
483 |
return False
|
484 |
|
485 |
-
def extract_label_value_pairs(text: str) -> List[Dict[str, Union[str, float]]]:
|
486 |
-
"""Extract pairs like 'LABEL: NUMBER' from free text."""
|
487 |
-
pairs: List[Dict[str, Union[str, float]]] = []
|
488 |
-
if not text:
|
489 |
-
return pairs
|
490 |
-
try:
|
491 |
-
raw_lines = text.split('\n')
|
492 |
-
for line in raw_lines:
|
493 |
-
s = line.strip()
|
494 |
-
if not s:
|
495 |
-
continue
|
496 |
-
s = s.lstrip('•*\t -')
|
497 |
-
m = re.match(r"^(.+?):\s*([0-9][0-9.,]*)$", s)
|
498 |
-
if m:
|
499 |
-
label = re.sub(r"[*_`]+", "", m.group(1)).strip()
|
500 |
-
try:
|
501 |
-
value = float(m.group(2).replace(',', ''))
|
502 |
-
pairs.append({"label": label, "value": value})
|
503 |
-
except Exception:
|
504 |
-
continue
|
505 |
-
return pairs
|
506 |
-
except Exception:
|
507 |
-
return pairs
|
508 |
-
|
509 |
def generate_plot(data, x_col, y_col, title, x_label, y_label):
|
510 |
"""Generate a plot from data and return the file path."""
|
511 |
plt.figure(figsize=(10, 6))
|
@@ -770,21 +746,44 @@ async def stream_agent_response(question: str, chat_history: List[List[str]], se
|
|
770 |
logger.error(f"Second-pass SQL synthesis failed: {e}")
|
771 |
|
772 |
# Fallback: if user asked for a chart and we didn't get SQL or chart yet,
|
773 |
-
#
|
774 |
if chart_fig is None:
|
775 |
wants_chart, desired_type = detect_chart_preferences(question)
|
776 |
if wants_chart:
|
|
|
777 |
candidate_text = ""
|
778 |
-
|
779 |
-
if isinstance(response_text, str) and response_text.strip():
|
780 |
-
candidate_text = response_text
|
781 |
-
# Otherwise look back at the latest assistant turn in history
|
782 |
-
if not candidate_text and chat_history:
|
783 |
for pair in reversed(chat_history):
|
784 |
if len(pair) >= 2 and isinstance(pair[1], str) and pair[1].strip():
|
785 |
candidate_text = pair[1]
|
786 |
break
|
787 |
-
data
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
788 |
logger.info(f"Fallback parse from text: extracted {len(data)} items for potential chart")
|
789 |
if len(data) >= 2:
|
790 |
chart_fig = generate_chart(
|
@@ -794,14 +793,8 @@ async def stream_agent_response(question: str, chat_history: List[List[str]], se
|
|
794 |
y="value",
|
795 |
title="Distribución"
|
796 |
)
|
797 |
-
|
798 |
-
|
799 |
-
response_text = (
|
800 |
-
f"Gráfico {('de barras' if desired_type=='bar' else desired_type)} "
|
801 |
-
f"con {len(data)} categorías basado en los datos previos."
|
802 |
-
)
|
803 |
-
if chart_fig is not None:
|
804 |
-
logger.info(f"Chart generated from text fallback: type={desired_type}, items={len(data)}")
|
805 |
|
806 |
# Update the assistant's message with the response
|
807 |
assistant_message["content"] = response_text
|
|
|
482 |
except Exception:
|
483 |
return False
|
484 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
485 |
def generate_plot(data, x_col, y_col, title, x_label, y_label):
|
486 |
"""Generate a plot from data and return the file path."""
|
487 |
plt.figure(figsize=(10, 6))
|
|
|
746 |
logger.error(f"Second-pass SQL synthesis failed: {e}")
|
747 |
|
748 |
# Fallback: if user asked for a chart and we didn't get SQL or chart yet,
|
749 |
+
# parse the most recent assistant text for lines like "LABEL: NUMBER" (bulleted or plain).
|
750 |
if chart_fig is None:
|
751 |
wants_chart, desired_type = detect_chart_preferences(question)
|
752 |
if wants_chart:
|
753 |
+
# Find the most recent assistant message with usable numeric pairs
|
754 |
candidate_text = ""
|
755 |
+
if chat_history:
|
|
|
|
|
|
|
|
|
756 |
for pair in reversed(chat_history):
|
757 |
if len(pair) >= 2 and isinstance(pair[1], str) and pair[1].strip():
|
758 |
candidate_text = pair[1]
|
759 |
break
|
760 |
+
# Also consider current response_text as a data source
|
761 |
+
if not candidate_text and isinstance(response_text, str) and response_text.strip():
|
762 |
+
candidate_text = response_text
|
763 |
+
if candidate_text:
|
764 |
+
raw_lines = candidate_text.split('\n')
|
765 |
+
# Normalize lines: strip bullets and markdown symbols
|
766 |
+
norm_lines = []
|
767 |
+
for l in raw_lines:
|
768 |
+
s = l.strip()
|
769 |
+
if not s:
|
770 |
+
continue
|
771 |
+
s = s.lstrip("•*-\t ")
|
772 |
+
# Remove surrounding markdown emphasis from labels later
|
773 |
+
norm_lines.append(s)
|
774 |
+
data = []
|
775 |
+
for l in norm_lines:
|
776 |
+
# Accept patterns like "**LABEL**: 123" or "LABEL: 1,234"
|
777 |
+
m = re.match(r"^(.+?):\s*([0-9][0-9.,]*)$", l)
|
778 |
+
if m:
|
779 |
+
label = m.group(1).strip()
|
780 |
+
# Strip common markdown emphasis
|
781 |
+
label = re.sub(r"[*_`]+", "", label).strip()
|
782 |
+
try:
|
783 |
+
val = float(m.group(2).replace(',', ''))
|
784 |
+
except Exception:
|
785 |
+
continue
|
786 |
+
data.append({"label": label, "value": val})
|
787 |
logger.info(f"Fallback parse from text: extracted {len(data)} items for potential chart")
|
788 |
if len(data) >= 2:
|
789 |
chart_fig = generate_chart(
|
|
|
793 |
y="value",
|
794 |
title="Distribución"
|
795 |
)
|
796 |
+
if chart_fig is not None:
|
797 |
+
logger.info(f"Chart generated from text fallback: type={desired_type}, items={len(data)}")
|
|
|
|
|
|
|
|
|
|
|
|
|
798 |
|
799 |
# Update the assistant's message with the response
|
800 |
assistant_message["content"] = response_text
|