Skip to content

Conversation

@vblagoje
Copy link
Member

@vblagoje vblagoje commented Dec 17, 2025

Why:

Prevents runtime failures by validating tool state mappings against the Agent's state schema at initialization and runtime. Catches misconfigured inputs_from_state and outputs_to_state early with clear error messages thus improving devX

What:

  • Added _validate_tools_against_state_schema method to validate state key references
  • Validates inputs_from_state keys exist in the Agent's state schema
  • Validates outputs_to_state keys exist in state schema (unless a handler is provided, which can create keys dynamically)
  • Validation runs during Agent initialization and when tools are selected at runtime via _select_tools

How can it be used:

  • When adding Tools to Agent

How did you test it:

  • Added tests and all tests verify ValueError is raised with appropriate error messages
  • Validation tested at both initialization time and runtime tool selection

Notes for the reviewer:

  • Error messages include fix suggestions; verify they're clear and actionable
  • Handler exception logic: outputs_to_state with a handler bypasses validation since handlers can create keys dynamically; ensure this exception is correct

@vercel
Copy link

vercel bot commented Dec 17, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
haystack-docs Ready Ready Preview, Comment Dec 17, 2025 2:09pm

@vblagoje vblagoje added the ignore-for-release-notes PRs with this flag won't be included in the release notes. label Dec 17, 2025
@github-actions github-actions bot added topic:tests type:documentation Improvements on the docs labels Dec 17, 2025
@coveralls
Copy link
Collaborator

coveralls commented Dec 17, 2025

Pull Request Test Coverage Report for Build 20305608747

Details

  • 0 of 0 changed or added relevant lines in 0 files are covered.
  • 10 unchanged lines in 1 file lost coverage.
  • Overall coverage increased (+0.002%) to 92.156%

Files with Coverage Reduction New Missed Lines %
components/agents/agent.py 10 96.66%
Totals Coverage Status
Change from base Build 20295900674: 0.002%
Covered Lines: 14146
Relevant Lines: 15350

💛 - Coveralls

@vblagoje vblagoje removed the ignore-for-release-notes PRs with this flag won't be included in the release notes. label Dec 17, 2025
@vblagoje vblagoje marked this pull request as ready for review December 17, 2025 14:17
@vblagoje vblagoje requested a review from a team as a code owner December 17, 2025 14:17
@vblagoje vblagoje requested review from anakin87 and removed request for a team December 17, 2025 14:17
@vblagoje
Copy link
Member Author

@anakin87 this is a sister PR to #10256 perhaps I can ask @sjrl to take it as we talked internally about this - he has more context. But feel free to spot issues

@vblagoje vblagoje requested a review from sjrl December 17, 2025 14:18
Comment on lines +228 to 234
# Validate tools' state mappings against state schema
if tools:
self._validate_tools_against_state_schema(tools)

self.tool_invoker_kwargs = tool_invoker_kwargs
self._tool_invoker = None
if self.tools:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already have a self.tools if check on line 234. Could we move this validation step in there?

Also does this validation work when using MCPToolset?

@anakin87 anakin87 removed their request for review December 19, 2025 10:37
tool_invoker_inputs=tool_invoker_inputs,
)

def _validate_tools_against_state_schema(self, tools: ToolsType) -> None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would make more sense to put this as util method in ./state/state_utils.py since this purely a tool to state check and doesn't really involve other parts of the Agent. Could we move it in there as a standalone method?

# Validate outputs_to_state keys exist in state schema (only when no handler)
if tool.outputs_to_state:
for state_key, config in tool.outputs_to_state.items():
if config.get("handler") is None and state_key not in self.state_schema:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does config.get("handler") need to be None to perform the state_key check?

Comment on lines +403 to +405
f"2. Or provide a handler to create the key dynamically:\n"
f" Tool(..., outputs_to_state={{'{state_key}':"
f" {{'source': 'output', 'handler': your_handler}}}})"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't correct. The handler does not create the state key dynamically. It handles how the merge operation should occur for an existing state key. For example, if we are writing to the state key documents: list[Document], the handler determines how the new value being written is merged with the existing value in state.

So the handler doesn't affect the key mapping at all.

@vblagoje
Copy link
Member Author

vblagoje commented Jan 2, 2026

Closing to restart from scratch on this one @sjrl

@vblagoje vblagoje closed this Jan 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

topic:tests type:documentation Improvements on the docs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants