diff options
Diffstat (limited to '')
-rw-r--r-- | g4f/Provider/needs_auth/GithubCopilot.py | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/g4f/Provider/needs_auth/GithubCopilot.py b/g4f/Provider/needs_auth/GithubCopilot.py new file mode 100644 index 00000000..0c12dfd0 --- /dev/null +++ b/g4f/Provider/needs_auth/GithubCopilot.py @@ -0,0 +1,93 @@ +from __future__ import annotations + +import json + +from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin, BaseConversation +from ...typing import AsyncResult, Messages, Cookies +from ...requests.raise_for_status import raise_for_status +from ...requests import StreamSession +from ...providers.helper import format_prompt +from ...cookies import get_cookies + +class Conversation(BaseConversation): + conversation_id: str + + def __init__(self, conversation_id: str): + self.conversation_id = conversation_id + +class GithubCopilot(AsyncGeneratorProvider, ProviderModelMixin): + url = "https://copilot.microsoft.com" + working = True + needs_auth = True + supports_stream = True + default_model = "gpt-4o" + models = [default_model, "o1-mini", "o1-preview", "claude-3.5-sonnet"] + + @classmethod + async def create_async_generator( + cls, + model: str, + messages: Messages, + stream: bool = False, + api_key: str = "X2eRgXPamxGK_TXS6seGGYy541mQuVJdH1CYljrvSPuc38je5J4KK4Aw0y5X2oVRFMjA4B1fo9sdsr4VJcl-VBae7H0Mr4U9GIkFnGx3hSs=", + proxy: str = None, + cookies: Cookies = None, + conversation_id: str = None, + conversation: Conversation = None, + return_conversation: bool = False, + **kwargs + ) -> AsyncResult: + if not model: + model = cls.default_model + if cookies is None: + cookies = get_cookies(".github.com") + async with StreamSession( + proxy=proxy, + impersonate="chrome", + cookies=cookies, + headers={ + "GitHub-Verified-Fetch": "true", + } + ) as session: + headers = {} + if api_key is None: + async with session.post("https://github.com/github-copilot/chat/token") as response: + await raise_for_status(response, "Get token") + api_key = (await response.json()).get("token") + headers = { + "Authorization": f"GitHub-Bearer {api_key}", + } + if conversation is not None: + conversation_id = conversation.conversation_id + if conversation_id is None: + print(headers) + async with session.post("https://api.individual.githubcopilot.com/github/chat/threads", headers=headers) as response: + await raise_for_status(response) + conversation_id = (await response.json()).get("thread_id") + if return_conversation: + yield Conversation(conversation_id) + content = messages[-1]["content"] + else: + content = format_prompt(messages) + json_data = { + "content": content, + "intent": "conversation", + "references":[], + "context": [], + "currentURL": f"https://github.com/copilot/c/{conversation_id}", + "streaming": True, + "confirmations": [], + "customInstructions": [], + "model": model, + "mode": "immersive" + } + async with session.post( + f"https://api.individual.githubcopilot.com/github/chat/threads/{conversation_id}/messages", + json=json_data, + headers=headers + ) as response: + async for line in response.iter_lines(): + if line.startswith(b"data: "): + data = json.loads(line[6:]) + if data.get("type") == "content": + yield data.get("body")
\ No newline at end of file |