Skip to content
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
8e34d8c
Basic backend architecture
hlbmtc Dec 15, 2025
589ec0f
BE: Disabled bots signup
hlbmtc Dec 15, 2025
ff3a948
BE: Disabled bots signup fix
hlbmtc Dec 16, 2025
a443cc7
Frontend implementation of bot human links
hlbmtc Dec 16, 2025
09d08f5
Backend changes
hlbmtc Dec 16, 2025
2fb74c6
Merge remote-tracking branch 'origin/feat/3938-bot-human-links' into …
hlbmtc Dec 16, 2025
57b8f3d
Extra improvements
hlbmtc Dec 16, 2025
dbe5b89
Merge branch 'main' into feat/3938-bot-human-links
hlbmtc Dec 17, 2025
e269826
Small fix
hlbmtc Dec 17, 2025
5063db9
Added Token Reveal functionality
hlbmtc Dec 17, 2025
ef87cb9
Adjusted mobile view
hlbmtc Dec 17, 2025
70b5527
Adjusted dark mode
hlbmtc Dec 17, 2025
f8d13ee
Small fix
hlbmtc Dec 17, 2025
883eb47
Small fix
hlbmtc Dec 17, 2025
815fdf7
Added spam detection
hlbmtc Dec 17, 2025
86ec455
Added #create popup shortcut
hlbmtc Dec 17, 2025
6054c02
AIB page changes!
hlbmtc Dec 18, 2025
7e040c7
Merge branch 'main' into feat/3938-bot-human-links
hlbmtc Dec 18, 2025
842a9c3
Small fix
hlbmtc Dec 18, 2025
3e5596c
Merge branch 'main' into feat/3938-bot-human-links
hlbmtc Dec 18, 2025
be50d04
Merge branch 'main' into feat/3938-bot-human-links
hlbmtc Dec 18, 2025
aed2bbc
Added bot impersonation
hlbmtc Dec 18, 2025
142cb7b
Disabled Bot Management settings for bot
hlbmtc Dec 18, 2025
ca071db
Small fix
hlbmtc Dec 18, 2025
6f6b513
PR Review Fixes
hlbmtc Dec 19, 2025
210551c
Adjusted `send_email_async` not to send emails to the empty address
hlbmtc Dec 19, 2025
7ad8fef
Don't allow secondary bots to post comments
hlbmtc Dec 19, 2025
70b47d4
Allow superusers to create >5 bots
hlbmtc Dec 22, 2025
db35965
Merge branch 'main' into feat/3938-bot-human-links
hlbmtc Dec 22, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion authentication/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ class Meta:
"username",
"email",
"password",
"is_bot",
"add_to_project",
"campaign_key",
"campaign_data",
Expand Down
3 changes: 1 addition & 2 deletions authentication/views/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ def signup_api_view(request):
email = serializer.validated_data["email"]
username = serializer.validated_data["username"]
password = serializer.validated_data["password"]
is_bot = serializer.validated_data.get("is_bot", False)

project = serializer.validated_data.get("add_to_project", None)
campaign_key = serializer.validated_data.get("campaign_key", None)
Expand Down Expand Up @@ -104,7 +103,7 @@ def signup_api_view(request):
email=email,
password=password,
is_active=is_active,
is_bot=is_bot,
is_bot=False,
language=language,
app_theme=app_theme,
newsletter_optin=newsletter_optin,
Expand Down
25 changes: 22 additions & 3 deletions front_end/messages/cs.json
Original file line number Diff line number Diff line change
Expand Up @@ -695,11 +695,8 @@
"FABHeroSubtitle": "Benchmark Series",
"FABHeroDesc": "Benchmarking nejnovějších výsledků v AI předpovídání proti nejlepším lidem na reálných otázkách.",
"FABGettingStarted": "Začínáme",
"FABRegisterBot": "Zaregistrujte svého bota do turnaje",
"FABCreateBot": "Vytvořit účet pro bota",
"FABSeparateBotAccount": "Váš bot potřebuje samostatný účet na Metaculus. Ujistěte se, že jste se odhlásili ze svého hlavního účtu a vraťte se na tuto stránku.",
"FABBotRegistered": "Váš bot byl úspěšně zaregistrován do turnaje.",
"FABShowToken": "Zobrazit můj token",
"FABTournamentPage": "Otázky",
"FABHowItWorks": "Začínáme",
"FABCreateBotAccount": "Vytvořit účet bota",
Expand Down Expand Up @@ -1762,5 +1759,27 @@
"privateNotes": "Soukromé poznámky",
"justNow": "právě teď",
"cmmButtonShort": "Mysl",
"FABRegisterBot": "Zaregistrujte se, abyste přihlásili svého robota do turnaje",
"FABRegisterBotSecondary": "Svého předpovědního robota vytvoříte po registraci.",
"FABCreateAccount": "Vytvořit účet",
"FABCreatePopupDescription": "Vytvořte si osobní účet Metaculus pro účast v turnaji.\nPo registraci budete navedeni k vytvoření svého předpovědního robota z\nNastavení → Moje předpovědní roboty.",
"FABCreateBotTitle": "Vytvořte svého prvního předpovědního robota",
"FABCreateBotDescription": "Jakmile je vytvořen, robot bude automaticky registrován do turnaje.",
"FABShowToken": "Zobrazit token robota",
"myForecastingBots": "Moje předpovědní roboty",
"myBots": "Moje roboty",
"createBot": "Vytvořit robota",
"myForecastingBotsDisclaimer": "Dlouhé komentáře robotů, které nepřidávají hodnotu, budou považovány za spam a postiženy podle našich pravidel, včetně deaktivace účtu při opakovaných přestupcích. Soukromé komentáře jsou v pořádku v rozumných mezích.",
"myBotsEmpty": "Ještě nemáte žádné roboty.\n\n Pokud potřebujete pomoc, podívejte se na naši dokumentaci o <link>Jak nastavit roboty</link>.",
"createBotDescription": "Tím vytvoříte robota propojeného s vaším uživatelem, což vám umožní spravovat jeho nastavení a aktivitu odsud.",
"botUsername": "Uživatelské jméno robota",
"botCreated": "Robot vytvořen",
"botCreatedDescription": "Toto je váš API klíč robota — zkopírujte a uložte ho bezpečně.\nMůžete ho později zobrazit v nastavení předpovědních robotů.",
"primaryBotEligibleDisclaimer": "Pouze váš první robot má nárok na ceny.",
"editBotDescription": "Aktualizujte detaily vašeho robota. Veškeré změny se promítnou na jeho profilové stránce.",
"revealApiKey": "Zobrazit API klíč",
"hideApiKey": "Skrýt API klíč",
"accessToken": "Přístupový token",
"copy": "kopírovat",
"othersCount": "Ostatní ({count})"
}
25 changes: 22 additions & 3 deletions front_end/messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -938,11 +938,15 @@
"FABHeroSubtitle": "Benchmark Series",
"FABHeroDesc": "Benchmarking the state of the art in AI forecasting against the best humans on real-world questions.",
"FABGettingStarted": "Getting Started",
"FABRegisterBot": "Register your bot for the tournament",
"FABRegisterBot": "Sign up to register your bot for the tournament",
"FABRegisterBotSecondary": "You’ll create your forecasting bot after signing up.",
"FABCreateBot": "Create a Bot Account",
"FABSeparateBotAccount": "Your bot needs a separate Metaculus account. Make sure to log out of your main account and come back to this page.",
"FABCreateAccount": "Create Account",
"FABCreatePopupDescription": "Create a personal Metaculus account to participate in the tournament.\nAfter signing up, you’ll be guided to create your forecasting bot from\nSettings → My Forecasting Bots.",
"FABCreateBotTitle": "Create your first forecasting bot",
"FABCreateBotDescription": "Once created, bot will be automatically registered for the tournament.",
"FABBotRegistered": "Your bot is successfully registered for the tournament.",
"FABShowToken": "Show My Token",
"FABShowToken": "Show Bot Token",
"FABTournamentPage": "The Questions",
"FABReadMore": "Read More",
"FABHowItWorks": "Getting Started",
Expand Down Expand Up @@ -1756,5 +1760,20 @@
"privateNotes": "Private Notes",
"justNow": "just now",
"cmmButtonShort": "Mind",
"myForecastingBots": "My Forecasting Bots",
"myBots": "My Bots",
"createBot": "Create Bot",
"myForecastingBotsDisclaimer": "Long bot comments that don’t add value will be considered spam and dealt with as provisioned in our guidelines, up to and including account deactivation for repeated offenses. Private comments are fine within reasonable limits.",
"myBotsEmpty": "You don’t have any bots yet.\n\n If you need help, check our documentation on <link>How to Set up Bots</link>.",
"createBotDescription": "This will create a bot linked to your user, enabling you to manage its settings and activity from here",
"botUsername": "Bot username",
"botCreated": "Bot created",
"botCreatedDescription": "This is your bot’s API key — copy and store it securely.\nYou can reveal it later in the forecasting bots settings.",
"primaryBotEligibleDisclaimer": "Only your first bot is eligible for prizes.",
"editBotDescription": "Update your bot’s details. All changes will be reflected on its profile page.",
"revealApiKey": "Reveal API Key",
"hideApiKey": "Hide API Key",
"accessToken": "Access Token",
"copy": "copy",
"none": "none"
}
25 changes: 22 additions & 3 deletions front_end/messages/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -697,11 +697,8 @@
"FABHeroSubtitle": "Serie de Referencia",
"FABHeroDesc": "Comparando el estado del arte en pronósticos de IA con los mejores humanos en preguntas del mundo real.",
"FABGettingStarted": "Comenzar",
"FABRegisterBot": "Registra tu bot en el torneo",
"FABCreateBot": "Crear una Cuenta de Bot",
"FABSeparateBotAccount": "Tu bot necesita una cuenta separada de Metaculus. Asegúrate de cerrar sesión en tu cuenta principal y regresar a esta página.",
"FABBotRegistered": "Tu bot ha sido registrado con éxito en el torneo.",
"FABShowToken": "Mostrar Mi Token",
"FABTournamentPage": "Las Preguntas",
"FABHowItWorks": "Comenzar",
"FABCreateBotAccount": "Crear una Cuenta de Bot",
Expand Down Expand Up @@ -1762,5 +1759,27 @@
"privateNotes": "Notas privadas",
"justNow": "justo ahora",
"cmmButtonShort": "Mente",
"FABRegisterBot": "Regístrate para inscribir tu bot en el torneo",
"FABRegisterBotSecondary": "Crearás tu bot de pronóstico después de registrarte.",
"FABCreateAccount": "Crear Cuenta",
"FABCreatePopupDescription": "Crea una cuenta personal en Metaculus para participar en el torneo.\nDespués de registrarte, se te guiará para crear tu bot de pronóstico desde\nConfiguración → Mis Bots de Pronóstico.",
"FABCreateBotTitle": "Crea tu primer bot de pronóstico",
"FABCreateBotDescription": "Una vez creado, el bot será registrado automáticamente para el torneo.",
"FABShowToken": "Mostrar Token del Bot",
"myForecastingBots": "Mis Bots de Pronóstico",
"myBots": "Mis Bots",
"createBot": "Crear Bot",
"myForecastingBotsDisclaimer": "Los comentarios extensos de bots que no añadan valor serán considerados spam y se tratarán según lo dispuesto en nuestras directrices, incluyendo la desactivación de la cuenta por reincidencia. Los comentarios privados son aceptables dentro de límites razonables.",
"myBotsEmpty": "Aún no tienes ningún bot.\n\n Si necesitas ayuda, consulta nuestra documentación sobre <link>Cómo Configurar Bots</link>.",
"createBotDescription": "Esto creará un bot vinculado a tu usuario, permitiéndote gestionar su configuración y actividad desde aquí",
"botUsername": "Nombre de usuario del Bot",
"botCreated": "Bot creado",
"botCreatedDescription": "Esta es la clave API de tu bot — cópiala y guárdala de forma segura.\nPuedes revelarla más adelante en la configuración de bots de pronóstico.",
"primaryBotEligibleDisclaimer": "Solo tu primer bot es elegible para premios.",
"editBotDescription": "Actualiza los detalles de tu bot. Todos los cambios se reflejarán en su página de perfil.",
"revealApiKey": "Revelar Clave API",
"hideApiKey": "Ocultar Clave API",
"accessToken": "Token de Acceso",
"copy": "copiar",
"othersCount": "Otros ({count})"
}
25 changes: 22 additions & 3 deletions front_end/messages/pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -776,11 +776,8 @@
"FABHeroSubtitle": "Série de Benchmark",
"FABHeroDesc": "Comparando o estado da arte em previsão por IA com os melhores humanos em perguntas do mundo real.",
"FABGettingStarted": "Primeiros Passos",
"FABRegisterBot": "Registre seu bot para o torneio",
"FABCreateBot": "Criar uma Conta de Bot",
"FABSeparateBotAccount": "Seu bot precisa de uma conta separada no Metaculus. Certifique-se de sair da sua conta principal e voltar a esta página.",
"FABBotRegistered": "Seu bot foi registrado com sucesso no torneio.",
"FABShowToken": "Mostrar Meu Token",
"FABTournamentPage": "As Perguntas",
"FABHowItWorks": "Como Funciona",
"FABCreateBotAccount": "Criar uma Conta de Bot",
Expand Down Expand Up @@ -1760,5 +1757,27 @@
"privateNotes": "Notas Privadas",
"justNow": "agora mesmo",
"cmmButtonShort": "Mente",
"FABRegisterBot": "Inscreva-se para registrar seu bot no torneio",
"FABRegisterBotSecondary": "Você criará seu bot de previsão após se inscrever.",
"FABCreateAccount": "Criar Conta",
"FABCreatePopupDescription": "Crie uma conta pessoal no Metaculus para participar do torneio.\nApós se inscrever, você será guiado para criar seu bot de previsão em\nConfigurações → Meus Bots de Previsão.",
"FABCreateBotTitle": "Crie seu primeiro bot de previsão",
"FABCreateBotDescription": "Uma vez criado, o bot será registrado automaticamente no torneio.",
"FABShowToken": "Mostrar Token do Bot",
"myForecastingBots": "Meus Bots de Previsão",
"myBots": "Meus Bots",
"createBot": "Criar Bot",
"myForecastingBotsDisclaimer": "Comentários longos de bots que não adicionam valor serão considerados spam e tratados conforme previsto em nossas diretrizes, podendo incluir a desativação da conta em caso de reincidência. Comentários privados são permitidos dentro de limites razoáveis.",
"myBotsEmpty": "Você ainda não tem bots.\n\nSe precisar de ajuda, consulte nossa documentação sobre <link>Como Configurar Bots</link>.",
"createBotDescription": "Isto criará um bot vinculado ao seu usuário, permitindo que você gerencie suas configurações e atividades daqui",
"botUsername": "Nome de usuário do Bot",
"botCreated": "Bot criado",
"botCreatedDescription": "Este é a chave da API do seu bot — copie e armazene com segurança.\nVocê pode revelá-la posteriormente nas configurações dos bots de previsão.",
"primaryBotEligibleDisclaimer": "Apenas seu primeiro bot é elegível para prêmios.",
"editBotDescription": "Atualize os detalhes do seu bot. Todas as alterações serão refletidas na página de perfil dele.",
"revealApiKey": "Revelar Chave da API",
"hideApiKey": "Ocultar Chave da API",
"accessToken": "Token de Acesso",
"copy": "copiar",
"othersCount": "Outros ({count})"
}
25 changes: 22 additions & 3 deletions front_end/messages/zh-TW.json
Original file line number Diff line number Diff line change
Expand Up @@ -838,11 +838,8 @@
"FABHeroSubtitle": "基準系列",
"FABHeroDesc": "在真實世界問題上,將AI預測的最前沿與最優秀的人類進行基準對比。",
"FABGettingStarted": "開始",
"FABRegisterBot": "註冊您的機器人參加比賽",
"FABCreateBot": "創建一個機器人帳號",
"FABSeparateBotAccount": "您的機器人需要獨立的Metaculus帳號。請確保登出您的主帳號並返回此頁面。",
"FABBotRegistered": "您的機器人已成功註冊參賽。",
"FABShowToken": "顯示我的令牌",
"FABTournamentPage": "問題",
"FABHowItWorks": "開始指南",
"FABCreateBotAccount": "創建一個機器人帳號",
Expand Down Expand Up @@ -1759,5 +1756,27 @@
"privateNotes": "私人筆記",
"justNow": "剛剛",
"cmmButtonShort": "心智",
"FABRegisterBot": "註冊以參加賽事",
"FABRegisterBotSecondary": "註冊後您將創建您的預測機器人。",
"FABCreateAccount": "創建帳號",
"FABCreatePopupDescription": "創建個人的Metaculus帳號以參加賽事。\n註冊後,您將被引導從\n設定 → 我的預測機器人創建您的預測機器人。",
"FABCreateBotTitle": "創建您的第一個預測機器人",
"FABCreateBotDescription": "一旦創建,機器人將自動註冊參加賽事。",
"FABShowToken": "顯示機器人令牌",
"myForecastingBots": "我的預測機器人",
"myBots": "我的機器人",
"createBot": "創建機器人",
"myForecastingBotsDisclaimer": "不增加價值的冗長機器人評論將被視為垃圾訊息,將按照我們的指導方針進行處理,包括在重複違規的情況下停用帳戶。私人評論在合理範圍內是可以的。",
"myBotsEmpty": "您還沒有任何機器人。\n\n如果需要幫助,請查閱我們的關於 <link>如何設置機器人</link> 的文檔。",
"createBotDescription": "這將創建一個鏈接到您的用戶的機器人,使您可以在此管理其設定和活動",
"botUsername": "機器人用戶名",
"botCreated": "機器人已創建",
"botCreatedDescription": "這是您的機器人的API密鑰——請複製並妥善存放。\n稍後可以在預測機器人的設置中查看。",
"primaryBotEligibleDisclaimer": "僅您的第一個機器人有資格獲得獎品。",
"editBotDescription": "更新您的機器人詳細信息。所有更改將反映在其頁面上。",
"revealApiKey": "顯示API密鑰",
"hideApiKey": "隱藏API密鑰",
"accessToken": "訪問令牌",
"copy": "複製",
"withdrawAfterPercentSetting2": "問題總生命周期後撤回"
}
25 changes: 22 additions & 3 deletions front_end/messages/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -686,11 +686,8 @@
"FABHeroSubtitle": "基準系列",
"FABHeroDesc": "在真實世界問題上對比最先進的人工智能預測與最優秀的人類。",
"FABGettingStarted": "開始",
"FABRegisterBot": "將你的機器人註冊到競賽",
"FABCreateBot": "創建機器人帳戶",
"FABSeparateBotAccount": "你的機器人需要一個單獨的Metaculus帳戶。確保登出你的主帳戶並返回此頁面。",
"FABBotRegistered": "你的機器人已成功註冊參加競賽。",
"FABShowToken": "顯示我的令牌",
"FABTournamentPage": "问题",
"FABHowItWorks": "入门",
"FABCreateBotAccount": "創建機器人帳戶",
Expand Down Expand Up @@ -1764,5 +1761,27 @@
"privateNotes": "私人筆記",
"justNow": "刚刚",
"cmmButtonShort": "心情",
"FABRegisterBot": "注册您的机器人以参加锦标赛",
"FABRegisterBotSecondary": "注册后,您将创建您的预测机器人。",
"FABCreateAccount": "创建账户",
"FABCreatePopupDescription": "创建一个个人 Metaculus 账户以参加锦标赛。\n注册后,您将在设置中创建您的预测机器人 → 我的预测机器人。",
"FABCreateBotTitle": "创建您的第一个预测机器人",
"FABCreateBotDescription": "一旦创建,机器人将自动注册参加锦标赛。",
"FABShowToken": "显示机器人令牌",
"myForecastingBots": "我的预测机器人",
"myBots": "我的机器人",
"createBot": "创建机器人",
"myForecastingBotsDisclaimer": "冗长的机器人评论如不具价值,将被视为垃圾信息,并按我们的指导原则处理,包括在多次违规情况下停用账户。在合理范围内,私人评论是可以的。",
"myBotsEmpty": "您还没有任何机器人。\n\n如果您需要帮助,请查看我们的文档<链接>如何设置机器人</链接>。",
"createBotDescription": "这将创建一个链接到您的用户的机器人,使您能够从这里管理其设置和活动",
"botUsername": "机器人用户名",
"botCreated": "机器人已创建",
"botCreatedDescription": "这是您机器人的 API 密钥——请妥善复制和保存。\n您可以稍后在预测机器人设置中揭示它。",
"primaryBotEligibleDisclaimer": "只有您的第一个机器人有资格获得奖品。",
"editBotDescription": "更新您机器人的详细信息。所有更改将反映在其个人资料页面上。",
"revealApiKey": "揭示 API 密钥",
"hideApiKey": "隐藏 API 密钥",
"accessToken": "访问令牌",
"copy": "复制",
"othersCount": "其他({count})"
}
4 changes: 4 additions & 0 deletions front_end/next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ const nextConfig = {
source: "/index/:slug",
destination: "/tournament/:slug",
},
{
source: "/aib",
destination: "/aib/2026/spring/",
},
];
},
eslint: {
Expand Down
4 changes: 4 additions & 0 deletions front_end/src/app/(main)/accounts/settings/(general)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import ServerProfileApi from "@/services/api/profile/profile.server";
import DisplayPreferences from "./components/display_preferences";
import PredictionPreferences from "./components/prediction_preferences";

export const metadata = {
title: "General Settings",
};

export default async function Settings() {
const currentUser = await ServerProfileApi.getMyProfile();
invariant(currentUser);
Expand Down
4 changes: 4 additions & 0 deletions front_end/src/app/(main)/accounts/settings/account/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ import ChangePassword from "./components/change_password";
import EmailEdit from "./components/email_edit";
import PreferencesSection from "../components/preferences_section";

export const metadata = {
title: "Account Settings",
};

export default async function Settings() {
const currentUser = await ServerProfileApi.getMyProfile();
const token = await getServerSession();
Expand Down
59 changes: 59 additions & 0 deletions front_end/src/app/(main)/accounts/settings/actions.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"use server";

import { revalidatePath } from "next/cache";

import ServerProfileApi from "@/services/api/profile/profile.server";
import { ApiError } from "@/utils/core/errors";

Expand Down Expand Up @@ -48,3 +50,60 @@ export async function emailMeMyData() {
};
}
}

export async function createBot(username: string) {
try {
const data = await ServerProfileApi.createBot({ username });

return {
token: data.token,
};
} catch (err) {
if (!ApiError.isApiError(err)) {
throw err;
}

return {
errors: err.data,
};
}
}

export async function updateBot(
botId: number,
data: { username?: string; bio?: string; website?: string }
) {
try {
const response = await ServerProfileApi.updateBot(botId, data);
revalidatePath(`/accounts/profile/${botId}/`);
return {
data: response,
};
} catch (err) {
if (!ApiError.isApiError(err)) {
throw err;
}

return {
errors: err.data,
};
}
}

export async function getBotTokenAction(botId: number) {
try {
const data = await ServerProfileApi.getBotToken(botId);

return {
token: data.token,
};
} catch (err) {
if (!ApiError.isApiError(err)) {
throw err;
}

return {
errors: err.data,
};
}
}
Loading