Spaces:
Sleeping
Sleeping
polish: refine H2EPR Explorer presentation
Browse files- README.md +32 -37
- app.py +7 -8
- src/h2epr_explorer/constants.py +1 -7
- src/h2epr_explorer/data_loader.py +8 -8
README.md
CHANGED
|
@@ -8,61 +8,56 @@ license: apache-2.0
|
|
| 8 |
---
|
| 9 |
|
| 10 |
[](https://agenticfinlab.github.io/H2EPR-Bench/)
|
| 11 |
-
[](https://github.com/AgenticFinLab/FinMycelium)
|
| 13 |
[](https://huggingface.co/datasets/AgenticFinLab/H2EPR-Bench-Gold)
|
| 14 |
[](https://github.com/AgenticFinLab/H2EPR-Bench)
|
| 15 |
|
| 16 |
# H²EPR-Bench Explorer
|
| 17 |
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
Draft EPG
|
| 22 |
-
public per-event Draft EPG for every event.
|
| 23 |
|
| 24 |
-
|
| 25 |
-
artifacts. Official benchmark scoring uses expert-adjudicated reference EPGs in
|
| 26 |
-
the [manual-gated companion](https://huggingface.co/datasets/AgenticFinLab/H2EPR-Bench-Gold).
|
| 27 |
-
The Explorer does not load reference EPGs or frozen evidence packages.
|
| 28 |
|
| 29 |
-
|
| 30 |
-
|
|
|
|
|
|
|
|
|
|
| 31 |
|
| 32 |
-
|
|
|
|
|
|
|
| 33 |
|
| 34 |
-
|
|
|
|
|
|
|
|
|
|
| 35 |
|
| 36 |
| Table | Role |
|
| 37 |
|---|---|
|
| 38 |
-
| `event_gallery.parquet` | Lightweight event discovery
|
| 39 |
-
| `event_catalog.parquet` |
|
| 40 |
-
| `event_instances.parquet` |
|
| 41 |
-
| `finalcascade_summary.parquet` |
|
| 42 |
-
| `event_stages.parquet` | Ordered
|
| 43 |
-
|
| 44 |
-
Selected Draft EPGs are loaded directly from
|
| 45 |
-
`draft_events/<H2EPR-ID>/draft_epg.json`. The path is derived only after the
|
| 46 |
-
canonical event ID has been validated. `manifests/draft_source_hashes.csv`
|
| 47 |
-
binds every direct file to its canonical source-payload digest and sanitized
|
| 48 |
-
record digest; the Explorer verifies both identities and the canonical JSON
|
| 49 |
-
digest before displaying a graph.
|
| 50 |
|
| 51 |
-
|
| 52 |
-
`
|
| 53 |
-
|
|
|
|
| 54 |
|
| 55 |
## Local development
|
| 56 |
|
| 57 |
-
|
| 58 |
-
access:
|
| 59 |
|
| 60 |
-
|
| 61 |
export H2EPR_EXPLORER_LOCAL_DATASET_DIR=/path/to/H2EPR-Bench
|
| 62 |
streamlit run app.py
|
| 63 |
-
|
| 64 |
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
application exposes no runtime revision override, so one process cannot mix
|
| 68 |
-
releases.
|
|
|
|
| 8 |
---
|
| 9 |
|
| 10 |
[](https://agenticfinlab.github.io/H2EPR-Bench/)
|
| 11 |
+
[](https://huggingface.co/datasets/AgenticFinLab/H2EPR-Bench)
|
| 12 |
[](https://github.com/AgenticFinLab/FinMycelium)
|
| 13 |
[](https://huggingface.co/datasets/AgenticFinLab/H2EPR-Bench-Gold)
|
| 14 |
[](https://github.com/AgenticFinLab/H2EPR-Bench)
|
| 15 |
|
| 16 |
# H²EPR-Bench Explorer
|
| 17 |
|
| 18 |
+
Explore 3,000 real-world event processes without navigating raw Dataset files.
|
| 19 |
+
Search by title, domain, category, or keyword; inspect graph statistics and
|
| 20 |
+
ordered stages; open an interactive timeline; and preview or download the
|
| 21 |
+
public Draft EPG for any event.
|
|
|
|
| 22 |
|
| 23 |
+
## What you can explore
|
|
|
|
|
|
|
|
|
|
| 24 |
|
| 25 |
+
- **3,000 event profiles** spanning six domains and 26 categories
|
| 26 |
+
- **8,843 ordered stages** with temporal and graph-level summaries
|
| 27 |
+
- **Interactive timelines** for calendar-based and relative-order processes
|
| 28 |
+
- **Draft EPG JSON** with participants, actions, outcomes, and typed relations
|
| 29 |
+
- **Direct links** to the Dataset and gated reference collection
|
| 30 |
|
| 31 |
+
The Explorer presents the public FinMycelium Draft EPGs. Expert-finalized
|
| 32 |
+
reference EPGs for official scoring are available through the
|
| 33 |
+
[gated companion](https://huggingface.co/datasets/AgenticFinLab/H2EPR-Bench-Gold).
|
| 34 |
|
| 35 |
+
## Data connection
|
| 36 |
+
|
| 37 |
+
The app reads five Parquet views from
|
| 38 |
+
[AgenticFinLab/H2EPR-Bench](https://huggingface.co/datasets/AgenticFinLab/H2EPR-Bench):
|
| 39 |
|
| 40 |
| Table | Role |
|
| 41 |
|---|---|
|
| 42 |
+
| `event_gallery.parquet` | Lightweight event discovery |
|
| 43 |
+
| `event_catalog.parquet` | Complete event registry |
|
| 44 |
+
| `event_instances.parquet` | Metadata and artifact access fields |
|
| 45 |
+
| `finalcascade_summary.parquet` | Event-level graph and temporal summaries |
|
| 46 |
+
| `event_stages.parquet` | Ordered Draft-EPG stages |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 47 |
|
| 48 |
+
Event-level graphs are loaded from
|
| 49 |
+
`draft_events/<H2EPR-ID>/draft_epg.json`. Remote reads are pinned to Dataset
|
| 50 |
+
commit `4b0f0f4000db3ba9b6e1a720e5b5cfbaae68353c`, and each file is verified
|
| 51 |
+
against the release hash registry before display.
|
| 52 |
|
| 53 |
## Local development
|
| 54 |
|
| 55 |
+
Point the app at a complete local Dataset tree:
|
|
|
|
| 56 |
|
| 57 |
+
~~~bash
|
| 58 |
export H2EPR_EXPLORER_LOCAL_DATASET_DIR=/path/to/H2EPR-Bench
|
| 59 |
streamlit run app.py
|
| 60 |
+
~~~
|
| 61 |
|
| 62 |
+
The Explorer source is Apache-2.0. Dataset content displayed by the app is
|
| 63 |
+
released under CC BY-NC 4.0.
|
|
|
|
|
|
app.py
CHANGED
|
@@ -21,7 +21,6 @@ from h2epr_explorer.constants import (
|
|
| 21 |
PUBLIC_DATASET_REPO,
|
| 22 |
PUBLIC_DATASET_REVISION_URL,
|
| 23 |
PROJECT_WEBSITE_URL,
|
| 24 |
-
RELEASE_BOUNDARY_NOTICE,
|
| 25 |
SOURCE_REPOSITORY_URL,
|
| 26 |
)
|
| 27 |
from h2epr_explorer.data_loader import (
|
|
@@ -111,10 +110,9 @@ div[data-testid="stMetric"] {
|
|
| 111 |
st.markdown('<div class="h2epr-kicker">H²EPR-Bench · public release explorer</div>', unsafe_allow_html=True)
|
| 112 |
st.markdown('<div class="h2epr-title">Event-process graph browser</div>', unsafe_allow_html=True)
|
| 113 |
st.markdown(
|
| 114 |
-
'<div class="h2epr-subtitle">
|
| 115 |
unsafe_allow_html=True,
|
| 116 |
)
|
| 117 |
-
st.info(RELEASE_BOUNDARY_NOTICE)
|
| 118 |
|
| 119 |
try:
|
| 120 |
release = load_release()
|
|
@@ -224,7 +222,7 @@ event_links = build_event_links(selected_event)
|
|
| 224 |
st.caption(filter_summary_text(len(filtered_rows), len(catalog_rows)))
|
| 225 |
|
| 226 |
tabs = st.tabs(
|
| 227 |
-
["Catalog", "Event detail", "Timeline", "Stages", "Draft EPG JSON", "
|
| 228 |
)
|
| 229 |
|
| 230 |
with tabs[0]:
|
|
@@ -309,15 +307,16 @@ with tabs[4]:
|
|
| 309 |
with tabs[5]:
|
| 310 |
st.markdown(
|
| 311 |
f"""
|
| 312 |
-
###
|
| 313 |
|
| 314 |
- Project Website: [H²EPR-Bench]({PROJECT_WEBSITE_URL}).
|
| 315 |
- Public Dataset: [`{PUBLIC_DATASET_REPO}`]({PUBLIC_DATASET_REVISION_URL}).
|
| 316 |
- FinMycelium System: [multi-agent event reconstruction system]({FINMYCELIUM_URL}).
|
| 317 |
- Reference EPGs (Gated): [`{GOLD_COMPANION_REPO}`]({GOLD_COMPANION_URL}).
|
| 318 |
- Release Repository: [`AgenticFinLab/H2EPR-Bench`]({SOURCE_REPOSITORY_URL}).
|
| 319 |
-
|
| 320 |
-
|
| 321 |
-
|
|
|
|
| 322 |
"""
|
| 323 |
)
|
|
|
|
| 21 |
PUBLIC_DATASET_REPO,
|
| 22 |
PUBLIC_DATASET_REVISION_URL,
|
| 23 |
PROJECT_WEBSITE_URL,
|
|
|
|
| 24 |
SOURCE_REPOSITORY_URL,
|
| 25 |
)
|
| 26 |
from h2epr_explorer.data_loader import (
|
|
|
|
| 110 |
st.markdown('<div class="h2epr-kicker">H²EPR-Bench · public release explorer</div>', unsafe_allow_html=True)
|
| 111 |
st.markdown('<div class="h2epr-title">Event-process graph browser</div>', unsafe_allow_html=True)
|
| 112 |
st.markdown(
|
| 113 |
+
'<div class="h2epr-subtitle">Search 3,000 real-world events, inspect their process structure, and open every public Draft EPG.</div>',
|
| 114 |
unsafe_allow_html=True,
|
| 115 |
)
|
|
|
|
| 116 |
|
| 117 |
try:
|
| 118 |
release = load_release()
|
|
|
|
| 222 |
st.caption(filter_summary_text(len(filtered_rows), len(catalog_rows)))
|
| 223 |
|
| 224 |
tabs = st.tabs(
|
| 225 |
+
["Catalog", "Event detail", "Timeline", "Stages", "Draft EPG JSON", "About"]
|
| 226 |
)
|
| 227 |
|
| 228 |
with tabs[0]:
|
|
|
|
| 307 |
with tabs[5]:
|
| 308 |
st.markdown(
|
| 309 |
f"""
|
| 310 |
+
### About H²EPR-Bench
|
| 311 |
|
| 312 |
- Project Website: [H²EPR-Bench]({PROJECT_WEBSITE_URL}).
|
| 313 |
- Public Dataset: [`{PUBLIC_DATASET_REPO}`]({PUBLIC_DATASET_REVISION_URL}).
|
| 314 |
- FinMycelium System: [multi-agent event reconstruction system]({FINMYCELIUM_URL}).
|
| 315 |
- Reference EPGs (Gated): [`{GOLD_COMPANION_REPO}`]({GOLD_COMPANION_URL}).
|
| 316 |
- Release Repository: [`AgenticFinLab/H2EPR-Bench`]({SOURCE_REPOSITORY_URL}).
|
| 317 |
+
|
| 318 |
+
The Explorer presents FinMycelium Draft EPGs for browsing and method
|
| 319 |
+
development. Official benchmark scoring uses the expert-finalized reference
|
| 320 |
+
EPGs in the gated companion.
|
| 321 |
"""
|
| 322 |
)
|
src/h2epr_explorer/constants.py
CHANGED
|
@@ -11,7 +11,7 @@ GOLD_COMPANION_URL = "https://huggingface.co/datasets/AgenticFinLab/H2EPR-Bench-
|
|
| 11 |
SOURCE_REPOSITORY_URL = "https://github.com/AgenticFinLab/H2EPR-Bench"
|
| 12 |
AGENTICFINLAB_URL = "https://agenticfinlab.github.io/"
|
| 13 |
|
| 14 |
-
DEFAULT_PUBLIC_DATASET_REVISION: str | None = "
|
| 15 |
PUBLIC_DATASET_REVISION = DEFAULT_PUBLIC_DATASET_REVISION
|
| 16 |
PUBLIC_DATASET_REVISION_URL = (
|
| 17 |
f"{PUBLIC_DATASET_URL}/tree/{PUBLIC_DATASET_REVISION}"
|
|
@@ -189,9 +189,3 @@ PROFILE_COLUMNS = (
|
|
| 189 |
"gold_reference_access_level",
|
| 190 |
"finalcascade_access_level",
|
| 191 |
)
|
| 192 |
-
|
| 193 |
-
RELEASE_BOUNDARY_NOTICE = (
|
| 194 |
-
"Public Draft EPGs are FinMycelium construction artifacts. Official benchmark "
|
| 195 |
-
"scoring uses reference EPGs in the manual-gated companion repository; this "
|
| 196 |
-
"Explorer loads neither reference EPGs nor frozen evidence packages."
|
| 197 |
-
)
|
|
|
|
| 11 |
SOURCE_REPOSITORY_URL = "https://github.com/AgenticFinLab/H2EPR-Bench"
|
| 12 |
AGENTICFINLAB_URL = "https://agenticfinlab.github.io/"
|
| 13 |
|
| 14 |
+
DEFAULT_PUBLIC_DATASET_REVISION: str | None = "4b0f0f4000db3ba9b6e1a720e5b5cfbaae68353c"
|
| 15 |
PUBLIC_DATASET_REVISION = DEFAULT_PUBLIC_DATASET_REVISION
|
| 16 |
PUBLIC_DATASET_REVISION_URL = (
|
| 17 |
f"{PUBLIC_DATASET_URL}/tree/{PUBLIC_DATASET_REVISION}"
|
|
|
|
| 189 |
"gold_reference_access_level",
|
| 190 |
"finalcascade_access_level",
|
| 191 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/h2epr_explorer/data_loader.py
CHANGED
|
@@ -61,7 +61,7 @@ class DatasetRevisionUnavailable(DatasetTransportError):
|
|
| 61 |
|
| 62 |
|
| 63 |
class ReleaseContractError(ExplorerDataError):
|
| 64 |
-
"""The loaded files do not form the expected
|
| 65 |
|
| 66 |
|
| 67 |
class DraftAssetMissing(ExplorerDataError):
|
|
@@ -73,7 +73,7 @@ class DraftIntegrityError(ExplorerDataError):
|
|
| 73 |
|
| 74 |
|
| 75 |
class InvalidEventId(ValueError):
|
| 76 |
-
"""An identifier is not a canonical
|
| 77 |
|
| 78 |
|
| 79 |
@dataclass
|
|
@@ -87,7 +87,7 @@ class ExplorerRelease:
|
|
| 87 |
validate_event_id(event_id)
|
| 88 |
rows = self.events.loc[self.events["event_id"].eq(event_id)]
|
| 89 |
if rows.empty:
|
| 90 |
-
raise InvalidEventId(f"Unknown
|
| 91 |
if len(rows) != 1:
|
| 92 |
raise ReleaseContractError(f"Duplicate event identity in joined view: {event_id}")
|
| 93 |
return rows.iloc[0]
|
|
@@ -109,10 +109,10 @@ def _as_local_root(local_dataset_dir: Path | str | None = None) -> Path | None:
|
|
| 109 |
|
| 110 |
def validate_event_id(event_id: str) -> str:
|
| 111 |
if not isinstance(event_id, str) or not re.fullmatch(EVENT_ID_PATTERN, event_id):
|
| 112 |
-
raise InvalidEventId(f"Invalid
|
| 113 |
number = int(event_id.rsplit("-", 1)[1])
|
| 114 |
if not EVENT_ID_MIN <= number <= EVENT_ID_MAX:
|
| 115 |
-
raise InvalidEventId(f"
|
| 116 |
return event_id
|
| 117 |
|
| 118 |
|
|
@@ -266,7 +266,7 @@ def _expected_event_ids() -> list[str]:
|
|
| 266 |
def _require_exact_event_order(frame: pd.DataFrame, column: str, table_name: str) -> None:
|
| 267 |
if frame[column].tolist() != _expected_event_ids():
|
| 268 |
raise ReleaseContractError(
|
| 269 |
-
f"{table_name} does not contain the exact numeric
|
| 270 |
)
|
| 271 |
|
| 272 |
|
|
@@ -346,7 +346,7 @@ def build_explorer_view(
|
|
| 346 |
summary: pd.DataFrame,
|
| 347 |
source_hashes: pd.DataFrame,
|
| 348 |
) -> pd.DataFrame:
|
| 349 |
-
"""Build the exact one-row-per-event
|
| 350 |
|
| 351 |
tables = (
|
| 352 |
(gallery, EVENT_GALLERY_SCHEMA, "event_gallery", "public_event_id"),
|
|
@@ -451,7 +451,7 @@ def build_explorer_view(
|
|
| 451 |
source_hashes, on="public_event_id", how="left", validate="one_to_one"
|
| 452 |
)
|
| 453 |
except Exception as exc:
|
| 454 |
-
raise ReleaseContractError("
|
| 455 |
|
| 456 |
_require_row_count(joined, EXPECTED_EVENT_COUNT, "joined Explorer view")
|
| 457 |
_require_no_nulls(joined, "joined Explorer view")
|
|
|
|
| 61 |
|
| 62 |
|
| 63 |
class ReleaseContractError(ExplorerDataError):
|
| 64 |
+
"""The loaded files do not form the expected H²EPR-Bench release."""
|
| 65 |
|
| 66 |
|
| 67 |
class DraftAssetMissing(ExplorerDataError):
|
|
|
|
| 73 |
|
| 74 |
|
| 75 |
class InvalidEventId(ValueError):
|
| 76 |
+
"""An identifier is not a canonical H²EPR-Bench event ID."""
|
| 77 |
|
| 78 |
|
| 79 |
@dataclass
|
|
|
|
| 87 |
validate_event_id(event_id)
|
| 88 |
rows = self.events.loc[self.events["event_id"].eq(event_id)]
|
| 89 |
if rows.empty:
|
| 90 |
+
raise InvalidEventId(f"Unknown H²EPR-Bench event ID: {event_id}")
|
| 91 |
if len(rows) != 1:
|
| 92 |
raise ReleaseContractError(f"Duplicate event identity in joined view: {event_id}")
|
| 93 |
return rows.iloc[0]
|
|
|
|
| 109 |
|
| 110 |
def validate_event_id(event_id: str) -> str:
|
| 111 |
if not isinstance(event_id, str) or not re.fullmatch(EVENT_ID_PATTERN, event_id):
|
| 112 |
+
raise InvalidEventId(f"Invalid H²EPR-Bench event ID: {event_id!r}")
|
| 113 |
number = int(event_id.rsplit("-", 1)[1])
|
| 114 |
if not EVENT_ID_MIN <= number <= EVENT_ID_MAX:
|
| 115 |
+
raise InvalidEventId(f"H²EPR-Bench event ID is out of range: {event_id}")
|
| 116 |
return event_id
|
| 117 |
|
| 118 |
|
|
|
|
| 266 |
def _require_exact_event_order(frame: pd.DataFrame, column: str, table_name: str) -> None:
|
| 267 |
if frame[column].tolist() != _expected_event_ids():
|
| 268 |
raise ReleaseContractError(
|
| 269 |
+
f"{table_name} does not contain the exact numeric H²EPR-Bench event order"
|
| 270 |
)
|
| 271 |
|
| 272 |
|
|
|
|
| 346 |
summary: pd.DataFrame,
|
| 347 |
source_hashes: pd.DataFrame,
|
| 348 |
) -> pd.DataFrame:
|
| 349 |
+
"""Build the exact one-row-per-event H²EPR-Bench Explorer view."""
|
| 350 |
|
| 351 |
tables = (
|
| 352 |
(gallery, EVENT_GALLERY_SCHEMA, "event_gallery", "public_event_id"),
|
|
|
|
| 451 |
source_hashes, on="public_event_id", how="left", validate="one_to_one"
|
| 452 |
)
|
| 453 |
except Exception as exc:
|
| 454 |
+
raise ReleaseContractError("H²EPR-Bench Explorer join multiplicity failure") from exc
|
| 455 |
|
| 456 |
_require_row_count(joined, EXPECTED_EVENT_COUNT, "joined Explorer view")
|
| 457 |
_require_no_nulls(joined, "joined Explorer view")
|