Skip to content

_ToolsetWrapper.__getitem__ doesn't support negative indices, unlike Toolset #11759

Description

@immuhammadfurqan

Describe the bug

Toolset documents that it "implements the collection interface (__iter__, __contains__, __len__, __getitem__), making it behave like a list of Tools." Toolset.__getitem__ delegates to a real list (self.tools[index]), so negative indices work as expected (e.g. toolset[-1] returns the last tool).

However, when you combine two Toolsets with +, the result is a _ToolsetWrapper (haystack/tools/toolset.py), whose __getitem__ only does a forward enumerate scan over self and never matches a negative index:

def __getitem__(self, index: int) -> Tool:
    """Get a tool by index across all toolsets."""
    # Leverage iteration instead of manual index tracking
    for i, tool in enumerate(self):
        if i == index:
            return tool
    raise IndexError("ToolsetWrapper index out of range")

So combined[-1] raises IndexError instead of returning the last tool, breaking the documented "behaves like a list" contract as soon as two toolsets are combined.

Error message

IndexError: ToolsetWrapper index out of range

Expected behavior

_ToolsetWrapper.__getitem__ should support negative indices the same way a plain Toolset/list does, so indexing behaves consistently whether or not the Toolset came from combining others with +.

To Reproduce

from haystack.tools import Toolset, create_tool_from_function


def addition_tool(a: int, b: int) -> int:
    return a + b


def multiplication_tool(a: int, b: int) -> int:
    return a * b


add_tool = create_tool_from_function(function=addition_tool, name="addition_tool", description="adds two ints")
mult_tool = create_tool_from_function(function=multiplication_tool, name="multiplication_tool", description="multiplies two ints")

combined = Toolset([add_tool]) + Toolset([mult_tool])  # -> _ToolsetWrapper
print(combined[0].name)   # "addition_tool" - fine
print(combined[1].name)   # "multiplication_tool" - fine
print(combined[-1].name)  # IndexError: ToolsetWrapper index out of range

# For comparison, a plain Toolset supports this fine:
print(Toolset([add_tool, mult_tool])[-1].name)  # "multiplication_tool"

Additional context

I'd like to fix _ToolsetWrapper.__getitem__ to support negative indices and add a regression test, then submit a PR.

System:

  • OS: Windows
  • Haystack version: main

Metadata

Metadata

Assignees

Labels

P3Low priority, leave it in the backlog

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions