mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-16 17:46:45 +00:00
feat(Anthropic Chat Model Node): Add configurable base URL for Anthropic API (#15063)
This commit is contained in:
@@ -21,6 +21,13 @@ export class AnthropicApi implements ICredentialType {
|
|||||||
required: true,
|
required: true,
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Base URL',
|
||||||
|
name: 'url',
|
||||||
|
type: 'string',
|
||||||
|
default: 'https://api.anthropic.com',
|
||||||
|
description: 'Override the default base URL for the API',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
authenticate: IAuthenticateGeneric = {
|
authenticate: IAuthenticateGeneric = {
|
||||||
@@ -34,7 +41,7 @@ export class AnthropicApi implements ICredentialType {
|
|||||||
|
|
||||||
test: ICredentialTestRequest = {
|
test: ICredentialTestRequest = {
|
||||||
request: {
|
request: {
|
||||||
baseURL: 'https://api.anthropic.com',
|
baseURL: '={{$credentials?.url}}',
|
||||||
url: '/v1/messages',
|
url: '/v1/messages',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
|
|||||||
@@ -266,8 +266,10 @@ export class LmChatAnthropic implements INodeType {
|
|||||||
};
|
};
|
||||||
|
|
||||||
async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
|
async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
|
||||||
const credentials = await this.getCredentials('anthropicApi');
|
const credentials = await this.getCredentials<{ url?: string; apiKey?: string }>(
|
||||||
|
'anthropicApi',
|
||||||
|
);
|
||||||
|
const baseURL = credentials.url ?? 'https://api.anthropic.com';
|
||||||
const version = this.getNode().typeVersion;
|
const version = this.getNode().typeVersion;
|
||||||
const modelName =
|
const modelName =
|
||||||
version >= 1.3
|
version >= 1.3
|
||||||
@@ -317,8 +319,9 @@ export class LmChatAnthropic implements INodeType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const model = new ChatAnthropic({
|
const model = new ChatAnthropic({
|
||||||
anthropicApiKey: credentials.apiKey as string,
|
anthropicApiKey: credentials.apiKey,
|
||||||
modelName,
|
modelName,
|
||||||
|
anthropicApiUrl: baseURL,
|
||||||
maxTokens: options.maxTokensToSample,
|
maxTokens: options.maxTokensToSample,
|
||||||
temperature: options.temperature,
|
temperature: options.temperature,
|
||||||
topK: options.topK,
|
topK: options.topK,
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ describe('searchModels', () => {
|
|||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mockContext = {
|
mockContext = {
|
||||||
|
getCredentials: jest.fn().mockResolvedValue({}),
|
||||||
helpers: {
|
helpers: {
|
||||||
httpRequestWithAuthentication: jest.fn().mockResolvedValue({
|
httpRequestWithAuthentication: jest.fn().mockResolvedValue({
|
||||||
data: mockModels,
|
data: mockModels,
|
||||||
@@ -50,11 +51,47 @@ describe('searchModels', () => {
|
|||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
|
// Reset the getCredentials mock to its default value
|
||||||
|
mockContext.getCredentials = jest.fn().mockResolvedValue({});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fetch models from Anthropic API', async () => {
|
it('should fetch models from default Anthropic API URL when no custom URL is provided', async () => {
|
||||||
const result = await searchModels.call(mockContext);
|
const result = await searchModels.call(mockContext);
|
||||||
|
|
||||||
|
expect(mockContext.getCredentials).toHaveBeenCalledWith('anthropicApi');
|
||||||
|
expect(mockContext.helpers.httpRequestWithAuthentication).toHaveBeenCalledWith('anthropicApi', {
|
||||||
|
url: 'https://api.anthropic.com/v1/models',
|
||||||
|
headers: {
|
||||||
|
'anthropic-version': '2023-06-01',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(result.results).toHaveLength(5);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fetch models from custom Anthropic API URL when provided in credentials', async () => {
|
||||||
|
const customUrl = 'https://custom-anthropic-api.example.com';
|
||||||
|
// Override the default mock to return credentials with a custom URL
|
||||||
|
mockContext.getCredentials = jest.fn().mockResolvedValue({ url: customUrl });
|
||||||
|
|
||||||
|
const result = await searchModels.call(mockContext);
|
||||||
|
|
||||||
|
expect(mockContext.getCredentials).toHaveBeenCalledWith('anthropicApi');
|
||||||
|
expect(mockContext.helpers.httpRequestWithAuthentication).toHaveBeenCalledWith('anthropicApi', {
|
||||||
|
url: `${customUrl}/v1/models`,
|
||||||
|
headers: {
|
||||||
|
'anthropic-version': '2023-06-01',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(result.results).toHaveLength(5);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should use default URL when empty URL is provided in credentials', async () => {
|
||||||
|
// Override the default mock to return credentials with an empty URL
|
||||||
|
mockContext.getCredentials = jest.fn().mockResolvedValue({ url: null });
|
||||||
|
|
||||||
|
const result = await searchModels.call(mockContext);
|
||||||
|
|
||||||
|
expect(mockContext.getCredentials).toHaveBeenCalledWith('anthropicApi');
|
||||||
expect(mockContext.helpers.httpRequestWithAuthentication).toHaveBeenCalledWith('anthropicApi', {
|
expect(mockContext.helpers.httpRequestWithAuthentication).toHaveBeenCalledWith('anthropicApi', {
|
||||||
url: 'https://api.anthropic.com/v1/models',
|
url: 'https://api.anthropic.com/v1/models',
|
||||||
headers: {
|
headers: {
|
||||||
|
|||||||
@@ -15,8 +15,11 @@ export async function searchModels(
|
|||||||
this: ILoadOptionsFunctions,
|
this: ILoadOptionsFunctions,
|
||||||
filter?: string,
|
filter?: string,
|
||||||
): Promise<INodeListSearchResult> {
|
): Promise<INodeListSearchResult> {
|
||||||
|
const credentials = await this.getCredentials<{ url?: string }>('anthropicApi');
|
||||||
|
|
||||||
|
const baseURL = credentials.url ?? 'https://api.anthropic.com';
|
||||||
const response = (await this.helpers.httpRequestWithAuthentication.call(this, 'anthropicApi', {
|
const response = (await this.helpers.httpRequestWithAuthentication.call(this, 'anthropicApi', {
|
||||||
url: 'https://api.anthropic.com/v1/models',
|
url: `${baseURL}/v1/models`,
|
||||||
headers: {
|
headers: {
|
||||||
'anthropic-version': '2023-06-01',
|
'anthropic-version': '2023-06-01',
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user