mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-27 21:08:00 +00:00
fix(ai): contain provider setup errors (#2411)
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
This commit is contained in:
co-authored by
Steven Enamakel
parent
70440039b9
commit
20c349fcdc
@@ -760,7 +760,6 @@ const ProviderKeyDialog = ({
|
||||
);
|
||||
};
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// Background loop controls + usage diagnostics
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ vi.mock('../../../../services/api/aiSettingsApi', () => ({
|
||||
saveAISettings: vi.fn(),
|
||||
loadLocalProviderSnapshot: vi.fn(),
|
||||
testProviderModel: vi.fn(),
|
||||
setCloudProviderKey: vi.fn(),
|
||||
setCloudProviderKey: vi.fn().mockResolvedValue(undefined),
|
||||
clearCloudProviderKey: vi.fn().mockResolvedValue(undefined),
|
||||
serializeProviderRef: vi.fn((r: { kind: string; providerSlug?: string; model?: string }) =>
|
||||
r.kind === 'openhuman'
|
||||
@@ -356,6 +356,25 @@ describe('AIPanel', () => {
|
||||
expect(screen.getByLabelText(/API key/i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('surfaces provider setup errors in an alert with technical details collapsed', async () => {
|
||||
vi.mocked(loadAISettings).mockResolvedValue({ ...baseSettings, cloudProviders: [] });
|
||||
vi.mocked(listProviderModels).mockRejectedValueOnce(
|
||||
new Error('Could not reach OpenAI: provider returned 401 Unauthorized')
|
||||
);
|
||||
|
||||
renderWithProviders(<AIPanel />);
|
||||
|
||||
fireEvent.click(await screen.findByRole('switch', { name: /Connect OpenAI/i }));
|
||||
const dialog = await screen.findByRole('dialog', { name: /Connect OpenAI/i });
|
||||
fireEvent.change(within(dialog).getByLabelText(/API key/i), {
|
||||
target: { value: 'sk-bad-key' },
|
||||
});
|
||||
fireEvent.click(within(dialog).getByRole('button', { name: /^Save$/i }));
|
||||
|
||||
const alert = await within(dialog).findByRole('alert');
|
||||
expect(alert).toHaveTextContent(/rejected the credentials/i);
|
||||
});
|
||||
|
||||
it('clicking the OpenRouter chip shows both API key entry and the OAuth button', async () => {
|
||||
vi.mocked(loadAISettings).mockResolvedValue({ ...baseSettings, cloudProviders: [] });
|
||||
|
||||
|
||||
@@ -222,9 +222,9 @@ const de5: TranslationMap = {
|
||||
'settings.mascot.characterDesc': 'Charakterbeschreibung',
|
||||
'settings.mascot.characterHeading': 'Zeichenüberschrift',
|
||||
'settings.mascot.customGifError':
|
||||
'Gib eine HTTPS-.gif-URL, eine Loopback-HTTP-.gif-URL, eine file://-.gif-URL oder einen lokalen .gif-Pfad ein.',
|
||||
'settings.mascot.customGifHeading': 'Eigener GIF-Avatar',
|
||||
'settings.mascot.customGifLabel': 'URL des eigenen GIF-Avatars',
|
||||
'GIF konnte nicht geladen werden. Bitte überprüfe die URL und versuche es erneut.',
|
||||
'settings.mascot.customGifHeading': 'Benutzerdefinierter GIF-Avatar',
|
||||
'settings.mascot.customGifLabel': 'URL für benutzerdefinierten GIF-Avatar',
|
||||
'settings.mascot.colorDesc': 'Farbbeschreibung',
|
||||
'settings.mascot.colorHeading': 'Farbüberschrift',
|
||||
'settings.mascot.loadingLibrary': 'OpenHuman-Bibliothek wird geladen…',
|
||||
|
||||
Reference in New Issue
Block a user