Skip to content

Commit

Permalink
[OpenAI connector] Fix OpenAI node package url (elastic#180955)
Browse files Browse the repository at this point in the history
## Summary

Fixes a bug with OpenAI (not azure) connectors when used with
`invokeAsyncIterator`:

```
ActionsClientChatOpenAI: an error occurred while running the action - Unexpected API Error: - 404 Invalid URL (POST /v1/chat/completions/chat/completions)
```

Our current default url for OpenAI connectors is
`https://api.openai.com/v1/chat/completions`

When using the `invokeAsyncIterator` subaction, we use the OpenAI node
package. This takes the url as an argument to instatiate. It wants the
URL of OpenAI, not the completions endpoint which is our default.

Looking back, I wish we had made the default url
`https://api.openai.com/v1`. However, because we want to support
existing connectors I think we should keep this the default and remove
the endpoint from the url when it is passed to the OpenAI node package.

### To test

Send a message in Security Assistant with an OpenAI (not azure)
connector with streaming enabled. Observe a successful response.

### Note to docs team

@elastic/security-docs We should call this out. If a user has an open
source OpenAI connector with a chat completions endpoint that does not
have the same structure as OpenAI's ending in `/chat/completions`, their
full endpoint url will be used with LangChain OpenAI Streaming
implementations. For example, if a user had a url like
`https://mycustomllm.com/execute/completions` and tries to use the the
Security Assistant with Knowledge Base on and Streaming on, they may get
this error:

```
ActionsClientChatOpenAI: an error occurred while running the action - Unexpected API Error: - 404 Invalid URL (POST /execute/completions/chat/completions)
```

We should instruct them to follow the same route structure as OpenAI.
Their endpoint needs to end in `/chat/completions`
  • Loading branch information
stephmilovic authored Apr 16, 2024
1 parent 448d42b commit f002b8f
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* 2.0.
*/

import { sanitizeRequest, getRequestWithStreamOption } from './openai_utils';
import { sanitizeRequest, getRequestWithStreamOption, removeEndpointFromUrl } from './openai_utils';
import {
DEFAULT_OPENAI_MODEL,
OPENAI_CHAT_URL,
Expand Down Expand Up @@ -182,4 +182,22 @@ describe('Open AI Utils', () => {
expect(sanitizedBodyString).toEqual(bodyString);
});
});
describe('removeEndpointFromUrl', () => {
test('removes "/chat/completions" from the end of the URL', () => {
const originalUrl = 'https://api.openai.com/v1/chat/completions';
const expectedUrl = 'https://api.openai.com/v1';
expect(removeEndpointFromUrl(originalUrl)).toBe(expectedUrl);
});

test('does not modify the URL if it does not end with "/chat/completions"', () => {
const originalUrl = 'https://api.openai.com/v1/some/other/endpoint';
expect(removeEndpointFromUrl(originalUrl)).toBe(originalUrl);
});

test('handles URLs with a trailing slash correctly', () => {
const originalUrl = 'https://api.openai.com/v1/chat/completions/';
const expectedUrl = 'https://api.openai.com/v1';
expect(removeEndpointFromUrl(originalUrl)).toBe(expectedUrl);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,10 @@ export const getRequestWithStreamOption = (

return body;
};

// removes the chat completions endpoint from the OpenAI url in order
// to provide the correct endpoint for the OpenAI node package
export const removeEndpointFromUrl = (url: string): string => {
const endpointToRemove = /\/chat\/completions\/?$/;
return url.replace(endpointToRemove, '');
};
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
ChatCompletionMessageParam,
} from 'openai/resources/chat/completions';
import { Stream } from 'openai/streaming';
import { removeEndpointFromUrl } from './lib/openai_utils';
import {
RunActionParamsSchema,
RunActionResponseSchema,
Expand Down Expand Up @@ -76,7 +77,7 @@ export class OpenAIConnector extends SubActionConnector<Config, Secrets> {
},
})
: new OpenAI({
baseURL: this.config.apiUrl,
baseURL: removeEndpointFromUrl(this.config.apiUrl),
apiKey: this.secrets.apiKey,
defaultHeaders: {
...this.config.headers,
Expand Down

0 comments on commit f002b8f

Please sign in to comment.