Skip to content

Commit

Permalink
Merge pull request #2456 from hlohaus/neww
Browse files Browse the repository at this point in the history
Add cookies to HuggingChat provider
  • Loading branch information
hlohaus authored Dec 5, 2024
2 parents b198d90 + e2c269c commit 636807d
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 153 deletions.
240 changes: 122 additions & 118 deletions g4f/Provider/needs_auth/HuggingChat.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
from __future__ import annotations

import json
import requests

try:
from curl_cffi.requests import Session
from curl_cffi.requests import Session, CurlMime
has_curl_cffi = True
except ImportError:
has_curl_cffi = False
from ...typing import CreateResult, Messages

from ...typing import CreateResult, Messages, Cookies
from ...errors import MissingRequirementsError
from ...requests.raise_for_status import raise_for_status
from ...cookies import get_cookies
from ..base_provider import ProviderModelMixin, AbstractProvider
from ..helper import format_prompt

Expand Down Expand Up @@ -53,127 +54,130 @@ def create_completion(
model: str,
messages: Messages,
stream: bool,
web_search: bool = False,
cookies: Cookies = None,
**kwargs
) -> CreateResult:
if not has_curl_cffi:
raise MissingRequirementsError('Install "curl_cffi" package | pip install -U curl_cffi')
model = cls.get_model(model)
if cookies is None:
cookies = get_cookies("huggingface.co")

session = Session(cookies=cookies)
session.headers = {
'accept': '*/*',
'accept-language': 'en',
'cache-control': 'no-cache',
'origin': 'https://huggingface.co',
'pragma': 'no-cache',
'priority': 'u=1, i',
'referer': 'https://huggingface.co/chat/',
'sec-ch-ua': '"Not)A;Brand";v="99", "Google Chrome";v="127", "Chromium";v="127"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"macOS"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-origin',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36',
}
json_data = {
'model': model,
}
response = session.post('https://huggingface.co/chat/conversation', json=json_data)
raise_for_status(response)

conversationId = response.json().get('conversationId')

if model in cls.models:
session = Session()
session.headers = {
'accept': '*/*',
'accept-language': 'en',
'cache-control': 'no-cache',
'origin': 'https://huggingface.co',
'pragma': 'no-cache',
'priority': 'u=1, i',
'referer': 'https://huggingface.co/chat/',
'sec-ch-ua': '"Not)A;Brand";v="99", "Google Chrome";v="127", "Chromium";v="127"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"macOS"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-origin',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36',
}
json_data = {
'model': model,
}
response = session.post('https://huggingface.co/chat/conversation', json=json_data)
raise_for_status(response)

conversationId = response.json().get('conversationId')

# Get the data response and parse it properly
response = session.get(f'https://huggingface.co/chat/conversation/{conversationId}/__data.json?x-sveltekit-invalidated=11')
raise_for_status(response)

# Split the response content by newlines and parse each line as JSON
# Get the data response and parse it properly
response = session.get(f'https://huggingface.co/chat/conversation/{conversationId}/__data.json?x-sveltekit-invalidated=11')
raise_for_status(response)

# Split the response content by newlines and parse each line as JSON
try:
json_data = None
for line in response.text.split('\n'):
if line.strip():
try:
parsed = json.loads(line)
if isinstance(parsed, dict) and "nodes" in parsed:
json_data = parsed
break
except json.JSONDecodeError:
continue

if not json_data:
raise RuntimeError("Failed to parse response data")

data: list = json_data["nodes"][1]["data"]
keys: list[int] = data[data[0]["messages"]]
message_keys: dict = data[keys[0]]
messageId: str = data[message_keys["id"]]

except (KeyError, IndexError, TypeError) as e:
raise RuntimeError(f"Failed to extract message ID: {str(e)}")

settings = {
"inputs": format_prompt(messages),
"id": messageId,
"is_retry": False,
"is_continue": False,
"web_search": web_search,
"tools": []
}

headers = {
'accept': '*/*',
'accept-language': 'en',
'cache-control': 'no-cache',
'origin': 'https://huggingface.co',
'pragma': 'no-cache',
'priority': 'u=1, i',
'referer': f'https://huggingface.co/chat/conversation/{conversationId}',
'sec-ch-ua': '"Not)A;Brand";v="99", "Google Chrome";v="127", "Chromium";v="127"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"macOS"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-origin',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36',
}

data = CurlMime()
data.addpart('data', data=json.dumps(settings, separators=(',', ':')))

response = session.post(
f'https://huggingface.co/chat/conversation/{conversationId}',
cookies=session.cookies,
headers=headers,
multipart=data,
stream=True
)
raise_for_status(response)

full_response = ""
for line in response.iter_lines():
if not line:
continue
try:
json_data = None
for line in response.text.split('\n'):
if line.strip():
try:
parsed = json.loads(line)
if isinstance(parsed, dict) and "nodes" in parsed:
json_data = parsed
break
except json.JSONDecodeError:
continue

if not json_data:
raise RuntimeError("Failed to parse response data")

data: list = json_data["nodes"][1]["data"]
keys: list[int] = data[data[0]["messages"]]
message_keys: dict = data[keys[0]]
messageId: str = data[message_keys["id"]]

except (KeyError, IndexError, TypeError) as e:
raise RuntimeError(f"Failed to extract message ID: {str(e)}")

settings = {
"inputs": format_prompt(messages),
"id": messageId,
"is_retry": False,
"is_continue": False,
"web_search": False,
"tools": []
}

headers = {
'accept': '*/*',
'accept-language': 'en',
'cache-control': 'no-cache',
'origin': 'https://huggingface.co',
'pragma': 'no-cache',
'priority': 'u=1, i',
'referer': f'https://huggingface.co/chat/conversation/{conversationId}',
'sec-ch-ua': '"Not)A;Brand";v="99", "Google Chrome";v="127", "Chromium";v="127"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"macOS"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-origin',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36',
}

files = {
'data': (None, json.dumps(settings, separators=(',', ':'))),
}

response = requests.post(
f'https://huggingface.co/chat/conversation/{conversationId}',
cookies=session.cookies,
headers=headers,
files=files,
)
raise_for_status(response)

full_response = ""
for line in response.iter_lines():
if not line:
continue
try:
line = json.loads(line)
except json.JSONDecodeError as e:
print(f"Failed to decode JSON: {line}, error: {e}")
continue

if "type" not in line:
raise RuntimeError(f"Response: {line}")

elif line["type"] == "stream":
token = line["token"].replace('\u0000', '')
full_response += token
if stream:
yield token

elif line["type"] == "finalAnswer":
break
line = json.loads(line)
except json.JSONDecodeError as e:
print(f"Failed to decode JSON: {line}, error: {e}")
continue

full_response = full_response.replace('<|im_end|', '').replace('\u0000', '').strip()
if "type" not in line:
raise RuntimeError(f"Response: {line}")

elif line["type"] == "stream":
token = line["token"].replace('\u0000', '')
full_response += token
if stream:
yield token

elif line["type"] == "finalAnswer":
break

full_response = full_response.replace('<|im_end|', '').replace('\u0000', '').strip()

if not stream:
yield full_response
if not stream:
yield full_response
12 changes: 5 additions & 7 deletions g4f/gui/client/static/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ body {
height: 100vh;
}

a:-webkit-any-link {
color: var(--accent);
}

.row {
display: flex;
gap: 10px;
Expand Down Expand Up @@ -124,7 +128,7 @@ body {

.new_version a {
color: var(--colour-4);
text-decoration: underline dotted;
text-decoration: underline;
}

.conversations {
Expand Down Expand Up @@ -975,11 +979,6 @@ ul {
display: flex;
}


a:-webkit-any-link {
color: var(--accent);
}

.conversation .user-input textarea {
font-size: 15px;
width: 100%;
Expand Down Expand Up @@ -1021,7 +1020,6 @@ a:-webkit-any-link {
background-image: url('data:image/svg+xml;utf-8,<svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M6 5C5.73478 5 5.48043 5.10536 5.29289 5.29289C5.10536 5.48043 5 5.73478 5 6V20C5 20.2652 5.10536 20.5196 5.29289 20.7071C5.48043 20.8946 5.73478 21 6 21H18C18.2652 21 18.5196 20.8946 18.7071 20.7071C18.8946 20.5196 19 20.2652 19 20V6C19 5.73478 18.8946 5.48043 18.7071 5.29289C18.5196 5.10536 18.2652 5 18 5H16C15.4477 5 15 4.55228 15 4C15 3.44772 15.4477 3 16 3H18C18.7956 3 19.5587 3.31607 20.1213 3.87868C20.6839 4.44129 21 5.20435 21 6V20C21 20.7957 20.6839 21.5587 20.1213 22.1213C19.5587 22.6839 18.7957 23 18 23H6C5.20435 23 4.44129 22.6839 3.87868 22.1213C3.31607 21.5587 3 20.7957 3 20V6C3 5.20435 3.31607 4.44129 3.87868 3.87868C4.44129 3.31607 5.20435 3 6 3H8C8.55228 3 9 3.44772 9 4C9 4.55228 8.55228 5 8 5H6Z" fill="white"/><path fill-rule="evenodd" clip-rule="evenodd" d="M7 3C7 1.89543 7.89543 1 9 1H15C16.1046 1 17 1.89543 17 3V5C17 6.10457 16.1046 7 15 7H9C7.89543 7 7 6.10457 7 5V3ZM15 3H9V5H15V3Z" fill="white"/></svg>');
background-repeat: no-repeat;
background-position: center;
transition: background-color 200ms ease, transform 200ms ease-out
}

.hljs-copy-button:hover {
Expand Down
30 changes: 2 additions & 28 deletions g4f/gui/client/static/js/chat.v1.js
Original file line number Diff line number Diff line change
Expand Up @@ -1065,6 +1065,7 @@ async function hide_sidebar() {
sidebar_button.classList.remove("rotated");
settings.classList.add("hidden");
chat.classList.remove("hidden");
log_storage.classList.add("hidden");
if (window.location.pathname == "/menu/" || window.location.pathname == "/settings/") {
history.back();
}
Expand Down Expand Up @@ -1182,31 +1183,6 @@ const say_hello = async () => {
}
}

// Theme storage for recurring viewers
const storeTheme = function (theme) {
appStorage.setItem("theme", theme);
};

// set theme when visitor returns
const setTheme = function () {
const activeTheme = appStorage.getItem("theme");
colorThemes.forEach((themeOption) => {
if (themeOption.id === activeTheme) {
themeOption.checked = true;
}
});
// fallback for no :has() support
document.documentElement.className = activeTheme;
};

colorThemes.forEach((themeOption) => {
themeOption.addEventListener("click", () => {
storeTheme(themeOption.id);
// fallback for no :has() support
document.documentElement.className = themeOption.id;
});
});

function count_tokens(model, text) {
if (model) {
if (window.llamaTokenizer)
Expand Down Expand Up @@ -1273,7 +1249,6 @@ window.addEventListener('pywebviewready', async function() {
});

async function on_load() {
setTheme();
count_input();

if (/\/chat\/.+/.test(window.location.href)) {
Expand All @@ -1290,8 +1265,7 @@ async function on_api() {
if (prompt_lock) return;

// If not mobile
if (!window.matchMedia("(pointer:coarse)").matches)
if (evt.keyCode === 13 && !evt.shiftKey) {
if (!window.matchMedia("(pointer:coarse)").matches && evt.keyCode === 13 && !evt.shiftKey) {
evt.preventDefault();
console.log("pressed enter");
prompt_lock = true;
Expand Down

0 comments on commit 636807d

Please sign in to comment.