diff --git a/.github/workflows/docs-website-test-docs-snippets.yml b/.github/workflows/docs-website-test-docs-snippets.yml index 35708b13b22..eb4b282b3e5 100644 --- a/.github/workflows/docs-website-test-docs-snippets.yml +++ b/.github/workflows/docs-website-test-docs-snippets.yml @@ -61,6 +61,7 @@ jobs: - name: Run snippet tests (verbose) shell: bash run: | + hatch -e test env run -- pip install huggingface-api-haystack # required by LLMMessagesRouter docstring example hatch -e test env run -- python docs-website/scripts/test_python_snippets.py --verbose tmp_api_reference/ notify-slack-on-failure: diff --git a/haystack/components/joiners/document_joiner.py b/haystack/components/joiners/document_joiner.py index fc3034a5eac..c63b821c9da 100644 --- a/haystack/components/joiners/document_joiner.py +++ b/haystack/components/joiners/document_joiner.py @@ -79,7 +79,7 @@ class DocumentJoiner: p.add_component(instance=DocumentJoiner(), name="joiner") p.connect("bm25_retriever", "joiner") p.connect("embedding_retriever", "joiner") - p.connect("text_embedder", "embedding_retriever") + p.connect("text_embedder.embedding", "embedding_retriever.query_embedding") query = "What is the capital of France?" p.run(data={"query": query, "text": query, "top_k": 1}) ``` diff --git a/haystack/components/joiners/list_joiner.py b/haystack/components/joiners/list_joiner.py index df63f4f1d44..ec96e04d09f 100644 --- a/haystack/components/joiners/list_joiner.py +++ b/haystack/components/joiners/list_joiner.py @@ -57,8 +57,8 @@ class ListJoiner: pipe.connect("feedback_llm.replies", "list_joiner") query = "What is nuclear physics?" - ans = pipe.run(data={"prompt_builder": {"template_variables":{"query": query}}, - "feedback_prompt_builder": {"template_variables":{"query": query}}}) + ans = pipe.run(data={"prompt_builder": {"query": query}, + "feedback_prompt_builder": {"query": query}}) print(ans["list_joiner"]["values"]) ``` diff --git a/haystack/components/routers/llm_messages_router.py b/haystack/components/routers/llm_messages_router.py index 6094b6562c5..3ad79673937 100644 --- a/haystack/components/routers/llm_messages_router.py +++ b/haystack/components/routers/llm_messages_router.py @@ -23,7 +23,7 @@ class LLMMessagesRouter: ### Usage example ```python - from haystack.components.generators.chat import HuggingFaceAPIChatGenerator + from haystack_integrations.components.generators.huggingface_api import HuggingFaceAPIChatGenerator from haystack.components.routers.llm_messages_router import LLMMessagesRouter from haystack.dataclasses import ChatMessage diff --git a/haystack/hooks/from_function.py b/haystack/hooks/from_function.py index 1e8fe7849d8..165fba9bfaf 100644 --- a/haystack/hooks/from_function.py +++ b/haystack/hooks/from_function.py @@ -140,9 +140,21 @@ def hook(function: Callable[[State], None | Awaitable[None]]) -> FunctionHook: ```python from haystack.components.agents import Agent + from haystack.components.generators.chat import OpenAIChatGenerator from haystack.hooks import hook from haystack.components.agents.state import State from haystack.dataclasses import ChatMessage + from haystack.tools import tool + + @tool + def weather_tool(city: str) -> str: + '''Get the current weather for a given city.''' + return f"The weather in {city} is sunny." + + @tool + def save(content: str) -> str: + '''Save content to durable storage.''' + return "Saved." @hook def require_save(state: State) -> None: @@ -150,7 +162,7 @@ def require_save(state: State) -> None: state.set("messages", [ChatMessage.from_system("You must call `save` before finishing.")]) state.set("continue_run", True) - agent = Agent(chat_generator=..., tools=[...], hooks={"on_exit": [require_save]}) + agent = Agent(chat_generator=OpenAIChatGenerator(), tools=[weather_tool, save], hooks={"on_exit": [require_save]}) ``` :param function: A callable taking the Agent's `State` and returning `None` (sync or async). diff --git a/haystack/hooks/human_in_the_loop/hooks.py b/haystack/hooks/human_in_the_loop/hooks.py index 10cb8b8f734..c43a7459dd5 100644 --- a/haystack/hooks/human_in_the_loop/hooks.py +++ b/haystack/hooks/human_in_the_loop/hooks.py @@ -24,6 +24,8 @@ class ConfirmationHook: ```python from haystack.components.agents import Agent + from haystack.components.generators.chat import OpenAIChatGenerator + from haystack.tools import tool from haystack.hooks.human_in_the_loop import ( AlwaysAskPolicy, BlockingConfirmationStrategy, @@ -33,14 +35,19 @@ class ConfirmationHook: SimpleConsoleUI, ) + @tool + def delete_file(path: str) -> str: + '''Delete the file at the given path.''' + return f"Deleted {path}." + hook = ConfirmationHook( confirmation_strategies={ - "my_tool": BlockingConfirmationStrategy( + "delete_file": BlockingConfirmationStrategy( confirmation_policy=NeverAskPolicy(), confirmation_ui=SimpleConsoleUI() ) } ) - agent = Agent(chat_generator=..., tools=[...], hooks={"before_tool": [hook]}) + agent = Agent(chat_generator=OpenAIChatGenerator(), tools=[delete_file], hooks={"before_tool": [hook]}) ``` A key may be a single tool name, a tuple of tool names sharing one strategy, or the wildcard `"*"` which applies diff --git a/haystack/hooks/tool_result_offloading/hooks.py b/haystack/hooks/tool_result_offloading/hooks.py index 0a29dd58f6f..077913bb58a 100644 --- a/haystack/hooks/tool_result_offloading/hooks.py +++ b/haystack/hooks/tool_result_offloading/hooks.py @@ -126,6 +126,7 @@ class ToolResultOffloadHook: the full result. Register it on an `Agent` under the `after_tool` hook point. Which tools offload, and under what condition, is controlled per tool by `offload_strategies`: + ```python from haystack.components.agents import Agent from haystack.components.generators.chat import OpenAIChatGenerator diff --git a/haystack/tools/skills/skill_toolset.py b/haystack/tools/skills/skill_toolset.py index 740eccb251d..c7ea90b6a7c 100644 --- a/haystack/tools/skills/skill_toolset.py +++ b/haystack/tools/skills/skill_toolset.py @@ -30,6 +30,7 @@ class SkillToolset(Toolset): ### Usage example + ```python from haystack.components.agents import Agent from haystack.components.generators.chat import OpenAIChatGenerator