Commit Graph

79 Commits

Author SHA1 Message Date
LHMQ878 f7f0bb09e6 fix: keep title keys inside OpenAPI singular example values (#12314)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-18 12:21:28 +02:00
Stefano Fiorucci d8e3bc11c1 refactor: Toolset refactoring - pt. 1 (#12298) 2026-08-11 11:49:02 +02:00
Sebastian Husch Lee 49f8d2d549 fix: make strict datetime filter comparison opt-in (#12257) 2026-08-07 09:03:19 +02:00
LHMQ878 1cd96fcd95 fix: don't strip title when it is a name, not a schema keyword (#12219)
Co-authored-by: LHMQ878 <LHMQ878@users.noreply.github.com>
Co-authored-by: David S. Batista <dsbatista@gmail.com>
2026-08-05 07:45:22 +00:00
Muhammad Furqan d69eb08483 fix: support negative indices in _ToolsetWrapper.__getitem__ (#11760)
Co-authored-by: Julian Risch <julian.risch@deepset.ai>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Julian Risch <julianrisch@gmx.de>
2026-08-04 12:02:07 +02:00
Stefano Fiorucci e3aa021da7 feat: add AgentTool (#12186) 2026-07-30 18:09:06 +02:00
Sohum Trivedi 3780936e45 fix: crash when a tool parameter is named properties (create_tool_from_function, @tool, ComponentTool) (#12037) 2026-07-20 14:41:12 +02:00
Stefano Fiorucci af7ec4a48b test: adopt MockChatGenerator in tests (#11994)
Co-authored-by: David S. Batista <dsbatista@gmail.com>
2026-07-14 10:42:28 +02:00
Sebastian Husch Lee 04435add0b fix: component tool schema description (#11909)
Co-authored-by: David S. Batista <dsbatista@gmail.com>
2026-07-09 14:27:53 +02:00
David S. Batista f317d87079 chore: consolidate outputs to state string (#11902) 2026-07-08 13:27:19 +02:00
Sebastian Husch Lee f5ee6b8b07 feat: Adding ImageContent and FileContent support to read_skill_file in SkillsToolset (#11681)
Co-authored-by: tstadel <60758086+tstadel@users.noreply.github.com>
2026-06-19 15:04:34 +02:00
Sebastian Husch Lee db7da0b24b feat: Add SkillsToolset to enable Haystack's Agent to read Skills (#11459)
Co-authored-by: tstadel <60758086+tstadel@users.noreply.github.com>
2026-06-19 09:50:02 +02:00
Stefano Fiorucci 6411c8cef9 chore!: remove sentence transformers components (#11646) 2026-06-16 12:23:49 +02:00
Sebastian Husch Lee 496c92a73b fix: Fix usage of SearchableToolset with Agent when selecting a subset of tools to be active (#11564)
Co-authored-by: Julian Risch <julian.risch@deepset.ai>
2026-06-16 10:52:29 +02:00
Julian Risch ec0d38291c chore!: remove SerperDevWebSearch (moved to integrations) (#11578)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 13:56:59 +00:00
Sebastian Husch Lee 41f85cff6c feat: Add shared param to InMemoryDocumentStore (#11605) 2026-06-12 12:59:56 +00:00
Stefano Fiorucci 2016e4244b refactor!: merge AsyncPipeline into Pipeline (#11587) 2026-06-12 14:51:27 +02:00
Sebastian Husch Lee 1771a300f3 fix: Various fixes to Agent around using SearchableToolset (#11557) 2026-06-09 14:29:49 +02:00
Sebastian Husch Lee 03061c3f67 fix: Make Toolset and _ToolsetWrapper warm_up methods idempotent and Agent now warms up passed in run-time tools (#11545) 2026-06-09 11:08:25 +02:00
Sebastian Husch Lee 8d7d179828 fix: Refactor SearchableToolset and fix serialization of catalog=Toolset (#11549) 2026-06-09 06:25:43 +00:00
Sebastian Husch Lee 1cab85a5d5 feat: Add support for async functions inside of Tool (#11426) 2026-06-01 11:42:37 +00:00
Sebastian Husch Lee 7dd1eedde3 chore: Merge main into v3 (#11456)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Pragnyan Ramtha <pragnyanramtha@gmail.com>
Co-authored-by: Julian Risch <julian.risch@deepset.ai>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Aarkin Karnik <56022539+Aarkin7@users.noreply.github.com>
Co-authored-by: Haystack Bot <73523382+HaystackBot@users.noreply.github.com>
Co-authored-by: Stefano Fiorucci <stefanofiorucci@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: davidsbatista <7937824+davidsbatista@users.noreply.github.com>
Co-authored-by: bogdankostic <48713846+bogdankostic@users.noreply.github.com>
Co-authored-by: bogdankostic <bogdankostic@web.de>
Co-authored-by: Sachin Yadav <118251564+sachinn854@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: anakin87 <44616784+anakin87@users.noreply.github.com>
Co-authored-by: Abdulhamid Onawole <93547612+HamidOna@users.noreply.github.com>
Co-authored-by: David S. Batista <dsbatista@gmail.com>
Co-authored-by: Aditya Raut <rautaditya2606@gmail.com>
Co-authored-by: Nhat Huy Vu <150295143+MechaCritter@users.noreply.github.com>
Co-authored-by: julian-risch <4181769+julian-risch@users.noreply.github.com>
2026-06-01 10:00:44 +02:00
Sebastian Husch Lee 692ebaf289 refactor!: Remove ToolInvoker and move tool calling code into Agent (#11415) 2026-05-28 09:30:55 +02:00
Sebastian Husch Lee c8f75f1674 feat!: Update PromptBuilder and ChatPromptBuilder to set required_variables="*" by default (#11344) 2026-05-20 12:39:07 +02:00
Max Swain 972b17ab65 chore: Add type checking to test/tools (#11284) 2026-05-13 11:11:01 +02:00
Sebastian Husch Lee e1ae2f4170 feat: Forward state to tools (#11064)
* adding injection of State or State | Optional with tests

* refactor to add new util function to reduce duplicate code

* Add reno

* update state docs
2026-04-09 14:56:50 +00:00
Stefano Fiorucci 750ef43788 test: remove resources leaks detected by pyleak (#10951)
* test leaking

* fixes on unit tests

* more leaks fixes

* rm deps

* cleanup

* more

* better comment
2026-03-27 14:47:44 +01:00
bogdankostic fdcfca58cd fix!: Update BM25 tokenization regex to match single char tokens (#10814)
* fix: correct off-by-one in BM25 average document length calculation

In `write_documents`, the average document length formula used
`len(self._bm25_attr)` after the new document was already inserted,
leading to an incorrect calculation:

  Before (wrong): (new_len + avg * N) / (N + 1)  — where N already includes new doc
  After  (fixed): (new_len + avg * (N - 1)) / N

This caused _avg_doc_len to be systematically underestimated, which
affects BM25 scoring accuracy (the length normalization term `b *
doc_len / avg_doc_len` would be too large, over-penalizing longer
documents).

The delete path was already correct since it adjusts `len` after
popping from `_bm25_attr`.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: update BM25 tokenization regex to match single char tokens

* Add tests

* update BM25 tokenization regex across multiple retriever tests

* add release note

* Update score values in tests

* Update release note

---------

Co-authored-by: gambletan <tan@echooo.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 15:44:48 +01:00
rob ddb747a51a feat: make SearchableToolset search_tools tool configurable (#10703)
* feat: make search_tools configurable in SearchableToolset

Add three optional parameters to SearchableToolset.__init__():
- search_tool_name: custom name for the bootstrap tool
- search_tool_description: custom description for the bootstrap tool
- search_tool_parameters_description: custom parameter descriptions

refs: deepset-ai/haystack#10670

* test: add tests for configurable search_tools tool

cover custom name, description, parameter descriptions, validation,
iteration/contains/getitem with custom name, serialization roundtrip
w and wo custom settings, and default behavior preservation.

* docs: add release note for configurable search_tools tool

* docs: escape braces in docstring for API ref generation

* fix: always serialize search tool fields in to_dict

* test: consolidate custom search tool tests

* test: remove redundant test

Co-authored-by: Stefano Fiorucci <stefanofiorucci@gmail.com>

* docs: add bootstrap tool customization section to SearchableToolset docs

* style: remove extra blank line

---------

Co-authored-by: Stefano Fiorucci <stefanofiorucci@gmail.com>
2026-03-03 10:22:41 +00:00
Vladimir Blagojevic 6c01184146 feat: Add SearchableToolset for dynamic tool discovery from large tool catalogs (#10426)
* feat: Add ToolSearchToolset for dynamic tool discovery from large catalogs

Implements ToolSearchToolset - a Toolset subclass that enables dynamic tool
discovery from large catalogs. Tools are discovered via `search_tools` bm25
based special search tool and become available to the LLM.

Key features:
- Single discovery mode: "bm25", postpone "embedding" for future
- Passthrough mode for small catalogs (< search_threshold)
- Self-contained BM25L search engine implementation
- Full serialization support (to_dict/from_dict)
- Auto warm-up when iterating to ensure bootstrap tool availability

* fix: Correct misleading search_tools description about return value

The description claimed to return "a JSON array of tool definitions"
but actually returns a plain text confirmation message with tool names.

* fix: Warm up discovered tools before making them available

Tools discovered via search_tools were added to _discovered_tools
without calling warm_up(), causing tools that require initialization
(connections, model loading) to fail when invoked.

* fix: Override __getitem__ to return tools from dynamic iteration

The inherited __getitem__ accessed self.tools which is always empty
in ToolSearchToolset. This caused IndexError for valid indexes even
when tools were available through __iter__.

* fix: Warm up catalog tools in passthrough mode

* feat: Add clear method to reset discovered tools

* docs: Add release note for ToolSearchToolset

* fix: reno note format

* Improve search_tools prompt to elicit tool keywords over user intent

Renamed the `query` parameter to `tool_keywords` and refined the
description to guide LLMs toward providing vocabulary from tool
names/descriptions rather than echoing user requests.

Before: LLMs often passed user intent like "south of france highlights"
After: LLMs provide tool vocabulary like "route weather search"

This improves BM25 matching since it relies on lexical overlap with
indexed tool names and descriptions.

* Rename ToolSearchToolset to SearchableToolset

Rename class and module for clarity:
- tool_search_toolset.py -> searchable_toolset.py
- ToolSearchToolset -> SearchableToolset
- Update all imports, tests, and release notes

* Replace _BM25SearchEngine with InMemoryDocumentStore

Remove the hand-rolled BM25L engine (~107 lines) and delegate to
Haystack's built-in InMemoryDocumentStore.bm25_retrieval(), which
uses the same algorithm and tokenization. Update tests accordingly.

* Use create_tool_from_function for search_tools and test fixtures

Replace manual Tool construction with create_tool_from_function and
Annotated type hints in _create_search_tool. Reduce test duplication
by using create_tool_from_function for fixtures and large_catalog.
Consolidate 4 integration tests into 1 deterministic math test and
remove the redundant integration_catalog fixture.

* Simplify SearchableToolset

* Minor fix

* Add support for lazy toolsets like MCPToolset with lazy flag

* improvements

* fix and simplify

* more unit tests

* amke is_passthrough private

* raise notimplementederror

* improve/simplify serde

* do not mention clear in relnote

---------

Co-authored-by: anakin87 <stefanofiorucci@gmail.com>
2026-02-25 11:32:45 +01:00
Stefano Fiorucci 819ed7244b chore: drop pylint (#10640)
* draft

* progress

* more fixes

* improvs

* strict

* rm pylint

* rm pylint comments

* fix and simplify

* standardize

* more

* alpha order

* final touch

* remove template

* rm ellipsis comments
2026-02-24 07:46:20 +00:00
Sebastian Husch Lee cd6f19b93f feat: Update ComponentTool to correctly handle parameters with top-level Optional types such as list[ChatMessage] | None (#10648)
* fix

* fix

* fix formatting of reno

* fix pylint
2026-02-23 15:40:35 +01:00
Stefano Fiorucci d6f8e4689a chore: add missing auto warm_up + other small changes (#10612)
* chore: remove unnecessary warm_up calls; mark EmbeddingBasedDocumentSplitter slow

* relnote
2026-02-17 17:39:04 +01:00
Julian Risch 97d8fce3f1 docs: fix typos in FileContent docstrings and examples (#10579)
* fix datta typo and base64_file/base64_data

* fix test

---------

Co-authored-by: anakin87 <stefanofiorucci@gmail.com>
2026-02-12 15:29:10 +00:00
Stefano Fiorucci a6602441bb feat: add FileContent support for ChatMessage + OpenAIChatGenerator implementation (#10548)
* FileContent first draft

* progress + tests

* reduce to_openai_dict complexity

* more tests

* schema tests + relnote

* better err msg

* refinement

* remove openai id handling - it is only for uploaded files
2026-02-10 16:07:29 +01:00
Stefano Fiorucci ecb30a7400 feat: support passing images in Tool results (#10410)
* wip: support images in tool results

* revert unneeded changes

* improve and test OpenAI responses message conversion

* improvements to tool, componenttool and pipelinetool

* test fixes

* better toolinvoker tests

* small fixes

* fix

* draft changes

* refinements

* simplify

* expande create_tool_from_function + docs

* fix + release note
2026-01-22 16:13:21 +01:00
Sebastian Husch Lee f63a2faa48 fix: Treat optional types properly during compatibility checks (#10391)
* Treat optional types properly during compatibility checks

* Fix unit test

* Add reno

* Use pep 604 union type building

* Refactor and expand tests

* More refactoring and parameterization
2026-01-16 08:55:19 +00:00
Michele Pangrazzi 96b8bc5be3 Skip callables in component tool schema generation (#10362)
* Skip callables in component tool schema generation (eg snapshot_callback)

* Release note

* Fix formatting on release note

* Update test/tools/test_component_tool.py

Co-authored-by: Sebastian Husch Lee <10526848+sjrl@users.noreply.github.com>

* Fix formatting

* Add same fix to create_tool_from_function

---------

Co-authored-by: Sebastian Husch Lee <10526848+sjrl@users.noreply.github.com>
2026-01-13 16:19:59 +01:00
tstadel 03279ea94c enhancement: support multiple Tool string outputs (#10279)
* enhancement: support multiple Tool string outputs

* fix reno

* fix reno

* Apply suggestion from @tstadel

* Apply suggestion from @tstadel

* apply feedback

* apply feedback

---------

Co-authored-by: Vladimir Blagojevic <dovlex@gmail.com>
2026-01-05 13:49:55 +01:00
Vladimir Blagojevic 239067c4d8 feat: Component tool state validation (#10256)
* Add ComponentTool state validation

* Move validation to Tool superclass, allow subclasses to hook into verification

* Simplify

* Details

* Edge cases

* Lint fix

* Fixes

* Pydoc clarification

* Better algorithm for default _get_valid_inputs

* Reno note

* PR review - add PipelineTool tests

* Remove Optional, use 3.10 syntax

* PR review
2026-01-05 12:28:30 +01:00
Stefano Fiorucci 8091034fb5 chore: remove unused imports and enforce related Ruff rule (#10278)
* chore: remove unused imports and enforce ruff rule

* fix

* enforce f401 rule

* pylint fix
2025-12-19 18:45:44 +01:00
Stefano Fiorucci 7c6323b960 refactor: support PEP604 typing syntax (X|Y and X|None) (#10255)
* adopt X|Y syntax: draft

* cast Union

* fix pylint + state testing

* use X|Y

* rm unused imports

* trigger e2e tests

* fix + simplification

* add compatibility tests

* rm e2e tests trigger

* fix

* add relnote

* simplify/fix pep604 union parsing

* fix comments

* test _is_optional_type

* introduce _build_pep604_union_type; make _is_union_type private

* try removing problematic test
2025-12-19 15:47:51 +01:00
lif d4e623d069 fix: Raise error when async function is passed to Tool (#10264)
* fix: Raise error when async function is passed to Tool

- Added validation in Tool.__post_init__ to check if function is async
- Added validation in create_tool_from_function for early error detection
- Updated docstring to clarify that functions must be synchronous
- Added tests for both Tool init and @tool decorator with async functions

Closes #9580

* fix: Remove redundant async check from create_tool_from_function

Per reviewer feedback, the async validation is only needed in the
Tool class itself, since create_tool_from_function creates a Tool.

- Remove async check from create_tool_from_function
- Update docstrings to remove async-related notes
- Remove redundant tests for async functions in from_function tests
- Add release note

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Add docstring note and tests for async function validation

- Updated Tool class docstring to indicate function must be synchronous
- Added test_from_function_async_raises_error test
- Added test_tool_decorator_async_raises_error test

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-19 12:40:38 +01:00
Sebastian Husch Lee b4b14c09c3 feat: Add support for Qwen3 rerankers when using SentenceTransformersSimilarityRanker (#10251)
* Add suffix params to ST ranker

* Add unit test

* Update reno

* Update reno

* Fix unit tests
2025-12-19 08:38:17 +00:00
Vladimir Blagojevic dfd678eff4 Improve flaky tool invocation integration test (#10187) 2025-12-03 15:42:26 +01:00
Vladimir Blagojevic 3ebe9b2df2 chore: Update default OpenAI model to gpt-5-mini (#10144)
* Update default OpenAI model to gpt-5-mini

* Update tests

* Fix tool invoker tests

* Update integration tests

* Update fragile test

* More robust tests

* Harden test

* More test improvements

* Better prompting, to trigger tools

* Simplify

* Simplify more

* Simplify even more, less maintenance in the future

* Mark two integration tests flaky

* Fixing fine details

* Add release note for OpenAI default model update to gpt-5-mini

* Add upgrade section to OpenAI default model release note
2025-12-01 13:55:53 +01:00
Amna Mubashar 071d2f18b9 feat: Add extra field in ToolCall and ToolCallDelta (#10018)
* Add extra to Toolcall

* Add release notes

* Update tests
2025-11-05 13:35:32 +01:00
HamidOna e7fb4f5ac5 fix: warm up individual tools inside Toolsets in warm_up_tools() (#10002)
* fix: warm up individual tools inside Toolsets in warm_up_tools()

Related Issues:

* Follows up on PR #9942 (feat: Add warm_up() method to ChatGenerators)

* Addresses bug discovered during implementation of PR #9942 for issue #9907

Proposed Changes:

The warm_up_tools() utility function was only calling warm_up() on

Toolset objects themselves, but not on the individual Tool instances

contained within them. This meant tools inside a Toolset were not

properly initialized before use.

This PR modifies warm_up_tools() to iterate through Toolsets and call

warm_up() on each individual tool, in addition to calling warm_up() on

the Toolset itself.

Changes:

- Modified warm_up_tools() in haystack/tools/utils.py to iterate through

  Toolsets when encountered (both as single argument and within lists)

- Added iteration to call warm_up() on each individual Tool inside Toolsets

- Added comprehensive test class TestWarmUpTools with 7 test cases

How did you test it:

- Added 7 comprehensive unit tests in test/tools/test_tools_utils.py:

  * test_warm_up_tools_with_none - handles None input

  * test_warm_up_tools_with_single_tool - single tool in list

  * test_warm_up_tools_with_single_toolset - KEY TEST: verifies both

    Toolset and individual tools are warmed

  * test_warm_up_tools_with_list_containing_toolset - toolset within list

  * test_warm_up_tools_with_multiple_toolsets - multiple toolsets

  * test_warm_up_tools_with_mixed_tools_and_toolsets - mixed scenarios

  * test_warm_up_tools_idempotency - safe to call multiple times

Notes for the reviewer:

I discovered this bug while implementing PR #9942 (for issue #9907).

When a Toolset object is passed to a component's tools parameter, the

warm_up_tools() function only calls Toolset.warm_up(), which is a no-op.

It doesn't iterate through the individual tools inside the Toolset to

warm them up.

 acknowledged by @vblagoje and @sjrl

This implementation:

- Modified warm_up_tools() to iterate through Toolsets and call warm_up() on each individual tool

 - Added comprehensive tests for Toolset warming behavior

- Verified both the Toolset and its contained tools are warmed up

Checklist:

I have read the contributors guidelines and the code of conduct

I have updated the related issue with new insights and changes

I added unit tests and updated the docstrings

I've used one of the conventional commit types for my PR title: fix:

I documented my code

I ran pre-commit hooks and fixed any issue

* added release note

* refactor: move tool warm-up iteration to Toolset.warm_up()

Addresses architectural feedback - moved iteration logic from warm_up_tools()
to base Toolset.warm_up() for better encapsulation. Subclasses can now
override warm_up() to customize initialization without breaking the contract.

- Toolset.warm_up() now iterates and warms tools by default
- warm_up_tools() simplified to delegate to warm_up()
- Updated tests and release notes

---------

Co-authored-by: HamidOna13 <abdulhamid.onawole@aizatron.com>
2025-11-05 09:59:23 +01:00
Vladimir Blagojevic 08f6969351 fix: Add warm_up() calls to tests after ChatGenerator tool initialization changes (#9965)
* In tests call agent.warm_up() where needed

* Add reno

* Update wording in reno note

* Update reno note
2025-10-29 13:52:57 +01:00
Vladimir Blagojevic 9bc59c3806 Add Tools warm_up (#9856)
Docker image release / Build base image (push) Has been cancelled
* Tools warmup initial

* Fix lint

* Improve pydocs for warm_up

* Further improve pydocs for warm_up

* No need to warm_up tools in Agent as they are warmed up by ToolInvoker

* Simplify Toolset __add__ logic

* Simplify _ToolsetWrapper

* Add unit tests

* ToolInvoker warm_up

* Improve Tool pydoc

* Resurrect serde_utils.py

* Update tests

* Call ToolInvoker warm_up in agent warm_up

* Lint

* Move warm_up tests to ToolInvoker

* Update tests

* Remove tests

* Pydoc nit

* PR feedback

* ToolInvoker's warm_up is idempotent

* Add reno note

* Update releasenotes/notes/tools-warm-up-support-e16cc043fed3653f.yaml

Co-authored-by: Sebastian Husch Lee <10526848+sjrl@users.noreply.github.com>

* Make ComponentTool warm_up idempotent

* Update warm_up_tools to use ToolsType

* Linting

* Add warm up test for mixed list of Tool/Toolset instances

---------

Co-authored-by: Sebastian Husch Lee <10526848+sjrl@users.noreply.github.com>
2025-10-20 12:11:34 +02:00