diff --git a/api/server/middleware/abortMiddleware.js b/api/server/middleware/abortMiddleware.js
index 811963174c..cc9b9fc051 100644
--- a/api/server/middleware/abortMiddleware.js
+++ b/api/server/middleware/abortMiddleware.js
@@ -14,7 +14,7 @@ async function abortMessage(req, res) {
}
if (!abortControllers.has(abortKey) && !res.headersSent) {
- return res.status(404).send({ message: 'Request not found' });
+ return res.status(204).send({ message: 'Request not found' });
}
const { abortController } = abortControllers.get(abortKey);
@@ -26,6 +26,8 @@ async function abortMessage(req, res) {
return sendMessage(res, finalEvent);
}
+ res.setHeader('Content-Type', 'application/json');
+
res.send(JSON.stringify(finalEvent));
}
diff --git a/client/src/components/Chat/Landing.tsx b/client/src/components/Chat/Landing.tsx
index 4831374084..1cc5df08e2 100644
--- a/client/src/components/Chat/Landing.tsx
+++ b/client/src/components/Chat/Landing.tsx
@@ -23,6 +23,7 @@ export default function Landing({ Header }: { Header?: ReactNode }) {
const endpointType = getEndpointField(endpointsConfig, endpoint, 'type');
const iconURL = getEndpointField(endpointsConfig, endpoint, 'iconURL');
const iconKey = endpointType ? 'unknown' : endpoint ?? 'unknown';
+ const Icon = icons[iconKey];
return (
@@ -31,7 +32,8 @@ export default function Landing({ Header }: { Header?: ReactNode }) {
{endpoint &&
- icons[iconKey]({
+ Icon &&
+ Icon({
size: 41,
context: 'landing',
className: 'h-2/3 w-2/3',
diff --git a/client/src/components/Chat/Menus/Endpoints/MenuItem.tsx b/client/src/components/Chat/Menus/Endpoints/MenuItem.tsx
index 74ab6f3765..3d37d60b4e 100644
--- a/client/src/components/Chat/Menus/Endpoints/MenuItem.tsx
+++ b/client/src/components/Chat/Menus/Endpoints/MenuItem.tsx
@@ -82,7 +82,7 @@ const MenuItem: FC
= ({
- {
+ {Icon && (
= ({
className="icon-md shrink-0 dark:text-white"
iconURL={getEndpointField(endpointsConfig, endpoint, 'iconURL')}
/>
- }
+ )}
{title}
{description}
diff --git a/client/src/components/Chat/Menus/Presets/PresetItems.tsx b/client/src/components/Chat/Menus/Presets/PresetItems.tsx
index b440b069d0..b0ed2b792f 100644
--- a/client/src/components/Chat/Menus/Presets/PresetItems.tsx
+++ b/client/src/components/Chat/Menus/Presets/PresetItems.tsx
@@ -97,7 +97,8 @@ const PresetItems: FC<{
const iconKey = getEndpointField(endpointsConfig, preset.endpoint, 'type')
? 'unknown'
- : preset.endpoint ?? 'unknown';
+ : preset.endpointType ?? preset.endpoint ?? 'unknown';
+ const Icon = icons[iconKey];
return (
@@ -109,12 +110,15 @@ const PresetItems: FC<{
title={getPresetTitle(preset)}
disableHover={true}
onClick={() => onSelectPreset(preset)}
- icon={icons[iconKey]({
- context: 'menu-item',
- iconURL: getEndpointField(endpointsConfig, preset.endpoint, 'iconURL'),
- className: 'icon-md mr-1 dark:text-white',
- endpoint: preset.endpoint,
- })}
+ icon={
+ Icon &&
+ Icon({
+ context: 'menu-item',
+ iconURL: getEndpointField(endpointsConfig, preset.endpoint, 'iconURL'),
+ className: 'icon-md mr-1 dark:text-white',
+ endpoint: preset.endpoint,
+ })
+ }
selected={false}
data-testid={`preset-item-${preset}`}
>
diff --git a/client/src/hooks/useSSE.ts b/client/src/hooks/useSSE.ts
index 0cc7957f5b..0a6ca109d3 100644
--- a/client/src/hooks/useSSE.ts
+++ b/client/src/hooks/useSSE.ts
@@ -4,6 +4,7 @@ import { useParams } from 'react-router-dom';
import {
/* @ts-ignore */
SSE,
+ EndpointURLs,
createPayload,
tMessageSchema,
tConvoUpdateSchema,
@@ -268,10 +269,11 @@ export default function useSSE(submission: TSubmission | null, index = 0) {
const abortConversation = (conversationId = '', submission: TSubmission) => {
console.log(submission);
- const { endpoint } = submission?.conversation || {};
+ const { endpoint: _endpoint, endpointType } = submission?.conversation || {};
+ const endpoint = endpointType ?? _endpoint;
let res: Response;
- fetch(`/api/ask/${endpoint}/abort`, {
+ fetch(`${EndpointURLs[endpoint ?? '']}/abort`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
@@ -283,7 +285,29 @@ export default function useSSE(submission: TSubmission | null, index = 0) {
})
.then((response) => {
res = response;
- return response.json();
+ // Check if the response is JSON
+ const contentType = response.headers.get('content-type');
+ if (contentType && contentType.includes('application/json')) {
+ return response.json();
+ } else if (response.status === 204) {
+ const responseMessage = {
+ ...submission.initialResponse,
+ text: submission.initialResponse.text.replace(
+ '█',
+ '',
+ ),
+ };
+
+ return {
+ requestMessage: submission.message,
+ responseMessage: responseMessage,
+ conversation: submission.conversation,
+ };
+ } else {
+ throw new Error(
+ 'Unexpected response from server; Status: ' + res.status + ' ' + res.statusText,
+ );
+ }
})
.then((data) => {
console.log('aborted', data);
@@ -295,6 +319,22 @@ export default function useSSE(submission: TSubmission | null, index = 0) {
.catch((error) => {
console.error('Error aborting request');
console.error(error);
+ const convoId = conversationId ?? v4();
+
+ const text =
+ submission.initialResponse?.text?.length > 45 ? submission.initialResponse?.text : '';
+
+ const errorMessage = {
+ ...submission,
+ ...submission.initialResponse,
+ text: text ?? error.message ?? 'Error cancelling request',
+ unfinished: !!text.length,
+ error: true,
+ };
+
+ const errorResponse = tMessageSchema.parse(errorMessage);
+ setMessages([...submission.messages, submission.message, errorResponse]);
+ newConversation({ template: { conversationId: convoId } });
setIsSubmitting(false);
});
return;