Skip to content

Commit

Permalink
feat: playground error propagation (#187)
Browse files Browse the repository at this point in the history
* feat: propagate error playground

* fix: prettier

* test: ensuring alert component is displayed if QueryState send one

* fix: remove useless comment

* fix: adding error to console.error

Signed-off-by: axel7083 <[email protected]>

* Update packages/backend/src/managers/playground.ts

Co-authored-by: Luca Stocchi <[email protected]>

---------

Signed-off-by: axel7083 <[email protected]>
Co-authored-by: Luca Stocchi <[email protected]>
  • Loading branch information
axel7083 and lstocchi authored Jan 30, 2024
1 parent 3a9a284 commit 29d869a
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 2 deletions.
11 changes: 9 additions & 2 deletions packages/backend/src/managers/playground.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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();
Expand All @@ -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();
Expand Down
23 changes: 23 additions & 0 deletions packages/frontend/src/lib/ErrorMessage.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<script lang="ts">
import Fa from 'svelte-fa';
import { faExclamationCircle } from '@fortawesome/free-solid-svg-icons';
import Tooltip from './Tooltip.svelte';
export let error: string;
export let icon = false;
</script>

{#if icon}
{#if error !== undefined && error !== ''}
<Tooltip tip="{error}" top>
<Fa size="18" class="cursor-pointer text-red-500 {$$props.class}" icon="{faExclamationCircle}" />
</Tooltip>
{/if}
{:else}
<div
class="text-red-500 p-1 flex flex-row items-center {$$props.class}"
class:opacity-0="{error === undefined || error === ''}">
<Fa size="18" class="cursor-pointer text-red-500" icon="{faExclamationCircle}" />
<div role="alert" aria-label="Error Message Content" class="ml-2">{error}</div>
</div>
{/if}
28 changes: 28 additions & 0 deletions packages/frontend/src/pages/ModelPlayground.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
});
});
15 changes: 15 additions & 0 deletions packages/frontend/src/pages/ModelPlayground.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -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(() => {
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -150,6 +160,11 @@
</script>

<div class="m-4 w-full flew flex-col">
{#if error}
<div class="mb-2">
<ErrorMessage error="{error}"/>
</div>
{/if}
<Card classes="bg-charcoal-800">
<div slot="content" class="my-2 mx-4 w-full text-base font-normal flex flex-row items-center">
{#key playgroundState?.status}
Expand Down
1 change: 1 addition & 0 deletions packages/shared/src/models/IPlaygroundQueryState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export interface QueryState {
modelId: string;
prompt: string;
response?: ModelResponse;
error?: string;
}

0 comments on commit 29d869a

Please sign in to comment.