From dcf6ce71b9bff40ace8b7194c22e9f14d71faf71 Mon Sep 17 00:00:00 2001 From: Julian Risch Date: Wed, 28 May 2025 12:35:21 +0200 Subject: [PATCH 1/6] add GitHub integration page --- integrations/github.md | 130 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 integrations/github.md diff --git a/integrations/github.md b/integrations/github.md new file mode 100644 index 00000000..9fa23f75 --- /dev/null +++ b/integrations/github.md @@ -0,0 +1,130 @@ +--- +layout: integration +name: github +description: Interact with GitHub repositories, issues, and pull requests within Haystack +authors: + - name: deepset + socials: + github: deepset-ai + twitter: deepset_ai + linkedin: https://www.linkedin.com/company/deepset-ai/ +pypi: https://pypi.org/project/github-haystack +repo: https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/github +type: Tools +report_issue: https://github.com/deepset-ai/haystack-core-integrations/issues +logo: /logos/github.png +version: Haystack 2.0 +toc: true +--- + +### **Table of Contents** + +- [Overview](#overview) +- [Installation](#installation) +- [Usage](#usage) + +## Overview + +The GitHub integration for Haystack provides a set of components and tools to interact with GitHub repositories, issues, and pull requests. It enables you to view repository contents, manage issues, create pull requests, and more within your Haystack agents and pipelines. + + +Some of the components and tools in this integration require GitHub authentication with a personal access token. +For example, it is required to post a comment on GitHub, fork a repository or open a pull request. You can create a (fine-graind personal access token)[https://github.com/settings/personal-access-tokens] or a [classic personal access token](https://github.com/settings/tokens) on GitHub and then expose it via an environment variable called `GITHUB_API_KEY`. + + +## Installation + +Install the GitHub integration with pip: + +```bash +pip install github-haystack +``` + +## Usage + +This integration comes with several components and tools: + +### Components +- `GitHubIssueViewer`: View issues and their details +- `GitHubIssueCommenter`: Add comments to issues +- `GitHubRepoViewer`: View repository contents and metadata +- `GitHubRepoForker`: Fork repositories +- `GitHubFileEditor`: Edit files in repositories +- `GitHubPRCreator`: Create pull requests + +### Tools +- `GitHubIssueViewerTool`: View issues +- `GitHubIssueCommenterTool`: Comment on issues +- `GitHubRepoViewerTool`: View repository contents +- `GitHubFileEditorTool`: Edit repository files +- `GitHubPRCreatorTool`: Create pull requests + +### Example Usage + +```python +import os +from getpass import getpass +from typing import List + +from haystack import Pipeline +from haystack.components.agents import Agent +from haystack.components.builders import ChatPromptBuilder +from haystack.components.converters import OutputAdapter +from haystack.dataclasses import ChatMessage, Document +from haystack.tools.from_function import tool + +from haystack_integrations.components.connectors.github import GitHubIssueViewer +from haystack_integrations.components.generators.anthropic import AnthropicChatGenerator + +from haystack_integrations.prompts.github import SYSTEM_PROMPT + +from haystack_integrations.tools.github import GitHubRepoViewerTool +repo_viewer_tool = GitHubRepoViewerTool() + +@tool +def create_comment(comment: str) -> str: + """ + Use this to create a Github comment once you finished your exploration. + """ + return comment + +chat_generator = AnthropicChatGenerator(model="claude-3-5-sonnet-latest", generation_kwargs={"max_tokens": 8000}) + +agent = Agent( + chat_generator=chat_generator, + system_prompt=SYSTEM_PROMPT, + tools=[repo_viewer_tool, create_comment], + exit_conditions=["create_comment"], + state_schema={"documents": {"type": List[Document]}}, +) + +issue_template = """ +Issue from: {{ url }} +{% for document in documents %} +{% if loop.index == 1 %} +**Title: {{ document.meta.title }}** +{% endif %} + +{{document.content}} + +{% endfor %} + """ + +issue_builder = ChatPromptBuilder(template=[ChatMessage.from_user(issue_template)], required_variables="*") + +issue_fetcher = GitHubIssueViewer() + +pipeline = Pipeline() + +pipeline.add_component("issue_fetcher", issue_fetcher) +pipeline.add_component("issue_builder", issue_builder) +pipeline.add_component("agent", agent) + +pipeline.connect("issue_fetcher.documents", "issue_builder.documents") +pipeline.connect("issue_builder.prompt", "agent.messages") + +issue_url = "https://github.com/deepset-ai/haystack-core-integrations/issues/1268" + +result = pipeline.run({"url": issue_url}) +print(result["agent"]["messages"][-1].tool_call_result.result) +``` From 7605b88372a2ab31e83c853a73b606521d48a8de Mon Sep 17 00:00:00 2001 From: Julian Risch Date: Wed, 28 May 2025 12:37:02 +0200 Subject: [PATCH 2/6] add github logo --- logos/github.png | Bin 0 -> 6393 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 logos/github.png diff --git a/logos/github.png b/logos/github.png new file mode 100644 index 0000000000000000000000000000000000000000..6cb3b705d018006a2bd4200ea94c9d5fb98b6f76 GIT binary patch literal 6393 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 Hu0mjfZ$b4` literal 0 HcmV?d00001 From 8f00d1c21a97af7baff1d801cb73f467553a7e3f Mon Sep 17 00:00:00 2001 From: Julian Risch Date: Wed, 28 May 2025 12:40:04 +0200 Subject: [PATCH 3/6] remove unused imports --- integrations/github.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/integrations/github.md b/integrations/github.md index 9fa23f75..576fd000 100644 --- a/integrations/github.md +++ b/integrations/github.md @@ -62,14 +62,11 @@ This integration comes with several components and tools: ### Example Usage ```python -import os -from getpass import getpass from typing import List from haystack import Pipeline from haystack.components.agents import Agent from haystack.components.builders import ChatPromptBuilder -from haystack.components.converters import OutputAdapter from haystack.dataclasses import ChatMessage, Document from haystack.tools.from_function import tool From 692b6d2fbdd744778a839a488a34c336940839f4 Mon Sep 17 00:00:00 2001 From: Julian Risch Date: Wed, 28 May 2025 14:27:41 +0200 Subject: [PATCH 4/6] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bilge Yücel --- integrations/github.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/integrations/github.md b/integrations/github.md index 576fd000..50e9f011 100644 --- a/integrations/github.md +++ b/integrations/github.md @@ -29,7 +29,7 @@ The GitHub integration for Haystack provides a set of components and tools to in Some of the components and tools in this integration require GitHub authentication with a personal access token. -For example, it is required to post a comment on GitHub, fork a repository or open a pull request. You can create a (fine-graind personal access token)[https://github.com/settings/personal-access-tokens] or a [classic personal access token](https://github.com/settings/tokens) on GitHub and then expose it via an environment variable called `GITHUB_API_KEY`. +For example, authentication is required to post a comment on GitHub, fork a repository, or open a pull request. You can create a (fine-graind personal access token)[https://github.com/settings/personal-access-tokens] or a [classic personal access token](https://github.com/settings/tokens) on GitHub and then expose it via an environment variable called `GITHUB_API_KEY`. ## Installation @@ -83,6 +83,7 @@ def create_comment(comment: str) -> str: """ Use this to create a Github comment once you finished your exploration. """ + # A mockup tool to showcase how Agent uses tools. You should use `GitHubIssueCommenterTool` instead of this one to write comments on GitHub. return comment chat_generator = AnthropicChatGenerator(model="claude-3-5-sonnet-latest", generation_kwargs={"max_tokens": 8000}) @@ -120,8 +121,8 @@ pipeline.add_component("agent", agent) pipeline.connect("issue_fetcher.documents", "issue_builder.documents") pipeline.connect("issue_builder.prompt", "agent.messages") -issue_url = "https://github.com/deepset-ai/haystack-core-integrations/issues/1268" +issue_url = "https://github.com///issues/1268" result = pipeline.run({"url": issue_url}) -print(result["agent"]["messages"][-1].tool_call_result.result) +print(result["agent"]["last_message"].tool_call_result.result) ``` From e96b014f357b2a17c76df3df0a5f6f9778419dea Mon Sep 17 00:00:00 2001 From: Julian Risch Date: Wed, 28 May 2025 14:28:09 +0200 Subject: [PATCH 5/6] type: Tool Integration --- integrations/github.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrations/github.md b/integrations/github.md index 50e9f011..00806b08 100644 --- a/integrations/github.md +++ b/integrations/github.md @@ -10,7 +10,7 @@ authors: linkedin: https://www.linkedin.com/company/deepset-ai/ pypi: https://pypi.org/project/github-haystack repo: https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/github -type: Tools +type: Tool Integration report_issue: https://github.com/deepset-ai/haystack-core-integrations/issues logo: /logos/github.png version: Haystack 2.0 From a0138361cf19fc63fbd60922c005d227ff06da9f Mon Sep 17 00:00:00 2001 From: Julian Risch Date: Wed, 28 May 2025 14:36:32 +0200 Subject: [PATCH 6/6] move repo_viewer_tool in example code --- integrations/github.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/integrations/github.md b/integrations/github.md index 00806b08..f7259769 100644 --- a/integrations/github.md +++ b/integrations/github.md @@ -72,11 +72,8 @@ from haystack.tools.from_function import tool from haystack_integrations.components.connectors.github import GitHubIssueViewer from haystack_integrations.components.generators.anthropic import AnthropicChatGenerator - from haystack_integrations.prompts.github import SYSTEM_PROMPT - from haystack_integrations.tools.github import GitHubRepoViewerTool -repo_viewer_tool = GitHubRepoViewerTool() @tool def create_comment(comment: str) -> str: @@ -86,6 +83,8 @@ def create_comment(comment: str) -> str: # A mockup tool to showcase how Agent uses tools. You should use `GitHubIssueCommenterTool` instead of this one to write comments on GitHub. return comment +repo_viewer_tool = GitHubRepoViewerTool() + chat_generator = AnthropicChatGenerator(model="claude-3-5-sonnet-latest", generation_kwargs={"max_tokens": 8000}) agent = Agent( @@ -106,7 +105,7 @@ Issue from: {{ url }} {{document.content}} {% endfor %} - """ +""" issue_builder = ChatPromptBuilder(template=[ChatMessage.from_user(issue_template)], required_variables="*")