Needle Field Constraints: A Complete Guide to Per-Argument Validation in `needle.Field`
needle.Field supports per-argument constraints including default, required, type, choices, numeric bounds (gt, ge, lt, le), length bounds (min_length, max_length), regex, nullable, and description.
The needle.Field class in the Cactus Compute Needle framework provides declarative validation for tool arguments. When you decorate a function with @tools.tool, each parameter annotated with Field(...) inherits automatic runtime validation powered by Pydantic. This article catalogs every available constraint based on the implementation in needle/agent/tools.py.
Core Constraint Categories
Value Presence and Defaults
| Constraint | Effect | Default |
|---|---|---|
required |
Argument must be provided explicitly | True |
default |
Value used when argument is omitted | None |
nullable |
Whether None is an acceptable value |
False |
Use required=False with default to create optional parameters:
from needle.agent import tools
@tools.tool
def fetch_data(
limit: tools.Field(default=100, required=False, nullable=False)
):
"""Return up to `limit` records."""
...
Type Enforcement
The type constraint accepts any Python type or Union of types. Validation occurs during Pydantic model construction:
@tools.tool
def calculate(
value: tools.Field(type=float),
count: tools.Field(type=int)
):
"""Process a float value `count` times."""
...
Choice-Based Validation
Restrict inputs to an explicit allowlist with choices:
@tools.tool
def set_environment(
env: tools.Field(choices=["dev", "staging", "production"])
):
"""Select deployment environment."""
...
Violation raises ValidationError with a clear message listing permitted values.
Numeric Bounds
Needle provides four comparison operators for number ranges:
| Constraint | Validates |
|---|---|
gt |
Greater than |
ge |
Greater than or equal |
lt |
Less than |
le |
Less than or equal |
Combine multiple constraints for closed or half-open intervals:
@tools.tool
def set_brightness(
level: tools.Field(type=int, ge=0, le=100)
):
"""Set screen brightness percentage."""
...
@tools.tool
def configure_timeout(
seconds: tools.Field(type=float, gt=0.0, lt=3600.0)
):
"""Set a timeout between 0 and 1 hour (exclusive)."""
...
String and Sequence Constraints
Length Bounds
Apply min_length and max_length to any sized collection:
@tools.tool
def create_passcode(
code: tools.Field(min_length=6, max_length=6)
):
"""Require exactly 6 characters."""
...
Regex Pattern Matching
The regex constraint accepts any valid Python regular expression. The match must cover the entire string (implicit ^...$ anchoring):
@tools.tool
def register_device(
serial: tools.Field(regex=r"[A-Z]{2}-\d{6}")
):
"""Validate serial format like 'AB-123456'."""
...
Documentation and Metadata
The description constraint populates generated OpenAPI schemas and tool documentation:
@tools.tool
def search(
query: tools.Field(description="Search terms for the document index"),
max_results: tools.Field(
type=int,
default=10,
ge=1,
le=100,
description="Maximum number of results to return"
)
):
"""Perform semantic search across indexed documents."""
...
Complete Parameter Example
Combine multiple constraints for robust validation in a single field:
from needle.agent import tools
from typing import Optional
@tools.tool
def send_notification(
recipient: tools.Field(
regex=r"^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$",
description="Valid email address"
),
subject: tools.Field(
min_length=1,
max_length=200,
description="Notification subject line"
),
priority: tools.Field(
default="normal",
choices=["low", "normal", "high", "urgent"],
description="Message priority level"
),
retry_count: tools.Field(
type=int,
default=3,
ge=0,
le=5,
nullable=False
),
metadata: tools.Field(
type=Optional[dict],
default=None,
nullable=True,
required=False
)
):
"""Send a prioritized notification with validation on all fields."""
...
Implementation Details
According to the cactus-compute/needle source code, needle.Field is implemented in [needle/agent/tools.py](https://github.com/cactus-compute/needle/blob/main/needle/agent/tools.py). The class constructs a Pydantic FieldInfo object internally, which means:
- All constraints map directly to Pydantic field parameters
- Validation errors use Pydantic's standard
ValidationErrorformat - Type coercion follows Pydantic's strict/lenient mode settings
The tool decorator (exposed via needle/agent/__init__.py) inspects function signatures at decoration time and builds a Pydantic model from Field annotations, enabling runtime validation without boilerplate.
Summary
needle.Fieldaccepts 11 distinct constraint parameters:default,required,type,choices,gt,ge,lt,le,min_length,max_length,regex,nullable, anddescription- Constraints compose arbitrarily: combine
typewith bounds,regexwithchoices, or any valid combination - Validation executes before tool logic runs, guaranteeing clean inputs
- Implementation leverages Pydantic, ensuring ecosystem compatibility and familiar error messages
Frequently Asked Questions
What happens if multiple constraints conflict in needle.Field?
Pydantic evaluates all constraints simultaneously. A value must satisfy every specified constraint. For example, Field(type=int, ge=0, le=10, choices=[2, 4, 6]) requires an even integer between 0 and 10. Conflicting constraints (like gt=10 with lt=5) create an impossible validation that rejects all inputs.
Does needle.Field support custom validation functions?
The base Field class in needle/agent/tools.py does not expose a validator parameter for arbitrary callables. For complex validation, annotate with Pydantic models directly or wrap the tool function and raise ValueError manually after the standard constraints pass.
How does nullable=True interact with default=None?
Both settings allow None values, but serve different purposes. nullable=True permits explicit None passed by the caller. default=None supplies None when the argument is omitted. Use Field(default=None, nullable=False) to treat "not provided" as None while rejecting explicit None values.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →