Phind.py 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  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. }
  57. async with session.post(f"{cls.url}/api/infer/followup/answer", headers=headers, json=data) as response:
  58. new_line = False
  59. async for line in response.iter_lines():
  60. if line.startswith(b"data: "):
  61. chunk = line[6:]
  62. if chunk.startswith(b"<PHIND_METADATA>"):
  63. pass
  64. elif chunk:
  65. yield chunk.decode()
  66. elif new_line:
  67. yield "\n"
  68. new_line = False
  69. else:
  70. new_line = True