GitHub Issue Resolver AI Agent with Haystack
In this notebook, we'll create a GitHub Issue Resolver Agent with Anthropic Claude 4 Sonnet. Given an issue URL, the agent will:
- Fetch and parse the issue description and comments
- Identify the relevant repository, directories, and files
- Retrieve and process file content
- Determine the next steps for resolution and post them as a comment
For this, we'll use the new Agent component. Agent is a Haystack component that implements a tool-calling functionality with provider-agnostic chat model support. We can use Agent either as a standalone component or within a pipeline.
Here's what our GitHub Issue Resolver Pipeline looks like:
Development Environment Setup
%%bash
pip install anthropic-haystack github-haystackimport os
from getpass import getpass
os.environ["ANTHROPIC_API_KEY"] = getpass("Anthropic Key: ")
os.environ["GITHUB_TOKEN"] = getpass("Github Token: ")Initialize a GitHubIssueViewer component
The GitHubIssueViewer component takes a GitHub issue URL and returns a list of Haystack documents. The first document contains the main issue content, while the subsequent documents contain the issue comments.
Initialize the component and test it with issue -> https://github.com/deepset-ai/haystack/issues/8903
Notice the data each Document object holds: content, url...
from haystack_integrations.components.connectors.github import GitHubIssueViewer
from haystack.utils.auth import Secret
issue_viewer = GitHubIssueViewer(github_token=Secret.from_env_var("GITHUB_TOKEN"))
issue_comments = issue_viewer.run(url="https://github.com/deepset-ai/haystack/issues/8903")
issue_commentsInitialize the Issue Builder Component
This component will get the Documents and render them in a prompt. Use ChatPromptBuilder to render the prompt in Jinja syntax
from haystack.components.builders import ChatPromptBuilder
from haystack.dataclasses import ChatMessage
issue_template = """
Issue from: {{ url }}
{% for document in documents %}
{% if loop.index == 1 %}
**Title: {{ document.meta.title }}**
{% endif %}
<issue-comment>
{{document.content}}
</issue-comment>
{% endfor %}
"""
issue_builder = ChatPromptBuilder(template=[ChatMessage.from_user(issue_template)],required_variables="*" )
issue_builder.run(documents=issue_comments["documents"], url="https://github.com/deepset-ai/haystack/issues/8903")Initialize a GitHubRepoViewer Tool
GitHubRepoViewer ToolThis tool retrieves content from a GitHub repository based on a given repo and path:
- If the
pathpoints to a directory, it returns a list of Documents—one per item—where each document contains the item's name (file or directory) along with full path and metadata inDocument.meta. - If the
pathpoints to a file, it returns a single Document containing the file content, with full path and metadata inDocument.meta. - If an error occurs, it returns a single Document with the error message, and
Document.metaincludestype="error".
from haystack_integrations.tools.github import GitHubRepoViewerTool
from haystack.utils.auth import Secret
repo_viewer_tool = GitHubRepoViewerTool(github_token=Secret.from_env_var("GITHUB_TOKEN"))
Initialize a GitHubIssueCommenter Tool from a function
GitHubIssueCommenter Tool from a function