Skip to content

Commit e8cda01

Browse files
committed
leaderboard configuration
1 parent 1f5d0cd commit e8cda01

File tree

3 files changed

+257
-12
lines changed

3 files changed

+257
-12
lines changed

.DS_Store

6 KB
Binary file not shown.

app/app.py

Lines changed: 195 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@
1616
from huggingface_hub import InferenceClient
1717
from pandas import DataFrame
1818
from transformers import pipeline, AutoTokenizer, AutoModelForCausalLM
19+
import threading
20+
from collections import defaultdict
1921

2022

21-
BASE_MODEL = os.getenv("MODEL", "google/gemma-3-12b-it")
23+
BASE_MODEL = os.getenv("MODEL", "google/gemma-3-12b-pt")
2224
ZERO_GPU = (
2325
bool(os.getenv("ZERO_GPU", False)) or True
2426
if str(os.getenv("ZERO_GPU")).lower() == "true"
@@ -471,9 +473,63 @@ def wrangle_retry_data(
471473
)
472474
return history, update_dataframe(dataframe, history)
473475

476+
# Global variables for tracking language data points
477+
LANGUAGE_DATA_POINTS = defaultdict(int)
478+
language_data_lock = threading.Lock()
479+
480+
def get_leaderboard_data():
481+
"""Get sorted leaderboard data for all languages"""
482+
with language_data_lock:
483+
leaderboard_data = {lang: LANGUAGE_DATA_POINTS.get(lang, 0) for lang in LANGUAGES.keys()}
484+
sorted_data = sorted(leaderboard_data.items(), key=lambda x: x[1], reverse=True)
485+
return sorted_data
486+
487+
def increment_language_data_point(language):
488+
"""Increment the data point count for a specific language"""
489+
with language_data_lock:
490+
LANGUAGE_DATA_POINTS[language] += 1
491+
return get_leaderboard_data()
492+
493+
def set_language_data_points(language, count):
494+
"""Manually set the data point count for a specific language"""
495+
with language_data_lock:
496+
LANGUAGE_DATA_POINTS[language] = count
497+
return get_leaderboard_data()
498+
499+
def load_initial_language_data():
500+
"""Load initial language data points from persistent storage or default values"""
501+
data_points_path, use_persistent = get_persistent_storage_path("language_data_points.json")
502+
503+
if data_points_path.exists():
504+
try:
505+
with open(data_points_path, "r", encoding="utf-8") as f:
506+
data = json.load(f)
507+
with language_data_lock:
508+
LANGUAGE_DATA_POINTS.clear()
509+
LANGUAGE_DATA_POINTS.update(data)
510+
except Exception as e:
511+
print(f"Error loading language data points: {e}")
512+
513+
for lang in LANGUAGES.keys():
514+
if lang not in LANGUAGE_DATA_POINTS:
515+
LANGUAGE_DATA_POINTS[lang] = 0
516+
517+
return get_leaderboard_data()
518+
519+
def save_language_data_points():
520+
"""Save language data points to persistent storage"""
521+
data_points_path, use_persistent = get_persistent_storage_path("language_data_points.json")
522+
523+
try:
524+
with language_data_lock:
525+
with open(data_points_path, "w", encoding="utf-8") as f:
526+
json.dump(dict(LANGUAGE_DATA_POINTS), f, ensure_ascii=False, indent=2)
527+
except Exception as e:
528+
print(f"Error saving language data points: {e}")
529+
474530

475531
def submit_conversation(dataframe, conversation_id, session_id, language):
476-
""" "Submit the conversation to dataset repo"""
532+
""" "Submit the conversation to dataset repo & update leaderboard"""
477533
if dataframe.empty or len(dataframe) < 2:
478534
gr.Info("No feedback to submit.")
479535
return (gr.Dataframe(value=None, interactive=False), [])
@@ -489,7 +545,10 @@ def submit_conversation(dataframe, conversation_id, session_id, language):
489545
"language": language,
490546
}
491547
save_feedback(input_object=conversation_data)
492-
return (gr.Dataframe(value=None, interactive=False), [])
548+
leaderboard_data = increment_language_data_point(language)
549+
save_language_data_points()
550+
551+
return (gr.Dataframe(value=None, interactive=False), [], leaderboard_data)
493552

494553

495554
def open_add_language_modal():
@@ -547,11 +606,72 @@ def save_new_language(lang_name, system_prompt):
547606
.user-agreement-container {
548607
box-shadow: 0 2px 5px rgba(0,0,0,0.1) !important;
549608
}
609+
610+
/* Leaderboard styles */
611+
.leaderboard-container {
612+
border-left: 1px solid #eaeaea;
613+
padding-left: 1rem;
614+
height: 100%;
615+
}
616+
.leaderboard-title {
617+
font-weight: bold;
618+
text-align: center;
619+
margin-bottom: 1rem;
620+
}
621+
.leaderboard-item {
622+
display: flex;
623+
justify-content: space-between;
624+
padding: 0.5rem 0;
625+
border-bottom: 1px solid #f0f0f0;
626+
}
627+
.leaderboard-rank {
628+
font-weight: bold;
629+
margin-right: 0.5rem;
630+
}
631+
.leaderboard-language {
632+
flex-grow: 1;
633+
}
634+
.leaderboard-count {
635+
font-weight: bold;
636+
}
637+
.leaderboard-admin-panel {
638+
margin-top: 1rem;
639+
padding-top: 1rem;
640+
border-top: 1px solid #eaeaea;
641+
}
550642
"""
551643

552-
with gr.Blocks(css=css) as demo:
644+
def get_config(request: gr.Request):
645+
"""Get configuration from cookies"""
646+
config = {"feel_consent": False}
647+
if request and 'feel_consent' in request.cookies:
648+
config["feel_consent"] = request.cookies['feel_consent'] == 'true'
649+
return config["feel_consent"]
650+
651+
js = '''function js(){
652+
window.set_cookie = function(key, value){
653+
console.log('Setting cookie:', key, value);
654+
document.cookie = key+'='+value+'; Path=/; SameSite=Strict; max-age=31536000'; // 1 year expiry
655+
console.log('Current cookies:', document.cookie);
656+
return [value]
657+
}
658+
659+
window.check_cookie = function(key){
660+
console.log('Checking cookie:', key);
661+
console.log('All cookies:', document.cookie);
662+
const value = document.cookie.split('; ').find(row => row.startsWith(key + '='))?.split('=')[1];
663+
console.log('Found value:', value);
664+
return [value === 'true']
665+
}
666+
}'''
667+
668+
669+
670+
671+
with gr.Blocks(css=css, js=js) as demo:
553672
# State variable to track if user has consented
554-
user_consented = gr.State(False)
673+
user_consented = gr.State(value=False)
674+
leaderboard_data = gr.State([])
555675

556676
# Landing page with user agreement
557677
with gr.Group(visible=True) as landing_page:
@@ -598,6 +718,37 @@ def save_new_language(lang_name, system_prompt):
598718
size="sm"
599719
)
600720

721+
# Right column with leaderboard
722+
with gr.Column(scale=3, elem_classes=["leaderboard-container"]):
723+
gr.Markdown("# Language Leaderboard", elem_classes=["leaderboard-title"])
724+
leaderboard_html = gr.HTML("Loading leaderboard...")
725+
726+
with gr.Accordion("Admin Controls", open=False, visible=False) as admin_panel:
727+
with gr.Row():
728+
admin_language = gr.Dropdown(choices=list(LANGUAGES.keys()), label="Language")
729+
admin_count = gr.Number(value=0, label="Data Points")
730+
set_count_btn = gr.Button("Set Count")
731+
732+
# toggle button for admin panel?
733+
admin_toggle = gr.Button("Admin Controls", visible=True)
734+
735+
# update leaderboard HTML
736+
def update_leaderboard_html(data):
737+
if not data:
738+
return "Loading leaderboard..."
739+
740+
html = "<div class='leaderboard-content'>"
741+
for idx, (lang, count) in enumerate(data):
742+
html += f"""
743+
<div class='leaderboard-item'>
744+
<span class='leaderboard-rank'>#{idx+1}</span>
745+
<span class='leaderboard-language'>{lang}</span>
746+
<span class='leaderboard-count'>{count}</span>
747+
</div>
748+
"""
749+
html += "</div>"
750+
return html
751+
601752

602753
# Create a hidden group instead of a modal
603754
with gr.Group(visible=False) as add_language_modal:
@@ -627,7 +778,6 @@ def save_new_language(lang_name, system_prompt):
627778
chatbot = gr.Chatbot(
628779
elem_id="chatbot",
629780
editable="all",
630-
bubble_full_width=False,
631781
value=[
632782
{
633783
"role": "system",
@@ -653,12 +803,12 @@ def save_new_language(lang_name, system_prompt):
653803
# Function to show main app after consent
654804
def show_main_app():
655805
return gr.Group(visible=False), gr.Group(visible=True), True
656-
657-
# Connect consent button to show main app
806+
658807
consent_btn.click(
659808
fn=show_main_app,
660809
inputs=[],
661-
outputs=[landing_page, main_app, user_consented]
810+
outputs=[landing_page, main_app, user_consented],
811+
js="(value) => { console.log('Consent button clicked'); set_cookie('feel_consent', 'true'); console.log('Cookie set after consent'); return value; }"
662812
)
663813

664814
##############################
@@ -680,6 +830,11 @@ def show_main_app():
680830
).then(update_dataframe, inputs=[dataframe, chatbot], outputs=[dataframe]).then(
681831
submit_conversation,
682832
inputs=[dataframe, conversation_id, session_id, language],
833+
outputs=[dataframe, chatbot, leaderboard_data]
834+
).then(
835+
update_leaderboard_html,
836+
inputs=[leaderboard_data],
837+
outputs=[leaderboard_html]
683838
)
684839

685840
chatbot.like(
@@ -721,11 +876,27 @@ def on_app_load():
721876
language_choices = list(LANGUAGES.keys())
722877

723878
return str(uuid.uuid4()), gr.Dropdown(choices=language_choices, value=language_choices[0])
724-
879+
880+
def toggle_admin_panel(visible):
881+
return gr.Accordion(visible=not visible)
882+
883+
def handle_set_count(language, count):
884+
updated_data = set_language_data_points(language, int(count))
885+
save_language_data_points()
886+
return update_leaderboard_html(updated_data), updated_data
887+
725888
demo.load(
726-
fn=on_app_load,
889+
fn=lambda: (on_app_load(), load_initial_language_data()),
727890
inputs=None,
728-
outputs=[session_id, language]
891+
outputs=[
892+
session_id,
893+
language,
894+
leaderboard_data
895+
]
896+
).then(
897+
fn=update_leaderboard_html,
898+
inputs=[leaderboard_data],
899+
outputs=[leaderboard_html]
729900
)
730901

731902
add_language_btn.click(
@@ -744,4 +915,16 @@ def on_app_load():
744915
outputs=[add_language_modal, refresh_html, language]
745916
)
746917

918+
admin_toggle.click(
919+
fn=toggle_admin_panel,
920+
inputs=[admin_panel],
921+
outputs=[admin_panel]
922+
)
923+
924+
set_count_btn.click(
925+
fn=handle_set_count,
926+
inputs=[admin_language, admin_count],
927+
outputs=[leaderboard_html, leaderboard_data]
928+
)
929+
747930
demo.launch()

app/leadboard_config.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import json
2+
from pathlib import Path
3+
import argparse
4+
5+
def set_initial_counts():
6+
"""command-line tool to set initial language data point counts"""
7+
parser = argparse.ArgumentParser(description='setup initial language data point counts for FeeL leaderboard')
8+
parser.add_argument('--language', type=str, help='Language to set count for')
9+
parser.add_argument('--count', type=int, help='Count to set for the language')
10+
parser.add_argument('--list', action='store_true', help='List current counts')
11+
12+
args = parser.parse_args()
13+
data_file = Path("language_data_points.json")
14+
15+
# Load existing data if available
16+
if data_file.exists():
17+
with open(data_file, "r", encoding="utf-8") as f:
18+
try:
19+
data = json.load(f)
20+
except json.JSONDecodeError:
21+
print("Error reading data file. Creating new data.")
22+
data = {}
23+
else:
24+
data = {}
25+
26+
# Load available languages
27+
languages_file = Path("languages.json")
28+
if languages_file.exists():
29+
with open(languages_file, "r", encoding="utf-8") as f:
30+
languages = json.load(f)
31+
else:
32+
print("Warning: languages.json not found. Cannot verify language names.")
33+
languages = {}
34+
35+
# current counts
36+
if args.list:
37+
print("Current language data point counts:")
38+
for lang in sorted(set(list(languages.keys()) + list(data.keys()))):
39+
count = data.get(lang, 0)
40+
print(f"{lang}: {count}")
41+
return
42+
43+
if args.language and args.count is not None:
44+
if args.language not in languages and languages:
45+
print(f"Warning: '{args.language}' is not in languages.json")
46+
confirm = input("Continue anyway? (y/n): ")
47+
if confirm.lower() != 'y':
48+
return
49+
50+
data[args.language] = args.count
51+
52+
# saving
53+
with open(data_file, "w", encoding="utf-8") as f:
54+
json.dump(data, f, ensure_ascii=False, indent=2)
55+
56+
print(f"Set count for {args.language} to {args.count}")
57+
elif not args.list:
58+
print("Please provide both --language and --count arguments")
59+
parser.print_help()
60+
61+
if __name__ == "__main__":
62+
set_initial_counts()

0 commit comments

Comments
 (0)