# Needle.Field Constraints: Complete Guide to JSON-Schema Validation in Python

> Learn about needle.Field constraints for JSON-Schema validation in Python. This guide covers all supported constraints for function parameters in the Needle framework.

- Repository: [Cactus Compute, Inc./needle](https://github.com/cactus-compute/needle)
- Tags: how-to-guide
- Published: 2026-08-31

---

**`needle.Field` is a lightweight descriptor that adds JSON-Schema-compatible validation constraints to function parameters in the Needle framework.**

`needle.Field` lets you attach rich metadata—descriptions, bounds, patterns, and more—to agent tool parameters. When functions are decorated with `@tool`, these constraints flow directly into the generated JSON Schema, making them discoverable by LLMs and validators.

## Where Field Constraints Live in the Codebase

The `Field` class is defined in [`needle/agent/tools.py`](https://github.com/cactus-compute/needle/blob/main/needle/agent/tools.py) (lines 18–36). Its constructor captures keyword arguments and stores them as instance attributes:

```python

# From needle/agent/tools.py L18-L36

class Field:
    def __init__(self, default=None, *, description=None, enum=None, const=None,
                 ge=None, le=None, gt=None, lt=None, multiple_of=None,
                 min_length=None, max_length=None, pattern=None, format=None,
                 min_items=None, max_items=None, unique_items=None):
        self.default = default
        self.description = description
        # ... additional constraints stored as attributes

```

During schema generation, the `apply` method (lines 36–49) copies non-`None` values into the final JSON-Schema dictionary.

## Complete List of Supported Constraints

Each parameter maps directly to a JSON-Schema keyword. Here are all supported `needle.Field` constraints organized by type:

### Metadata Constraints

- **`description`** — Human-readable explanation of the parameter's purpose
- **`default`** — Value used when the argument is omitted (positional parameter, not keyword)

### Value Constraints

- **`enum`** — List of allowed literal values
- **`const`** — Single fixed value the argument must equal

### Numeric Bounds

- **`ge`** / **`le`** — Inclusive lower (`>=`) and upper (`<=`) bounds
- **`gt`** / **`lt`** — Exclusive lower (`>`) and upper (`<`) bounds
- **`multiple_of`** — Value must be divisible by this number

### String Constraints

- **`min_length`** / **`max_length`** — Character count limits
- **`pattern`** — Regular expression the string must match
- **`format`** — Semantic format hint (e.g., `email`, `uri`, `date-time`)

### Array Constraints

- **`min_items`** / **`max_items`** — Minimum and maximum element count
- **`unique_items`** — If `True`, all array elements must be distinct

## Practical Code Examples

### Numeric Validation with Bounds and Multiplicity

```python
from needle.agent.tools import Field, tool

@tool
def generate_numbers(count: int = Field(ge=1, le=10, multiple_of=2)):
    """Generate an even number of items between 2 and 10."""
    return list(range(count))

```

This produces the schema keyword `minimum: 1`, `maximum: 10`, and `multipleOf: 2`.

### String Pattern and Enum Validation

```python
from needle.agent.tools import Field, tool

@tool
def set_mode(mode: str = Field(enum=["auto", "manual"], pattern="^(auto|manual)$")):
    """Select operating mode with strict validation."""
    return f"Mode set to {mode}"

```

Both `enum` and `pattern` appear in the generated schema, providing redundant validation layers.

### Array Size and Uniqueness Constraints

```python
from needle.agent.tools import Field, tool

@tool
def upload_files(files: list = Field(min_items=1, max_items=5, unique_items=True)):
    """Upload 1 to 5 unique file paths."""
    return f"{len(files)} files uploaded"

```

The `unique_items=True` constraint maps to JSON-Schema's `uniqueItems` keyword.

### Constant Value Enforcement

```python
from needle.agent.tools import Field, tool

@tool
def ping(server: str = Field(const="localhost")):
    """Ping only the localhost server."""
    return f"Pinging {server}"

```

The `const` keyword forces the argument to always equal `"localhost"`.

## How Constraints Flow Into JSON Schema

When `@tool` processes a function, it calls `build_schema` from [`needle/agent/tools.py`](https://github.com/cactus-compute/needle/blob/main/needle/agent/tools.py). For each parameter with a `Field` default, the framework invokes `field.apply(schema_dict)`, which injects the constraints:

```python

# Conceptual flow from tools.py L36-49

def apply(self, schema):
    if self.description is not None:
        schema["description"] = self.description
    if self.enum is not None:
        schema["enum"] = self.enum
    # ... additional constraint mappings

```

The resulting schema is compatible with OpenAI function calling, JSON Schema Draft 7+, and standard API validators.

## Summary

- **`needle.Field`** supports **14+ constraints** spanning metadata, numeric bounds, string patterns, and array validation
- All constraints map **directly to JSON-Schema keywords** for universal compatibility
- The implementation lives in **[`needle/agent/tools.py`](https://github.com/cactus-compute/needle/blob/main/needle/agent/tools.py)** with the `Field` constructor (lines 18–36) and `apply` method (lines 36–49)
- Use **`@tool`** decoration to automatically expose constraints to LLMs and validators

## Frequently Asked Questions

### What happens if I specify both `ge` and `gt` on the same Field?

Both values are included in the schema, but JSON Schema validators typically treat them as independent constraints. The stricter bound effectively applies. According to the [`needle/agent/tools.py`](https://github.com/cactus-compute/needle/blob/main/needle/agent/tools.py) source, there is no runtime validation—constraints are purely declarative for schema generation.

### Does `needle.Field` validate values at runtime?

No. `needle.Field` is a **schema-only descriptor**. It captures constraints for `build_schema` to emit, but Python does not enforce them during function calls. Validation happens at the consumer level—by the LLM, API gateway, or downstream JSON-Schema validator.

### Can I combine `enum` and `pattern` constraints?

Yes. As shown in the set_mode example, both can coexist. The generated schema includes both `enum` and `pattern` keywords, allowing validators to check against either or both depending on their implementation.

### What JSON Schema version does needle target?

The constraints align with **JSON Schema Draft 7** and **OpenAI's function-calling schema**, which covers the keywords listed here: `description`, `enum`, `const`, `minimum`/`maximum`, `exclusiveMinimum`/`exclusiveMaximum`, `multipleOf`, `minLength`/`maxLength`, `pattern`, `format`, `minItems`/`maxItems`, and `uniqueItems`.