Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -929,24 +929,108 @@ with gr.Blocks(title="Toxicology PDF → Grounded Extractor") as demo:
|
|
| 929 |
chunk_chars = gr.Slider(1200, 9000, value=3200, step=100, label="Chunk size (chars)")
|
| 930 |
max_context_chars = gr.Slider(5000, 45000, value=20000, step=1000, label="Max context sent to GPT (chars)")
|
| 931 |
|
|
|
|
|
|
|
|
|
|
| 932 |
gr.Markdown("## Controlled Vocabulary (guided editor)")
|
| 933 |
-
|
| 934 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 935 |
with gr.Row():
|
| 936 |
-
vocab_category = gr.Dropdown(label="Category (lists only)", choices=[], value=None)
|
| 937 |
vocab_term_add = gr.Textbox(label="Add term", placeholder="type term and click Add")
|
| 938 |
vocab_add_btn = gr.Button("Add")
|
|
|
|
| 939 |
with gr.Row():
|
| 940 |
vocab_term_remove = gr.Textbox(label="Remove term", placeholder="type exact term and click Remove")
|
| 941 |
vocab_remove_btn = gr.Button("Remove")
|
| 942 |
vocab_apply_btn = gr.Button("Apply table changes to category")
|
| 943 |
vocab_reset_btn = gr.Button("Reset vocab to defaults")
|
| 944 |
-
|
| 945 |
-
vocab_terms_df
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 946 |
vocab_status = gr.Textbox(label="Vocab status", interactive=False)
|
| 947 |
-
|
| 948 |
with gr.Accordion("Advanced: Raw vocab JSON (auto-generated)", open=False):
|
| 949 |
vocab_json = gr.Textbox(label="Controlled vocab JSON", lines=12, interactive=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 950 |
|
| 951 |
gr.Markdown("## Extraction Spec (Field Builder)")
|
| 952 |
with gr.Row():
|
|
|
|
| 929 |
chunk_chars = gr.Slider(1200, 9000, value=3200, step=100, label="Chunk size (chars)")
|
| 930 |
max_context_chars = gr.Slider(5000, 45000, value=20000, step=1000, label="Max context sent to GPT (chars)")
|
| 931 |
|
| 932 |
+
# -------------------------
|
| 933 |
+
# Controlled Vocabulary (guided editor)
|
| 934 |
+
# -------------------------
|
| 935 |
gr.Markdown("## Controlled Vocabulary (guided editor)")
|
| 936 |
+
|
| 937 |
+
vocab_mode = gr.Radio(
|
| 938 |
+
choices=["Guided", "Advanced (Raw JSON)"],
|
| 939 |
+
value="Guided",
|
| 940 |
+
label="Vocab editor mode"
|
| 941 |
+
)
|
| 942 |
+
|
| 943 |
+
vocab_category = gr.Dropdown(label="Category (lists only)", choices=[], value=None)
|
| 944 |
+
|
| 945 |
+
# NEW: Search box
|
| 946 |
+
vocab_search = gr.Textbox(
|
| 947 |
+
label="Search terms",
|
| 948 |
+
placeholder="Type to filter (e.g., 471, AMES, comet)",
|
| 949 |
+
lines=1
|
| 950 |
+
)
|
| 951 |
+
|
| 952 |
with gr.Row():
|
|
|
|
| 953 |
vocab_term_add = gr.Textbox(label="Add term", placeholder="type term and click Add")
|
| 954 |
vocab_add_btn = gr.Button("Add")
|
| 955 |
+
|
| 956 |
with gr.Row():
|
| 957 |
vocab_term_remove = gr.Textbox(label="Remove term", placeholder="type exact term and click Remove")
|
| 958 |
vocab_remove_btn = gr.Button("Remove")
|
| 959 |
vocab_apply_btn = gr.Button("Apply table changes to category")
|
| 960 |
vocab_reset_btn = gr.Button("Reset vocab to defaults")
|
| 961 |
+
|
| 962 |
+
# IMPORTANT: define vocab_terms_df BEFORE using it in any event wiring
|
| 963 |
+
vocab_terms_df = gr.Dataframe(
|
| 964 |
+
headers=["term"],
|
| 965 |
+
label="Terms (full list; edit directly)",
|
| 966 |
+
interactive=True,
|
| 967 |
+
wrap=True
|
| 968 |
+
)
|
| 969 |
+
|
| 970 |
+
# NEW: filtered preview (read-only)
|
| 971 |
+
vocab_terms_filtered = gr.Dataframe(
|
| 972 |
+
headers=["term"],
|
| 973 |
+
label="Filtered preview (read-only)",
|
| 974 |
+
interactive=False,
|
| 975 |
+
wrap=True
|
| 976 |
+
)
|
| 977 |
+
|
| 978 |
vocab_status = gr.Textbox(label="Vocab status", interactive=False)
|
| 979 |
+
|
| 980 |
with gr.Accordion("Advanced: Raw vocab JSON (auto-generated)", open=False):
|
| 981 |
vocab_json = gr.Textbox(label="Controlled vocab JSON", lines=12, interactive=False)
|
| 982 |
+
|
| 983 |
+
# -------------------------
|
| 984 |
+
# Filtering helper + event
|
| 985 |
+
# -------------------------
|
| 986 |
+
def vocab_filter_preview(terms_df, search):
|
| 987 |
+
try:
|
| 988 |
+
df = terms_df if isinstance(terms_df, pd.DataFrame) else pd.DataFrame(terms_df, columns=["term"])
|
| 989 |
+
except Exception:
|
| 990 |
+
df = pd.DataFrame(columns=["term"])
|
| 991 |
+
return _filter_terms_df(df, search)
|
| 992 |
+
|
| 993 |
+
# Wire events AFTER components exist
|
| 994 |
+
vocab_category.change(
|
| 995 |
+
fn=vocab_load_category,
|
| 996 |
+
inputs=[vocab_state, vocab_category, vocab_search],
|
| 997 |
+
outputs=[vocab_terms_df, vocab_terms_filtered, vocab_status]
|
| 998 |
+
)
|
| 999 |
+
|
| 1000 |
+
vocab_search.change(
|
| 1001 |
+
fn=vocab_filter_preview,
|
| 1002 |
+
inputs=[vocab_terms_df, vocab_search],
|
| 1003 |
+
outputs=[vocab_terms_filtered]
|
| 1004 |
+
)
|
| 1005 |
+
|
| 1006 |
+
vocab_add_btn.click(
|
| 1007 |
+
fn=vocab_add_term,
|
| 1008 |
+
inputs=[vocab_state, vocab_category, vocab_term_add, vocab_search],
|
| 1009 |
+
outputs=[vocab_terms_df, vocab_terms_filtered, vocab_term_add, vocab_status]
|
| 1010 |
+
)
|
| 1011 |
+
|
| 1012 |
+
vocab_remove_btn.click(
|
| 1013 |
+
fn=vocab_remove_term,
|
| 1014 |
+
inputs=[vocab_state, vocab_category, vocab_term_remove, vocab_search],
|
| 1015 |
+
outputs=[vocab_terms_df, vocab_terms_filtered, vocab_term_remove, vocab_status]
|
| 1016 |
+
)
|
| 1017 |
+
|
| 1018 |
+
vocab_apply_btn.click(
|
| 1019 |
+
fn=vocab_apply_df,
|
| 1020 |
+
inputs=[vocab_state, vocab_category, vocab_terms_df, vocab_search],
|
| 1021 |
+
outputs=[vocab_json, vocab_terms_filtered, vocab_status]
|
| 1022 |
+
)
|
| 1023 |
+
|
| 1024 |
+
vocab_reset_btn.click(
|
| 1025 |
+
fn=vocab_reset_defaults,
|
| 1026 |
+
inputs=None,
|
| 1027 |
+
outputs=[vocab_state, vocab_category, vocab_terms_df, vocab_json, vocab_status]
|
| 1028 |
+
).then(
|
| 1029 |
+
fn=vocab_load_category,
|
| 1030 |
+
inputs=[vocab_state, vocab_category, vocab_search],
|
| 1031 |
+
outputs=[vocab_terms_df, vocab_terms_filtered, vocab_status]
|
| 1032 |
+
)
|
| 1033 |
+
|
| 1034 |
|
| 1035 |
gr.Markdown("## Extraction Spec (Field Builder)")
|
| 1036 |
with gr.Row():
|