mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
fix(OpenAI Chat Model Node): Respect baseURL override for /models (#10076)
This commit is contained in:
parent
09f2cf9eaf
commit
e5dda5731d
|
@ -90,7 +90,11 @@ export class LmChatOpenAi implements INodeType {
|
||||||
{
|
{
|
||||||
type: 'filter',
|
type: 'filter',
|
||||||
properties: {
|
properties: {
|
||||||
pass: "={{ $responseItem.id.startsWith('gpt-') && !$responseItem.id.includes('instruct') }}",
|
// If the baseURL is not set or is set to api.openai.com, include only chat models
|
||||||
|
pass: `={{
|
||||||
|
($parameter.options?.baseURL && !$parameter.options?.baseURL?.includes('api.openai.com')) ||
|
||||||
|
($responseItem.id.startsWith('gpt-') && !$responseItem.id.includes('instruct'))
|
||||||
|
}}`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -119,6 +123,18 @@ export class LmChatOpenAi implements INodeType {
|
||||||
},
|
},
|
||||||
default: 'gpt-3.5-turbo',
|
default: 'gpt-3.5-turbo',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
displayName:
|
||||||
|
'When using non-OpenAI models via "Base URL" override, not all models might be chat-compatible or support other features, like tools calling or JSON response format',
|
||||||
|
name: 'notice',
|
||||||
|
type: 'notice',
|
||||||
|
default: '',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
'/options.baseURL': [{ _cnd: { exists: true } }],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Options',
|
displayName: 'Options',
|
||||||
name: 'options',
|
name: 'options',
|
||||||
|
|
|
@ -97,6 +97,18 @@ export class LmOpenAi implements INodeType {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
displayName:
|
||||||
|
'When using non OpenAI models via Base URL override, not all models might be chat-compatible or support other features, like tools calling or JSON response format.',
|
||||||
|
name: 'notice',
|
||||||
|
type: 'notice',
|
||||||
|
default: '',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
'/options.baseURL': [{ _cnd: { exists: true } }],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Options',
|
displayName: 'Options',
|
||||||
name: 'options',
|
name: 'options',
|
||||||
|
@ -198,7 +210,7 @@ export class LmOpenAi implements INodeType {
|
||||||
})) as { data: Array<{ owned_by: string; id: string }> };
|
})) as { data: Array<{ owned_by: string; id: string }> };
|
||||||
|
|
||||||
for (const model of data) {
|
for (const model of data) {
|
||||||
if (!model.owned_by?.startsWith('system')) continue;
|
if (!options.baseURL && !model.owned_by?.startsWith('system')) continue;
|
||||||
results.push({
|
results.push({
|
||||||
name: model.id,
|
name: model.id,
|
||||||
value: model.id,
|
value: model.id,
|
||||||
|
|
|
@ -1296,7 +1296,8 @@ export type DisplayCondition =
|
||||||
| { _cnd: { startsWith: string } }
|
| { _cnd: { startsWith: string } }
|
||||||
| { _cnd: { endsWith: string } }
|
| { _cnd: { endsWith: string } }
|
||||||
| { _cnd: { includes: string } }
|
| { _cnd: { includes: string } }
|
||||||
| { _cnd: { regex: string } };
|
| { _cnd: { regex: string } }
|
||||||
|
| { _cnd: { exists: true } };
|
||||||
|
|
||||||
export interface IDisplayOptions {
|
export interface IDisplayOptions {
|
||||||
hide?: {
|
hide?: {
|
||||||
|
|
|
@ -359,7 +359,7 @@ const declarativeNodeOptionParameters: INodeProperties = {
|
||||||
export function isSubNodeType(
|
export function isSubNodeType(
|
||||||
typeDescription: Pick<INodeTypeDescription, 'outputs'> | null,
|
typeDescription: Pick<INodeTypeDescription, 'outputs'> | null,
|
||||||
): boolean {
|
): boolean {
|
||||||
if (!typeDescription || !typeDescription.outputs || typeof typeDescription.outputs === 'string') {
|
if (!typeDescription?.outputs || typeof typeDescription.outputs === 'string') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const outputTypes = getConnectionTypes(typeDescription.outputs);
|
const outputTypes = getConnectionTypes(typeDescription.outputs);
|
||||||
|
@ -521,6 +521,9 @@ const checkConditions = (
|
||||||
if (key === 'regex') {
|
if (key === 'regex') {
|
||||||
return new RegExp(targetValue as string).test(propertyValue as string);
|
return new RegExp(targetValue as string).test(propertyValue as string);
|
||||||
}
|
}
|
||||||
|
if (key === 'exists') {
|
||||||
|
return propertyValue !== null && propertyValue !== undefined && propertyValue !== '';
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1887,6 +1887,274 @@ describe('NodeHelpers', () => {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
description:
|
||||||
|
'simple values with displayOptions "show" using exists condition. No values set.',
|
||||||
|
input: {
|
||||||
|
nodePropertiesArray: [
|
||||||
|
{
|
||||||
|
name: 'field1',
|
||||||
|
displayName: 'Field 1',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'field2',
|
||||||
|
displayName: 'Field 2',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
field1: [{ _cnd: { exists: true } }],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
type: 'string',
|
||||||
|
default: 'default field2',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
nodeValues: {},
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
noneDisplayedFalse: {
|
||||||
|
defaultsFalse: {},
|
||||||
|
defaultsTrue: {
|
||||||
|
field1: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
noneDisplayedTrue: {
|
||||||
|
defaultsFalse: {},
|
||||||
|
defaultsTrue: {
|
||||||
|
field1: '',
|
||||||
|
field2: 'default field2',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description:
|
||||||
|
'simple values with displayOptions "show" using exists condition. Field1 has a value.',
|
||||||
|
input: {
|
||||||
|
nodePropertiesArray: [
|
||||||
|
{
|
||||||
|
name: 'field1',
|
||||||
|
displayName: 'Field 1',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'field2',
|
||||||
|
displayName: 'Field 2',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
field1: [{ _cnd: { exists: true } }],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
type: 'string',
|
||||||
|
default: 'default field2',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
nodeValues: {
|
||||||
|
field1: 'some value',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
noneDisplayedFalse: {
|
||||||
|
defaultsFalse: {
|
||||||
|
field1: 'some value',
|
||||||
|
},
|
||||||
|
defaultsTrue: {
|
||||||
|
field1: 'some value',
|
||||||
|
field2: 'default field2',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
noneDisplayedTrue: {
|
||||||
|
defaultsFalse: {
|
||||||
|
field1: 'some value',
|
||||||
|
},
|
||||||
|
defaultsTrue: {
|
||||||
|
field1: 'some value',
|
||||||
|
field2: 'default field2',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description:
|
||||||
|
'complex type "fixedCollection" with "multipleValues: false" and with displayOptions "show" using exists condition.',
|
||||||
|
input: {
|
||||||
|
nodePropertiesArray: [
|
||||||
|
{
|
||||||
|
name: 'values',
|
||||||
|
displayName: 'Values',
|
||||||
|
type: 'fixedCollection',
|
||||||
|
default: {},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'data',
|
||||||
|
displayName: 'Data',
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
name: 'field1',
|
||||||
|
displayName: 'Field 1',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'field2',
|
||||||
|
displayName: 'Field 2',
|
||||||
|
type: 'string',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
field1: [{ _cnd: { exists: true } }],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: 'default field2',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
nodeValues: {
|
||||||
|
values: {
|
||||||
|
data: {
|
||||||
|
field1: 'some value',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
noneDisplayedFalse: {
|
||||||
|
defaultsFalse: {
|
||||||
|
values: {
|
||||||
|
data: {
|
||||||
|
field1: 'some value',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
defaultsTrue: {
|
||||||
|
values: {
|
||||||
|
data: {
|
||||||
|
field1: 'some value',
|
||||||
|
field2: 'default field2',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
noneDisplayedTrue: {
|
||||||
|
defaultsFalse: {
|
||||||
|
values: {
|
||||||
|
data: {
|
||||||
|
field1: 'some value',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
defaultsTrue: {
|
||||||
|
values: {
|
||||||
|
data: {
|
||||||
|
field1: 'some value',
|
||||||
|
field2: 'default field2',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description:
|
||||||
|
'complex type "collection" with "multipleValues: true" and with displayOptions "show" using exists condition.',
|
||||||
|
input: {
|
||||||
|
nodePropertiesArray: [
|
||||||
|
{
|
||||||
|
name: 'values',
|
||||||
|
displayName: 'Values',
|
||||||
|
type: 'collection',
|
||||||
|
typeOptions: {
|
||||||
|
multipleValues: true,
|
||||||
|
},
|
||||||
|
default: {},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'field1',
|
||||||
|
displayName: 'Field 1',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'field2',
|
||||||
|
displayName: 'Field 2',
|
||||||
|
type: 'string',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
field1: [{ _cnd: { exists: true } }],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: 'default field2',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
nodeValues: {
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
field1: 'value1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field1: '',
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
noneDisplayedFalse: {
|
||||||
|
defaultsFalse: {
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
field1: 'value1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field1: '',
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
defaultsTrue: {
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
field1: 'value1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field1: '',
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
noneDisplayedTrue: {
|
||||||
|
defaultsFalse: {
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
field1: 'value1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field1: '',
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
defaultsTrue: {
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
field1: 'value1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field1: '',
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
for (const testData of tests) {
|
for (const testData of tests) {
|
||||||
|
|
Loading…
Reference in a new issue