diff --git a/api/app/clients/prompts/formatMessages.js b/api/app/clients/prompts/formatMessages.js index e288b28caa..5489a8ae01 100644 --- a/api/app/clients/prompts/formatMessages.js +++ b/api/app/clients/prompts/formatMessages.js @@ -44,6 +44,16 @@ const formatMessage = ({ message, userName, assistantName, langChain = false }) formattedMessage.name = assistantName; } + if (formattedMessage.name) { + // Conform to API regex: ^[a-zA-Z0-9_-]{1,64}$ + // https://community.openai.com/t/the-format-of-the-name-field-in-the-documentation-is-incorrect/175684/2 + formattedMessage.name = formattedMessage.name.replace(/[^a-zA-Z0-9_-]/g, '_'); + + if (formattedMessage.name.length > 64) { + formattedMessage.name = formattedMessage.name.substring(0, 64); + } + } + if (!langChain) { return formattedMessage; } diff --git a/api/app/clients/prompts/formatMessages.spec.js b/api/app/clients/prompts/formatMessages.spec.js index 16c400739e..0497e4c47a 100644 --- a/api/app/clients/prompts/formatMessages.spec.js +++ b/api/app/clients/prompts/formatMessages.spec.js @@ -18,6 +18,36 @@ describe('formatMessage', () => { }); }); + it('sanitizes the name by replacing invalid characters (per OpenAI)', () => { + const input = { + message: { + sender: 'user', + text: 'Hello', + }, + userName: ' John$Doe@Example! ', + }; + const result = formatMessage(input); + expect(result).toEqual({ + role: 'user', + content: 'Hello', + name: '_John_Doe_Example__', + }); + }); + + it('trims the name to a maximum length of 64 characters', () => { + const longName = 'a'.repeat(100); + const input = { + message: { + sender: 'user', + text: 'Hello', + }, + userName: longName, + }; + const result = formatMessage(input); + expect(result.name.length).toBe(64); + expect(result.name).toBe('a'.repeat(64)); + }); + it('formats a realistic user message', () => { const input = { message: { diff --git a/api/app/clients/specs/OpenAIClient.test.js b/api/app/clients/specs/OpenAIClient.test.js index 6dc4123a6a..7257aec36a 100644 --- a/api/app/clients/specs/OpenAIClient.test.js +++ b/api/app/clients/specs/OpenAIClient.test.js @@ -221,7 +221,7 @@ describe('OpenAIClient', () => { isChatCompletion: true, }); const hasUserWithName = result.prompt.some( - (item) => item.role === 'user' && item.name === 'Test User', + (item) => item.role === 'user' && item.name === 'Test_User', ); expect(hasUserWithName).toBe(true); });