Phind.py 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. from __future__ import annotations
  2. from datetime import datetime
  3. from ..typing import AsyncResult, Messages
  4. from .base_provider import AsyncGeneratorProvider
  5. from ..requests import StreamSession
  6. class Phind(AsyncGeneratorProvider):
  7. url = "https://www.phind.com"
  8. working = True
  9. supports_gpt_4 = True
  10. supports_stream = True
  11. supports_message_history = True
  12. @classmethod
  13. async def create_async_generator(
  14. cls,
  15. model: str,
  16. messages: Messages,
  17. proxy: str = None,
  18. timeout: int = 120,
  19. creative_mode: bool = False,
  20. **kwargs
  21. ) -> AsyncResult:
  22. headers = {
  23. "Accept": "*/*",
  24. "Origin": cls.url,
  25. "Referer": f"{cls.url}/search",
  26. "Sec-Fetch-Dest": "empty",
  27. "Sec-Fetch-Mode": "cors",
  28. "Sec-Fetch-Site": "same-origin",
  29. }
  30. async with StreamSession(
  31. impersonate="chrome110",
  32. proxies={"https": proxy},
  33. timeout=timeout
  34. ) as session:
  35. prompt = messages[-1]["content"]
  36. data = {
  37. "question": prompt,
  38. "questionHistory": [
  39. message["content"] for message in messages[:-1] if message["role"] == "user"
  40. ],
  41. "answerHistory": [
  42. message["content"] for message in messages if message["role"] == "assistant"
  43. ],
  44. "webResults": [],
  45. "options": {
  46. "date": datetime.now().strftime("%d.%m.%Y"),
  47. "language": "en-US",
  48. "detailed": True,
  49. "anonUserId": "",
  50. "answerModel": "GPT-4" if model.startswith("gpt-4") else "Phind Model",
  51. "creativeMode": creative_mode,
  52. "customLinks": []
  53. },
  54. "context": "",
  55. "rewrittenQuestion": prompt,
  56. "challenge": 0.21132115912208504
  57. }
  58. async with session.post(f"{cls.url}/api/infer/followup/answer", headers=headers, json=data) as response:
  59. new_line = False
  60. async for line in response.iter_lines():
  61. if line.startswith(b"data: "):
  62. chunk = line[6:]
  63. if chunk.startswith(b"<PHIND_METADATA>") or chunk.startswith(b"<PHIND_INDICATOR>"):
  64. pass
  65. elif chunk:
  66. yield chunk.decode()
  67. elif new_line:
  68. yield "\n"
  69. new_line = False
  70. else:
  71. new_line = True