diff --git a/packages/backend/src/managers/playground.ts b/packages/backend/src/managers/playground.ts index 2921a8371..3ef1b3503 100644 --- a/packages/backend/src/managers/playground.ts +++ b/packages/backend/src/managers/playground.ts @@ -178,11 +178,11 @@ export class PlayGroundManager { throw new Error('model is not running'); } - const query = { + const query: QueryState = { id: this.getNextQueryId(), modelId: modelInfo.id, prompt: prompt, - } as QueryState; + }; const post_data = JSON.stringify({ model: modelInfo.file, @@ -213,6 +213,7 @@ export class PlayGroundManager { if (!q) { throw new Error('query not found in state'); } + q.error = undefined; q.response = result as ModelResponse; this.queries.set(query.id, q); this.sendQueriesState(); @@ -222,6 +223,12 @@ export class PlayGroundManager { // post the data post_req.write(post_data); post_req.end(); + post_req.on('error', error => { + console.error('connection on error.', error); + const q = this.queries.get(query.id); + q.error = `Something went wrong while trying to request model.${String(error)}`; + this.sendQueriesState(); + }); this.queries.set(query.id, query); this.sendQueriesState(); diff --git a/packages/frontend/src/lib/ErrorMessage.svelte b/packages/frontend/src/lib/ErrorMessage.svelte new file mode 100644 index 000000000..7751df732 --- /dev/null +++ b/packages/frontend/src/lib/ErrorMessage.svelte @@ -0,0 +1,23 @@ + + +{#if icon} + {#if error !== undefined && error !== ''} + + + + {/if} +{:else} +
+ + +
+{/if} diff --git a/packages/frontend/src/pages/ModelPlayground.spec.ts b/packages/frontend/src/pages/ModelPlayground.spec.ts index 14617bd68..e62c37737 100644 --- a/packages/frontend/src/pages/ModelPlayground.spec.ts +++ b/packages/frontend/src/pages/ModelPlayground.spec.ts @@ -140,3 +140,31 @@ test('should display query without response', async () => { expect(response).toBeInTheDocument(); expect(response).toHaveValue('The response is 2'); }); + +test('should display error alert', async () => { + mocks.playgroundQueriesSubscribeMock.mockReturnValue([ + { + id: 1, + modelId: 'model1', + prompt: 'what is 1+1?', + error: 'dummy error', + }, + ]); + render(ModelPlayground, { + model: { + id: 'model1', + name: 'Model 1', + description: 'A description', + hw: 'CPU', + registry: 'Hugging Face', + popularity: 3, + license: '?', + url: 'https://huggingface.co/TheBloke/Llama-2-7B-Chat-GGUF/resolve/main/llama-2-7b-chat.Q5_K_S.gguf', + } as ModelInfo, + }); + + await waitFor(() => { + const alert = screen.getByRole('alert'); + expect(alert).toBeDefined(); + }); +}); diff --git a/packages/frontend/src/pages/ModelPlayground.svelte b/packages/frontend/src/pages/ModelPlayground.svelte index 7394256b9..96b317f3b 100644 --- a/packages/frontend/src/pages/ModelPlayground.svelte +++ b/packages/frontend/src/pages/ModelPlayground.svelte @@ -12,11 +12,13 @@ export let model: ModelInfo | undefined; import Fa from 'svelte-fa'; import { faPlay, faStop, faInfo, faWarning } from '@fortawesome/free-solid-svg-icons'; + import ErrorMessage from '/@/lib/ErrorMessage.svelte'; let prompt = ''; let queryId: number; let result: ModelResponseChoice | undefined = undefined; let inProgress = false; + let error: string | undefined = undefined; let playgroundState: PlaygroundState | undefined = undefined; onMount(() => { @@ -53,6 +55,12 @@ }); function displayQuery(query: QueryState) { + if(query.error) { + error = query.error; + inProgress = false; + return; + } + if (query.response) { inProgress = false; prompt = query.prompt; @@ -72,6 +80,8 @@ } inProgress = true; result = undefined; + error = undefined; + // do not display anything before we get a response from askPlayground // (we can receive a new queryState before the new QueryId) queryId = -1; @@ -150,6 +160,11 @@
+ {#if error} +
+ +
+ {/if}
{#key playgroundState?.status} diff --git a/packages/shared/src/models/IPlaygroundQueryState.ts b/packages/shared/src/models/IPlaygroundQueryState.ts index 9f8ae9349..32483bdaf 100644 --- a/packages/shared/src/models/IPlaygroundQueryState.ts +++ b/packages/shared/src/models/IPlaygroundQueryState.ts @@ -5,4 +5,5 @@ export interface QueryState { modelId: string; prompt: string; response?: ModelResponse; + error?: string; }