github-haystack 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- github_haystack-1.0.0.dist-info/METADATA +45 -0
- github_haystack-1.0.0.dist-info/RECORD +26 -0
- github_haystack-1.0.0.dist-info/WHEEL +4 -0
- github_haystack-1.0.0.dist-info/licenses/LICENSE.txt +73 -0
- haystack_integrations/components/connectors/github/__init__.py +19 -0
- haystack_integrations/components/connectors/github/file_editor.py +303 -0
- haystack_integrations/components/connectors/github/issue_commenter.py +161 -0
- haystack_integrations/components/connectors/github/issue_viewer.py +216 -0
- haystack_integrations/components/connectors/github/pr_creator.py +277 -0
- haystack_integrations/components/connectors/github/repo_forker.py +306 -0
- haystack_integrations/components/connectors/github/repo_viewer.py +272 -0
- haystack_integrations/prompts/github/__init__.py +22 -0
- haystack_integrations/prompts/github/context_prompt.py +176 -0
- haystack_integrations/prompts/github/file_editor_prompt.py +122 -0
- haystack_integrations/prompts/github/issue_commenter_prompt.py +21 -0
- haystack_integrations/prompts/github/issue_viewer_prompt.py +25 -0
- haystack_integrations/prompts/github/pr_creator_prompt.py +83 -0
- haystack_integrations/prompts/github/repo_viewer_prompt.py +81 -0
- haystack_integrations/prompts/github/system_prompt.py +63 -0
- haystack_integrations/tools/github/__init__.py +16 -0
- haystack_integrations/tools/github/file_editor_tool.py +128 -0
- haystack_integrations/tools/github/issue_commenter_tool.py +123 -0
- haystack_integrations/tools/github/issue_viewer_tool.py +123 -0
- haystack_integrations/tools/github/pr_creator_tool.py +117 -0
- haystack_integrations/tools/github/repo_viewer_tool.py +138 -0
- haystack_integrations/tools/github/utils.py +73 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2023-present deepset GmbH <info@deepset.ai>
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
from typing import Any, Callable, Dict, Optional, Union
|
|
5
|
+
|
|
6
|
+
from haystack.core.serialization import generate_qualified_class_name
|
|
7
|
+
from haystack.tools import ComponentTool
|
|
8
|
+
from haystack.utils import Secret, deserialize_secrets_inplace
|
|
9
|
+
|
|
10
|
+
from haystack_integrations.components.connectors.github.file_editor import GitHubFileEditor
|
|
11
|
+
from haystack_integrations.prompts.github.file_editor_prompt import FILE_EDITOR_PROMPT, FILE_EDITOR_SCHEMA
|
|
12
|
+
from haystack_integrations.tools.github.utils import deserialize_handlers, serialize_handlers
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class GitHubFileEditorTool(ComponentTool):
|
|
16
|
+
"""
|
|
17
|
+
A tool for editing files in GitHub repositories.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
def __init__(
|
|
21
|
+
self,
|
|
22
|
+
*,
|
|
23
|
+
name: Optional[str] = "file_editor",
|
|
24
|
+
description: Optional[str] = FILE_EDITOR_PROMPT,
|
|
25
|
+
parameters: Optional[Dict[str, Any]] = FILE_EDITOR_SCHEMA,
|
|
26
|
+
github_token: Secret = Secret.from_env_var("GITHUB_TOKEN"),
|
|
27
|
+
repo: Optional[str] = None,
|
|
28
|
+
branch: str = "main",
|
|
29
|
+
raise_on_failure: bool = True,
|
|
30
|
+
outputs_to_string: Optional[Dict[str, Union[str, Callable[[Any], str]]]] = None,
|
|
31
|
+
inputs_from_state: Optional[Dict[str, str]] = None,
|
|
32
|
+
outputs_to_state: Optional[Dict[str, Dict[str, Union[str, Callable]]]] = None,
|
|
33
|
+
):
|
|
34
|
+
"""
|
|
35
|
+
Initialize the GitHub file editor tool.
|
|
36
|
+
|
|
37
|
+
:param name: Optional name for the tool.
|
|
38
|
+
:param description: Optional description.
|
|
39
|
+
:param parameters: Optional JSON schema defining the parameters expected by the Tool.
|
|
40
|
+
:param github_token: GitHub personal access token for API authentication
|
|
41
|
+
:param repo: Default repository in owner/repo format
|
|
42
|
+
:param branch: Default branch to work with
|
|
43
|
+
:param raise_on_failure: If True, raises exceptions on API errors
|
|
44
|
+
:param outputs_to_string:
|
|
45
|
+
Optional dictionary defining how a tool outputs should be converted into a string.
|
|
46
|
+
If the source is provided only the specified output key is sent to the handler.
|
|
47
|
+
If the source is omitted the whole tool result is sent to the handler.
|
|
48
|
+
Example: {
|
|
49
|
+
"source": "docs", "handler": format_documents
|
|
50
|
+
}
|
|
51
|
+
:param inputs_from_state:
|
|
52
|
+
Optional dictionary mapping state keys to tool parameter names.
|
|
53
|
+
Example: {"repository": "repo"} maps state's "repository" to tool's "repo" parameter.
|
|
54
|
+
:param outputs_to_state:
|
|
55
|
+
Optional dictionary defining how tool outputs map to keys within state as well as optional handlers.
|
|
56
|
+
If the source is provided only the specified output key is sent to the handler.
|
|
57
|
+
Example: {
|
|
58
|
+
"documents": {"source": "docs", "handler": custom_handler}
|
|
59
|
+
}
|
|
60
|
+
If the source is omitted the whole tool result is sent to the handler.
|
|
61
|
+
Example: {
|
|
62
|
+
"documents": {"handler": custom_handler}
|
|
63
|
+
}
|
|
64
|
+
"""
|
|
65
|
+
self.name = name
|
|
66
|
+
self.description = description
|
|
67
|
+
self.parameters = parameters
|
|
68
|
+
self.github_token = github_token
|
|
69
|
+
self.repo = repo
|
|
70
|
+
self.branch = branch
|
|
71
|
+
self.raise_on_failure = raise_on_failure
|
|
72
|
+
self.outputs_to_string = outputs_to_string
|
|
73
|
+
self.inputs_from_state = inputs_from_state
|
|
74
|
+
self.outputs_to_state = outputs_to_state
|
|
75
|
+
|
|
76
|
+
file_editor = GitHubFileEditor(
|
|
77
|
+
github_token=github_token,
|
|
78
|
+
repo=repo,
|
|
79
|
+
branch=branch,
|
|
80
|
+
raise_on_failure=raise_on_failure,
|
|
81
|
+
)
|
|
82
|
+
super().__init__(
|
|
83
|
+
component=file_editor,
|
|
84
|
+
name=name,
|
|
85
|
+
description=description,
|
|
86
|
+
parameters=parameters,
|
|
87
|
+
outputs_to_string=outputs_to_string,
|
|
88
|
+
inputs_from_state=inputs_from_state,
|
|
89
|
+
outputs_to_state=outputs_to_state,
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
93
|
+
"""
|
|
94
|
+
Serializes the tool to a dictionary.
|
|
95
|
+
|
|
96
|
+
:returns:
|
|
97
|
+
Dictionary with serialized data.
|
|
98
|
+
"""
|
|
99
|
+
serialized = {
|
|
100
|
+
"name": self.name,
|
|
101
|
+
"description": self.description,
|
|
102
|
+
"parameters": self.parameters,
|
|
103
|
+
"github_token": self.github_token.to_dict() if self.github_token else None,
|
|
104
|
+
"repo": self.repo,
|
|
105
|
+
"branch": self.branch,
|
|
106
|
+
"raise_on_failure": self.raise_on_failure,
|
|
107
|
+
"outputs_to_string": self.outputs_to_string,
|
|
108
|
+
"inputs_from_state": self.inputs_from_state,
|
|
109
|
+
"outputs_to_state": self.outputs_to_state,
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
serialize_handlers(serialized, self.outputs_to_state, self.outputs_to_string)
|
|
113
|
+
return {"type": generate_qualified_class_name(type(self)), "data": serialized}
|
|
114
|
+
|
|
115
|
+
@classmethod
|
|
116
|
+
def from_dict(cls, data: Dict[str, Any]) -> "GitHubFileEditorTool":
|
|
117
|
+
"""
|
|
118
|
+
Deserializes the tool from a dictionary.
|
|
119
|
+
|
|
120
|
+
:param data:
|
|
121
|
+
Dictionary to deserialize from.
|
|
122
|
+
:returns:
|
|
123
|
+
Deserialized tool.
|
|
124
|
+
"""
|
|
125
|
+
inner_data = data["data"]
|
|
126
|
+
deserialize_secrets_inplace(inner_data, keys=["github_token"])
|
|
127
|
+
deserialize_handlers(inner_data)
|
|
128
|
+
return cls(**inner_data)
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2023-present deepset GmbH <info@deepset.ai>
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
from typing import Any, Callable, Dict, Optional, Union
|
|
5
|
+
|
|
6
|
+
from haystack.core.serialization import generate_qualified_class_name
|
|
7
|
+
from haystack.tools import ComponentTool
|
|
8
|
+
from haystack.utils import Secret, deserialize_secrets_inplace
|
|
9
|
+
|
|
10
|
+
from haystack_integrations.components.connectors.github.issue_commenter import GitHubIssueCommenter
|
|
11
|
+
from haystack_integrations.prompts.github.issue_commenter_prompt import ISSUE_COMMENTER_PROMPT, ISSUE_COMMENTER_SCHEMA
|
|
12
|
+
from haystack_integrations.tools.github.utils import deserialize_handlers, serialize_handlers
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class GitHubIssueCommenterTool(ComponentTool):
|
|
16
|
+
"""
|
|
17
|
+
A tool for commenting on GitHub issues.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
def __init__(
|
|
21
|
+
self,
|
|
22
|
+
*,
|
|
23
|
+
name: Optional[str] = "issue_commenter",
|
|
24
|
+
description: Optional[str] = ISSUE_COMMENTER_PROMPT,
|
|
25
|
+
parameters: Optional[Dict[str, Any]] = ISSUE_COMMENTER_SCHEMA,
|
|
26
|
+
github_token: Secret = Secret.from_env_var("GITHUB_TOKEN"),
|
|
27
|
+
raise_on_failure: bool = True,
|
|
28
|
+
retry_attempts: int = 2,
|
|
29
|
+
outputs_to_string: Optional[Dict[str, Union[str, Callable[[Any], str]]]] = None,
|
|
30
|
+
inputs_from_state: Optional[Dict[str, str]] = None,
|
|
31
|
+
outputs_to_state: Optional[Dict[str, Dict[str, Union[str, Callable]]]] = None,
|
|
32
|
+
):
|
|
33
|
+
"""
|
|
34
|
+
Initialize the GitHub issue commenter tool.
|
|
35
|
+
|
|
36
|
+
:param name: Optional name for the tool.
|
|
37
|
+
:param description: Optional description.
|
|
38
|
+
:param parameters: Optional JSON schema defining the parameters expected by the Tool.
|
|
39
|
+
:param github_token: GitHub personal access token for API authentication
|
|
40
|
+
:param raise_on_failure: If True, raises exceptions on API errors
|
|
41
|
+
:param retry_attempts: Number of retry attempts for failed requests
|
|
42
|
+
:param outputs_to_string:
|
|
43
|
+
Optional dictionary defining how a tool outputs should be converted into a string.
|
|
44
|
+
If the source is provided only the specified output key is sent to the handler.
|
|
45
|
+
If the source is omitted the whole tool result is sent to the handler.
|
|
46
|
+
Example: {
|
|
47
|
+
"source": "docs", "handler": format_documents
|
|
48
|
+
}
|
|
49
|
+
:param inputs_from_state:
|
|
50
|
+
Optional dictionary mapping state keys to tool parameter names.
|
|
51
|
+
Example: {"repository": "repo"} maps state's "repository" to tool's "repo" parameter.
|
|
52
|
+
:param outputs_to_state:
|
|
53
|
+
Optional dictionary defining how tool outputs map to keys within state as well as optional handlers.
|
|
54
|
+
If the source is provided only the specified output key is sent to the handler.
|
|
55
|
+
Example: {
|
|
56
|
+
"documents": {"source": "docs", "handler": custom_handler}
|
|
57
|
+
}
|
|
58
|
+
If the source is omitted the whole tool result is sent to the handler.
|
|
59
|
+
Example: {
|
|
60
|
+
"documents": {"handler": custom_handler}
|
|
61
|
+
}
|
|
62
|
+
"""
|
|
63
|
+
self.name = name
|
|
64
|
+
self.description = description
|
|
65
|
+
self.parameters = parameters
|
|
66
|
+
self.github_token = github_token
|
|
67
|
+
self.raise_on_failure = raise_on_failure
|
|
68
|
+
self.retry_attempts = retry_attempts
|
|
69
|
+
self.outputs_to_string = outputs_to_string
|
|
70
|
+
self.inputs_from_state = inputs_from_state
|
|
71
|
+
self.outputs_to_state = outputs_to_state
|
|
72
|
+
|
|
73
|
+
issue_commenter = GitHubIssueCommenter(
|
|
74
|
+
github_token=github_token,
|
|
75
|
+
raise_on_failure=raise_on_failure,
|
|
76
|
+
retry_attempts=retry_attempts,
|
|
77
|
+
)
|
|
78
|
+
super().__init__(
|
|
79
|
+
component=issue_commenter,
|
|
80
|
+
name=name,
|
|
81
|
+
description=description,
|
|
82
|
+
parameters=parameters,
|
|
83
|
+
outputs_to_string=outputs_to_string,
|
|
84
|
+
inputs_from_state=inputs_from_state,
|
|
85
|
+
outputs_to_state=outputs_to_state,
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
89
|
+
"""
|
|
90
|
+
Serializes the tool to a dictionary.
|
|
91
|
+
|
|
92
|
+
:returns:
|
|
93
|
+
Dictionary with serialized data.
|
|
94
|
+
"""
|
|
95
|
+
serialized = {
|
|
96
|
+
"name": self.name,
|
|
97
|
+
"description": self.description,
|
|
98
|
+
"parameters": self.parameters,
|
|
99
|
+
"github_token": self.github_token.to_dict() if self.github_token else None,
|
|
100
|
+
"raise_on_failure": self.raise_on_failure,
|
|
101
|
+
"retry_attempts": self.retry_attempts,
|
|
102
|
+
"outputs_to_string": self.outputs_to_string,
|
|
103
|
+
"inputs_from_state": self.inputs_from_state,
|
|
104
|
+
"outputs_to_state": self.outputs_to_state,
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
serialize_handlers(serialized, self.outputs_to_state, self.outputs_to_string)
|
|
108
|
+
return {"type": generate_qualified_class_name(type(self)), "data": serialized}
|
|
109
|
+
|
|
110
|
+
@classmethod
|
|
111
|
+
def from_dict(cls, data: Dict[str, Any]) -> "GitHubIssueCommenterTool":
|
|
112
|
+
"""
|
|
113
|
+
Deserializes the tool from a dictionary.
|
|
114
|
+
|
|
115
|
+
:param data:
|
|
116
|
+
Dictionary to deserialize from.
|
|
117
|
+
:returns:
|
|
118
|
+
Deserialized tool.
|
|
119
|
+
"""
|
|
120
|
+
inner_data = data["data"]
|
|
121
|
+
deserialize_secrets_inplace(inner_data, keys=["github_token"])
|
|
122
|
+
deserialize_handlers(inner_data)
|
|
123
|
+
return cls(**inner_data)
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2023-present deepset GmbH <info@deepset.ai>
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
from typing import Any, Callable, Dict, Optional, Union
|
|
5
|
+
|
|
6
|
+
from haystack.core.serialization import generate_qualified_class_name
|
|
7
|
+
from haystack.tools import ComponentTool
|
|
8
|
+
from haystack.utils import Secret, deserialize_secrets_inplace
|
|
9
|
+
|
|
10
|
+
from haystack_integrations.components.connectors.github.issue_viewer import GitHubIssueViewer
|
|
11
|
+
from haystack_integrations.prompts.github.issue_viewer_prompt import ISSUE_VIEWER_PROMPT, ISSUE_VIEWER_SCHEMA
|
|
12
|
+
from haystack_integrations.tools.github.utils import deserialize_handlers, serialize_handlers
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class GitHubIssueViewerTool(ComponentTool):
|
|
16
|
+
"""
|
|
17
|
+
A tool for viewing GitHub issues.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
def __init__(
|
|
21
|
+
self,
|
|
22
|
+
*,
|
|
23
|
+
name: Optional[str] = "issue_viewer",
|
|
24
|
+
description: Optional[str] = ISSUE_VIEWER_PROMPT,
|
|
25
|
+
parameters: Optional[Dict[str, Any]] = ISSUE_VIEWER_SCHEMA,
|
|
26
|
+
github_token: Optional[Secret] = None,
|
|
27
|
+
raise_on_failure: bool = True,
|
|
28
|
+
retry_attempts: int = 2,
|
|
29
|
+
outputs_to_string: Optional[Dict[str, Union[str, Callable[[Any], str]]]] = None,
|
|
30
|
+
inputs_from_state: Optional[Dict[str, str]] = None,
|
|
31
|
+
outputs_to_state: Optional[Dict[str, Dict[str, Union[str, Callable]]]] = None,
|
|
32
|
+
):
|
|
33
|
+
"""
|
|
34
|
+
Initialize the GitHub issue viewer tool.
|
|
35
|
+
|
|
36
|
+
:param name: Optional name for the tool.
|
|
37
|
+
:param description: Optional description.
|
|
38
|
+
:param parameters: Optional JSON schema defining the parameters expected by the Tool.
|
|
39
|
+
:param github_token: Optional GitHub personal access token for API authentication
|
|
40
|
+
:param raise_on_failure: If True, raises exceptions on API errors
|
|
41
|
+
:param retry_attempts: Number of retry attempts for failed requests
|
|
42
|
+
:param outputs_to_string:
|
|
43
|
+
Optional dictionary defining how a tool outputs should be converted into a string.
|
|
44
|
+
If the source is provided only the specified output key is sent to the handler.
|
|
45
|
+
If the source is omitted the whole tool result is sent to the handler.
|
|
46
|
+
Example: {
|
|
47
|
+
"source": "docs", "handler": format_documents
|
|
48
|
+
}
|
|
49
|
+
:param inputs_from_state:
|
|
50
|
+
Optional dictionary mapping state keys to tool parameter names.
|
|
51
|
+
Example: {"repository": "repo"} maps state's "repository" to tool's "repo" parameter.
|
|
52
|
+
:param outputs_to_state:
|
|
53
|
+
Optional dictionary defining how tool outputs map to keys within state as well as optional handlers.
|
|
54
|
+
If the source is provided only the specified output key is sent to the handler.
|
|
55
|
+
Example: {
|
|
56
|
+
"documents": {"source": "docs", "handler": custom_handler}
|
|
57
|
+
}
|
|
58
|
+
If the source is omitted the whole tool result is sent to the handler.
|
|
59
|
+
Example: {
|
|
60
|
+
"documents": {"handler": custom_handler}
|
|
61
|
+
}
|
|
62
|
+
"""
|
|
63
|
+
self.name = name
|
|
64
|
+
self.description = description
|
|
65
|
+
self.parameters = parameters
|
|
66
|
+
self.github_token = github_token
|
|
67
|
+
self.raise_on_failure = raise_on_failure
|
|
68
|
+
self.retry_attempts = retry_attempts
|
|
69
|
+
self.outputs_to_string = outputs_to_string
|
|
70
|
+
self.inputs_from_state = inputs_from_state
|
|
71
|
+
self.outputs_to_state = outputs_to_state
|
|
72
|
+
|
|
73
|
+
issue_viewer = GitHubIssueViewer(
|
|
74
|
+
github_token=github_token,
|
|
75
|
+
raise_on_failure=raise_on_failure,
|
|
76
|
+
retry_attempts=retry_attempts,
|
|
77
|
+
)
|
|
78
|
+
super().__init__(
|
|
79
|
+
component=issue_viewer,
|
|
80
|
+
name=name,
|
|
81
|
+
description=description,
|
|
82
|
+
parameters=parameters,
|
|
83
|
+
outputs_to_string=outputs_to_string,
|
|
84
|
+
inputs_from_state=inputs_from_state,
|
|
85
|
+
outputs_to_state=outputs_to_state,
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
89
|
+
"""
|
|
90
|
+
Serializes the tool to a dictionary.
|
|
91
|
+
|
|
92
|
+
:returns:
|
|
93
|
+
Dictionary with serialized data.
|
|
94
|
+
"""
|
|
95
|
+
serialized = {
|
|
96
|
+
"name": self.name,
|
|
97
|
+
"description": self.description,
|
|
98
|
+
"parameters": self.parameters,
|
|
99
|
+
"github_token": self.github_token.to_dict() if self.github_token else None,
|
|
100
|
+
"raise_on_failure": self.raise_on_failure,
|
|
101
|
+
"retry_attempts": self.retry_attempts,
|
|
102
|
+
"outputs_to_string": self.outputs_to_string,
|
|
103
|
+
"inputs_from_state": self.inputs_from_state,
|
|
104
|
+
"outputs_to_state": self.outputs_to_state,
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
serialize_handlers(serialized, self.outputs_to_state, self.outputs_to_string)
|
|
108
|
+
return {"type": generate_qualified_class_name(type(self)), "data": serialized}
|
|
109
|
+
|
|
110
|
+
@classmethod
|
|
111
|
+
def from_dict(cls, data: Dict[str, Any]) -> "GitHubIssueViewerTool":
|
|
112
|
+
"""
|
|
113
|
+
Deserializes the tool from a dictionary.
|
|
114
|
+
|
|
115
|
+
:param data:
|
|
116
|
+
Dictionary to deserialize from.
|
|
117
|
+
:returns:
|
|
118
|
+
Deserialized tool.
|
|
119
|
+
"""
|
|
120
|
+
inner_data = data["data"]
|
|
121
|
+
deserialize_secrets_inplace(inner_data, keys=["github_token"])
|
|
122
|
+
deserialize_handlers(inner_data)
|
|
123
|
+
return cls(**inner_data)
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2023-present deepset GmbH <info@deepset.ai>
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
from typing import Any, Callable, Dict, Optional, Union
|
|
5
|
+
|
|
6
|
+
from haystack.core.serialization import generate_qualified_class_name
|
|
7
|
+
from haystack.tools import ComponentTool
|
|
8
|
+
from haystack.utils import Secret, deserialize_secrets_inplace
|
|
9
|
+
|
|
10
|
+
from haystack_integrations.components.connectors.github.pr_creator import GitHubPRCreator
|
|
11
|
+
from haystack_integrations.prompts.github.pr_creator_prompt import PR_CREATOR_PROMPT, PR_CREATOR_SCHEMA
|
|
12
|
+
from haystack_integrations.tools.github.utils import deserialize_handlers, serialize_handlers
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class GitHubPRCreatorTool(ComponentTool):
|
|
16
|
+
"""
|
|
17
|
+
A tool for creating pull requests in GitHub repositories.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
def __init__(
|
|
21
|
+
self,
|
|
22
|
+
*,
|
|
23
|
+
name: Optional[str] = "pr_creator",
|
|
24
|
+
description: Optional[str] = PR_CREATOR_PROMPT,
|
|
25
|
+
parameters: Optional[Dict[str, Any]] = PR_CREATOR_SCHEMA,
|
|
26
|
+
github_token: Secret = Secret.from_env_var("GITHUB_TOKEN"),
|
|
27
|
+
raise_on_failure: bool = True,
|
|
28
|
+
outputs_to_string: Optional[Dict[str, Union[str, Callable[[Any], str]]]] = None,
|
|
29
|
+
inputs_from_state: Optional[Dict[str, str]] = None,
|
|
30
|
+
outputs_to_state: Optional[Dict[str, Dict[str, Union[str, Callable]]]] = None,
|
|
31
|
+
):
|
|
32
|
+
"""
|
|
33
|
+
Initialize the GitHub PR creator tool.
|
|
34
|
+
|
|
35
|
+
:param name: Optional name for the tool.
|
|
36
|
+
:param description: Optional description.
|
|
37
|
+
:param parameters: Optional JSON schema defining the parameters expected by the Tool.
|
|
38
|
+
:param github_token: GitHub personal access token for API authentication
|
|
39
|
+
:param raise_on_failure: If True, raises exceptions on API errors
|
|
40
|
+
:param outputs_to_string:
|
|
41
|
+
Optional dictionary defining how a tool outputs should be converted into a string.
|
|
42
|
+
If the source is provided only the specified output key is sent to the handler.
|
|
43
|
+
If the source is omitted the whole tool result is sent to the handler.
|
|
44
|
+
Example: {
|
|
45
|
+
"source": "docs", "handler": format_documents
|
|
46
|
+
}
|
|
47
|
+
:param inputs_from_state:
|
|
48
|
+
Optional dictionary mapping state keys to tool parameter names.
|
|
49
|
+
Example: {"repository": "repo"} maps state's "repository" to tool's "repo" parameter.
|
|
50
|
+
:param outputs_to_state:
|
|
51
|
+
Optional dictionary defining how tool outputs map to keys within state as well as optional handlers.
|
|
52
|
+
If the source is provided only the specified output key is sent to the handler.
|
|
53
|
+
Example: {
|
|
54
|
+
"documents": {"source": "docs", "handler": custom_handler}
|
|
55
|
+
}
|
|
56
|
+
If the source is omitted the whole tool result is sent to the handler.
|
|
57
|
+
Example: {
|
|
58
|
+
"documents": {"handler": custom_handler}
|
|
59
|
+
}
|
|
60
|
+
"""
|
|
61
|
+
self.name = name
|
|
62
|
+
self.description = description
|
|
63
|
+
self.parameters = parameters
|
|
64
|
+
self.github_token = github_token
|
|
65
|
+
self.raise_on_failure = raise_on_failure
|
|
66
|
+
self.outputs_to_string = outputs_to_string
|
|
67
|
+
self.inputs_from_state = inputs_from_state
|
|
68
|
+
self.outputs_to_state = outputs_to_state
|
|
69
|
+
|
|
70
|
+
pr_creator = GitHubPRCreator(
|
|
71
|
+
github_token=github_token,
|
|
72
|
+
raise_on_failure=raise_on_failure,
|
|
73
|
+
)
|
|
74
|
+
super().__init__(
|
|
75
|
+
component=pr_creator,
|
|
76
|
+
name=name,
|
|
77
|
+
description=description,
|
|
78
|
+
parameters=parameters,
|
|
79
|
+
outputs_to_string=outputs_to_string,
|
|
80
|
+
inputs_from_state=inputs_from_state,
|
|
81
|
+
outputs_to_state=outputs_to_state,
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
85
|
+
"""
|
|
86
|
+
Serializes the tool to a dictionary.
|
|
87
|
+
|
|
88
|
+
:returns:
|
|
89
|
+
Dictionary with serialized data.
|
|
90
|
+
"""
|
|
91
|
+
serialized = {
|
|
92
|
+
"name": self.name,
|
|
93
|
+
"description": self.description,
|
|
94
|
+
"parameters": self.parameters,
|
|
95
|
+
"github_token": self.github_token.to_dict() if self.github_token else None,
|
|
96
|
+
"raise_on_failure": self.raise_on_failure,
|
|
97
|
+
"outputs_to_string": self.outputs_to_string,
|
|
98
|
+
"inputs_from_state": self.inputs_from_state,
|
|
99
|
+
"outputs_to_state": self.outputs_to_state,
|
|
100
|
+
}
|
|
101
|
+
serialize_handlers(serialized, self.outputs_to_state, self.outputs_to_string)
|
|
102
|
+
return {"type": generate_qualified_class_name(type(self)), "data": serialized}
|
|
103
|
+
|
|
104
|
+
@classmethod
|
|
105
|
+
def from_dict(cls, data: Dict[str, Any]) -> "GitHubPRCreatorTool":
|
|
106
|
+
"""
|
|
107
|
+
Deserializes the tool from a dictionary.
|
|
108
|
+
|
|
109
|
+
:param data:
|
|
110
|
+
Dictionary to deserialize from.
|
|
111
|
+
:returns:
|
|
112
|
+
Deserialized tool.
|
|
113
|
+
"""
|
|
114
|
+
inner_data = data["data"]
|
|
115
|
+
deserialize_secrets_inplace(inner_data, keys=["github_token"])
|
|
116
|
+
deserialize_handlers(inner_data)
|
|
117
|
+
return cls(**inner_data)
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2023-present deepset GmbH <info@deepset.ai>
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
from typing import Any, Callable, Dict, Optional, Union
|
|
5
|
+
|
|
6
|
+
from haystack.core.serialization import generate_qualified_class_name
|
|
7
|
+
from haystack.tools import ComponentTool
|
|
8
|
+
from haystack.utils import Secret, deserialize_secrets_inplace
|
|
9
|
+
|
|
10
|
+
from haystack_integrations.components.connectors.github.repo_viewer import GitHubRepoViewer
|
|
11
|
+
from haystack_integrations.prompts.github.repo_viewer_prompt import REPO_VIEWER_PROMPT, REPO_VIEWER_SCHEMA
|
|
12
|
+
from haystack_integrations.tools.github.utils import deserialize_handlers, message_handler, serialize_handlers
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class GitHubRepoViewerTool(ComponentTool):
|
|
16
|
+
"""
|
|
17
|
+
A tool for viewing files and directories in GitHub repositories.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
def __init__(
|
|
21
|
+
self,
|
|
22
|
+
*,
|
|
23
|
+
name: Optional[str] = "repo_viewer",
|
|
24
|
+
description: Optional[str] = REPO_VIEWER_PROMPT,
|
|
25
|
+
parameters: Optional[Dict[str, Any]] = REPO_VIEWER_SCHEMA,
|
|
26
|
+
github_token: Optional[Secret] = None,
|
|
27
|
+
repo: Optional[str] = None,
|
|
28
|
+
branch: str = "main",
|
|
29
|
+
raise_on_failure: bool = True,
|
|
30
|
+
max_file_size: int = 1_000_000, # 1MB default limit
|
|
31
|
+
outputs_to_string: Optional[Dict[str, Union[str, Callable[[Any], str]]]] = None,
|
|
32
|
+
inputs_from_state: Optional[Dict[str, str]] = None,
|
|
33
|
+
outputs_to_state: Optional[Dict[str, Dict[str, Union[str, Callable]]]] = None,
|
|
34
|
+
):
|
|
35
|
+
"""
|
|
36
|
+
Initialize the GitHub repository viewer tool.
|
|
37
|
+
|
|
38
|
+
:param name: Optional name for the tool.
|
|
39
|
+
:param description: Optional description.
|
|
40
|
+
:param parameters: Optional JSON schema defining the parameters expected by the Tool.
|
|
41
|
+
:param github_token: Optional GitHub personal access token for API authentication
|
|
42
|
+
:param repo: Default repository in owner/repo format
|
|
43
|
+
:param branch: Default branch to work with
|
|
44
|
+
:param raise_on_failure: If True, raises exceptions on API errors
|
|
45
|
+
:param max_file_size: Maximum file size in bytes to read
|
|
46
|
+
:param outputs_to_string:
|
|
47
|
+
Optional dictionary defining how a tool outputs should be converted into a string.
|
|
48
|
+
By default, truncates the document.content of the viewed files to 150,000 characters each.
|
|
49
|
+
If the source is provided only the specified output key is sent to the handler.
|
|
50
|
+
If the source is omitted the whole tool result is sent to the handler.
|
|
51
|
+
Example: {
|
|
52
|
+
"source": "docs", "handler": format_documents
|
|
53
|
+
}
|
|
54
|
+
:param inputs_from_state:
|
|
55
|
+
Optional dictionary mapping state keys to tool parameter names.
|
|
56
|
+
By default, the tool does not use any inputs from state.
|
|
57
|
+
Example: {"repository": "repo"} maps state's "repository" to tool's "repo" parameter.
|
|
58
|
+
:param outputs_to_state:
|
|
59
|
+
Optional dictionary defining how tool outputs map to keys within state as well as optional handlers.
|
|
60
|
+
By default, outputs the viewed files as documents to the state.
|
|
61
|
+
If the source is provided only the specified output key is sent to the handler.
|
|
62
|
+
Example: {
|
|
63
|
+
"documents": {"source": "docs", "handler": custom_handler}
|
|
64
|
+
}
|
|
65
|
+
If the source is omitted the whole tool result is sent to the handler.
|
|
66
|
+
Example: {
|
|
67
|
+
"documents": {"handler": custom_handler}
|
|
68
|
+
}
|
|
69
|
+
"""
|
|
70
|
+
self.name = name
|
|
71
|
+
self.description = description
|
|
72
|
+
self.parameters = parameters
|
|
73
|
+
self.github_token = github_token
|
|
74
|
+
self.repo = repo
|
|
75
|
+
self.branch = branch
|
|
76
|
+
self.raise_on_failure = raise_on_failure
|
|
77
|
+
self.max_file_size = max_file_size
|
|
78
|
+
|
|
79
|
+
# Set default values for mutable parameters
|
|
80
|
+
self.outputs_to_string = outputs_to_string or {"source": "documents", "handler": message_handler}
|
|
81
|
+
self.inputs_from_state = inputs_from_state or {}
|
|
82
|
+
self.outputs_to_state = outputs_to_state or {"documents": {"source": "documents"}}
|
|
83
|
+
|
|
84
|
+
repo_viewer = GitHubRepoViewer(
|
|
85
|
+
github_token=github_token,
|
|
86
|
+
repo=repo,
|
|
87
|
+
branch=branch,
|
|
88
|
+
raise_on_failure=raise_on_failure,
|
|
89
|
+
max_file_size=max_file_size,
|
|
90
|
+
)
|
|
91
|
+
super().__init__(
|
|
92
|
+
component=repo_viewer,
|
|
93
|
+
name=name,
|
|
94
|
+
description=description,
|
|
95
|
+
parameters=parameters,
|
|
96
|
+
outputs_to_string=self.outputs_to_string,
|
|
97
|
+
inputs_from_state=self.inputs_from_state,
|
|
98
|
+
outputs_to_state=self.outputs_to_state,
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
102
|
+
"""
|
|
103
|
+
Serializes the tool to a dictionary.
|
|
104
|
+
|
|
105
|
+
:returns:
|
|
106
|
+
Dictionary with serialized data.
|
|
107
|
+
"""
|
|
108
|
+
serialized = {
|
|
109
|
+
"name": self.name,
|
|
110
|
+
"description": self.description,
|
|
111
|
+
"parameters": self.parameters,
|
|
112
|
+
"github_token": self.github_token.to_dict() if self.github_token else None,
|
|
113
|
+
"repo": self.repo,
|
|
114
|
+
"branch": self.branch,
|
|
115
|
+
"raise_on_failure": self.raise_on_failure,
|
|
116
|
+
"max_file_size": self.max_file_size,
|
|
117
|
+
"outputs_to_string": self.outputs_to_string,
|
|
118
|
+
"inputs_from_state": self.inputs_from_state,
|
|
119
|
+
"outputs_to_state": self.outputs_to_state,
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
serialize_handlers(serialized, self.outputs_to_state, self.outputs_to_string)
|
|
123
|
+
return {"type": generate_qualified_class_name(type(self)), "data": serialized}
|
|
124
|
+
|
|
125
|
+
@classmethod
|
|
126
|
+
def from_dict(cls, data: Dict[str, Any]) -> "GitHubRepoViewerTool":
|
|
127
|
+
"""
|
|
128
|
+
Deserializes the tool from a dictionary.
|
|
129
|
+
|
|
130
|
+
:param data:
|
|
131
|
+
Dictionary to deserialize from.
|
|
132
|
+
:returns:
|
|
133
|
+
Deserialized tool.
|
|
134
|
+
"""
|
|
135
|
+
inner_data = data["data"]
|
|
136
|
+
deserialize_secrets_inplace(inner_data, keys=["github_token"])
|
|
137
|
+
deserialize_handlers(inner_data)
|
|
138
|
+
return cls(**inner_data)
|