{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "VeilCLI Agent Configuration",
  "type": "object",
  "required": [
    "name",
    "model"
  ],
  "additionalProperties": false,
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "description": {
      "type": "string"
    },
    "model": {
      "type": "string",
      "minLength": 1,
      "description": "Model identifier string e.g. 'anthropic/claude-4-6-sonnet'. Must be a string, NOT an object."
    },
    "temperature": {
      "type": "number",
      "minimum": 0,
      "maximum": 2
    },
    "reasoning": {
      "oneOf": [
        {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "effort": {
              "type": "string",
              "minLength": 1
            },
            "max_tokens": {
              "type": "integer",
              "minimum": 1
            }
          },
          "required": [
            "effort"
          ]
        },
        {
          "type": "string",
          "description": "Legacy bare-string shape (e.g. 'high'). Auto-folded to { effort: <string> } at load time. Prefer the object form."
        }
      ],
      "description": "Unified reasoning config: { effort: 'none'|'auto'|'minimal'|'low'|'medium'|'high'|'xhigh'|'max'|<custom>, max_tokens?: int }. Engine-blind: openai providers see effort/max_tokens directly (with xhigh/max capped to high); claude-cli maps to SDK effort + thinking.budgetTokens."
    },
    "maxTokens": {
      "type": "integer",
      "minimum": 1
    },
    "memory": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "enabled": {
          "type": "boolean"
        },
        "maxLines": {
          "type": "integer",
          "minimum": 10
        }
      }
    },
    "skillDiscovery": {
      "type": "boolean"
    },
    "defaultCompaction": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "enabled": {
          "type": "boolean",
          "description": "Enable or disable all compaction for this agent (default: true). When false, both auto-compact and the manual /compact endpoint are disabled."
        },
        "compactionCount": {
          "type": "number",
          "minimum": 1,
          "maximum": 99,
          "description": "Percentage of context to compact per compaction run (default: 50)"
        },
        "autoThreshold": {
          "type": "number",
          "minimum": 1,
          "maximum": 99,
          "description": "Auto-compact when context_size / context_size_limit * 100 reaches this percentage. Omit to disable auto-compaction."
        },
        "model": {
          "type": "string",
          "description": "Model to use for the compaction LLM call. Use \"default\" (or omit) to use the same model as the agent itself. Set to a cheaper model to reduce cost."
        },
        "customInstructions": {
          "type": "string",
          "description": "Additional instructions appended to the compaction system prompt. Use this to preserve domain-specific context (e.g. active task lists, decision logs, running state)."
        }
      }
    },
    "modes": {
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "chat": {
          "$ref": "#/definitions/chatModeConfig"
        }
      }
    }
  },
  "definitions": {
    "permissionsConfig": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "allow": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "deny": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      }
    },
    "baseModeConfig": {
      "type": "object",
      "required": [
        "enabled"
      ],
      "properties": {
        "enabled": {
          "type": "boolean"
        },
        "tools": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "disallowedTools": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "preActivatedTools": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Custom tools to pre-activate for this mode. Each entry is a tool name (resolved through the three-tier discovery: agent \u2192 project \u2192 global). Pre-activated tools appear in the LLM's tools[] list on turn one \u2014 no tool_search / tool_activate dance needed. Still subject to tools / disallowedTools permission gating."
        },
        "skills": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "autoLoadSkills": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "mcpServers": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "allowedAgents": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "disallowedAgents": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "permissions": {
          "$ref": "#/definitions/permissionsConfig"
        }
      }
    },
    "chatModeConfig": {
      "allOf": [
        {
          "$ref": "#/definitions/baseModeConfig"
        }
      ],
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "enabled": {
          "type": "boolean"
        },
        "tools": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "disallowedTools": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "preActivatedTools": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Custom tools to pre-activate for this mode. Each entry is a tool name (resolved through the three-tier discovery: agent \u2192 project \u2192 global). Pre-activated tools appear in the LLM's tools[] list on turn one \u2014 no tool_search / tool_activate dance needed. Still subject to tools / disallowedTools permission gating."
        },
        "skills": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "autoLoadSkills": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "mcpServers": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "allowedAgents": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "disallowedAgents": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "permissions": {
          "$ref": "#/definitions/permissionsConfig"
        }
      }
    }
  }
}
