Spaces:
Running
Running
Food Desert commited on
Commit ·
0ea3247
1
Parent(s): 6964fd9
Render architecture diagram as embedded static PNG in docs section
Browse files- app.py +36 -128
- docs/assets/architecture_overview.png +3 -0
- docs/space_overview.md +1 -36
app.py
CHANGED
|
@@ -5,6 +5,7 @@ import time
|
|
| 5 |
import json
|
| 6 |
import csv
|
| 7 |
import re
|
|
|
|
| 8 |
from datetime import datetime
|
| 9 |
from functools import lru_cache
|
| 10 |
from PIL import Image
|
|
@@ -24,6 +25,10 @@ from psq_rag.retrieval.state import (
|
|
| 24 |
)
|
| 25 |
from psq_rag.ui.group_ranked_display import rank_groups_from_tfidf, _load_enabled_groups
|
| 26 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
|
| 28 |
_CORPORATE_HARDBLOCK_PATTERNS = [
|
| 29 |
# Rating-like explicitness markers.
|
|
@@ -114,8 +119,8 @@ def _load_tag_wiki_defs() -> Dict[str, str]:
|
|
| 114 |
@lru_cache(maxsize=1)
|
| 115 |
def _load_about_docs_markdown() -> str:
|
| 116 |
candidates = [
|
| 117 |
-
|
| 118 |
-
|
| 119 |
]
|
| 120 |
for p in candidates:
|
| 121 |
if not p.exists():
|
|
@@ -132,6 +137,15 @@ def _load_about_docs_markdown() -> str:
|
|
| 132 |
parts = text.split("---", 2)
|
| 133 |
if len(parts) >= 3:
|
| 134 |
text = parts[2].strip()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 135 |
if text:
|
| 136 |
return text
|
| 137 |
return (
|
|
@@ -155,6 +169,20 @@ def _tooltip_text_for_tag(tag: str) -> str:
|
|
| 155 |
return "\n".join(parts).strip()
|
| 156 |
|
| 157 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 158 |
def _selection_source_rank(origin: str) -> int:
|
| 159 |
o = _normalize_selection_origin(origin)
|
| 160 |
if o == "structural":
|
|
@@ -1399,29 +1427,12 @@ css = """
|
|
| 1399 |
line-height: 1.42 !important;
|
| 1400 |
}
|
| 1401 |
|
| 1402 |
-
.about-docs
|
| 1403 |
-
|
| 1404 |
-
|
| 1405 |
-
|
| 1406 |
-
.about-docs .mermaid-diagram {
|
| 1407 |
-
background: #ffffff;
|
| 1408 |
border: 1px solid #d2d7e0;
|
| 1409 |
border-radius: 10px;
|
| 1410 |
-
|
| 1411 |
-
margin: 10px 0;
|
| 1412 |
-
overflow-x: auto;
|
| 1413 |
-
}
|
| 1414 |
-
|
| 1415 |
-
.about-docs .mermaid-diagram svg {
|
| 1416 |
-
min-width: 920px;
|
| 1417 |
-
max-width: none;
|
| 1418 |
-
height: auto !important;
|
| 1419 |
-
}
|
| 1420 |
-
|
| 1421 |
-
.about-docs .mermaid-diagram .nodeLabel p,
|
| 1422 |
-
.about-docs .mermaid-diagram .edgeLabel p {
|
| 1423 |
-
margin: 0 !important;
|
| 1424 |
-
line-height: 1.2 !important;
|
| 1425 |
}
|
| 1426 |
|
| 1427 |
.top-instruction {
|
|
@@ -1472,108 +1483,6 @@ css = """
|
|
| 1472 |
|
| 1473 |
client_js = """
|
| 1474 |
() => {
|
| 1475 |
-
let mermaidInit = null;
|
| 1476 |
-
|
| 1477 |
-
const ensureMermaid = async () => {
|
| 1478 |
-
if (window.mermaid) return window.mermaid;
|
| 1479 |
-
if (mermaidInit) return mermaidInit;
|
| 1480 |
-
mermaidInit = new Promise((resolve, reject) => {
|
| 1481 |
-
const script = document.createElement("script");
|
| 1482 |
-
script.src = "https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.min.js";
|
| 1483 |
-
script.async = true;
|
| 1484 |
-
script.onload = () => {
|
| 1485 |
-
try {
|
| 1486 |
-
window.mermaid.initialize({
|
| 1487 |
-
startOnLoad: false,
|
| 1488 |
-
securityLevel: "loose",
|
| 1489 |
-
theme: "base",
|
| 1490 |
-
flowchart: {
|
| 1491 |
-
htmlLabels: false,
|
| 1492 |
-
padding: 18,
|
| 1493 |
-
nodeSpacing: 42,
|
| 1494 |
-
rankSpacing: 56,
|
| 1495 |
-
},
|
| 1496 |
-
themeVariables: {
|
| 1497 |
-
primaryColor: "#e8f0ff",
|
| 1498 |
-
primaryTextColor: "#111827",
|
| 1499 |
-
primaryBorderColor: "#365e9d",
|
| 1500 |
-
secondaryColor: "#edf7ef",
|
| 1501 |
-
secondaryTextColor: "#111827",
|
| 1502 |
-
secondaryBorderColor: "#2f7a3f",
|
| 1503 |
-
lineColor: "#334155",
|
| 1504 |
-
textColor: "#111827",
|
| 1505 |
-
fontSize: "15px",
|
| 1506 |
-
noteBkgColor: "#fffbe8",
|
| 1507 |
-
noteBorderColor: "#8b6c00",
|
| 1508 |
-
noteTextColor: "#111827"
|
| 1509 |
-
},
|
| 1510 |
-
});
|
| 1511 |
-
resolve(window.mermaid);
|
| 1512 |
-
} catch (e) {
|
| 1513 |
-
reject(e);
|
| 1514 |
-
}
|
| 1515 |
-
};
|
| 1516 |
-
script.onerror = () => reject(new Error("mermaid load failed"));
|
| 1517 |
-
document.head.appendChild(script);
|
| 1518 |
-
});
|
| 1519 |
-
try {
|
| 1520 |
-
return await mermaidInit;
|
| 1521 |
-
} catch (_) {
|
| 1522 |
-
return null;
|
| 1523 |
-
}
|
| 1524 |
-
};
|
| 1525 |
-
|
| 1526 |
-
const renderAboutMermaid = async () => {
|
| 1527 |
-
const root = document.querySelector("#about-docs");
|
| 1528 |
-
if (!root) return;
|
| 1529 |
-
const extractMermaid = (text) => {
|
| 1530 |
-
const raw = (text || "").trim();
|
| 1531 |
-
if (!raw) return "";
|
| 1532 |
-
const rx = /(flowchart|sequenceDiagram|graph|classDiagram|stateDiagram|erDiagram)\\b[\\s\\S]*/i;
|
| 1533 |
-
const m = raw.match(rx);
|
| 1534 |
-
if (!m) return "";
|
| 1535 |
-
return (m[0] || "").trim();
|
| 1536 |
-
};
|
| 1537 |
-
|
| 1538 |
-
const candidates = [];
|
| 1539 |
-
const codeBlocks = root.querySelectorAll("pre code.language-mermaid");
|
| 1540 |
-
for (const codeEl of codeBlocks) {
|
| 1541 |
-
const pre = codeEl.closest("pre");
|
| 1542 |
-
if (!pre || pre.dataset.psqMermaidDone === "1") continue;
|
| 1543 |
-
const src = extractMermaid(codeEl.textContent || "");
|
| 1544 |
-
if (src) candidates.push({ container: pre, src });
|
| 1545 |
-
}
|
| 1546 |
-
|
| 1547 |
-
// Hugging Face sometimes flattens mermaid blocks into plain paragraph text.
|
| 1548 |
-
const paraBlocks = root.querySelectorAll("p");
|
| 1549 |
-
for (const p of paraBlocks) {
|
| 1550 |
-
if (!p || p.dataset.psqMermaidDone === "1") continue;
|
| 1551 |
-
if (p.closest("pre")) continue;
|
| 1552 |
-
if (p.classList.contains("mermaid-diagram")) continue;
|
| 1553 |
-
const src = extractMermaid(p.textContent || "");
|
| 1554 |
-
if (src) candidates.push({ container: p, src });
|
| 1555 |
-
}
|
| 1556 |
-
|
| 1557 |
-
if (!candidates.length) return;
|
| 1558 |
-
const mermaid = await ensureMermaid();
|
| 1559 |
-
if (!mermaid) return;
|
| 1560 |
-
|
| 1561 |
-
for (const { container, src } of candidates) {
|
| 1562 |
-
if (!container || container.dataset.psqMermaidDone === "1") continue;
|
| 1563 |
-
try {
|
| 1564 |
-
const id = "psq-mermaid-" + Math.random().toString(36).slice(2);
|
| 1565 |
-
const out = await mermaid.render(id, src);
|
| 1566 |
-
const host = document.createElement("div");
|
| 1567 |
-
host.className = "mermaid-diagram";
|
| 1568 |
-
host.innerHTML = out.svg;
|
| 1569 |
-
container.replaceWith(host);
|
| 1570 |
-
container.dataset.psqMermaidDone = "1";
|
| 1571 |
-
} catch (_) {
|
| 1572 |
-
// Keep raw markdown mermaid block visible if render fails.
|
| 1573 |
-
}
|
| 1574 |
-
}
|
| 1575 |
-
};
|
| 1576 |
-
|
| 1577 |
const readTooltipMap = () => {
|
| 1578 |
const el = document.querySelector("#psq-tooltip-map textarea, #psq-tooltip-map input");
|
| 1579 |
if (!el) return { rows: [], tips: {} };
|
|
@@ -1620,7 +1529,6 @@ client_js = """
|
|
| 1620 |
requestAnimationFrame(() => {
|
| 1621 |
scheduled = false;
|
| 1622 |
applyTooltips();
|
| 1623 |
-
void renderAboutMermaid();
|
| 1624 |
});
|
| 1625 |
};
|
| 1626 |
|
|
@@ -2384,5 +2292,5 @@ with gr.Blocks(css=css, js=client_js) as app:
|
|
| 2384 |
show_progress="hidden",
|
| 2385 |
)
|
| 2386 |
|
| 2387 |
-
if __name__ == "__main__":
|
| 2388 |
-
app.queue().launch(allowed_paths=[str(MASCOT_DIR)])
|
|
|
|
| 5 |
import json
|
| 6 |
import csv
|
| 7 |
import re
|
| 8 |
+
import base64
|
| 9 |
from datetime import datetime
|
| 10 |
from functools import lru_cache
|
| 11 |
from PIL import Image
|
|
|
|
| 25 |
)
|
| 26 |
from psq_rag.ui.group_ranked_display import rank_groups_from_tfidf, _load_enabled_groups
|
| 27 |
|
| 28 |
+
APP_DIR = Path(__file__).parent
|
| 29 |
+
DOCS_DIR = APP_DIR / "docs"
|
| 30 |
+
ARCH_DIAGRAM_FILE = DOCS_DIR / "assets" / "architecture_overview.png"
|
| 31 |
+
|
| 32 |
|
| 33 |
_CORPORATE_HARDBLOCK_PATTERNS = [
|
| 34 |
# Rating-like explicitness markers.
|
|
|
|
| 119 |
@lru_cache(maxsize=1)
|
| 120 |
def _load_about_docs_markdown() -> str:
|
| 121 |
candidates = [
|
| 122 |
+
DOCS_DIR / "space_overview.md",
|
| 123 |
+
APP_DIR / "PROJECT_SUMMARY.md",
|
| 124 |
]
|
| 125 |
for p in candidates:
|
| 126 |
if not p.exists():
|
|
|
|
| 137 |
parts = text.split("---", 2)
|
| 138 |
if len(parts) >= 3:
|
| 139 |
text = parts[2].strip()
|
| 140 |
+
if "{{ARCHITECTURE_DIAGRAM}}" in text:
|
| 141 |
+
arch_uri = _load_arch_diagram_data_uri()
|
| 142 |
+
if arch_uri:
|
| 143 |
+
text = text.replace(
|
| 144 |
+
"{{ARCHITECTURE_DIAGRAM}}",
|
| 145 |
+
f'<img src="{arch_uri}" alt="Architecture diagram" />',
|
| 146 |
+
)
|
| 147 |
+
else:
|
| 148 |
+
text = text.replace("{{ARCHITECTURE_DIAGRAM}}", "`(architecture diagram unavailable)`")
|
| 149 |
if text:
|
| 150 |
return text
|
| 151 |
return (
|
|
|
|
| 169 |
return "\n".join(parts).strip()
|
| 170 |
|
| 171 |
|
| 172 |
+
@lru_cache(maxsize=1)
|
| 173 |
+
def _load_arch_diagram_data_uri() -> str:
|
| 174 |
+
if not ARCH_DIAGRAM_FILE.exists():
|
| 175 |
+
return ""
|
| 176 |
+
try:
|
| 177 |
+
raw = ARCH_DIAGRAM_FILE.read_bytes()
|
| 178 |
+
except Exception:
|
| 179 |
+
return ""
|
| 180 |
+
if not raw:
|
| 181 |
+
return ""
|
| 182 |
+
b64 = base64.b64encode(raw).decode("ascii")
|
| 183 |
+
return f"data:image/png;base64,{b64}"
|
| 184 |
+
|
| 185 |
+
|
| 186 |
def _selection_source_rank(origin: str) -> int:
|
| 187 |
o = _normalize_selection_origin(origin)
|
| 188 |
if o == "structural":
|
|
|
|
| 1427 |
line-height: 1.42 !important;
|
| 1428 |
}
|
| 1429 |
|
| 1430 |
+
.about-docs img {
|
| 1431 |
+
max-width: 100% !important;
|
| 1432 |
+
height: auto !important;
|
|
|
|
|
|
|
|
|
|
| 1433 |
border: 1px solid #d2d7e0;
|
| 1434 |
border-radius: 10px;
|
| 1435 |
+
background: #ffffff;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1436 |
}
|
| 1437 |
|
| 1438 |
.top-instruction {
|
|
|
|
| 1483 |
|
| 1484 |
client_js = """
|
| 1485 |
() => {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1486 |
const readTooltipMap = () => {
|
| 1487 |
const el = document.querySelector("#psq-tooltip-map textarea, #psq-tooltip-map input");
|
| 1488 |
if (!el) return { rows: [], tips: {} };
|
|
|
|
| 1529 |
requestAnimationFrame(() => {
|
| 1530 |
scheduled = false;
|
| 1531 |
applyTooltips();
|
|
|
|
| 1532 |
});
|
| 1533 |
};
|
| 1534 |
|
|
|
|
| 2292 |
show_progress="hidden",
|
| 2293 |
)
|
| 2294 |
|
| 2295 |
+
if __name__ == "__main__":
|
| 2296 |
+
app.queue().launch(allowed_paths=[str(MASCOT_DIR), str(DOCS_DIR)])
|
docs/assets/architecture_overview.png
ADDED
|
Git LFS Details
|
docs/space_overview.md
CHANGED
|
@@ -15,42 +15,7 @@ Design goals:
|
|
| 15 |
|
| 16 |
## Architecture At A Glance
|
| 17 |
|
| 18 |
-
|
| 19 |
-
flowchart TB
|
| 20 |
-
U["User Prompt"] --> P["Orchestrator app.py"]
|
| 21 |
-
|
| 22 |
-
subgraph LLM["LLM Calls"]
|
| 23 |
-
direction LR
|
| 24 |
-
R["Rewrite"]
|
| 25 |
-
S["Structural Inference"]
|
| 26 |
-
Q["Probe Inference"]
|
| 27 |
-
X["Closed-Set Selection"]
|
| 28 |
-
end
|
| 29 |
-
|
| 30 |
-
C["Retrieval Candidates"]
|
| 31 |
-
|
| 32 |
-
subgraph OUT["Output"]
|
| 33 |
-
direction LR
|
| 34 |
-
I["Implication Expansion"]
|
| 35 |
-
G["Ranked Rows"]
|
| 36 |
-
UI["Toggle UI and Suggested Prompt"]
|
| 37 |
-
end
|
| 38 |
-
|
| 39 |
-
P --> R
|
| 40 |
-
P --> S
|
| 41 |
-
P --> Q
|
| 42 |
-
R --> C
|
| 43 |
-
S --> C
|
| 44 |
-
Q --> C
|
| 45 |
-
C --> X
|
| 46 |
-
S --> X
|
| 47 |
-
Q --> X
|
| 48 |
-
X --> I
|
| 49 |
-
I --> G
|
| 50 |
-
G --> UI
|
| 51 |
-
|
| 52 |
-
style LLM fill:#f3e8ff,stroke:#6d28d9,stroke-width:2px,color:#111827
|
| 53 |
-
```
|
| 54 |
|
| 55 |
## What Each Step Does
|
| 56 |
|
|
|
|
| 15 |
|
| 16 |
## Architecture At A Glance
|
| 17 |
|
| 18 |
+
{{ARCHITECTURE_DIAGRAM}}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
|
| 20 |
## What Each Step Does
|
| 21 |
|