# How to Apply Value Constraints with `needle.Field`: A Complete Guide

> Learn to apply value constraints with needle.Field using typing Annotated. Define ranges, patterns, and enums for Needle tool parameters effortlessly.

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

---

**Use `needle.Field` as a descriptor inside `typing.Annotated` to attach JSON Schema constraints—such as ranges, patterns, and enums—to function arguments that become Needle tool parameters.**

The `Field` class in the Needle framework provides a declarative way to enforce input validation for AI agent tools. When you decorate a function with `@needle.tool`, the framework automatically converts `Field` constraints into standard JSON Schema definitions, enabling both runtime validation and structured tool descriptions for large language models.

## Understanding `needle.Field` Constraints

The `Field` class lives in [`needle/agent/tools.py`](https://github.com/cactus-compute/needle/blob/main/needle/agent/tools.py) and exposes parameters that map directly to JSON Schema keywords. When `build_schema` processes a tool function, it extracts `Field` instances from `typing.Annotated` metadata and invokes `field.apply(schema)` to inject the constraints ([source](https://github.com/cactus-compute/needle/blob/main/needle/agent/tools.py#L35-L38)).

| Constraint Parameter | Generated JSON Schema | Description |
|----------------------|----------------------|-------------|
| `ge` / `le` | `minimum` / `maximum` | Inclusive numeric bounds |
| `gt` / `lt` | `exclusiveMinimum` / `exclusiveMaximum` | Exclusive numeric bounds |
| `multiple_of` | `multipleOf` | Value must be a multiple of the given number |
| `min_length` / `max_length` | `minLength` / `maxLength` | String character limits |
| `pattern` | `pattern` | Regular expression that strings must match |
| `format` | `format` | Semantic format hint (e.g., `email`, `date-time`) |
| `enum` | `enum` | Array of allowed values |
| `const` | `const` | Fixed value that the input must equal |
| `min_items` / `max_items` / `unique_items` | `minItems` / `maxItems` / `uniqueItems` | Array validation rules |
| `description` | `description` | Human-readable documentation in the schema |

The `apply` method implementation ([source](https://github.com/cactus-compute/needle/blob/main/needle/agent/tools.py#L36-L49)) merges these parameters into the schema dictionary, ensuring compatibility with OpenAI function calling and other agent protocols.

## Applying Numeric Constraints with `ge`, `le`, `gt`, `lt`

Use inclusive bounds (`ge`, `le`) for closed ranges and exclusive bounds (`gt`, `lt`) for open ranges.

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

@tool
def set_volume(
    level: Annotated[int, Field(ge=0, le=100, enum=[0, 25, 50, 75, 100])]
):
    """Set speaker volume to predefined levels."""
    return {"volume": level}

```

This generates a schema requiring integers between 0 and 100, limited to specific step values.

For strictly positive values, combine `gt` with validation:

```python
@tool
def set_temperature(
    kelvin: Annotated[float, Field(gt=0, lt=10000, description="Temperature in Kelvin")]
):
    """Set the reactor temperature."""
    return {"temperature": kelvin}

```

## Validating Strings with `min_length`, `max_length`, and `pattern`

String constraints ensure user inputs meet formatting requirements before reaching your tool logic.

```python
@tool
def create_user(
    name: Annotated[
        str,
        Field(
            min_length=3,
            max_length=30,
            pattern=r'^[A-Za-z0-9_]+$',
            description='Username with alphanumeric characters and underscores'
        )
    ]
):
    """Create a new user account."""
    return {"username": name}

```

The `pattern` parameter accepts any valid Python regular expression. Needle passes this directly to JSON Schema's `pattern` keyword, which uses ECMAScript regex syntax.

## Constraining Arrays with `min_items`, `max_items`, and `unique_items`

Array parameters accept lists and can enforce size limits and uniqueness constraints.

```python
@tool
def upload_images(
    urls: Annotated[
        list[str],
        Field(
            min_items=1,
            max_items=5,
            unique_items=True,
            description='List of unique image URLs to process (1-5 items)'
        )
    ]
):
    """Upload and process up to five unique images."""
    return {"processed": len(urls)}

```

Setting `unique_items=True` ensures no duplicates exist in the array—valuable for batch operations where repetition would cause errors.

## Enforcing Fixed Values with `const` and `enum`

Use `const` for parameters that must always match a specific value, typically for feature flags or version indicators.

```python
@tool
def enable_feature(
    flag: Annotated[bool, Field(const=True, description="Must be True to enable")]
):
    """Enable the experimental feature. The flag must always be True."""
    return {"enabled": flag}

```

For multiple allowed values, `enum` provides a restricted set:

```python
from enum import Enum

class Priority(str, Enum):
    low = "low"
    medium = "medium"
    high = "high"

@tool
def create_ticket(
    priority: Annotated[
        str,
        Field(enum=["low", "medium", "high"], description="Ticket priority level")
    ]
):
    """Create a support ticket with specified priority."""
    return {"ticket": {"priority": priority}}

```

## Complete Example: Multi-Constraint Tool Definition

Combine multiple constraint types for robust parameter validation.

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

@tool
def schedule_meeting(
    email: Annotated[
        str,
        Field(
            format="email",
            description="Organizer email address"
        )
    ],
    duration_minutes: Annotated[
        int,
        Field(
            ge=15,
            le=240,
            multiple_of=15,
            description="Meeting duration in 15-minute increments"
        )
    ],
    attendees: Annotated[
        list[str],
        Field(
            min_items=1,
            max_items=50,
            description="List of attendee email addresses"
        )
    ],
    notify: Annotated[
        bool,
        Field(
            const=True,
            description="Notification flag (always True)"
        )
    ] = True
):
    """Schedule a meeting with validated parameters."""
    return {
        "organizer": email,
        "duration": duration_minutes,
        "attendee_count": len(attendees)
    }

```

## Summary

- **Import from `needle.agent.tools`**: `Field` and `tool` provide the complete validation interface.

- **Wrap with `typing.Annotated`**: All constraints attach via `Annotated[type, Field(...)]` syntax.

- **Map to JSON Schema**: Each `Field` parameter generates standard schema keywords for interoperability.

- **Apply runs automatically**: The `build_schema` function calls `field.apply(schema)` during `@tool` registration.

- **Source location**: Constraint logic resides in [`needle/agent/tools.py`](https://github.com/cactus-compute/needle/blob/main/needle/agent/tools.py).

## Frequently Asked Questions

### What happens if a constraint is violated at runtime?

Needle validates inputs against the generated JSON Schema before executing your tool function. Violations raise a validation error with details about which constraint failed, preventing invalid data from reaching your business logic.

### Can I combine multiple constraints in a single `Field` call?

Yes. `Field` accepts any combination of compatible parameters. For example, `Field(ge=0, le=100, multiple_of=10)` creates a range-limited value that must be divisible by 10. The `apply` method merges all provided constraints into the final schema.

### Does `needle.Field` support custom validation logic?

No. `Field` strictly provides JSON Schema-compatible constraints. For complex validation requiring runtime computation, implement checks inside your tool function after receiving the validated parameters. The framework ensures schema-compliant values reach your code, then you apply additional business rules.