diff --git a/plugins/_model_config/AGENTS.md b/plugins/_model_config/AGENTS.md index f6350ea11..1c4dce812 100644 --- a/plugins/_model_config/AGENTS.md +++ b/plugins/_model_config/AGENTS.md @@ -26,6 +26,7 @@ - The optional `vision` slot is strictly per preset and never inherited from `Default`; an empty slot disables the separate Vision Model for that preset. - Main native vision wins by default. A configured Vision Model handles `vision_load` when Main lacks vision, or when that preset explicitly enables `override_main`. - Keep the optional Vision provider/model selector inside the Main Model card and flush with Main's field alignment, without a nested left inset. Show it only while Main vision is disabled or `override_main` is enabled; do not render a standalone Vision Model card. +- Keep Vision timeout and maximum-output-token controls, plus the Agent Editor prompt-customization note, inside the visible Vision sidecar's Advanced Settings only. The Vision call limits belong to the preset/model builder, not to `vision_load` call-site constants. - Show `Use separate Vision Model` immediately below `Supports Vision` while Main vision is enabled, not inside Advanced Settings; describe the disabled state as using Main's native vision. - In model overviews, render the effective Vision Model as a text-only `Vision override / Provider / Model` child aligned with Main's provider column, not as an icon-bearing peer row. - Changing a model provider in the settings UI must clear `api_base` and `kwargs` because both may be provider-specific. diff --git a/plugins/_model_config/helpers/model_config.py b/plugins/_model_config/helpers/model_config.py index 0c6f539c2..0aa73a37f 100644 --- a/plugins/_model_config/helpers/model_config.py +++ b/plugins/_model_config/helpers/model_config.py @@ -11,6 +11,8 @@ PRESETS_FILE = "presets.yaml" FALLBACK_PRESETS_FILE = "mode_presets_fallback.yaml" PROVIDER_METADATA_FILE = "provider_metadata.yaml" DEFAULT_PRESET_NAME = "Default" +DEFAULT_VISION_TIMEOUT_SECONDS = 300 +DEFAULT_VISION_MAX_TOKENS = 2000 MODEL_PRESET_CONFIG_KEY = "model_preset" PRESET_SCOPE_GLOBAL = "global" PRESET_SCOPE_PROJECT = "project" @@ -25,6 +27,8 @@ IMPLICIT_PRESET_SLOT_DEFAULTS = { "vision": { "vision": True, "max_embeds": 10, + "timeout": DEFAULT_VISION_TIMEOUT_SECONDS, + "max_tokens": DEFAULT_VISION_MAX_TOKENS, "override_main": False, "rl_requests": 0, "rl_input": 0, @@ -873,8 +877,18 @@ def build_vision_model(agent=None): cfg = get_vision_model_config(agent) mc = build_model_config(cfg, models.ModelType.CHAT) mc.vision = True + kwargs = mc.build_kwargs() + for key, default in ( + ("timeout", DEFAULT_VISION_TIMEOUT_SECONDS), + ("max_tokens", DEFAULT_VISION_MAX_TOKENS), + ): + value = cfg.get(key) + if value not in (None, ""): + kwargs[key] = _normalize_kwargs({key: value})[key] + else: + kwargs.setdefault(key, default) return models.get_chat_model( - mc.provider, mc.name, model_config=mc, **mc.build_kwargs() + mc.provider, mc.name, model_config=mc, **kwargs ) diff --git a/plugins/_model_config/webui/model-config-store.js b/plugins/_model_config/webui/model-config-store.js index 1ab6d8c8e..74c723132 100644 --- a/plugins/_model_config/webui/model-config-store.js +++ b/plugins/_model_config/webui/model-config-store.js @@ -63,6 +63,8 @@ const IMPLICIT_PRESET_SLOT_DEFAULTS = { vision: { vision: true, max_embeds: 10, + timeout: 300, + max_tokens: 2000, override_main: false, rl_requests: 0, rl_input: 0, @@ -222,7 +224,23 @@ export const store = createStore("modelConfig", { const source = (rawPresets || []).filter(p => p && typeof p === 'object'); const rawDefault = source.find(p => String(p.name || '').toLowerCase() === 'default') || {}; const slot = value => ({ provider: '', name: '', api_key: '', api_base: '', kwargs: {}, ...(value || {}) }); - const visionSlot = value => ({ ...slot(value), vision: true, max_embeds: Number(value?.max_embeds ?? 10), override_main: !!value?.override_main }); + const visionSlot = value => { + const normalized = slot(value); + const kwargs = { ...(normalized.kwargs || {}) }; + const timeout = Number(value?.timeout ?? kwargs.timeout ?? 300); + const maxTokens = Number(value?.max_tokens ?? kwargs.max_tokens ?? 2000); + delete kwargs.timeout; + delete kwargs.max_tokens; + return { + ...normalized, + vision: true, + max_embeds: Number(value?.max_embeds ?? 10), + timeout, + max_tokens: maxTokens, + override_main: !!value?.override_main, + kwargs, + }; + }; const defaultConfig = { chat_model: slot(rawDefault.chat), vision_model: hasModelIdentity(rawDefault.vision) ? visionSlot(rawDefault.vision) : {}, @@ -234,10 +252,11 @@ export const store = createStore("modelConfig", { const effective = String(p.name || '').toLowerCase() === 'default' ? defaultConfig : configFromPreset(p, defaultConfig, true); + const vision = visionSlot(effective.vision_model); return { name: p.name || '', chat: { ...slot(effective.chat_model), _kwargs_text: kwargsToText(effective.chat_model?.kwargs) }, - vision: { ...visionSlot(effective.vision_model), _kwargs_text: kwargsToText(effective.vision_model?.kwargs) }, + vision: { ...vision, _kwargs_text: kwargsToText(vision.kwargs) }, utility: { ...slot(effective.utility_model), _kwargs_text: kwargsToText(effective.utility_model?.kwargs) }, embedding: { ...slot(effective.embedding_model), _kwargs_text: kwargsToText(effective.embedding_model?.kwargs) }, }; @@ -360,7 +379,7 @@ export const store = createStore("modelConfig", { || this.presets[0] || { chat: { provider: '', name: '', api_base: '', kwargs: {}, _kwargs_text: '' }, - vision: { provider: '', name: '', api_base: '', vision: true, max_embeds: 10, override_main: false, kwargs: {}, _kwargs_text: '' }, + vision: { provider: '', name: '', api_base: '', vision: true, max_embeds: 10, timeout: 300, max_tokens: 2000, override_main: false, kwargs: {}, _kwargs_text: '' }, utility: { provider: '', name: '', api_base: '', kwargs: {}, _kwargs_text: '' }, embedding: { provider: '', name: '', api_base: '', kwargs: {}, _kwargs_text: '' }, } diff --git a/plugins/_model_config/webui/model-field.html b/plugins/_model_config/webui/model-field.html index 51c70741a..a0703ddb3 100644 --- a/plugins/_model_config/webui/model-field.html +++ b/plugins/_model_config/webui/model-field.html @@ -9,7 +9,7 @@ ') + vision_advanced_start = model_field.index('