Skip to content

feat: introduce model profiles — distribute optimized model configs with the project #131

Description

@siculo

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:

  1. Load the profile file from models/<profile>.toml
  2. Apply any field-level overrides from config.toml
  3. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions