Skip to content

Commit 341e086

Browse files
authored
🛠️ fix: Completion Edge Cases & Improve Error Handling UX (#3968)
* fix: edge cases concerning completion response as an array * refactor: improve invalid request error UX
1 parent 0148b9b commit 341e086

File tree

6 files changed

+21
-7
lines changed

6 files changed

+21
-7
lines changed

api/app/clients/BaseClient.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const fetch = require('node-fetch');
33
const {
44
supportsBalanceCheck,
55
isAgentsEndpoint,
6+
paramEndpoints,
67
ErrorTypes,
78
Constants,
89
CacheKeys,
@@ -561,6 +562,7 @@ class BaseClient {
561562
});
562563
}
563564

565+
/** @type {string|string[]|undefined} */
564566
const completion = await this.sendCompletion(payload, opts);
565567
this.abortController.requestCompleted = true;
566568

@@ -580,9 +582,11 @@ class BaseClient {
580582

581583
if (typeof completion === 'string') {
582584
responseMessage.text = addSpaceIfNeeded(generation) + completion;
583-
} else if (completion) {
585+
} else if (Array.isArray(completion) && paramEndpoints.has(this.options.endpoint)) {
584586
responseMessage.text = '';
585587
responseMessage.content = completion;
588+
} else if (Array.isArray(completion)) {
589+
responseMessage.text = addSpaceIfNeeded(generation) + completion.join('');
586590
}
587591

588592
if (

api/app/clients/OpenAIClient.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1271,7 +1271,7 @@ ${convo}
12711271
const { choices } = chatCompletion;
12721272
if (!Array.isArray(choices) || choices.length === 0) {
12731273
logger.warn('[OpenAIClient] Chat completion response has no choices');
1274-
return intermediateReply;
1274+
return intermediateReply.join('');
12751275
}
12761276

12771277
const { message, finish_reason } = choices[0] ?? {};
@@ -1281,7 +1281,7 @@ ${convo}
12811281

12821282
if (!message) {
12831283
logger.warn('[OpenAIClient] Message is undefined in chatCompletion response');
1284-
return intermediateReply;
1284+
return intermediateReply.join('');
12851285
}
12861286

12871287
if (typeof message.content !== 'string' || message.content.trim() === '') {
@@ -1316,7 +1316,7 @@ ${convo}
13161316
logger.error('[OpenAIClient] Known OpenAI error:', err);
13171317
return intermediateReply.join('');
13181318
} else if (err instanceof OpenAI.APIError) {
1319-
if (intermediateReply) {
1319+
if (intermediateReply.length > 0) {
13201320
return intermediateReply.join('');
13211321
} else {
13221322
throw err;

api/server/middleware/abortMiddleware.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const { isAssistantsEndpoint } = require('librechat-data-provider');
1+
const { isAssistantsEndpoint, ErrorTypes } = require('librechat-data-provider');
22
const { sendMessage, sendError, countTokens, isEnabled } = require('~/server/utils');
33
const { truncateText, smartTruncateText } = require('~/app/clients/prompts');
44
const clearPendingReq = require('~/cache/clearPendingReq');
@@ -165,10 +165,14 @@ const handleAbortError = async (res, req, error, data) => {
165165
);
166166
}
167167

168-
const errorText = error?.message?.includes('"type"')
168+
let errorText = error?.message?.includes('"type"')
169169
? error.message
170170
: 'An error occurred while processing your request. Please contact the Admin.';
171171

172+
if (error?.type === ErrorTypes.INVALID_REQUEST) {
173+
errorText = `{"type":"${ErrorTypes.INVALID_REQUEST}"}`;
174+
}
175+
172176
const respondWithError = async (partialText) => {
173177
let options = {
174178
sender,

client/src/components/Messages/Content/Error.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ const errorMessages = {
4242
[ErrorTypes.NO_USER_KEY]: 'com_error_no_user_key',
4343
[ErrorTypes.INVALID_USER_KEY]: 'com_error_invalid_user_key',
4444
[ErrorTypes.NO_BASE_URL]: 'com_error_no_base_url',
45+
[ErrorTypes.INVALID_REQUEST]: 'com_error_invalid_request',
4546
[ErrorTypes.EXPIRED_USER_KEY]: (json: TExpiredKey, localize: LocalizeFunction) => {
4647
const { expiredAt, endpoint } = json;
4748
return localize('com_error_expired_user_key', endpoint, expiredAt);

client/src/localization/languages/Eng.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ export default {
2222
'It appears that the content submitted has been flagged by our moderation system for not aligning with our community guidelines. We\'re unable to proceed with this specific topic. If you have any other questions or topics you\'d like to explore, please edit your message, or create a new conversation.',
2323
com_error_no_user_key: 'No key found. Please provide a key and try again.',
2424
com_error_no_base_url: 'No base URL found. Please provide one and try again.',
25+
com_error_invalid_request:
26+
'The AI service rejected the request due to an error. This could be caused by an invalid API key or an improperly formatted request.',
2527
com_error_invalid_user_key: 'Invalid key provided. Please provide a valid key and try again.',
2628
com_error_expired_user_key:
2729
'Provided key for {0} expired at {1}. Please provide a new key and try again.',

packages/data-provider/src/config.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -943,11 +943,14 @@ export enum ErrorTypes {
943943
* Moderation error
944944
*/
945945
MODERATION = 'moderation',
946-
947946
/**
948947
* Prompt exceeds max length
949948
*/
950949
INPUT_LENGTH = 'INPUT_LENGTH',
950+
/**
951+
* Invalid request error, API rejected request
952+
*/
953+
INVALID_REQUEST = 'invalid_request_error',
951954
}
952955

953956
/**

0 commit comments

Comments
 (0)