Skip to content

teff.tool.builtin.github

teff.tool.builtin.github

GitHub tools — list pull requests, fetch diffs, post comments, approve.

A small, purpose-built REST client over the GitHub API so a workflow can review pull requests without hand-rolling http_request calls: auth headers, endpoint paths and error surfacing are handled here.

All tools read token (a personal access token) from config and default to the public https://api.github.com base URL — override it with url for GitHub Enterprise. A repo is owner/repo. PRs are addressed by their number (the #N from the web UI).

Classes:

Name Description
GitHubApproveTool

Approve a pull request by submitting an APPROVE review.

GitHubGetPRChangesTool

Fetch a pull request's diff (changed files + per-file patches).

GitHubListOpenPRsTool

List open pull requests for an owner/repo.

GitHubPostCommentTool

Post a comment on a pull request (as an issue comment).

GitHubApproveTool

Bases: _GitHubBase

Approve a pull request by submitting an APPROVE review.

Parameters:

Name Type Description Default
repo

owner/repo.

required
number

Pull request number.

required
Source code in teff/tool/builtin/github.py
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
class GitHubApproveTool(_GitHubBase):
    """Approve a pull request by submitting an APPROVE review.

    Args:
        repo: ``owner/repo``.
        number: Pull request number.
    """

    name = "github_approve"
    description = "Approve a GitHub pull request"

    async def arun(  # type: ignore[override]
        self, repo: str, number: str
    ) -> str:
        r = self._repo(repo)
        path = f"/{r}/pulls/{number}/reviews"
        await self._request(
            "POST", path, json_body={"event": "APPROVE", "body": "Approved"}
        )
        return f"approved PR #{number}"

GitHubGetPRChangesTool

Bases: _GitHubBase

Fetch a pull request's diff (changed files + per-file patches).

Parameters:

Name Type Description Default
repo

owner/repo.

required
number

Pull request number (the #N).

required
max_chars

Cap on the returned diff text (default 20000).

required
Source code in teff/tool/builtin/github.py
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
class GitHubGetPRChangesTool(_GitHubBase):
    """Fetch a pull request's diff (changed files + per-file patches).

    Args:
        repo: ``owner/repo``.
        number: Pull request number (the ``#N``).
        max_chars: Cap on the returned diff text (default 20000).
    """

    name = "github_get_pr_changes"
    description = "Fetch the diff of a GitHub pull request"

    async def arun(  # type: ignore[override]
        self, repo: str, number: str, max_chars: int = 20000
    ) -> str:
        r = self._repo(repo)
        path = f"/{r}/pulls/{number}/files"
        text = await self._request("GET", path)
        data = json.loads(text)
        out = [f"# PR #{number}"]
        for change in data:
            out.append(
                f"\n== {change.get('filename', '')} "
                f"(+{change.get('additions', 0)} "
                f"-{change.get('deletions', 0)} {change.get('status', '')})"
            )
            patch = change.get("patch", "")
            out.append(patch[:max_chars])
        return "\n".join(out) if data else f"no changes for PR #{number}"

GitHubListOpenPRsTool

Bases: _GitHubBase

List open pull requests for an owner/repo.

Parameters:

Name Type Description Default
repo

owner/repo.

required
limit

Maximum number of PRs to return (default 50).

required
state

PR state filter (default open).

required
Source code in teff/tool/builtin/github.py
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
class GitHubListOpenPRsTool(_GitHubBase):
    """List open pull requests for an ``owner/repo``.

    Args:
        repo: ``owner/repo``.
        limit: Maximum number of PRs to return (default 50).
        state: PR state filter (default ``open``).
    """

    name = "github_list_open_prs"
    description = "List open pull requests for a GitHub repository"

    async def arun(  # type: ignore[override]
        self, repo: str, limit: int = 50, state: str = "open"
    ) -> str:
        r = self._repo(repo)
        path = f"/{r}/pulls?state={state}&per_page={limit}"
        text = await self._request("GET", path)
        data = json.loads(text)
        lines = []
        for pr in data:
            lines.append(
                f"#{pr['number']}\t{pr.get('state', '')}\t"
                f"{pr.get('title', '')}\t(pr_id={pr.get('id')})"
            )
        return "\n".join(lines) if lines else "no open pull requests"

GitHubPostCommentTool

Bases: _GitHubBase

Post a comment on a pull request (as an issue comment).

Parameters:

Name Type Description Default
repo

owner/repo.

required
number

Pull request number.

required
body

The comment text to post.

required
Source code in teff/tool/builtin/github.py
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
class GitHubPostCommentTool(_GitHubBase):
    """Post a comment on a pull request (as an issue comment).

    Args:
        repo: ``owner/repo``.
        number: Pull request number.
        body: The comment text to post.
    """

    name = "github_post_comment"
    description = "Post a comment on a GitHub pull request"

    async def arun(  # type: ignore[override]
        self, repo: str, number: str, body: str
    ) -> str:
        r = self._repo(repo)
        path = f"/{r}/issues/{number}/comments"
        text = await self._request("POST", path, json_body={"body": body})
        data = json.loads(text)
        return f"comment posted on #{number} (comment_id={data.get('id')})"