nsarrazin HF staff victor HF staff commited on
Commit
2d45a3c
1 Parent(s): 05c5f0c

Add a more visible retry button on failure to generate (#530)

Browse files

* Add a more visible retry button on failure to generate

* clean up props

* lint

* simplify

* color

* fix linting

---------

Co-authored-by: Victor Mustar <victor.mustar@gmail.com>

src/lib/components/RetryBtn.svelte ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script lang="ts">
2
+ import CarbonRotate360 from "~icons/carbon/rotate-360";
3
+
4
+ export let classNames = "";
5
+ </script>
6
+
7
+ <button
8
+ type="button"
9
+ on:click
10
+ class="btn flex h-8 rounded-lg border bg-white px-3 py-1 text-gray-500 shadow-sm transition-all hover:bg-gray-100 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-300 dark:hover:bg-gray-600 {classNames}"
11
+ >
12
+ <CarbonRotate360 class="mr-2 text-xs " /> Retry
13
+ </button>
src/lib/components/StopGeneratingBtn.svelte CHANGED
@@ -7,7 +7,7 @@
7
  <button
8
  type="button"
9
  on:click
10
- class="btn flex h-9 rounded-lg border bg-white px-3 py-1 shadow-sm transition-all hover:bg-gray-100 dark:border-gray-600 dark:bg-gray-700 dark:hover:bg-gray-600 {classNames}"
11
  >
12
- <CarbonStopFilledAlt class="-ml-1 mr-1 h-[1.25rem] w-[1.1875rem] text-gray-400" /> Stop generating
13
  </button>
 
7
  <button
8
  type="button"
9
  on:click
10
+ class="btn flex h-8 rounded-lg border bg-white px-3 py-1 shadow-sm transition-all hover:bg-gray-100 dark:border-gray-600 dark:bg-gray-700 dark:hover:bg-gray-600 {classNames}"
11
  >
12
+ <CarbonStopFilledAlt class="-ml-1 mr-1 h-[1.25rem] w-[1.1875rem] text-gray-300" /> Stop generating
13
  </button>
src/lib/components/WebSearchToggle.svelte CHANGED
@@ -7,7 +7,7 @@
7
  </script>
8
 
9
  <div
10
- class="flex h-9 cursor-pointer select-none items-center gap-2 rounded-xl border bg-white p-1.5 shadow-sm hover:shadow-none dark:border-gray-800 dark:bg-gray-900"
11
  on:click={toggle}
12
  on:keypress={toggle}
13
  aria-checked={$webSearchParameters.useSearch}
 
7
  </script>
8
 
9
  <div
10
+ class="flex h-8 cursor-pointer select-none items-center gap-2 rounded-lg border bg-white p-1.5 shadow-sm hover:shadow-none dark:border-gray-800 dark:bg-gray-900"
11
  on:click={toggle}
12
  on:keypress={toggle}
13
  aria-checked={$webSearchParameters.useSearch}
src/lib/components/chat/ChatInput.svelte CHANGED
@@ -46,6 +46,7 @@
46
  tabindex="0"
47
  rows="1"
48
  class="scrollbar-custom absolute top-0 m-0 h-full w-full resize-none scroll-p-3 overflow-x-hidden overflow-y-scroll border-0 bg-transparent p-3 outline-none focus:ring-0 focus-visible:ring-0"
 
49
  bind:value
50
  bind:this={textareaElement}
51
  {disabled}
 
46
  tabindex="0"
47
  rows="1"
48
  class="scrollbar-custom absolute top-0 m-0 h-full w-full resize-none scroll-p-3 overflow-x-hidden overflow-y-scroll border-0 bg-transparent p-3 outline-none focus:ring-0 focus-visible:ring-0"
49
+ class:text-gray-400={disabled}
50
  bind:value
51
  bind:this={textareaElement}
52
  {disabled}
src/lib/components/chat/ChatWindow.svelte CHANGED
@@ -17,6 +17,7 @@
17
  import type { WebSearchUpdate } from "$lib/types/MessageUpdate";
18
  import { page } from "$app/stores";
19
  import DisclaimerModal from "../DisclaimerModal.svelte";
 
20
 
21
  export let messages: Message[] = [];
22
  export let loading = false;
@@ -45,6 +46,8 @@
45
  dispatch("message", message);
46
  message = "";
47
  };
 
 
48
  </script>
49
 
50
  <div class="relative min-h-0 min-w-0">
@@ -84,14 +87,21 @@
84
  <div
85
  class="dark:via-gray-80 pointer-events-none absolute inset-x-0 bottom-0 z-0 mx-auto flex w-full max-w-3xl flex-col items-center justify-center bg-gradient-to-t from-white via-white/80 to-white/0 px-3.5 py-4 dark:border-gray-800 dark:from-gray-900 dark:to-gray-900/0 max-md:border-t max-md:bg-white max-md:dark:bg-gray-900 sm:px-5 md:py-8 xl:max-w-4xl [&>*]:pointer-events-auto"
86
  >
87
- <div class="flex w-full pb-3 max-md:justify-between">
88
  {#if settings?.searchEnabled}
89
  <WebSearchToggle />
90
  {/if}
91
  {#if loading}
92
- <StopGeneratingBtn
93
- classNames={settings?.searchEnabled ? "md:-translate-x-1/2 md:mx-auto" : "mx-auto"}
94
- on:click={() => dispatch("stop")}
 
 
 
 
 
 
 
95
  />
96
  {/if}
97
  </div>
@@ -101,19 +111,23 @@
101
  {isReadOnly ? 'opacity-30' : ''}"
102
  >
103
  <div class="flex w-full flex-1 border-none bg-transparent">
104
- <ChatInput
105
- placeholder="Ask anything"
106
- bind:value={message}
107
- on:submit={handleSubmit}
108
- on:keypress={(ev) => {
109
- if ($page.data.loginRequired) {
110
- ev.preventDefault();
111
- loginModalOpen = true;
112
- }
113
- }}
114
- maxRows={4}
115
- disabled={isReadOnly}
116
- />
 
 
 
 
117
 
118
  {#if loading}
119
  <button
 
17
  import type { WebSearchUpdate } from "$lib/types/MessageUpdate";
18
  import { page } from "$app/stores";
19
  import DisclaimerModal from "../DisclaimerModal.svelte";
20
+ import RetryBtn from "../RetryBtn.svelte";
21
 
22
  export let messages: Message[] = [];
23
  export let loading = false;
 
46
  dispatch("message", message);
47
  message = "";
48
  };
49
+
50
+ $: lastIsError = messages[messages.length - 1]?.from === "user" && !loading;
51
  </script>
52
 
53
  <div class="relative min-h-0 min-w-0">
 
87
  <div
88
  class="dark:via-gray-80 pointer-events-none absolute inset-x-0 bottom-0 z-0 mx-auto flex w-full max-w-3xl flex-col items-center justify-center bg-gradient-to-t from-white via-white/80 to-white/0 px-3.5 py-4 dark:border-gray-800 dark:from-gray-900 dark:to-gray-900/0 max-md:border-t max-md:bg-white max-md:dark:bg-gray-900 sm:px-5 md:py-8 xl:max-w-4xl [&>*]:pointer-events-auto"
89
  >
90
+ <div class="flex w-full pb-3">
91
  {#if settings?.searchEnabled}
92
  <WebSearchToggle />
93
  {/if}
94
  {#if loading}
95
+ <StopGeneratingBtn classNames="ml-auto" on:click={() => dispatch("stop")} />
96
+ {/if}
97
+ {#if lastIsError}
98
+ <RetryBtn
99
+ classNames="ml-auto"
100
+ on:click={() =>
101
+ dispatch("retry", {
102
+ id: messages[messages.length - 1].id,
103
+ content: messages[messages.length - 1].content,
104
+ })}
105
  />
106
  {/if}
107
  </div>
 
111
  {isReadOnly ? 'opacity-30' : ''}"
112
  >
113
  <div class="flex w-full flex-1 border-none bg-transparent">
114
+ {#if lastIsError}
115
+ <ChatInput value="Sorry, something went wrong. Please try again." disabled={true} />
116
+ {:else}
117
+ <ChatInput
118
+ placeholder="Ask anything"
119
+ bind:value={message}
120
+ on:submit={handleSubmit}
121
+ on:keypress={(ev) => {
122
+ if ($page.data.loginRequired) {
123
+ ev.preventDefault();
124
+ loginModalOpen = true;
125
+ }
126
+ }}
127
+ maxRows={4}
128
+ disabled={isReadOnly || lastIsError}
129
+ />
130
+ {/if}
131
 
132
  {#if loading}
133
  <button