mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-27 21:08:00 +00:00
@@ -3319,7 +3319,7 @@ const AIPanel = ({ embedded = false }: AIPanelProps = {}) => {
|
||||
disabled={busyAction === 'codex-auth' || busyAction === 'toggle-openai'}>
|
||||
{busyAction === 'codex-auth' || busyAction === 'toggle-openai'
|
||||
? t('settings.ai.connecting')
|
||||
: t('settings.ai.codexAuthButton', 'Codex 인증')}
|
||||
: t('settings.ai.codexAuthButton', 'Connect Codex')}
|
||||
</Button>
|
||||
<span className="text-xs text-content-muted">
|
||||
{t(
|
||||
|
||||
@@ -893,6 +893,26 @@ describe('AIPanel', () => {
|
||||
expect(screen.queryByRole('switch', { name: /Disconnect OpenAI/i })).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
// Regression for #4852: the Codex auth button had a hardcoded Korean fallback
|
||||
// (`Codex 인증`) because the `settings.ai.codexAuthButton` key was missing from
|
||||
// every locale, so the English UI rendered Korean text. Assert the English
|
||||
// label renders and no Korean survives.
|
||||
it('renders the Codex auth button with the active-locale (English) label', async () => {
|
||||
vi.mocked(loadAISettings).mockResolvedValue({ ...baseSettings, cloudProviders: [] });
|
||||
|
||||
renderWithProviders(<AIPanel />);
|
||||
|
||||
await waitFor(() =>
|
||||
expect(screen.getByRole('switch', { name: /Connect OpenAI/i })).toBeInTheDocument()
|
||||
);
|
||||
|
||||
const codexButton = screen.getByRole('button', { name: /Connect Codex/i });
|
||||
expect(codexButton).toBeInTheDocument();
|
||||
// The Korean fallback must be gone from the English onboarding screen.
|
||||
expect(screen.queryByText(/인증/)).not.toBeInTheDocument();
|
||||
expect(screen.queryByRole('button', { name: /Codex 인증/i })).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('connects OpenAI through Codex CLI auth without storing an API key', async () => {
|
||||
vi.mocked(loadAISettings).mockResolvedValue({ ...baseSettings, cloudProviders: [] });
|
||||
|
||||
@@ -902,7 +922,7 @@ describe('AIPanel', () => {
|
||||
expect(screen.getByRole('switch', { name: /Connect OpenAI/i })).toBeInTheDocument()
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: /Codex 인증/i }));
|
||||
fireEvent.click(screen.getByRole('button', { name: /Connect Codex/i }));
|
||||
|
||||
await waitFor(() => expect(vi.mocked(importOpenAiCodexCliAuth)).toHaveBeenCalledTimes(1));
|
||||
expect(vi.mocked(startOpenAiCodexOAuth)).not.toHaveBeenCalled();
|
||||
@@ -947,7 +967,7 @@ describe('AIPanel', () => {
|
||||
expect(screen.getByRole('switch', { name: /Connect OpenAI/i })).toBeInTheDocument()
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: /Codex 인증/i }));
|
||||
fireEvent.click(screen.getByRole('button', { name: /Connect Codex/i }));
|
||||
|
||||
await waitFor(() => expect(screen.getByRole('alert')).toHaveTextContent(expectedMessage));
|
||||
expect(vi.mocked(setCloudProviderKey)).not.toHaveBeenCalled();
|
||||
|
||||
@@ -4523,6 +4523,8 @@ const messages: TranslationMap = {
|
||||
'settings.ai.openRouterOauthDescription':
|
||||
'وقع مع OpenRouter وإستيراد مفتاح ×xxxxx متحكم به مستخدماً',
|
||||
'settings.ai.connecting': 'جارٍ الاتصال...',
|
||||
'settings.ai.codexAuthButton': 'ربط Codex',
|
||||
'settings.ai.codexAuthHelper': 'يستخدم تسجيل دخول Codex CLI الحالي من ~/.codex/auth.json.',
|
||||
'settings.ai.backgroundLoops': 'حلقات الخلفية',
|
||||
'settings.ai.backgroundLoopsDesc':
|
||||
'شاهدْ ما يَعْملُ بدون رسالةِ دردشةِ، يَتوقّفُ عملَ نبضات القلب، ويَتفحصُ مؤخراً دفترِ دفاترِ الإئتمانِ.',
|
||||
|
||||
@@ -4638,6 +4638,8 @@ const messages: TranslationMap = {
|
||||
'settings.ai.openRouterOauthDescription':
|
||||
'xqxqxx সহযোগে সাইন করুন এবং xqxyqx ব্যবহার করে একটি ব্যবহারকারী xxqx কী ইম্পোর্ট করুন',
|
||||
'settings.ai.connecting': 'সংযোগ করা হচ্ছে...',
|
||||
'settings.ai.codexAuthButton': 'Codex সংযুক্ত করুন',
|
||||
'settings.ai.codexAuthHelper': '~/.codex/auth.json থেকে বিদ্যমান Codex CLI লগইন ব্যবহার করে।',
|
||||
'settings.ai.backgroundLoops': 'ব্যাকগ্রাউন্ড লুপস',
|
||||
'settings.ai.backgroundLoopsDesc':
|
||||
'লক্ষ্য করুন যে, কোন আড্ডা ছাড়াই কি করা হয়, হার্টবিটের কাজ বিরতি দিন এবং সম্প্রতি ক্রেডিট কার্ড পরীক্ষা করুন ।',
|
||||
|
||||
@@ -4769,6 +4769,9 @@ const messages: TranslationMap = {
|
||||
'settings.ai.openRouterOauthDescription':
|
||||
'Melden Sie sich mit OpenRouter an und importieren Sie einen benutzergesteuerten API-Schlüssel mit PKCE.',
|
||||
'settings.ai.connecting': 'Verbindung wird hergestellt...',
|
||||
'settings.ai.codexAuthButton': 'Codex verbinden',
|
||||
'settings.ai.codexAuthHelper':
|
||||
'Verwendet die vorhandene Codex-CLI-Anmeldung aus ~/.codex/auth.json.',
|
||||
'settings.ai.backgroundLoops': 'Hintergrundschleifen',
|
||||
'settings.ai.backgroundLoopsDesc':
|
||||
'Sehen Sie, was ohne Chat-Nachricht läuft, pausieren Sie die Herzschlagarbeit und überprüfen Sie die letzten Kreditbuchzeilen.',
|
||||
|
||||
@@ -5344,6 +5344,8 @@ const en: TranslationMap = {
|
||||
'settings.ai.openRouterOauthDescription':
|
||||
'Sign in with OpenRouter and import a user-controlled API key using PKCE.',
|
||||
'settings.ai.connecting': 'Connecting...',
|
||||
'settings.ai.codexAuthButton': 'Connect Codex',
|
||||
'settings.ai.codexAuthHelper': 'Uses the existing Codex CLI login from ~/.codex/auth.json.',
|
||||
'settings.ai.backgroundLoops': 'Background loops',
|
||||
'settings.ai.backgroundLoopsDesc':
|
||||
'See what runs without a chat message, pause heartbeat work, and inspect recent credit ledger rows.',
|
||||
|
||||
@@ -4717,6 +4717,9 @@ const messages: TranslationMap = {
|
||||
'settings.ai.openRouterOauthDescription':
|
||||
'Inicia sesión con OpenRouter e importa una clave API controlada por el usuario usando PKCE.',
|
||||
'settings.ai.connecting': 'Conectando...',
|
||||
'settings.ai.codexAuthButton': 'Conectar Codex',
|
||||
'settings.ai.codexAuthHelper':
|
||||
'Usa el inicio de sesión existente de Codex CLI desde ~/.codex/auth.json.',
|
||||
'settings.ai.backgroundLoops': 'Bucles de fondo',
|
||||
'settings.ai.backgroundLoopsDesc':
|
||||
'Vea qué se ejecuta sin un mensaje de chat, pause el trabajo de latido y examine las filas recientes del libro mayor de créditos.',
|
||||
|
||||
@@ -4746,6 +4746,9 @@ const messages: TranslationMap = {
|
||||
'settings.ai.openRouterOauthDescription':
|
||||
"Connectez-vous avec OpenRouter et importez une clé API contrôlée par l'utilisateur en utilisant PKCE.",
|
||||
'settings.ai.connecting': 'Connexion...',
|
||||
'settings.ai.codexAuthButton': 'Connecter Codex',
|
||||
'settings.ai.codexAuthHelper':
|
||||
'Utilise la connexion Codex CLI existante depuis ~/.codex/auth.json.',
|
||||
'settings.ai.backgroundLoops': 'Boucles de fond',
|
||||
'settings.ai.backgroundLoopsDesc':
|
||||
"Voyez ce qui s'exécute sans message de discussion, interrompez le travail du battement de cœur et inspectez les lignes récentes du grand livre de crédit.",
|
||||
|
||||
@@ -4637,6 +4637,8 @@ const messages: TranslationMap = {
|
||||
'settings.ai.openRouterOauthDescription':
|
||||
'OpenRouter के साथ साइन इन करें और PKCE का उपयोग करके उपयोगकर्ता नियंत्रित API कुंजी आयात करें।',
|
||||
'settings.ai.connecting': 'कनेक्ट हो रहा है...',
|
||||
'settings.ai.codexAuthButton': 'Codex कनेक्ट करें',
|
||||
'settings.ai.codexAuthHelper': '~/.codex/auth.json से मौजूदा Codex CLI लॉगिन का उपयोग करता है।',
|
||||
'settings.ai.backgroundLoops': 'पृष्ठभूमि लूप',
|
||||
'settings.ai.backgroundLoopsDesc':
|
||||
'क्या एक चैट संदेश के बिना चलाता है, दिल की धड़कन काम को रोकें, और हाल ही में क्रेडिट लेजर पंक्तियों का निरीक्षण करें।',
|
||||
|
||||
@@ -4653,6 +4653,8 @@ const messages: TranslationMap = {
|
||||
'settings.ai.openRouterOauthDescription':
|
||||
'Masuk dengan kunci OpenRouter dan impor sebuah user yang dikendalikan API menggunakan PKCE.',
|
||||
'settings.ai.connecting': 'Menghubungkan...',
|
||||
'settings.ai.codexAuthButton': 'Hubungkan Codex',
|
||||
'settings.ai.codexAuthHelper': 'Menggunakan login Codex CLI yang ada dari ~/.codex/auth.json.',
|
||||
'settings.ai.backgroundLoops': 'Perulangan latar belakang',
|
||||
'settings.ai.backgroundLoopsDesc':
|
||||
'Lihat apa yang berjalan tanpa pesan obrolan, jeda kerja detak jantung, dan memeriksa buku kas kredit baru-baru ini.',
|
||||
|
||||
@@ -4711,6 +4711,8 @@ const messages: TranslationMap = {
|
||||
'settings.ai.openRouterOauthDescription':
|
||||
"Accedi con OpenRouter e importa una chiave API controllata dall'utente usando PKCE.",
|
||||
'settings.ai.connecting': 'Connessione in corso...',
|
||||
'settings.ai.codexAuthButton': 'Connetti Codex',
|
||||
'settings.ai.codexAuthHelper': 'Usa il login Codex CLI esistente da ~/.codex/auth.json.',
|
||||
'settings.ai.backgroundLoops': 'Loop in background',
|
||||
'settings.ai.backgroundLoopsDesc':
|
||||
'Vedi cosa funziona senza un messaggio di chat, metti in pausa il lavoro del battito cardiaco e ispeziona le righe recenti del libro mastro dei crediti.',
|
||||
|
||||
@@ -4585,6 +4585,8 @@ const messages: TranslationMap = {
|
||||
'settings.ai.openRouterOauthDescription':
|
||||
'OpenRouter로 로그인하고 PKCE를 사용해 사용자가 제어하는 API 키를 가져옵니다.',
|
||||
'settings.ai.connecting': '연결 중...',
|
||||
'settings.ai.codexAuthButton': 'Codex 연결',
|
||||
'settings.ai.codexAuthHelper': '~/.codex/auth.json의 기존 Codex CLI 로그인을 사용합니다.',
|
||||
'settings.ai.backgroundLoops': '백그라운드 루프',
|
||||
'settings.ai.backgroundLoopsDesc':
|
||||
'채팅 메시지 없이 실행되는 항목을 확인하고, 하트비트 작업을 일시 중지하며, 최근 크레딧 원장 행을 검사합니다.',
|
||||
|
||||
@@ -4707,6 +4707,8 @@ const messages: TranslationMap = {
|
||||
'settings.ai.openRouterOauthDescription':
|
||||
'Zaloguj się przez OpenRouter i zaimportuj kontrolowany przez użytkownika klucz API z użyciem PKCE.',
|
||||
'settings.ai.connecting': 'Łączenie...',
|
||||
'settings.ai.codexAuthButton': 'Połącz Codex',
|
||||
'settings.ai.codexAuthHelper': 'Używa istniejącego logowania Codex CLI z ~/.codex/auth.json.',
|
||||
'settings.ai.backgroundLoops': 'Pętle w tle',
|
||||
'settings.ai.backgroundLoopsDesc':
|
||||
'Zobacz, co działa bez wiadomości na czacie, wstrzymaj pracę heartbeat i sprawdź ostatnie wiersze księgi kredytów.',
|
||||
|
||||
@@ -4704,6 +4704,8 @@ const messages: TranslationMap = {
|
||||
'settings.ai.openRouterOauthDescription':
|
||||
'Faça login com OpenRouter e importe uma chave API controlada pelo usuário usando PKCE.',
|
||||
'settings.ai.connecting': 'Conectando...',
|
||||
'settings.ai.codexAuthButton': 'Conectar Codex',
|
||||
'settings.ai.codexAuthHelper': 'Usa o login existente da CLI do Codex de ~/.codex/auth.json.',
|
||||
'settings.ai.backgroundLoops': 'Loops de segundo plano.',
|
||||
'settings.ai.backgroundLoopsDesc':
|
||||
'Veja o que funciona sem uma mensagem de chat, pause o trabalho do pulso e inspecione as linhas recentes do livro razão de créditos.',
|
||||
|
||||
@@ -4681,6 +4681,8 @@ const messages: TranslationMap = {
|
||||
'settings.ai.openRouterOauthDescription':
|
||||
'Войдите в систему с помощью OpenRouter и импортируйте управляемый пользователем ключ API с помощью PKCE.',
|
||||
'settings.ai.connecting': 'Подключение...',
|
||||
'settings.ai.codexAuthButton': 'Подключить Codex',
|
||||
'settings.ai.codexAuthHelper': 'Использует существующий вход Codex CLI из ~/.codex/auth.json.',
|
||||
'settings.ai.backgroundLoops': 'Фоновые циклы',
|
||||
'settings.ai.backgroundLoopsDesc':
|
||||
'Посмотрите, что выполняется без сообщения чата, приостановите работу Heartbeat и проверьте последние строки кредитной книги.',
|
||||
|
||||
@@ -4387,6 +4387,8 @@ const messages: TranslationMap = {
|
||||
'settings.ai.openRouterOauthDescription':
|
||||
'使用 OpenRouter 登录,并通过 PKCE 导入由用户控制的 API 密钥。',
|
||||
'settings.ai.connecting': '正在连接...',
|
||||
'settings.ai.codexAuthButton': '连接 Codex',
|
||||
'settings.ai.codexAuthHelper': '使用来自 ~/.codex/auth.json 的现有 Codex CLI 登录。',
|
||||
'settings.ai.backgroundLoops': '背景循环',
|
||||
'settings.ai.backgroundLoopsDesc':
|
||||
'查看没有聊天消息时运行的内容,暂停心跳任务,并检查最近的额度账本行。',
|
||||
|
||||
Reference in New Issue
Block a user