{
  "_comment": "B5 Fusion configuration sample — save to ~/.pi/b5-fusion-settings.json and edit.",
  "_schema_version": 6,

  "version": 6,
  "enabled": true,
  "language": "auto",

  "_candidates_comment": [
    "Each candidate is an independent OpenAI-compatible endpoint.",
    "ALL enabled candidates run on every turn.",
    "Use $ENV_VAR syntax in apiKey to read from the environment.",
    "Available thinking: off | minimal | low | medium | high | xhigh"
  ],
  "candidates": [
    {
      "label": "fast",
      "enabled": true,
      "baseUrl": "https://api.openrouter.ai/v1",
      "apiKey": "$OPENROUTER_API_KEY",
      "model": "deepseek/deepseek-chat",
      "thinking": "minimal"
    },
    {
      "label": "code",
      "enabled": true,
      "baseUrl": "https://api.openrouter.ai/v1",
      "apiKey": "$OPENROUTER_API_KEY",
      "model": "anthropic/claude-3.5-sonnet",
      "thinking": "low"
    },
    {
      "label": "reason",
      "enabled": true,
      "baseUrl": "https://api.openrouter.ai/v1",
      "apiKey": "$OPENROUTER_API_KEY",
      "model": "deepseek/deepseek-reasoner",
      "thinking": "high"
    },
    {
      "label": "long",
      "enabled": true,
      "baseUrl": "https://api.openrouter.ai/v1",
      "apiKey": "$OPENROUTER_API_KEY",
      "model": "google/gemini-2.5-pro",
      "thinking": "medium"
    }
  ],

  "_aggregator_comment": [
    "The aggregator (fusion model) — a single member.",
    "Receives all candidate drafts as context and synthesizes the final answer.",
    "MUST support tool calling for the agent to use read/bash/edit/etc."
  ],
  "aggregator": {
    "baseUrl": "https://api.openrouter.ai/v1",
    "apiKey": "$OPENROUTER_API_KEY",
    "model": "anthropic/claude-3.5-sonnet",
    "thinking": "low"
  },

  "_tunables_comment": [
    "minSuccessfulProposers: how many candidates must succeed before fusion proceeds.",
    "quorumGraceSeconds:    after quorum met, wait this long for slow candidates then abort.",
    "proposerTimeoutSeconds / aggregatorTimeoutSeconds: hard per-request limits.",
    "draftMaxChars:         truncate each candidate draft before sending to the aggregator.",
    "shuffleCandidates:     randomize draft order to remove position bias."
  ],
  "minSuccessfulProposers": 3,
  "proposerTimeoutSeconds": 1200,
  "aggregatorTimeoutSeconds": 1800,
  "draftMaxChars": 8000,
  "shuffleCandidates": true,
  "quorumGraceSeconds": 10
}
