Files
arc53-machine 7b516ade82 Add a built-in GitHub connector for repository sync and read-only tools
One GitHub connection feeds both a Knowledge source and an agent tool.
Users connect with a personal access token, checked against GitHub and
named after the account, or, when an admin registers a GitHub App
(GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET, GITHUB_APP_SLUG), with Sign in
with GitHub. App tokens expire after eight hours and are refreshed before
each sync or tool call; tokens with no expiry are never treated as expired.

The catalog gains an optional second sign-in method (oauth_settings,
exposed as sign_in_methods) without changing any other connector.

Sync lists the repositories the connection can read (the token's own, or
the App installations') and ingests one with the connection's token. The
tool is GitHub's read-only MCP server (api.githubcopilot.com/mcp/readonly):
setup discovers its actions and creates it bound to the connection, and
the executor sends the connection's token only to that server.
2026-09-29 10:41:03 +01:00

111 lines
3.6 KiB
Python

from docsgpt.parser.connectors.confluence.auth import ConfluenceAuth
from docsgpt.parser.connectors.confluence.loader import ConfluenceLoader
from docsgpt.parser.connectors.github.auth import GitHubAuth
from docsgpt.parser.connectors.google_drive.auth import GoogleDriveAuth
from docsgpt.parser.connectors.google_drive.loader import GoogleDriveLoader
from docsgpt.parser.connectors.share_point.auth import SharePointAuth
from docsgpt.parser.connectors.share_point.loader import SharePointLoader
class ConnectorCreator:
"""
Factory class for creating external knowledge base connectors and auth providers.
These are different from remote loaders as they typically require
authentication and connect to external document storage systems.
"""
connectors = {
"confluence": ConfluenceLoader,
"google_drive": GoogleDriveLoader,
"share_point": SharePointLoader,
}
# GitHub signs in here too, but its repositories are read by the remote
# GitHub loader, so it has an auth provider and no connector class.
auth_providers = {
"confluence": ConfluenceAuth,
"github": GitHubAuth,
"google_drive": GoogleDriveAuth,
"share_point": SharePointAuth,
}
@classmethod
def create_connector(cls, connector_type, *args, **kwargs):
"""
Create a connector instance for the specified type.
Args:
connector_type: Type of connector to create (e.g., 'google_drive')
*args, **kwargs: Arguments to pass to the connector constructor
Returns:
Connector instance
Raises:
ValueError: If connector type is not supported
"""
connector_class = cls.connectors.get(connector_type.lower())
if not connector_class:
raise ValueError(f"No connector class found for type {connector_type}")
return connector_class(*args, **kwargs)
@classmethod
def create_auth(cls, connector_type):
"""
Create an auth provider instance for the specified connector type.
Args:
connector_type: Type of connector auth to create (e.g., 'google_drive')
Returns:
Auth provider instance
Raises:
ValueError: If connector type is not supported for auth
"""
auth_class = cls.auth_providers.get(connector_type.lower())
if not auth_class:
raise ValueError(f"No auth class found for type {connector_type}")
return auth_class()
@classmethod
def get_supported_connectors(cls):
"""
Get list of supported connector types.
Returns:
List of supported connector type strings
"""
return list(cls.connectors.keys())
@classmethod
def has_auth(cls, connector_type: str) -> bool:
"""Whether ``connector_type`` signs in through the OAuth callback.
Args:
connector_type: Provider key, e.g. ``google_drive`` or ``github``.
Returns:
True when an auth provider is registered for it.
"""
return (connector_type or "").lower() in cls.auth_providers
@classmethod
def get_auth_providers(cls) -> list:
"""Provider keys that sign in through the OAuth callback."""
return list(cls.auth_providers.keys())
@classmethod
def is_supported(cls, connector_type):
"""
Check if a connector type is supported.
Args:
connector_type: Type of connector to check
Returns:
True if supported, False otherwise
"""
return connector_type.lower() in cls.connectors