summaryrefslogtreecommitdiffstats
path: root/g4f/Provider
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--g4f/Provider/Phind.py50
1 files changed, 48 insertions, 2 deletions
diff --git a/g4f/Provider/Phind.py b/g4f/Provider/Phind.py
index e7156842..a7fdbeca 100644
--- a/g4f/Provider/Phind.py
+++ b/g4f/Provider/Phind.py
@@ -1,5 +1,6 @@
from __future__ import annotations
+from urllib import parse
from datetime import datetime
from ..typing import AsyncResult, Messages
@@ -55,9 +56,9 @@ class Phind(AsyncGeneratorProvider):
"customLinks": []
},
"context": "\n".join([message["content"] for message in messages if message["role"] == "system"]),
- "rewrittenQuestion": prompt,
- "challenge": 0.21132115912208504
}
+ data["challenge"] = generate_challenge(data)
+
async with session.post(f"https://https.api.phind.com/infer/", headers=headers, json=data) as response:
new_line = False
async for line in response.iter_lines():
@@ -65,6 +66,8 @@ class Phind(AsyncGeneratorProvider):
chunk = line[6:]
if chunk.startswith(b'<PHIND_DONE/>'):
break
+ if chunk.startswith(b'<PHIND_BACKEND_ERROR>'):
+ raise RuntimeError(f"Response: {chunk}")
if chunk.startswith(b'<PHIND_WEBRESULTS>') or chunk.startswith(b'<PHIND_FOLLOWUP>'):
pass
elif chunk.startswith(b"<PHIND_METADATA>") or chunk.startswith(b"<PHIND_INDICATOR>"):
@@ -78,3 +81,46 @@ class Phind(AsyncGeneratorProvider):
new_line = False
else:
new_line = True
+
+def deterministic_stringify(obj):
+ def handle_value(value):
+ if isinstance(value, (dict, list)):
+ if isinstance(value, list):
+ return '[' + ','.join(sorted(map(handle_value, value))) + ']'
+ else: # It's a dict
+ return '{' + deterministic_stringify(value) + '}'
+ elif isinstance(value, bool):
+ return 'true' if value else 'false'
+ elif isinstance(value, (int, float)):
+ return format(value, '.8f').rstrip('0').rstrip('.')
+ elif isinstance(value, str):
+ return f'"{value}"'
+ else:
+ return 'null'
+
+ items = sorted(obj.items(), key=lambda x: x[0])
+ return ','.join([f'{k}:{handle_value(v)}' for k, v in items if handle_value(v) is not None])
+
+def simple_hash(s):
+ d = 0
+ for char in s:
+ if len(char) > 1 or ord(char) >= 256:
+ continue
+ d = ((d << 5) - d + ord(char[0])) & 0xFFFFFFFF
+ if d > 0x7FFFFFFF: # 2147483647
+ d -= 0x100000000 # Subtract 2**32
+ return d
+
+def generate_challenge(obj):
+ deterministic_str = deterministic_stringify(obj)
+ encoded_str = parse.quote(deterministic_str, safe='')
+
+ c = simple_hash(encoded_str)
+ a = (9301 * c + 49297)
+ b = 233280
+
+ # If negativ, we need a special logic
+ if a < 0:
+ return ((a%b)-b)/b
+ else:
+ return a%b/b \ No newline at end of file