How to Add Greater-Than, Less-Than, and Regex Constraints to Needle Tool Parameters
Use the Field class from needle.agent.tools to declare ge, le, gt, lt for numeric bounds and pattern for regex constraints on parameters decorated with @needle.tool, and Needle's byte-level grammar will enforce them during generation.
Needle (cactus-compute/needle) validates tool arguments at the token-generation level by converting Python type hints into JSON Schema constraints. By attaching a Field object to your function parameters, you can enforce greater-than, less-than, and regex validation before the model even emits a tool call.
The Field Class and Schema Building
The constraint system is implemented in [needle/agent/tools.py](https://github.com/cactus-compute/needle/blob/main/needle/agent/tools.py). The Field class accepts arguments that map directly to JSON Schema validation keywords. When a function is decorated with @needle.tool, the decorator invokes build_schema() to:
- Extract type hints and default values from the signature.
- Detect any
Fieldinstance attached to parameters via_field_of(). - Call
Field.apply()to inject constraints into the JSON schema (see lines 36-48).
This schema then drives Needle's grammar-constrained generation, ensuring the model can only produce valid arguments.
Supported Constraint Types
Numeric Bounds (ge, le, gt, lt)
For integer and float parameters, use these exclusive and inclusive bounds:
ge/le: Inclusive lower and upper bounds (≥,≤).gt/lt: Exclusive lower and upper bounds (>,<).
@needle.tool
def set_volume(level: int = Field(ge=0, lt=100)):
"""Set speaker volume between 0 (inclusive) and 100 (exclusive)."""
return {"level": level}
String Patterns and Length
Control string formats using regex and length limits:
pattern: A regular expression that the string must match.min_length/max_length: Minimum and maximum character counts.
@needle.tool
def lookup_user(user_id: str = Field(pattern=r'^[A-Z]{2}\d{4}$')):
"""Retrieve user by ID matching format 'AB1234'."""
return {"user_id": user_id}
Categorical and Special Constraints
enum: Restrict input to an explicit list of allowed values.multiple_of: Ensure numeric values are multiples of a specified integer.
@needle.tool
def select_color(color: str = Field(enum=["red", "green", "blue"])):
"""Select from a predefined palette."""
return {"color": color}
How Constraints Are Enforced at Generation Time
The JSON schema generated by Field.apply() feeds directly into Needle's byte-level grammar. During tool call generation, the grammar restricts the model's token selection to only those values satisfying the declared constraints.
If the model attempts to generate a value outside the specified bounds or failing to match the regex pattern, the grammar rejects the token sequence and forces the model to retry. This happens at generation time, not as post-hoc validation, eliminating invalid tool calls before they are emitted.
Practical Implementation Examples
Combine multiple constraints on a single parameter for complex validation logic:
import needle
from needle.agent.tools import Field
@needle.tool
def schedule_meeting(
start_hour: int = Field(ge=0, le=23),
duration_min: int = Field(gt=0, le=180, multiple_of=15),
title: str = Field(min_length=5, max_length=100, pattern=r'^[\w\s]+$')
):
"""
Schedule a meeting with:
- Start hour between 0-23 (inclusive)
- Duration between 1-180 minutes, in 15-minute increments
- Title 5-100 characters, alphanumeric and spaces only
"""
return {
"start": start_hour,
"duration": duration_min,
"title": title
}
When passed to needle.Needle(tools=[schedule_meeting]), the agent will only generate meeting requests respecting all declared bounds and patterns.
Summary
- The
Fieldclass inneedle/agent/tools.pyenables JSON Schema constraint declaration through thege,le,gt,lt,pattern,enum,min_length,max_length, andmultiple_ofarguments. - Constraints are applied during schema construction via
Field.apply()and line 36-48 of the source file. - Needle enforces these constraints at generation time through byte-level grammar, preventing invalid arguments from being emitted.
- Combine multiple constraints on a single parameter to create sophisticated validation rules without external validation logic.
Frequently Asked Questions
What file contains the Field class definition in Needle?
The Field class is defined in [needle/agent/tools.py](https://github.com/cactus-compute/needle/blob/main/needle/agent/tools.py), which also contains the build_schema() function and _field_of() helper used by the @needle.tool decorator.
Can I combine multiple constraints on a single parameter?
Yes. You can mix numeric bounds like ge=0 and lt=100, or combine pattern with min_length and max_length on string parameters. The Field class accepts multiple constraint arguments simultaneously and merges them into a single JSON Schema constraint object.
How does Needle enforce these constraints during generation?
Needle converts the constraints into a JSON Schema that drives a byte-level grammar. As the model generates the tool call, the grammar masks invalid tokens, ensuring only values satisfying your ge, lt, pattern, or other constraints can be produced. This ensures the model "knows" the bounds while generating.
Are these constraints validated at runtime or generation time?
Constraints are enforced at generation time by the grammar engine. This prevents invalid values from being produced in the first place, rather than catching them during runtime execution of the tool function.
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 →