melch

Configure model providers per agent on a single line

A prefix table maps each agent’s model identifier to a provider adapter. If a syndicate, an agent team declared in one configuration file, names five providers, the runtime executes whichever models have environment keys present.

Switch five providers by model prefix

Selecting a provider updates the star’s colour and sets a valid model identifier. The key line names the matching environment variable, while the rest of the file runs the same team unchanged.

youα Tutorgemini-3.1-flash-lite
orchestrator:
  name: "Tutor"
  model: "gemini-3.1-flash-lite"

# Environment variable read by the provider
GOOGLE_GENAI_API_KEY=…

The runtime routes requests by the model id prefix: gemini-, claude-, gpt- and o, grok-, or ollama/.

The Model Zoo proves optionality

The file configures one lightweight agent per provider on a single prompt. Running npm run demo:models sends that message to every provider matching an active key, printing thinking traces alongside token counts and latency measurements. Running the script lets you observe provider optionality directly in working execution traces.

npm run demo:models

Local models run through Ollama’s OpenAI-compatible API with the context window set explicitly. Ollama’s default context is small enough to truncate a long instruction block without reporting the loss, so the runtime specifies the window size directly.

config/agents/examples/model_zoo.yaml
# ============================================================
# MODEL ZOO — one lightweight agent per provider.
#
# This file is the proof of model optionality: five agents whose
# ONLY meaningful difference is the `model:` line. The framework
# reads that string and routes each agent to the right provider:
#
#   ollama/qwen3.5:9b → local Ollama   (keyless — nothing leaves your machine)
#   claude-*          → Anthropic      (ANTHROPIC_API_KEY)
#   grok-*            → xAI            (XAI_API_KEY)
#   gpt-*             → OpenAI         (OPENAI_API_KEY)
#   gemini-*          → Google         (GOOGLE_GENAI_API_KEY)
#
# Run the proof:  npm run demo:models        (scripts/demo_model_optionality.ts
#   sends "explain quantum mechanics" to every agent whose provider is
#   available, and prints input, thinking, output, and a token/latency trace.
#   Providers without a key are skipped, never fatal.)
#
# Or chat with the zoo:  npm run chat:syndicate -- --syndicate model_zoo
#   (the orchestrator delegates your question to a provider you name).
# ============================================================

syndicate_name: "Model Zoo"
memory_system: "session-only"

orchestrator:
  name: "Zookeeper"
  model: "gemini-3.1-flash-lite"
  instruction: |
    You are the Zookeeper, coordinator of a menagerie of language models from
    five different providers. When the user asks a question, delegate it to
    the subagent they name (qwen_local, claude, grok, gpt, or gemini) — or,
    if they name none, pick one and say which you chose. Return the
    subagent's answer verbatim, attributed to it.

subagents:
  - name: "qwen_local"
    # Qwen3.5 is the newest generation that ships small dense sizes; the
    # 9B is the largest that fits a 16/18 GB laptop with room for context.
    # Qwen3.8 is stronger but 27B-only (18 GB of weights) — see the size
    # table in lib/models/ollamaLlm.ts before changing this line.
    description: "Qwen 3.5 (9B), an open-weight model running locally via Ollama. Keyless."
    model: "ollama/qwen3.5:9b"
    instruction: |
      You are a concise explainer. Answer in three short paragraphs at most,
      plain language first, one concrete example, no headings.

  - name: "claude"
    description: "Claude Sonnet, by Anthropic."
    model: "claude-sonnet-4-6"
    instruction: |
      You are a concise explainer. Answer in three short paragraphs at most,
      plain language first, one concrete example, no headings.
    # Extended thinking: the adapter maps thinkingBudget to Anthropic's
    # thinking parameter and surfaces the scratchpad as THINKING output.
    generateContentConfig:
      thinkingConfig:
        thinkingBudget: 2048

  - name: "grok"
    description: "Grok 4.7 (reasoning effort: medium), by xAI."
    # The adapter pins reasoning effort 'medium' for grok-4.5/4.7 requests
    # (DEFAULT_GROK_REASONING_EFFORT, lib/config.ts).
    model: "grok-4.7"
    instruction: |
      You are a concise explainer. Answer in three short paragraphs at most,
      plain language first, one concrete example, no headings.

  - name: "gpt"
    description: "GPT-5 mini, by OpenAI."
    model: "gpt-5-mini"
    instruction: |
      You are a concise explainer. Answer in three short paragraphs at most,
      plain language first, one concrete example, no headings.

  - name: "gemini"
    description: "Gemini Flash Lite, by Google."
    model: "gemini-3.1-flash-lite"
    instruction: |
      You are a concise explainer. Answer in three short paragraphs at most,
      plain language first, one concrete example, no headings.