chore: import upstream snapshot with attribution
Sync docs with Docusaurus / sync (push) Waiting to run
Tests / Check if changed (push) Waiting to run
Tests / format (push) Blocked by required conditions
Tests / check-imports (push) Blocked by required conditions
Tests / Unit / macos-latest (push) Blocked by required conditions
Tests / Unit / ubuntu-latest (push) Blocked by required conditions
Tests / Unit / windows-latest (push) Blocked by required conditions
Tests / mypy (push) Blocked by required conditions
Tests / Integration / ubuntu-latest (push) Blocked by required conditions
Tests / Integration / macos-latest (push) Blocked by required conditions
Tests / Integration / windows-latest (push) Blocked by required conditions
Tests / notify-slack-on-failure (push) Blocked by required conditions
Tests / Mark tests as completed (push) Blocked by required conditions
Docker image release / Build base image (push) Waiting to run
CodeQL / Analyze (python) (push) Has been cancelled
Update Platform Components Table / update (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 13:22:28 +08:00
commit c56bef871b
9296 changed files with 1854228 additions and 0 deletions
@@ -0,0 +1,40 @@
# SPDX-FileCopyrightText: 2022-present deepset GmbH <info@deepset.ai>
#
# SPDX-License-Identifier: Apache-2.0
from haystack.testing.sample_components.accumulate import Accumulate
from haystack.testing.sample_components.add_value import AddFixedValue
from haystack.testing.sample_components.concatenate import Concatenate
from haystack.testing.sample_components.double import Double
from haystack.testing.sample_components.fstring import FString
from haystack.testing.sample_components.future_annotations import HelloUsingFutureAnnotations
from haystack.testing.sample_components.greet import Greet
from haystack.testing.sample_components.hello import Hello
from haystack.testing.sample_components.joiner import StringJoiner, StringListJoiner
from haystack.testing.sample_components.parity import Parity
from haystack.testing.sample_components.remainder import Remainder
from haystack.testing.sample_components.repeat import Repeat
from haystack.testing.sample_components.subtract import Subtract
from haystack.testing.sample_components.sum import Sum
from haystack.testing.sample_components.text_splitter import TextSplitter
from haystack.testing.sample_components.threshold import Threshold
__all__ = [
"Concatenate",
"Subtract",
"Parity",
"Remainder",
"Accumulate",
"Threshold",
"AddFixedValue",
"Repeat",
"Sum",
"Greet",
"Double",
"StringJoiner",
"Hello",
"HelloUsingFutureAnnotations",
"TextSplitter",
"StringListJoiner",
"FString",
]
@@ -0,0 +1,70 @@
# SPDX-FileCopyrightText: 2022-present deepset GmbH <info@deepset.ai>
#
# SPDX-License-Identifier: Apache-2.0
from collections.abc import Callable
from typing import Any
from haystack.core.component import component
from haystack.core.errors import ComponentDeserializationError
from haystack.core.serialization import default_to_dict
from haystack.utils.callable_serialization import deserialize_callable, serialize_callable
def _default_function(first: int, second: int) -> int:
return first + second
@component
class Accumulate:
"""
Accumulates the value flowing through the connection into an internal attribute.
The sum function can be customized. Example of how to deal with serialization when some of the parameters
are not directly serializable.
"""
def __init__(self, function: Callable | None = None) -> None:
"""
Class constructor
:param function:
the function to use to accumulate the values.
The function must take exactly two values.
If it's a callable, it's used as it is.
If it's a string, the component will look for it in sys.modules and
import it at need. This is also a parameter.
"""
self.state = 0
self.function: Callable = _default_function if function is None else function
def to_dict(self) -> dict[str, Any]:
"""Converts the component to a dictionary"""
return default_to_dict(self, function=serialize_callable(self.function))
@classmethod
def from_dict(cls, data: dict[str, Any]) -> "Accumulate":
"""Loads the component from a dictionary"""
if "type" not in data:
raise ComponentDeserializationError("Missing 'type' in component serialization data")
if data["type"] != f"{cls.__module__}.{cls.__name__}":
raise ComponentDeserializationError(f"Class '{data['type']}' can't be deserialized as '{cls.__name__}'")
init_params = data.get("init_parameters", {})
# Resolve the function through `deserialize_callable` so it passes the deserialization
# allowlist instead of importing arbitrary handles directly.
function = init_params.get("function")
accumulator_function = deserialize_callable(function) if function else None
return cls(function=accumulator_function)
@component.output_types(value=int)
def run(self, value: int):
"""
Accumulates the value flowing through the connection into an internal attribute.
The sum function can be customized.
"""
self.state = self.function(self.state, value)
return {"value": self.state}
@@ -0,0 +1,24 @@
# SPDX-FileCopyrightText: 2022-present deepset GmbH <info@deepset.ai>
#
# SPDX-License-Identifier: Apache-2.0
from haystack.core.component import component
@component
class AddFixedValue:
"""
Adds two values together.
"""
def __init__(self, add: int = 1) -> None:
self.add = add
@component.output_types(result=int)
def run(self, value: int, add: int | None = None):
"""
Adds two values together.
"""
if add is None:
add = self.add
return {"result": value + add}
@@ -0,0 +1,29 @@
# SPDX-FileCopyrightText: 2022-present deepset GmbH <info@deepset.ai>
#
# SPDX-License-Identifier: Apache-2.0
from haystack.core.component import component
@component
class Concatenate:
"""
Concatenates two values
"""
@component.output_types(value=list[str])
def run(self, first: list[str] | str, second: list[str] | str):
"""
Concatenates two values
"""
if isinstance(first, str) and isinstance(second, str):
res = [first, second]
elif isinstance(first, list) and isinstance(second, list):
res = first + second
elif isinstance(first, list) and isinstance(second, str):
res = first + [second]
elif isinstance(first, str) and isinstance(second, list):
res = [first] + second
else:
res = None
return {"value": res}
@@ -0,0 +1,19 @@
# SPDX-FileCopyrightText: 2022-present deepset GmbH <info@deepset.ai>
#
# SPDX-License-Identifier: Apache-2.0
from haystack.core.component import component
@component
class Double:
"""
Doubles the input value.
"""
@component.output_types(value=int)
def run(self, value: int):
"""
Doubles the input value.
"""
return {"value": value * 2}
@@ -0,0 +1,32 @@
# SPDX-FileCopyrightText: 2022-present deepset GmbH <info@deepset.ai>
#
# SPDX-License-Identifier: Apache-2.0
from typing import Any
from haystack.core.component import component
@component
class FString:
"""
Takes a template string and a list of variables in input and returns the formatted string in output.
"""
def __init__(self, template: str, variables: list[str] | None = None) -> None:
self.template = template
self.variables = variables or []
if "template" in self.variables:
raise ValueError("The variable name 'template' is reserved and cannot be used.")
component.set_input_types(self, **dict.fromkeys(self.variables, Any))
@component.output_types(string=str)
def run(self, template: str | None = None, **kwargs):
"""
Takes a template string and a list of variables in input and returns the formatted string in output.
If the template is not given, the component will use the one given at initialization.
"""
if not template:
template = self.template
return {"string": template.format(**kwargs)}
@@ -0,0 +1,15 @@
# SPDX-FileCopyrightText: 2022-present deepset GmbH <info@deepset.ai>
#
# SPDX-License-Identifier: Apache-2.0
from __future__ import annotations
from haystack import component
@component
class HelloUsingFutureAnnotations:
@component.output_types(output=str)
def run(self, word: str) -> dict[str, str]:
"""Takes a string in input and returns "Hello, <string>!"in output."""
return {"output": f"Hello, {word}!"}
@@ -0,0 +1,48 @@
# SPDX-FileCopyrightText: 2022-present deepset GmbH <info@deepset.ai>
#
# SPDX-License-Identifier: Apache-2.0
import logging
import haystack.logging as haystack_logging
from haystack.core.component import component
logger = haystack_logging.getLogger(__name__)
@component
class Greet:
"""
Logs a greeting message without affecting the value passing on the connection.
"""
def __init__(
self, message: str = "\nGreeting component says: Hi! The value is {value}\n", log_level: str = "INFO"
) -> None:
"""
Class constructor
:param message: the message to log. Can use `{value}` to embed the value.
:param log_level: the level to log at.
"""
if log_level and not getattr(logging, log_level):
raise ValueError(f"This log level does not exist: {log_level}")
self.message = message
self.log_level = log_level
@component.output_types(value=int)
def run(self, value: int, message: str | None = None, log_level: str | None = None):
"""
Logs a greeting message without affecting the value passing on the connection.
"""
if not message:
message = self.message
if not log_level:
log_level = self.log_level
level = getattr(logging, log_level, None)
if not level:
raise ValueError(f"This log level does not exist: {log_level}")
logger.log(level=level, msg=message.format(value=value))
return {"value": value}
@@ -0,0 +1,13 @@
# SPDX-FileCopyrightText: 2022-present deepset GmbH <info@deepset.ai>
#
# SPDX-License-Identifier: Apache-2.0
from haystack.core.component import component
@component
class Hello:
@component.output_types(output=str)
def run(self, word: str):
"""Takes a string in input and returns "Hello, <string>!"in output."""
return {"output": f"Hello, {word}!"}
@@ -0,0 +1,35 @@
# SPDX-FileCopyrightText: 2022-present deepset GmbH <info@deepset.ai>
#
# SPDX-License-Identifier: Apache-2.0
from haystack.core.component import component
from haystack.core.component.types import Variadic
@component
class StringJoiner:
@component.output_types(output=str)
def run(self, input_str: Variadic[str]):
"""
Take strings from multiple input nodes and join them into a single one returned in output.
Since `input_str` is Variadic, we know we'll receive a list[str].
"""
return {"output": " ".join(input_str)}
@component
class StringListJoiner:
@component.output_types(output=str)
def run(self, inputs: Variadic[list[str]]):
"""
Take list of strings from multiple input nodes and join them into a single one returned in output.
Since `input_str` is Variadic, we know we'll receive a list[list[str]].
"""
retval: list[str] = []
for list_of_strings in inputs:
retval += list_of_strings
return {"output": retval}
@@ -0,0 +1,22 @@
# SPDX-FileCopyrightText: 2022-present deepset GmbH <info@deepset.ai>
#
# SPDX-License-Identifier: Apache-2.0
from haystack.core.component import component
@component
class Parity:
"""
Redirects the value, unchanged, along the 'even' connection if even, or along the 'odd' one if odd.
"""
@component.output_types(even=int, odd=int)
def run(self, value: int):
"""
:param value: The value to check for parity
"""
remainder = value % 2
if remainder:
return {"odd": value}
return {"even": value}
@@ -0,0 +1,21 @@
# SPDX-FileCopyrightText: 2022-present deepset GmbH <info@deepset.ai>
#
# SPDX-License-Identifier: Apache-2.0
from haystack.core.component import component
@component
class Remainder:
def __init__(self, divisor: int = 3) -> None:
if divisor == 0:
raise ValueError("Can't divide by zero")
self.divisor = divisor
component.set_output_types(self, **{f"remainder_is_{val}": int for val in range(divisor)})
def run(self, value: int):
"""
:param value: the value to check the remainder of.
"""
remainder = value % self.divisor
return {f"remainder_is_{remainder}": value}
@@ -0,0 +1,19 @@
# SPDX-FileCopyrightText: 2022-present deepset GmbH <info@deepset.ai>
#
# SPDX-License-Identifier: Apache-2.0
from haystack.core.component import component
@component
class Repeat:
def __init__(self, outputs: list[str]) -> None:
self._outputs = outputs
component.set_output_types(self, **dict.fromkeys(outputs, int))
def run(self, value: int):
"""
:param value: the value to repeat.
"""
return dict.fromkeys(self._outputs, value)
@@ -0,0 +1,22 @@
# SPDX-FileCopyrightText: 2022-present deepset GmbH <info@deepset.ai>
#
# SPDX-License-Identifier: Apache-2.0
from haystack.core.component import component
@component
class Subtract:
"""
Compute the difference between two values.
"""
@component.output_types(difference=int)
def run(self, first_value: int, second_value: int):
"""
Run the component.
:param first_value: name of the connection carrying the value to subtract from.
:param second_value: name of the connection carrying the value to subtract.
"""
return {"difference": first_value - second_value}
+16
View File
@@ -0,0 +1,16 @@
# SPDX-FileCopyrightText: 2022-present deepset GmbH <info@deepset.ai>
#
# SPDX-License-Identifier: Apache-2.0
from haystack.core.component import component
from haystack.core.component.types import Variadic
@component
class Sum:
@component.output_types(total=int)
def run(self, values: Variadic[int]):
"""
:param value: the values to sum.
"""
return {"total": sum(values)}
@@ -0,0 +1,14 @@
# SPDX-FileCopyrightText: 2022-present deepset GmbH <info@deepset.ai>
#
# SPDX-License-Identifier: Apache-2.0
from haystack.core.component import component
@component
class TextSplitter:
@component.output_types(output=list[str])
def run(self, sentence: str):
"""Takes a sentence in input and returns its words in output."""
return {"output": sentence.split()}
@@ -0,0 +1,34 @@
# SPDX-FileCopyrightText: 2022-present deepset GmbH <info@deepset.ai>
#
# SPDX-License-Identifier: Apache-2.0
from haystack.core.component import component
@component
class Threshold:
"""
Redirects the value, along a different connection whether the value is above or below the given threshold.
:param threshold: the number to compare the input value against. This is also a parameter.
"""
def __init__(self, threshold: int = 10) -> None:
"""
:param threshold: the number to compare the input value against.
"""
self.threshold = threshold
@component.output_types(above=int, below=int)
def run(self, value: int, threshold: int | None = None):
"""
Redirects the value, along a different connection whether the value is above or below the given threshold.
:param threshold: the number to compare the input value against. This is also a parameter.
"""
if threshold is None:
threshold = self.threshold
if value < threshold:
return {"below": value}
return {"above": value}