Skip to content

Commit f812831

Browse files
committed
feat(core): Make manual models defined on allowedModels always show up on the model picker
1 parent e102b6d commit f812831

File tree

3 files changed

+48
-30
lines changed

3 files changed

+48
-30
lines changed

packages/@n8n/api-types/src/chat-hub.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ const chatProviderSettingsSchema = z.object({
300300
z.object({
301301
displayName: z.string(),
302302
model: z.string(),
303+
isManual: z.boolean().optional(),
303304
}),
304305
),
305306
createdAt: z.string(),

packages/frontend/editor-ui/src/features/ai/chatHub/components/ModelSelector.vue

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,25 @@ const menu = computed(() => {
128128
if (settings && !settings.enabled) continue;
129129
130130
const theAgents = agents.value[provider].models;
131+
132+
// Add any manually defined models in settings
133+
if (settings && settings.limitModels) {
134+
for (const model of settings.allowedModels) {
135+
if (model.isManual) {
136+
theAgents.push({
137+
name: model.displayName,
138+
description: '',
139+
model: {
140+
provider,
141+
model: model.model,
142+
},
143+
createdAt: '',
144+
updatedAt: null,
145+
});
146+
}
147+
}
148+
}
149+
131150
const error = agents.value[provider].error;
132151
const agentOptions =
133152
theAgents.length > 0

packages/frontend/editor-ui/src/features/ai/chatHub/components/ProviderSettingsModal.vue

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ import CredentialPicker from '@/features/credentials/components/CredentialPicker
2222
import TagsDropdown from '@/features/shared/tags/components/TagsDropdown.vue';
2323
import { type ITag } from '@n8n/rest-api-client';
2424
25+
interface IModel extends ITag {
26+
isManual?: boolean;
27+
}
28+
2529
const props = defineProps<{
2630
modalName: string;
2731
data: {
@@ -37,9 +41,10 @@ const modalBus = ref(createEventBus());
3741
const loadingSettings = ref(false);
3842
const loadingModels = ref(false);
3943
const availableModels = ref<ChatModelDto[]>([]);
44+
const customModels = ref<string[]>([]);
4045
41-
const allModels = computed<ITag[]>(() => {
42-
const models = new Map(
46+
const allModels = computed<IModel[]>(() => {
47+
const models: Map<string, IModel> = new Map(
4348
availableModels.value
4449
.filter((model) => model.model.provider !== 'custom-agent' && model.model.provider !== 'n8n')
4550
.map((model) => [
@@ -51,21 +56,19 @@ const allModels = computed<ITag[]>(() => {
5156
]),
5257
);
5358
54-
// Ensure any custom selected models are also included
55-
if (settings.value?.allowedModels) {
56-
for (const allowed of settings.value.allowedModels) {
57-
models.set(allowed.model, {
58-
id: allowed.model,
59-
name: allowed.model,
60-
});
61-
}
59+
for (const model of customModels.value) {
60+
models.set(model, {
61+
id: model,
62+
name: model,
63+
isManual: true,
64+
});
6265
}
6366
6467
return Array.from(models.values());
6568
});
6669
67-
const modelsById = computed<Record<string, ITag>>(() => {
68-
const map: Record<string, ITag> = {};
70+
const modelsById = computed<Record<string, IModel>>(() => {
71+
const map: Record<string, IModel> = {};
6972
allModels.value.forEach((model) => {
7073
map[model.id] = model;
7174
});
@@ -82,28 +85,18 @@ const selectedModels = computed({
8285
.map((model) => ({
8386
model: model.id,
8487
displayName: model.name,
88+
isManual: model.isManual,
8589
}));
90+
91+
customModels.value = settings.value.allowedModels
92+
.filter((model) => model.isManual)
93+
.map((model) => model.model);
8694
}
8795
},
8896
});
8997
90-
// TODO: While we're able to support creating new models here
91-
// this won't make them available in the model selector at the momenst,
92-
// as the models list is fetched from the backend based on credentials.
93-
// We should somehow track that these are custom manually defined models
94-
// and they should always be shown...
95-
async function createModel(name: string): Promise<ITag> {
96-
availableModels.value.push({
97-
name,
98-
model: {
99-
provider: props.data.provider,
100-
model: name,
101-
} satisfies ChatHubBaseLLMModel,
102-
description: '',
103-
updatedAt: new Date().toISOString(),
104-
createdAt: new Date().toISOString(),
105-
});
106-
98+
async function addManualModel(name: string): Promise<IModel> {
99+
customModels.value.push(name);
107100
return {
108101
id: name,
109102
name,
@@ -148,6 +141,11 @@ function onCancel() {
148141
149142
async function loadSettings() {
150143
settings.value = await chatStore.fetchProviderSettings(props.data.provider);
144+
if (settings.value.allowedModels) {
145+
customModels.value = settings.value.allowedModels
146+
.filter((model) => model.isManual)
147+
.map((model) => model.model);
148+
}
151149
}
152150
153151
async function loadAvailableModels(credentialId: string) {
@@ -300,7 +298,7 @@ watch(
300298
:all-tags="allModels"
301299
:is-loading="loadingModels"
302300
:tags-by-id="modelsById"
303-
:create-tag="createModel"
301+
:create-tag="addManualModel"
304302
:create-tag-i18n-key="'settings.chatHub.providers.modal.edit.models.create'"
305303
/>
306304
</div>

0 commit comments

Comments
 (0)