github-agent 2.4.3__py3-none-any.whl → 2.4.5__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_agent/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "2.4.3"
1
+ __version__ = "2.4.5"
@@ -4,11 +4,10 @@
4
4
  import logging
5
5
  from typing import Any
6
6
 
7
- from agent_connector_sdk.exceptions import MissingParameterError, ParameterError
7
+ from agent_connector_sdk.exceptions import MissingParameterError
8
8
  from agent_connector_sdk.tls.profile import ResolvedTLSProfile
9
9
  from agent_connector_sdk.tls.resolve import resolve_tls_profile
10
- from gql import Client, gql
11
- from gql.transport.requests import RequestsHTTPTransport
10
+ from agent_connector_sdk.transports.graphql import GraphQLAuth, GraphQLClient
12
11
 
13
12
 
14
13
  class GraphQL:
@@ -44,29 +43,21 @@ class GraphQL:
44
43
  # GitHub GraphQL authenticates with a bearer token (classic PAT,
45
44
  # fine-grained PAT, or OAuth/GitHub-App installation token).
46
45
  self.headers = {"Authorization": f"Bearer {token}"}
47
- self.transport = RequestsHTTPTransport(
48
- url=self.url,
49
- headers=self.headers,
50
- **self.tls_profile.requests_kwargs(),
51
- )
52
- self.client = Client(
53
- transport=self.transport, fetch_schema_from_transport=False
46
+ self._gql = GraphQLClient(
47
+ self.url,
48
+ auth=GraphQLAuth.bearer(token),
49
+ tls_profile=self.tls_profile,
50
+ tls_service="github",
54
51
  )
55
52
 
53
+ @property
54
+ def client(self) -> Any:
55
+ """The underlying protocol client, built on first use."""
56
+ return self._gql.client
57
+
56
58
  def close(self) -> None:
57
- """Release GraphQL transport state and runtime-only TLS material.
58
-
59
- ``Client.close_sync()`` unconditionally asserts ``self.session`` is a
60
- ``SyncClientSession`` — but under gql 4.0 that attribute is only ever
61
- set by ``connect_sync()`` (called implicitly by ``execute_gql`` /
62
- ``client.execute``). If this ``GraphQL`` was constructed but never
63
- used to run a query, the underlying ``Client`` has no ``session``
64
- attribute yet and ``close_sync()`` raises ``AttributeError`` instead
65
- of being a no-op. Only close a session that was actually opened.
66
- """
67
- if hasattr(self.client, "session"):
68
- self.client.close_sync()
69
- self.tls_profile.cleanup()
59
+ """Release GraphQL transport state and runtime-only TLS material."""
60
+ self._gql.close()
70
61
 
71
62
  @staticmethod
72
63
  def _graphql_endpoint(url: str) -> str:
@@ -91,17 +82,7 @@ class GraphQL:
91
82
  Raises:
92
83
  ParameterError: If the query fails or the response carries errors.
93
84
  """
94
- try:
95
- query = gql(query_str)
96
- result = self.client.execute(
97
- query, variable_values=variables, operation_name=operation_name
98
- )
99
- if "errors" in result:
100
- raise ParameterError(f"GraphQL errors: {result['errors']}")
101
- return result
102
- except Exception as e:
103
- logging.error("GraphQL execution failed: error_type=%s", type(e).__name__)
104
- raise ParameterError(f"Query execution failed: {type(e).__name__}") from e
85
+ return self._gql.execute(query_str, variables, operation_name)
105
86
 
106
87
  def enable_pull_request_auto_merge(
107
88
  self, pull_request_id: str, merge_method: str = "MERGE"
@@ -39,7 +39,7 @@ from github_agent.auth import (
39
39
  )
40
40
  from github_agent.github_response_models import PagesAlreadyEnabled, PagesNotEnabled
41
41
 
42
- __version__ = "2.4.3"
42
+ __version__ = "2.4.5"
43
43
  logger = get_logger("GithubMCPServer")
44
44
  logger.setLevel(logging.INFO)
45
45
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: github-agent
3
- Version: 2.4.3
3
+ Version: 2.4.5
4
4
  Summary: GitHub Agent for MCP
5
5
  Author-email: Project Maintainers <maintainers@users.noreply.github.com>
6
6
  License: MIT
@@ -12,9 +12,8 @@ Classifier: Programming Language :: Python :: 3
12
12
  Requires-Python: >=3.12
13
13
  Description-Content-Type: text/markdown
14
14
  License-File: LICENSE
15
- Requires-Dist: gql[requests]>=4.4.0
16
15
  Requires-Dist: requests>=2.34.2
17
- Requires-Dist: agent-connector-sdk[mcp]<1.0.0,>=0.3.11
16
+ Requires-Dist: agent-connector-sdk[graphql,mcp]<1.0.0,>=0.3.18
18
17
  Provides-Extra: mcp
19
18
  Provides-Extra: all
20
19
  Provides-Extra: test
@@ -45,7 +44,7 @@ Dynamic: license-file
45
44
  ![PyPI - Wheel](https://img.shields.io/pypi/wheel/github-agent)
46
45
  ![PyPI - Implementation](https://img.shields.io/pypi/implementation/github-agent)
47
46
 
48
- *Version: 2.4.3*
47
+ *Version: 2.4.5*
49
48
 
50
49
  > **Documentation** — Installation, deployment, and usage across the MCP, API, and
51
50
  > [official documentation](https://knuckles-team.github.io/github-agent/).
@@ -1,14 +1,14 @@
1
- github_agent/__init__.py,sha256=OPBnVa8RJVtYMGheuiuNN0f5i8tn6elz4XCmUBGelSo,22
1
+ github_agent/__init__.py,sha256=zcb2VyQ6EBDMkktW4mmZ-qJGw-tYB_UjmzqDEz6RI9w,22
2
2
  github_agent/__main__.py,sha256=O4Xg__fMvKfUsA6m61pLV56jlYY6EORiLhgDLlp0vJ8,92
3
3
  github_agent/api_client.py,sha256=O69YfkXBKyVd59EC8szaMlw3_ZxwEEvsLSvhWlfYnvk,1581
4
4
  github_agent/auth.py,sha256=isNd6DYbl_syB_wIbC399d_-157jqH1jqJfDmBn8h-0,4671
5
- github_agent/github_gql.py,sha256=GdkazLUDRwu5AKv2cikT8evpQAGHD1nBZ4f4BtJ2f84,5382
5
+ github_agent/github_gql.py,sha256=8LxyFlUdtJArPO3s-YgZSL5WqnjGLp3ZuvGgVbPtVHM,4322
6
6
  github_agent/github_http.py,sha256=v-H9Nny1Q45yQH-1vsDpog4GOvAUSI786XFkctmXdik,4362
7
7
  github_agent/github_input_models.py,sha256=yqqPGHb206th736MZvbnxq9F1JRsBUBODNeNVc08F3A,15568
8
8
  github_agent/github_response_models.py,sha256=mllSt0frBgzklUtfuHywJ2Ald3m99So948Xikt3H2Tc,8859
9
9
  github_agent/kg_ingest.py,sha256=iH_NKpd8a6GtNxfZTp8Oah8VZkcXjI74KDf8P9NbtjA,17978
10
10
  github_agent/mcp_config.json,sha256=2OOXrwO1sDLyHQqpZwhvDHizPIe3by6YmK4KFE333gI,23
11
- github_agent/mcp_server.py,sha256=ChllOlIhkx8PzIJxtDwtDGzH2F6ybRTr0B5YuJmAgbg,126620
11
+ github_agent/mcp_server.py,sha256=JwpJy_1QH_3kEjqfWAI3mv4mrBpl00b6xW4m2GNgYz4,126620
12
12
  github_agent/api/__init__.py,sha256=ntaEPqk-dsAV3HyyDLc2hYpc9nTTyG5CKI-SVDDjc24,27
13
13
  github_agent/api/api_client_base.py,sha256=tMXKrZIXg6aQ6OK4kNKBDcNc8BrM0Vml_66SwA5ZgEw,7485
14
14
  github_agent/api/api_client_branches.py,sha256=bCmqGUWQ27GFTGxcFkQ7D-ZEltKp6APVsk_Fw9wzdjY,3940
@@ -92,7 +92,7 @@ github_agent/skills/github-triage-resolver/WORKFLOW.md,sha256=orvcRmaV-qb_JKoGSw
92
92
  github_agent/skills/github-triage-resolver/references/resolution-rules.md,sha256=lGPvfLCSHpNIeh2rKWcH2k_2lla3ovgBxzwvtMmyQ-0,4133
93
93
  github_agent/skills/github-triage-resolver/scripts/classify_safe.py,sha256=8BhcDF9Q8rjJIEVOmdyO-dO-eHBjW7T-bzaYC16uY5I,9556
94
94
  github_agent/skills/github-triage-resolver/scripts/gh_write.py,sha256=SL5oA1A3lFRLepNri4CzEcuEsg9D5WKJ1000fCRKBEM,4125
95
- github_agent-2.4.3.dist-info/licenses/LICENSE,sha256=5ALbh4fIALWVsUhO7q1nFT1bQb-CL9sWKf7p3GgLEG8,1070
95
+ github_agent-2.4.5.dist-info/licenses/LICENSE,sha256=5ALbh4fIALWVsUhO7q1nFT1bQb-CL9sWKf7p3GgLEG8,1070
96
96
  scripts/security_sanitizer.py,sha256=gE65xtYMGx43oYUnK0kozBm73Hx97mCdrQUM7GGzIbk,9449
97
97
  scripts/verify_api_integration.py,sha256=3AK8HKW52o1yxCDaEUtXngnh7CjYw6NiG9Eb3EIoXNE,10256
98
98
  tests/conftest.py,sha256=kgpOLUp_q8IZaI6Xd7F1tbFuio81-_l5Gd4jaGiMrnY,3636
@@ -101,10 +101,11 @@ tests/test_api_client_endpoints.py,sha256=Hbw0vssQU5Up-KvJmUDLDCP4t2u8pU-xPfWAhF
101
101
  tests/test_api_validation.py,sha256=CRZq7kfc1U8CLZJRTGusBhTN2Tlfc1FIeDqIm895XoI,3301
102
102
  tests/test_auth_client_edge_cases.py,sha256=QjQAtjd7vDDsSSvIZuUXbd9Z58te8Xp9giPFmwJTBsA,6470
103
103
  tests/test_comment_crud.py,sha256=mHA0scds_0W0oND-VI0QMvNaYarYkHjiXd4H9-9d5kE,27341
104
+ tests/test_default_content_surfaces.py,sha256=UQdDIHHd-X4lvsj2ti2QnNwtsQAayL7b003dQ8UXqMo,1403
104
105
  tests/test_fleet_name.py,sha256=qCLzYTPuiaS3y0I0NLuMRloXlf_o0sue0aVH-Sn-tYQ,1893
105
106
  tests/test_github_agent_api_brute_force_coverage.py,sha256=5jWW6oVU7cmXL2sS3OZ-3gbYGhyjlYPIWqH2rsdF2fw,7347
106
107
  tests/test_github_agent_brute_force_coverage.py,sha256=Z_voXtChOYRqaNEmNzMfzvwQMj2xFBn1m8mXx5ubUe8,4849
107
- tests/test_github_gql.py,sha256=mpn814s9UhN4jnlp1TB8XE3OZ04adR9nhfPM9j0Gpyc,1892
108
+ tests/test_github_gql.py,sha256=M55X5V2orZ1kVek16s1zaMJIUb6FhlfbC8k0cKkD07Y,2709
108
109
  tests/test_github_http.py,sha256=uuSMrot71Kj8WQf-QyazO4rWzpWSucRTQ1tt5wRvC_E,9563
109
110
  tests/test_hardening.py,sha256=sdlKmtk7B5yncc-r1LuFgoJfro6wNlCqY0xI73IVC4M,3710
110
111
  tests/test_init_dynamics.py,sha256=fPE_4M-bONKiqvtWLn12A0q18CUlzQhdx1UoXYkbbPk,1839
@@ -123,8 +124,8 @@ tests/test_skill_org_remediation_classify_fix_risk.py,sha256=0Y8289lhxtJ3pxYUHzO
123
124
  tests/test_skill_pr_review_sweep_summarize_prs.py,sha256=NrNaucQvM7K-k1WBcOBKtTGjxJbW16VgTHbC7dSsjm4,3821
124
125
  tests/test_skill_triage_resolver_classify_safe.py,sha256=B-aDeVmsKTsxYO8TwMEx-cmpVSmZdlKXw5993Da2ubc,9489
125
126
  tests/test_startup.py,sha256=Ix_g69k0tsZbY0-Vkeh8ADWojUdbYwTwwmnM4_hVuCc,1245
126
- github_agent-2.4.3.dist-info/METADATA,sha256=p61ZwVHzoGYvHKxzHWA7ulhSIKJhb9w1ofIF_LneNBU,34536
127
- github_agent-2.4.3.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
128
- github_agent-2.4.3.dist-info/entry_points.txt,sha256=Wi6GhziOqmJl-22qTYkjfVuIHEHKRrBvyyloc7NqV80,367
129
- github_agent-2.4.3.dist-info/top_level.txt,sha256=53Ecr8n7o_EMIqZClc11PBU07uQIggYZOk5WnvBbeOQ,50
130
- github_agent-2.4.3.dist-info/RECORD,,
127
+ github_agent-2.4.5.dist-info/METADATA,sha256=Z-n6EslHieTPYOaM7agThz-EQd0j6KS8AkR0St59tpI,34508
128
+ github_agent-2.4.5.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
129
+ github_agent-2.4.5.dist-info/entry_points.txt,sha256=Wi6GhziOqmJl-22qTYkjfVuIHEHKRrBvyyloc7NqV80,367
130
+ github_agent-2.4.5.dist-info/top_level.txt,sha256=53Ecr8n7o_EMIqZClc11PBU07uQIggYZOk5WnvBbeOQ,50
131
+ github_agent-2.4.5.dist-info/RECORD,,
@@ -0,0 +1,43 @@
1
+ """CONN-GITHUB-AGENT-CONNECTOR-CONTENT-R001: the server lists its packaged skills, ontology and prompts by default."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import asyncio
6
+ import importlib
7
+ from pathlib import Path
8
+
9
+ import pytest
10
+ from fastmcp import Client
11
+
12
+ PACKAGE = "github_agent"
13
+ ROOT = Path(list(importlib.import_module(PACKAGE).__path__)[0])
14
+
15
+ pytestmark = pytest.mark.spec("CONN-GITHUB-AGENT-CONNECTOR-CONTENT-R001")
16
+
17
+
18
+ def _server():
19
+ namespace = {"__name__": PACKAGE + ".mcp_server"}
20
+ exec(
21
+ "from agent_connector_sdk.mcp.server import create_mcp_server\n"
22
+ "result = create_mcp_server('github-mcp', version='0', command_args=[])",
23
+ namespace,
24
+ )
25
+ return namespace["result"][1]
26
+
27
+
28
+ async def _listings():
29
+ async with Client(_server()) as client:
30
+ resources = {str(r.uri) for r in await client.list_resources()}
31
+ prompts = {p.name for p in await client.list_prompts()}
32
+ return resources, prompts
33
+
34
+
35
+ def test_default_content_surfaces() -> None:
36
+ resources, prompts = asyncio.run(_listings())
37
+ if list(ROOT.glob("skills/*/SKILL.md")):
38
+ assert any(u.startswith("skill://") for u in resources)
39
+ if list(ROOT.glob("ontology/*.ttl")):
40
+ assert any(u.startswith("ontology://github-mcp/") for u in resources)
41
+ for path in ROOT.glob("prompts/*.json"):
42
+ if not path.name.startswith("_"):
43
+ assert path.stem in prompts
tests/test_github_gql.py CHANGED
@@ -37,19 +37,37 @@ def test_construction_sets_bearer_header():
37
37
 
38
38
 
39
39
  def test_close_without_session_does_not_raise():
40
- """Regression guard: under gql 4.0, Client.close_sync() unconditionally
41
- asserts ``self.session`` — an attribute only ever set by connect_sync()
42
- (called implicitly the first time a query executes). A GraphQL client
43
- that was constructed but never used to run a query has no such session
44
- yet, so close() must be a safe no-op rather than raising AttributeError.
45
- """
46
- g = GraphQL(url="https://api.github.com", token="tok123")
47
- g.close()
40
+ """close() on a never-used client is a safe no-op."""
41
+ GraphQL(url="https://api.github.com", token="tok123").close()
42
+
43
+
44
+ @pytest.mark.spec("CONN-GITHUB-AGENT-CONNECTOR-IDENTITY-R002")
45
+ def test_wrapper_delegates_to_shared_graphql_client():
46
+ from unittest.mock import patch
47
+
48
+ from agent_connector_sdk.tls.resolve import resolve_tls_profile
49
+ from agent_connector_sdk.transports.graphql import GraphQLClient
50
+
51
+ profile = resolve_tls_profile("github")
52
+ g = GraphQL(url="https://github.example/api/v3", token="tok123", tls_profile=profile)
53
+ assert isinstance(g._gql, GraphQLClient)
54
+ assert g._gql.endpoint == "https://github.example/api/graphql"
55
+ assert g._gql.headers["Authorization"] == "Bearer tok123"
56
+ assert g._gql.tls_profile is profile
57
+ with patch.object(GraphQLClient, "execute", return_value={"viewer": {}}) as ex:
58
+ assert g.execute_gql("query { viewer { login } }", {"a": 1}, "Op") == {
59
+ "viewer": {}
60
+ }
61
+ ex.assert_called_once_with("query { viewer { login } }", {"a": 1}, "Op")
62
+
63
+
64
+ def test_execute_failure_message_is_redacted_class_name():
65
+ from unittest.mock import patch
48
66
 
67
+ from agent_connector_sdk.exceptions import ParameterError
68
+ from agent_connector_sdk.transports.graphql import GraphQLClient
49
69
 
50
- def test_close_after_session_opened_closes_cleanly():
51
- """Once a sync session has actually been opened, close() still closes it."""
52
70
  g = GraphQL(url="https://api.github.com", token="tok123")
53
- g.client.connect_sync()
54
- assert hasattr(g.client, "session")
55
- g.close()
71
+ with patch.object(GraphQLClient, "_attempt", side_effect=ValueError("boom")):
72
+ with pytest.raises(ParameterError, match="Query execution failed: ValueError"):
73
+ g.execute_gql("query { viewer { login } }")