Spaces:
Sleeping
Sleeping
admin-fixes
#2
by macayaven - opened
app.py
CHANGED
|
@@ -289,14 +289,6 @@ def create_app(language='en'):
|
|
| 289 |
with gr.Tab(t['chat']['title']):
|
| 290 |
# Settings row (agentic only)
|
| 291 |
with gr.Row():
|
| 292 |
-
model_name = gr.Textbox(
|
| 293 |
-
label="Model (HF)",
|
| 294 |
-
value=os.getenv("MODEL_NAME", "meta-llama/Llama-3.1-8B-Instruct"),
|
| 295 |
-
info=(
|
| 296 |
-
"Requires HF Inference API token (HF_TOKEN or HUGGINGFACEHUB_API_TOKEN)"
|
| 297 |
-
),
|
| 298 |
-
)
|
| 299 |
-
gr.Markdown("Agentic mode only. No local fallback. Set `HF_TOKEN` in Secrets.")
|
| 300 |
gr.LoginButton()
|
| 301 |
billing_notice = gr.Markdown("")
|
| 302 |
|
|
@@ -318,8 +310,11 @@ def create_app(language='en'):
|
|
| 318 |
reframe_output = gr.Markdown(label="Reframe Suggestion")
|
| 319 |
situations_output = gr.Markdown(label="Similar Situations")
|
| 320 |
|
| 321 |
-
# Internal state for agent instance and agentic enable flag
|
| 322 |
agent_state = gr.State(value=None)
|
|
|
|
|
|
|
|
|
|
| 323 |
agentic_enabled_state = gr.State(value=True)
|
| 324 |
# Admin runtime settings (e.g., per-user limit override)
|
| 325 |
admin_state = gr.State(value={"per_user_limit_override": None})
|
|
@@ -499,6 +494,11 @@ def create_app(language='en'):
|
|
| 499 |
return "anon"
|
| 500 |
|
| 501 |
user_id = _user_id(request, profile)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 502 |
|
| 503 |
# Per-user interaction quota (counts 1 per message)
|
| 504 |
def _interactions_today(uid: str) -> int:
|
|
@@ -544,7 +544,7 @@ def create_app(language='en'):
|
|
| 544 |
per_user_limit = int(override)
|
| 545 |
except Exception:
|
| 546 |
pass
|
| 547 |
-
if per_user_limit is not None and
|
| 548 |
0, per_user_limit
|
| 549 |
):
|
| 550 |
_inc_metric("blocked_interactions")
|
|
@@ -593,6 +593,7 @@ def create_app(language='en'):
|
|
| 593 |
return
|
| 594 |
# Count one interaction for this user upfront
|
| 595 |
_inc_interactions_today(user_id)
|
|
|
|
| 596 |
|
| 597 |
# Lazily initialize agent if requested
|
| 598 |
_ensure_hf_token_env()
|
|
@@ -720,7 +721,7 @@ def create_app(language='en'):
|
|
| 720 |
remaining = (
|
| 721 |
None
|
| 722 |
if per_user_limit is None
|
| 723 |
-
else max(0, per_user_limit -
|
| 724 |
)
|
| 725 |
if remaining is not None:
|
| 726 |
notice = (
|
|
@@ -746,7 +747,7 @@ def create_app(language='en'):
|
|
| 746 |
inputs=[
|
| 747 |
msg_input,
|
| 748 |
chatbot_ui,
|
| 749 |
-
|
| 750 |
agent_state,
|
| 751 |
agentic_enabled_state,
|
| 752 |
admin_state,
|
|
@@ -767,7 +768,7 @@ def create_app(language='en'):
|
|
| 767 |
inputs=[
|
| 768 |
msg_input,
|
| 769 |
chatbot_ui,
|
| 770 |
-
|
| 771 |
agent_state,
|
| 772 |
agentic_enabled_state,
|
| 773 |
admin_state,
|
|
@@ -802,8 +803,8 @@ def create_app(language='en'):
|
|
| 802 |
with gr.Tab(t['learn']['title']):
|
| 803 |
create_learn_tab(t['learn'], COGNITIVE_DISTORTIONS)
|
| 804 |
|
| 805 |
-
# Owner Tab (
|
| 806 |
-
with gr.Tab("Owner"):
|
| 807 |
# Locked panel shown to non-admins
|
| 808 |
locked_panel = gr.Column(visible=True)
|
| 809 |
with locked_panel:
|
|
@@ -815,6 +816,20 @@ def create_app(language='en'):
|
|
| 815 |
gr.Markdown("## Admin Dashboard")
|
| 816 |
admin_summary = gr.Markdown("")
|
| 817 |
admin_limit_info = gr.Markdown("")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 818 |
with gr.Row():
|
| 819 |
override_tb = gr.Textbox(
|
| 820 |
label="Per-user interaction limit override (blank to clear)"
|
|
@@ -824,7 +839,12 @@ def create_app(language='en'):
|
|
| 824 |
|
| 825 |
def _owner_is(profile: "gr.OAuthProfile | None") -> bool:
|
| 826 |
try:
|
| 827 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 828 |
if not owner:
|
| 829 |
return False
|
| 830 |
# Try common profile fields
|
|
@@ -918,8 +938,9 @@ def create_app(language='en'):
|
|
| 918 |
def show_admin(profile: "gr.OAuthProfile | None"):
|
| 919 |
visible = _owner_is(profile)
|
| 920 |
return (
|
| 921 |
-
gr.update(visible=visible),
|
| 922 |
-
gr.update(visible=
|
|
|
|
| 923 |
_summarize_metrics_md() if visible else "",
|
| 924 |
_limit_info_md(admin_state.value if hasattr(admin_state, "value") else None)
|
| 925 |
if visible
|
|
@@ -945,6 +966,7 @@ def create_app(language='en'):
|
|
| 945 |
return _summarize_metrics_md()
|
| 946 |
|
| 947 |
# Wire admin interactions
|
|
|
|
| 948 |
set_override_btn.click(
|
| 949 |
admin_set_limit,
|
| 950 |
inputs=[override_tb, admin_state],
|
|
@@ -952,9 +974,12 @@ def create_app(language='en'):
|
|
| 952 |
)
|
| 953 |
refresh_btn.click(admin_refresh, outputs=[admin_summary])
|
| 954 |
|
| 955 |
-
# Gate admin panel visibility on load (OAuth)
|
| 956 |
try:
|
| 957 |
-
app.load(
|
|
|
|
|
|
|
|
|
|
| 958 |
except Exception:
|
| 959 |
# If OAuth not available, keep admin hidden
|
| 960 |
pass
|
|
|
|
| 289 |
with gr.Tab(t['chat']['title']):
|
| 290 |
# Settings row (agentic only)
|
| 291 |
with gr.Row():
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 292 |
gr.LoginButton()
|
| 293 |
billing_notice = gr.Markdown("")
|
| 294 |
|
|
|
|
| 310 |
reframe_output = gr.Markdown(label="Reframe Suggestion")
|
| 311 |
situations_output = gr.Markdown(label="Similar Situations")
|
| 312 |
|
| 313 |
+
# Internal state for agent instance, selected model, and agentic enable flag
|
| 314 |
agent_state = gr.State(value=None)
|
| 315 |
+
model_state = gr.State(
|
| 316 |
+
value=os.getenv("MODEL_NAME", "meta-llama/Llama-3.1-8B-Instruct")
|
| 317 |
+
)
|
| 318 |
agentic_enabled_state = gr.State(value=True)
|
| 319 |
# Admin runtime settings (e.g., per-user limit override)
|
| 320 |
admin_state = gr.State(value={"per_user_limit_override": None})
|
|
|
|
| 494 |
return "anon"
|
| 495 |
|
| 496 |
user_id = _user_id(request, profile)
|
| 497 |
+
interactions_before = 0
|
| 498 |
+
try:
|
| 499 |
+
interactions_before = _interactions_today(user_id)
|
| 500 |
+
except Exception:
|
| 501 |
+
interactions_before = 0
|
| 502 |
|
| 503 |
# Per-user interaction quota (counts 1 per message)
|
| 504 |
def _interactions_today(uid: str) -> int:
|
|
|
|
| 544 |
per_user_limit = int(override)
|
| 545 |
except Exception:
|
| 546 |
pass
|
| 547 |
+
if per_user_limit is not None and interactions_before >= max(
|
| 548 |
0, per_user_limit
|
| 549 |
):
|
| 550 |
_inc_metric("blocked_interactions")
|
|
|
|
| 593 |
return
|
| 594 |
# Count one interaction for this user upfront
|
| 595 |
_inc_interactions_today(user_id)
|
| 596 |
+
interactions_after = interactions_before + 1
|
| 597 |
|
| 598 |
# Lazily initialize agent if requested
|
| 599 |
_ensure_hf_token_env()
|
|
|
|
| 721 |
remaining = (
|
| 722 |
None
|
| 723 |
if per_user_limit is None
|
| 724 |
+
else max(0, per_user_limit - interactions_after)
|
| 725 |
)
|
| 726 |
if remaining is not None:
|
| 727 |
notice = (
|
|
|
|
| 747 |
inputs=[
|
| 748 |
msg_input,
|
| 749 |
chatbot_ui,
|
| 750 |
+
model_state,
|
| 751 |
agent_state,
|
| 752 |
agentic_enabled_state,
|
| 753 |
admin_state,
|
|
|
|
| 768 |
inputs=[
|
| 769 |
msg_input,
|
| 770 |
chatbot_ui,
|
| 771 |
+
model_state,
|
| 772 |
agent_state,
|
| 773 |
agentic_enabled_state,
|
| 774 |
admin_state,
|
|
|
|
| 803 |
with gr.Tab(t['learn']['title']):
|
| 804 |
create_learn_tab(t['learn'], COGNITIVE_DISTORTIONS)
|
| 805 |
|
| 806 |
+
# Owner Tab (hidden unless Space owner is logged in)
|
| 807 |
+
with gr.Tab("Owner", visible=False) as owner_tab:
|
| 808 |
# Locked panel shown to non-admins
|
| 809 |
locked_panel = gr.Column(visible=True)
|
| 810 |
with locked_panel:
|
|
|
|
| 816 |
gr.Markdown("## Admin Dashboard")
|
| 817 |
admin_summary = gr.Markdown("")
|
| 818 |
admin_limit_info = gr.Markdown("")
|
| 819 |
+
# Owner-only model selection
|
| 820 |
+
model_dropdown = gr.Dropdown(
|
| 821 |
+
label="Model (HF)",
|
| 822 |
+
choices=[
|
| 823 |
+
"meta-llama/Llama-3.1-8B-Instruct",
|
| 824 |
+
"meta-llama/Llama-3.1-70B-Instruct",
|
| 825 |
+
"Qwen/Qwen2.5-7B-Instruct",
|
| 826 |
+
"mistralai/Mixtral-8x7B-Instruct-v0.1",
|
| 827 |
+
"google/gemma-2-9b-it",
|
| 828 |
+
],
|
| 829 |
+
value=os.getenv("MODEL_NAME", "meta-llama/Llama-3.1-8B-Instruct"),
|
| 830 |
+
allow_custom_value=True,
|
| 831 |
+
info="Only visible to owner. Requires HF Inference API token.",
|
| 832 |
+
)
|
| 833 |
with gr.Row():
|
| 834 |
override_tb = gr.Textbox(
|
| 835 |
label="Per-user interaction limit override (blank to clear)"
|
|
|
|
| 839 |
|
| 840 |
def _owner_is(profile: "gr.OAuthProfile | None") -> bool:
|
| 841 |
try:
|
| 842 |
+
# Prefer explicit OWNER_USER, fallback to the Space author (useful if OWNER_USER not set)
|
| 843 |
+
owner = (
|
| 844 |
+
os.getenv("OWNER_USER")
|
| 845 |
+
or os.getenv("SPACE_AUTHOR_NAME")
|
| 846 |
+
or ""
|
| 847 |
+
).strip().lower()
|
| 848 |
if not owner:
|
| 849 |
return False
|
| 850 |
# Try common profile fields
|
|
|
|
| 938 |
def show_admin(profile: "gr.OAuthProfile | None"):
|
| 939 |
visible = _owner_is(profile)
|
| 940 |
return (
|
| 941 |
+
gr.update(visible=visible), # owner_tab
|
| 942 |
+
gr.update(visible=visible), # admin_panel
|
| 943 |
+
gr.update(visible=not visible), # locked_panel
|
| 944 |
_summarize_metrics_md() if visible else "",
|
| 945 |
_limit_info_md(admin_state.value if hasattr(admin_state, "value") else None)
|
| 946 |
if visible
|
|
|
|
| 966 |
return _summarize_metrics_md()
|
| 967 |
|
| 968 |
# Wire admin interactions
|
| 969 |
+
model_dropdown.change(lambda v: v, inputs=[model_dropdown], outputs=[model_state])
|
| 970 |
set_override_btn.click(
|
| 971 |
admin_set_limit,
|
| 972 |
inputs=[override_tb, admin_state],
|
|
|
|
| 974 |
)
|
| 975 |
refresh_btn.click(admin_refresh, outputs=[admin_summary])
|
| 976 |
|
| 977 |
+
# Gate Owner tab & admin panel visibility on load (OAuth)
|
| 978 |
try:
|
| 979 |
+
app.load(
|
| 980 |
+
show_admin,
|
| 981 |
+
outputs=[owner_tab, admin_panel, locked_panel, admin_summary, admin_limit_info],
|
| 982 |
+
)
|
| 983 |
except Exception:
|
| 984 |
# If OAuth not available, keep admin hidden
|
| 985 |
pass
|