Skip to content

Commit

Permalink
🛠️ fix: Completion Edge Cases & Improve Error Handling UX (#3968)
Browse files Browse the repository at this point in the history
* fix: edge cases concerning completion response as an array

* refactor: improve invalid request error UX
  • Loading branch information
danny-avila authored Sep 10, 2024
1 parent 0148b9b commit 341e086
Show file tree
Hide file tree
Showing 6 changed files with 21 additions and 7 deletions.
6 changes: 5 additions & 1 deletion api/app/clients/BaseClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const fetch = require('node-fetch');
const {
supportsBalanceCheck,
isAgentsEndpoint,
paramEndpoints,
ErrorTypes,
Constants,
CacheKeys,
Expand Down Expand Up @@ -561,6 +562,7 @@ class BaseClient {
});
}

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

Expand All @@ -580,9 +582,11 @@ class BaseClient {

if (typeof completion === 'string') {
responseMessage.text = addSpaceIfNeeded(generation) + completion;
} else if (completion) {
} else if (Array.isArray(completion) && paramEndpoints.has(this.options.endpoint)) {
responseMessage.text = '';
responseMessage.content = completion;
} else if (Array.isArray(completion)) {
responseMessage.text = addSpaceIfNeeded(generation) + completion.join('');
}

if (
Expand Down
6 changes: 3 additions & 3 deletions api/app/clients/OpenAIClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -1271,7 +1271,7 @@ ${convo}
const { choices } = chatCompletion;
if (!Array.isArray(choices) || choices.length === 0) {
logger.warn('[OpenAIClient] Chat completion response has no choices');
return intermediateReply;
return intermediateReply.join('');
}

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

if (!message) {
logger.warn('[OpenAIClient] Message is undefined in chatCompletion response');
return intermediateReply;
return intermediateReply.join('');
}

if (typeof message.content !== 'string' || message.content.trim() === '') {
Expand Down Expand Up @@ -1316,7 +1316,7 @@ ${convo}
logger.error('[OpenAIClient] Known OpenAI error:', err);
return intermediateReply.join('');
} else if (err instanceof OpenAI.APIError) {
if (intermediateReply) {
if (intermediateReply.length > 0) {
return intermediateReply.join('');
} else {
throw err;
Expand Down
8 changes: 6 additions & 2 deletions api/server/middleware/abortMiddleware.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { isAssistantsEndpoint } = require('librechat-data-provider');
const { isAssistantsEndpoint, ErrorTypes } = require('librechat-data-provider');
const { sendMessage, sendError, countTokens, isEnabled } = require('~/server/utils');
const { truncateText, smartTruncateText } = require('~/app/clients/prompts');
const clearPendingReq = require('~/cache/clearPendingReq');
Expand Down Expand Up @@ -165,10 +165,14 @@ const handleAbortError = async (res, req, error, data) => {
);
}

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

if (error?.type === ErrorTypes.INVALID_REQUEST) {
errorText = `{"type":"${ErrorTypes.INVALID_REQUEST}"}`;
}

const respondWithError = async (partialText) => {
let options = {
sender,
Expand Down
1 change: 1 addition & 0 deletions client/src/components/Messages/Content/Error.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ const errorMessages = {
[ErrorTypes.NO_USER_KEY]: 'com_error_no_user_key',
[ErrorTypes.INVALID_USER_KEY]: 'com_error_invalid_user_key',
[ErrorTypes.NO_BASE_URL]: 'com_error_no_base_url',
[ErrorTypes.INVALID_REQUEST]: 'com_error_invalid_request',
[ErrorTypes.EXPIRED_USER_KEY]: (json: TExpiredKey, localize: LocalizeFunction) => {
const { expiredAt, endpoint } = json;
return localize('com_error_expired_user_key', endpoint, expiredAt);
Expand Down
2 changes: 2 additions & 0 deletions client/src/localization/languages/Eng.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ export default {
'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.',
com_error_no_user_key: 'No key found. Please provide a key and try again.',
com_error_no_base_url: 'No base URL found. Please provide one and try again.',
com_error_invalid_request:
'The AI service rejected the request due to an error. This could be caused by an invalid API key or an improperly formatted request.',
com_error_invalid_user_key: 'Invalid key provided. Please provide a valid key and try again.',
com_error_expired_user_key:
'Provided key for {0} expired at {1}. Please provide a new key and try again.',
Expand Down
5 changes: 4 additions & 1 deletion packages/data-provider/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -943,11 +943,14 @@ export enum ErrorTypes {
* Moderation error
*/
MODERATION = 'moderation',

/**
* Prompt exceeds max length
*/
INPUT_LENGTH = 'INPUT_LENGTH',
/**
* Invalid request error, API rejected request
*/
INVALID_REQUEST = 'invalid_request_error',
}

/**
Expand Down

0 comments on commit 341e086

Please sign in to comment.