Problem
Model configuration is currently defined entirely inline in config.toml, under [ai.providers.ollama.models.<name>]. This means:
- Every user must manually look up and configure the right
num_ctx, prompt_template, supported_languages, etc. for each model they want to use
- Optimal settings for well-known models are not shared — users have to rediscover them
- The knowledge of how to use a model is not versioned with the project
Proposed Solution
Introduce model profiles: TOML files distributed in a models/ directory at the project root, each containing the recommended configuration for a specific model. In config.toml, a model entry can reference a profile by name and optionally override individual fields.
Model profile file (models/qwen3-5.toml)
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: 2026 The Photometoria contributors
[model]
model_name = "qwen3.5:latest"
description = "Qwen 3.5 — recommended for production, strong multilingual support"
capabilities = ["vision", "multilingual"]
supported_languages = ["English", "Italian", "French", "German", "Spanish"]
context_window = 8192
prompt_template = """
Analyze this image and return descriptive tags as keywords.
Respond ONLY with valid JSON, no other text.
The JSON object must have a single key "tags" containing an array of objects.
Each object must have ONLY one key "tag" with a keyword string value.
Example: {"tags": [{"tag": "sunset"}, {"tag": "mountain"}]}.
All tags returned must be in {{language}} language."""
Updated config.toml (referencing a profile)
[ai.providers.ollama.models.qwen3_5]
profile = "qwen3-5" # loads defaults from models/qwen3-5.toml
# optional field-level overrides:
# context_window = 4096
Inline model (no profile, fully explicit — still supported)
[ai.providers.ollama.models.custom]
model_name = "my-custom-model:latest"
capabilities = ["vision"]
context_window = 4096
prompt_template = "..."
Field changes
| Old field |
New field |
Notes |
ollama_model |
model_name |
Provider-agnostic name |
supports_vision = true|false |
capabilities = ["vision", ...] |
Extensible list |
num_ctx |
context_window |
More descriptive, provider-agnostic |
description |
description |
Unchanged |
prompt_template |
prompt_template |
Unchanged |
supported_languages |
supported_languages |
Unchanged |
Resolution logic
When a model entry in config.toml references a profile:
- Load the profile file from
models/<profile>.toml
- Apply any field-level overrides from
config.toml
- Use the merged result as the effective model config
If no profile is specified, the entry is used as-is (fully inline).
Scope
- New
models/ directory at project root with profiles for currently supported models (qwen3.5, qwen3-vl:8b, llava, ministral-3, gemma3n:e4b)
- Updated
OllamaModelConfig struct in api/src/config/ai.rs to reflect renamed fields and new capabilities type
- Profile loading and merge logic in the config layer
- Updated
api/config.toml to use profile references
- Update
api/CLAUDE.md model table accordingly
Out of scope
- Fetching profiles from remote URLs
- Auto-discovery of installed Ollama models
Problem
Model configuration is currently defined entirely inline in
config.toml, under[ai.providers.ollama.models.<name>]. This means:num_ctx,prompt_template,supported_languages, etc. for each model they want to useProposed Solution
Introduce model profiles: TOML files distributed in a
models/directory at the project root, each containing the recommended configuration for a specific model. Inconfig.toml, a model entry can reference a profile by name and optionally override individual fields.Model profile file (
models/qwen3-5.toml)Updated
config.toml(referencing a profile)Inline model (no profile, fully explicit — still supported)
Field changes
ollama_modelmodel_namesupports_vision = true|falsecapabilities = ["vision", ...]num_ctxcontext_windowdescriptiondescriptionprompt_templateprompt_templatesupported_languagessupported_languagesResolution logic
When a model entry in
config.tomlreferences aprofile:models/<profile>.tomlconfig.tomlIf no
profileis specified, the entry is used as-is (fully inline).Scope
models/directory at project root with profiles for currently supported models (qwen3.5,qwen3-vl:8b,llava,ministral-3,gemma3n:e4b)OllamaModelConfigstruct inapi/src/config/ai.rsto reflect renamed fields and newcapabilitiestypeapi/config.tomlto use profile referencesapi/CLAUDE.mdmodel table accordinglyOut of scope