How to Configure Tool Argument Constraints in Needle: Enums, Min/Max Values, and Patterns
Use the Field class from needle/agent/tools.py to set constraints like enum, ge/le for bounds, and pattern for regex validation on tool parameters.
The Needle library transforms Python functions into LLM-callable tools by automatically generating JSON schemas from function signatures. This guide covers how to configure tool argument constraints—including enums, minimum/maximum values, and regex patterns—using the Field class and Python's type system.
Core Constraint System in Needle
The constraint machinery lives in needle/agent/tools.py. The Field class (lines 17‑30) captures constraint metadata, and build_schema (line 57 onwards) converts it into valid JSON Schema.
When you use Field as a parameter default, field.apply(schema) (lines 25‑28) copies non-None values directly into the output schema. The mapping follows standard JSON Schema terminology:
Field Argument |
JSON Schema Key |
|---|---|
enum |
enum |
ge / le |
minimum / maximum |
gt / lt |
exclusiveMinimum / exclusiveMaximum |
pattern |
pattern |
min_length / max_length |
minLength / maxLength |
multiple_of |
multipleOf |
min_items / max_items |
minItems / maxItems |
unique_items |
uniqueItems |
const |
const |
format |
format |
description |
description |
Type conversion is handled by _json_type (lines 57‑81), which maps Python types to JSON Schema types before constraints are applied.
Configuring Enum Constraints
Enums restrict parameters to a fixed set of values. Needle supports two patterns: typing.Literal for inline enums and enum.Enum for named constants.
Using typing.Literal
from needle import tool
import typing
@tool
def set_mode(mode: typing.Literal["fast", "slow"]):
"""Select execution mode."""
...
Generated schema fragment:
{
"mode": {"type": "string", "enum": ["fast", "slow"]}
}
Using enum.Enum
from needle import tool
import enum
class Color(enum.Enum):
RED = "red"
GREEN = "green"
BLUE = "blue"
@tool
def paint(color: Color):
"""Paint with a specific colour."""
...
Schema output uses the enum values:
{
"color": {"type": "string", "enum": ["red", "green", "blue"]}
}
Configuring Minimum and Maximum Values
Numeric bounds use ge (greater than or equal), le (less than or equal), gt, and lt for inclusive and exclusive boundaries.
from needle import tool, Field
@tool
def set_temperature(temp: int = Field(description="Temperature in °C", ge=0, le=100)):
"""Set a thermostat."""
...
Resulting schema:
{
"temp": {
"type": "integer",
"description": "Temperature in °C",
"minimum": 0,
"maximum": 100
}
}
For exclusive bounds, use gt and lt instead—these map to exclusiveMinimum and exclusiveMaximum in JSON Schema.
Configuring Pattern (Regex) Constraints
String validation via regular expressions uses the pattern argument:
from needle import tool, Field
@tool
def create_username(name: str = Field(pattern="^[a-z][a-z0-9_]{2,15}$")):
"""Create a username matching the required regex."""
...
Schema fragment:
{
"name": {
"type": "string",
"pattern": "^[a-z][a-z0-9_]{2,15}$"
}
}
Combining Multiple Constraints
Multiple constraints can coexist on a single parameter. This example demonstrates tool argument constraints for age bounds and email format together:
from needle import tool, Field
@tool
def add_user(
age: int = Field(ge=13, le=120),
email: str = Field(pattern="^[^@]+@[^@]+\\.[^@]+$", description="User e‑mail")
):
"""Register a new user."""
...
Full schema output:
{
"age": {"type": "integer", "minimum": 13, "maximum": 120},
"email": {
"type": "string",
"pattern": "^[^@]+@[^@]+\\.[^@]+$",
"description": "User e‑mail"
}
}
The @tool Decorator
The @tool decorator (defined in needle/agent/tools.py, lines 62‑64) triggers schema generation and attaches it to the function as _needle_tool. This happens at import time—no runtime overhead per call.
Example from the source:
# From needle/agent/tools.py lines 62-64
def tool(func):
func._needle_tool = build_schema(func)
return func
Both tool and Field are exposed publicly via needle/__init__.py for clean imports.
Test Coverage
The test suite in tests/test_tools.py validates these patterns. See test_field_constraints_and_docstring_args (lines 86‑102) for assertions covering enum handling, numeric bounds, and pattern matching.
Summary
- Import from:
from needle import tool, Field - Apply constraints: Use
Fieldas a default value withge/le,pattern,enum, or other arguments - Enum options:
typing.Literalfor simple cases,enum.Enumfor reusable constants - Schema generation: Automatic via
@tooldecorator usingbuild_schemainneedle/agent/tools.py - Full constraint support: All standard JSON Schema validations map through
Field.apply
Frequently Asked Questions
What happens if I don't use Field for a parameter?
Parameters without Field defaults still get type information from annotations via _json_type, but have no additional constraints. The schema will include only type and description (from the docstring).
Can I use Field with non-default parameters?
No—Field must be used as a default value since Python requires default values to follow non-default parameters. For required constrained parameters, use ... (Ellipsis) as the default: param: int = Field(ge=0, default=...).
Does Needle validate arguments at runtime?
No. The constraints populate the JSON Schema for LLM consumption. Runtime validation depends on the LLM or downstream consumer honoring the schema. Needle's role is schema generation, not enforcement.
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 →