How Response Validation Detects Unknown Tools in Forge
Forge's ResponseValidator uses a whitelist-based approach to detect unknown tools by comparing incoming ToolCall objects against a predefined list of allowed tool names, triggering a corrective nudge when mismatches are found.
In the antoinezambelli/forge repository, response validation serves as a critical safety mechanism to prevent Large Language Models (LLMs) from invoking undefined or unauthorized tools. The ResponseValidator class implements a strict whitelist verification system that intercepts tool calls at validation time, ensuring only explicitly registered tools can execute within a workflow.
The Whitelist Mechanism in ResponseValidator
The detection logic centers on a simple but effective whitelist check implemented in src/forge/guardrails/response_validator.py. When instantiated, the validator receives a definitive catalog of permissible tool names and stores them for subsequent comparison operations against any model-generated tool calls.
Storing Allowed Tool Names
The ResponseValidator initialization accepts a list of valid tool identifiers through the tool_names parameter. This list becomes the authoritative reference set stored as self.tool_names, against which all incoming tool calls are evaluated during the validation phase.
from forge.guardrails.response_validator import ResponseValidator
# Allowed tools for this workflow
valid_tools = ["search", "calculate", "summarize"]
validator = ResponseValidator(tool_names=valid_tools)
Scanning Incoming Tool Calls
During the validate method execution, the code specifically handles responses that are already parsed as lists of ToolCall objects. At lines 81-84 of the source file, the validator constructs a filtered list comprehension to identify any calls whose tool attribute falls outside the allowed set:
unknown = [tc for tc in tool_calls if tc.tool not in self.tool_names]
This single line performs the core detection logic, identifying any tool names not present in self.tool_names and collecting them for subsequent error handling.
Triggering Recovery Through Nudge Generation
When unknown tools are detected, the validator does not raise exceptions or silently fail. Instead, it generates a structured recovery prompt using the unknown_tool_nudge function defined in src/forge/prompts/nudges.py.
Constructing the ValidationResult
If the unknown list contains any entries, the validator returns a ValidationResult with needs_retry set to True and a populated Nudge object. The nudge includes a user-facing message that explicitly names the invalid tool and lists all available alternatives according to the following implementation pattern:
return ValidationResult(
tool_calls=None,
nudge=Nudge(
role="user",
content=unknown_tool_nudge(unknown[0].tool, self.tool_names),
kind="unknown_tool",
),
needs_retry=True,
)
Workflow Integration and Retry Logic
The surrounding workflow inspects the needs_retry flag and automatically injects the nudge content back into the conversation context. This creates a feedback loop where the model receives immediate correction about the available tool catalog and can issue a valid tool call on the subsequent attempt.
Practical Implementation Examples
The following examples demonstrate the complete detection flow using the ResponseValidator with ToolCall objects defined in src/forge/core/workflow.py.
Detecting an Unknown Tool Call
When a model responds with a call to a tool not present in the whitelist, the validator flags it immediately:
from forge.core.workflow import ToolCall
# Model responded with a call to a non-existent tool "translate"
response = [ToolCall(tool="translate", args={"text": "hola"})]
result = validator.validate(response)
assert result.needs_retry # True – a nudge will be sent
assert result.nudge.kind == "unknown_tool"
print(result.nudge.content)
# → "Tool 'translate' does not exist. Available tools: search, calculate, summarize. Call one of them."
Processing a Valid Tool Call
For tool calls that match the whitelist, the validator passes them through without triggering retry mechanisms:
response = [ToolCall(tool="search", args={"query": "latest AI news"})]
result = validator.validate(response)
assert not result.needs_retry # False – the call is accepted
assert result.tool_calls == response
Summary
- Whitelist validation occurs in
src/forge/guardrails/response_validator.pywhereResponseValidatormaintains an authoritative list of allowed tool names inself.tool_names. - Unknown tool detection uses a list comprehension at lines 81-84 to filter
ToolCallobjects whosetoolattribute is not present in the whitelist. - Recovery mechanism generates a
ValidationResultwithneeds_retry=Trueand aNudgeobject created byunknown_tool_nudge, guiding the model back to valid tools. - Workflow integration automatically handles the retry logic by injecting nudge content into the conversation when validation fails.
Frequently Asked Questions
How does Forge determine which tools are considered "known"?
Forge determines known tools through the tool_names parameter passed during ResponseValidator instantiation. This list represents the complete whitelist of executable tools for a specific workflow, and any ToolCall with a tool attribute not present in this list is immediately flagged as unknown.
What happens when the validator detects an unknown tool?
When an unknown tool is detected, the validate method returns a ValidationResult with needs_retry set to True and a Nudge object containing a corrective message. The workflow then automatically injects this nudge into the conversation history, prompting the LLM to select a valid tool from the available catalog on its next turn.
Where is the validation logic located in the codebase?
The core validation logic resides in src/forge/guardrails/response_validator.py, specifically within the ResponseValidator.validate method. The error message templates are defined in src/forge/prompts/nudges.py, while the data structures ToolCall and ValidationResult are implemented in src/forge/core/workflow.py.
Can a workflow recover automatically from an unknown tool call?
Yes, workflows recover automatically through the nudge mechanism. Because the validator returns needs_retry=True rather than raising an exception, the orchestration layer can seamlessly append the guidance message to the conversation context and request a new response from the model without interrupting the overall task execution.
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 →