@@ -22,6 +22,10 @@ import CredentialPicker from '@/features/credentials/components/CredentialPicker
2222import TagsDropdown from ' @/features/shared/tags/components/TagsDropdown.vue' ;
2323import { type ITag } from ' @n8n/rest-api-client' ;
2424
25+ interface IModel extends ITag {
26+ isManual? : boolean ;
27+ }
28+
2529const props = defineProps <{
2630 modalName: string ;
2731 data: {
@@ -37,9 +41,10 @@ const modalBus = ref(createEventBus());
3741const loadingSettings = ref (false );
3842const loadingModels = ref (false );
3943const 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
149142async 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
153151async 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