How to Apply Value Constraints with `needle.Field`: A Complete Guide
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 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).
| 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) 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.
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:
@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.
@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.
@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.
@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:
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.
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:Fieldandtoolprovide the complete validation interface. -
Wrap with
typing.Annotated: All constraints attach viaAnnotated[type, Field(...)]syntax. -
Map to JSON Schema: Each
Fieldparameter generates standard schema keywords for interoperability. -
Apply runs automatically: The
build_schemafunction callsfield.apply(schema)during@toolregistration. -
Source location: Constraint logic resides in
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.
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 →