# `Nous.Tool.Validator`
[🔗](https://github.com/nyo16/nous/blob/v0.17.1/lib/nous/tool/validator.ex#L1)

Validates tool arguments against JSON schema.

Provides validation of arguments before tool execution to catch
errors early and provide helpful feedback to the LLM.

## Example

    schema = %{
      "type" => "object",
      "properties" => %{
        "query" => %{"type" => "string"},
        "limit" => %{"type" => "integer"}
      },
      "required" => ["query"]
    }

    args = %{"query" => "elixir", "limit" => 10}
    {:ok, args} = Validator.validate(args, schema)

    # Missing required field
    {:error, {:missing_required, ["query"]}} = Validator.validate(%{}, schema)

    # Wrong type
    {:error, {:type_mismatch, [{"limit", "integer", "string"}]}} =
      Validator.validate(%{"query" => "x", "limit" => "not a number"}, schema)

## Integration with ToolExecutor

When `tool.validate_args` is `true`, the ToolExecutor will validate
arguments before calling the tool function.

# `validation_error`

```elixir
@type validation_error() ::
  {:missing_required, [String.t()]}
  | {:type_mismatch, [{String.t(), String.t(), String.t()}]}
  | {:validation_failed, String.t()}
```

# `format_error`

```elixir
@spec format_error(validation_error()) :: String.t()
```

Format validation errors into a human-readable string.

## Example

    error = {:missing_required, ["query", "limit"]}
    Validator.format_error(error)
    # => "Missing required fields: query, limit"

# `matches_type?`

```elixir
@spec matches_type?(any(), String.t()) :: boolean()
```

Check if a value matches a JSON schema type.

Supports: string, integer, number, boolean, array, object, null

## Example

    Validator.matches_type?("hello", "string")  # => true
    Validator.matches_type?(42, "integer")      # => true
    Validator.matches_type?(3.14, "number")     # => true
    Validator.matches_type?([1, 2], "array")    # => true
    Validator.matches_type?(%{}, "object")      # => true

# `typeof`

```elixir
@spec typeof(any()) :: String.t()
```

Get the JSON schema type name for a value.

## Example

    Validator.typeof("hello")  # => "string"
    Validator.typeof(42)       # => "integer"
    Validator.typeof(3.14)     # => "number"
    Validator.typeof([])       # => "array"
    Validator.typeof(%{})      # => "object"
    Validator.typeof(nil)      # => "null"

# `validate`

```elixir
@spec validate(map(), map()) :: {:ok, map()} | {:error, validation_error()}
```

Validate arguments against a JSON schema.

## Parameters

- `args` - The arguments map to validate
- `schema` - JSON schema with "properties" and "required" fields

## Returns

- `{:ok, args}` - Arguments are valid
- `{:error, reason}` - Validation failed

## Example

    schema = %{
      "type" => "object",
      "properties" => %{
        "name" => %{"type" => "string"}
      },
      "required" => ["name"]
    }

    Validator.validate(%{"name" => "Alice"}, schema)
    # => {:ok, %{"name" => "Alice"}}

# `validate!`

```elixir
@spec validate!(map(), map()) :: map()
```

Validate arguments and raise on error.

Useful for tests or when you want to fail fast.

## Example

    Validator.validate!(args, schema)  # Raises on invalid

# `validate_required`

```elixir
@spec validate_required(map(), [String.t()]) ::
  :ok | {:error, {:missing_required, [String.t()]}}
```

Validate that all required fields are present.

## Example

    Validator.validate_required(%{"a" => 1}, ["a", "b"])
    # => {:error, {:missing_required, ["b"]}}

# `validate_types`

```elixir
@spec validate_types(map(), map()) :: :ok | {:error, {:type_mismatch, list()}}
```

Validate argument types against schema properties.

## Example

    properties = %{
      "count" => %{"type" => "integer"}
    }

    Validator.validate_types(%{"count" => "not a number"}, properties)
    # => {:error, {:type_mismatch, [{"count", "integer", "string"}]}}

---

*Consult [api-reference.md](api-reference.md) for complete listing*
