nagents-channel-github-issues
An installable, typed GitHub Issues connector for the public Nagents Channel API. It polls the GitHub REST API for issue comments and issue lifecycle events, and exposes explicit tools to comment on issues and manage them. Works against GitHub.com and GitHub Enterprise Server. Python 3.11+; MIT licensed.
The connector only receives and sends through the channel API. It never opens a session database, chooses agent sessions, or auto-replies to events. Session routing stays with the application hosting the connector.
Install
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
python -m pip install 'nagents>=0.11.0,<0.12' nagents-channel-github-issues
Set a token in the environment (never in source files):
export GITHUB_TOKEN=... # fine-grained or classic token with repo read/write
The connector sends Authorization: Bearer <token>, Accept: application/vnd.github+json, X-GitHub-Api-Version: 2022-11-28, and a
User-Agent on every request. Tokens are read from configuration or the
environment only and are never logged or embedded in errors.
Use
import asyncio
import os
from pathlib import Path
from nagents import Agent, Provider, ProviderType, SessionManager
from nagents_channel_github_issues import GitHubIssuesChannel
async def main() -> None:
agent = Agent(
Provider(
ProviderType.OPENAI_COMPATIBLE,
api_key=os.environ["OPENAI_API_KEY"],
model=os.environ["OPENAI_MODEL"],
),
SessionManager(Path("agent.db")),
system_prompt="Coordinate my GitHub issues and decide when to reply.",
)
agent.add_channel(
GitHubIssuesChannel(
os.environ["GITHUB_TOKEN"],
repos=["abi-jey/nagents"],
include_self=False,
)
)
try:
await agent.listen(session_id="github-issues")
finally:
await agent.close()
asyncio.run(main())
Configuration-driven discovery
from nagents import load_channel
channel = load_channel(
"github-issues",
{
"name": "project-issues",
"token_env": "GITHUB_TOKEN",
"repos": ["abi-jey/nagents"],
"poll_interval": 30,
"lookback": 300,
},
)
The nagents.channels entry point is github-issues and exposes a
ChannelPlugin whose token property is writeOnly, so management clients
store it privately and never echo saved values.
Received events
Each inbound event becomes one ChannelMessage:
| Field | Value |
|---|---|
conversation_id |
owner/repo#issue_number |
message_id |
comment:<id> or issue:<number>:<updated_at> |
reply_to |
issue number |
sender_id |
user.login |
text |
comment or issue body |
sent_at |
epoch seconds of created_at |
event_type |
comment or issue |
metadata |
repo, number, event, html_url, state, labels, comment_id |
Pull-request entries are skipped. Comments on pull requests are skipped when the repository's issue polling has identified the number as a pull request. Events with empty bodies and unknown event types are skipped.
Filters:
allowed_usersadmits only the listed logins (case-insensitive). Empty admits everyone.include_self(defaultfalse) skips events authored by the authenticated user.
Actions
| Action | Arguments |
|---|---|
create_issue |
repo, title, optional body, optional labels |
close_issue |
destination (owner/repo#number) |
reopen_issue |
destination |
add_labels |
destination, labels |
edit_comment |
repo, comment_id, body |
Arguments are validated strictly against the advertised JSON Schemas. Writes are
sent once and never retried; a lost response raises ChannelError with
outcome_unknown=True, and rate limits surface retry_after.
Polling behaviour
- Repo-level issue comments (
/repos/{owner}/{repo}/issues/comments) and issues (/repos/{owner}/{repo}/issues) are polled withsort=created,direction=asc,since, andper_page=100. - Pagination follows the
Linkheaderrel="next"; page parameters are never constructed by hand. Only same-origin next links are followed. - Conditional requests send
If-None-Match; a304 Not Modifiedcosts no primary rate limit and preserves the cursor. retry-afterandx-ratelimit-resetdrive backoff; transient failures in one repository never stop the others.- In-memory cursors, ETags, and deduplication can be persisted with
state_pathfor restarts.
Enterprise Server
Set base_url to the enterprise REST base:
GitHubIssuesChannel(token, base_url="https://github.example.com/api/v3", repos=["team/repo"])
Develop
python -m venv .venv
.venv/bin/pip install -e '.[dev]'
.venv/bin/python -m pytest
PATH="$PWD/.venv/bin:$PATH" pre-commit run --all-files
All tests are offline: they use an aiohttp test server that emulates the REST endpoints, including pagination, conditional requests, and rate limiting.
Metadata
Release files for nagents-channel-github-issues 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| nagents_channel_github_issues-0.1.0.tar.gz | 32.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| nagents_channel_github_issues-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 53.6 kB
Release files / nagents_channel_github_issues-0.1.0.tar.gz
| Download URL | nagents_channel_github_issues-0.1.0.tar.gz |
|---|---|
| Size | 32.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f042291c30fa974c49a68efbb785ab193783af672d6b8095b0e569d8e446934e
|
|
BLAKE2b-256 checksum How to use checksums |
d91fdfc15bae04395e5add8a5014d4a181dfed8b0cd05baa81dbe63d82dd78ad
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.
Transparency logRelease files / nagents_channel_github_issues-0.1.0-py3-none-any.whl
| Download URL | nagents_channel_github_issues-0.1.0-py3-none-any.whl |
|---|---|
| Size | 21.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9aadecc18c7b5eb45418400cae09986be5f5c3c69e294e1075de108ff3ad2df5
|
|
BLAKE2b-256 checksum How to use checksums |
48efd7d35f65acbb3327b3f41ed79f3a8a5d664ac7dbeb79722648f37a37fd78
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.
Transparency log