项目文件夹

文件
Gelei Deng 6a767aae02 Model support (#274)
* feat: 🎸 add new models

* minor readme update

* style: format code with Black

This commit fixes the style issues introduced in dafa18b according to the output
from Black.

Details: https://github.com/GreyDGL/PentestGPT/pull/274

---------

Co-authored-by: deepsource-autofix[bot] <62050782+deepsource-autofix[bot]@users.noreply.github.com>
2025-05-01 18:02:42 +08:00

99 行
3.5 KiB
Python

import asyncio
import json
import aiohttp
import tiktoken
from loguru import logger
from app.config import PERPLEXITY_API_KEY
from llm_generation.config import DEEPSEEK_MAX_TOKEN_LENGTH
from llm_generation.models.base import BaseModel
from llm_generation.models.data_structure import StreamingDelta
class Perplexity(BaseModel):
def __init__(self, model_name: str = "sonar-reasoning-pro"):
super().__init__(model_name)
async def generate_response(
self, user_prompt: str, conversation: list = None, **kwargs
) -> str:
# Truncate the user prompt to MAX_TOKEN_LENGTH tokens, use tiktoken for deepseek temporarily
tokenizer = tiktoken.encoding_for_model("gpt-4o")
user_prompt_tokens = tokenizer.encode(user_prompt)
if len(user_prompt_tokens) > DEEPSEEK_MAX_TOKEN_LENGTH:
user_prompt = tokenizer.decode(
user_prompt_tokens[:DEEPSEEK_MAX_TOKEN_LENGTH]
)
conversation = conversation or []
headers = {
"Authorization": f"Bearer {PERPLEXITY_API_KEY}",
"Content-Type": "application/json",
}
payload = {
"model": self.model_name,
"messages": conversation + [{"role": "user", "content": user_prompt}],
"search_recency_filter": "day",
**kwargs,
}
async with aiohttp.ClientSession() as session:
async with session.post(
"https://api.perplexity.ai/chat/completions",
headers=headers,
json=payload,
) as response:
if "stream" in kwargs:
content = ""
if self.streaming_callback is None:
logger.warning(
"No streaming callback is set, skipping callback function"
)
async for line in response.content:
if not line:
continue
line = line.decode("utf-8").strip()
if not line or not line.startswith("data: "):
continue
data = line[6:] # Remove 'data: ' prefix
if data == "[DONE]":
break
try:
chunk = json.loads(data)
if not chunk["choices"]:
continue
delta_dict = chunk["choices"][0]["delta"]
delta = StreamingDelta(**delta_dict)
# Call the streaming callback function
if self.streaming_callback:
if asyncio.iscoroutinefunction(self.streaming_callback):
await self.streaming_callback(content, delta)
else:
self.streaming_callback(content, delta)
# Append the content
if delta.content:
content += delta.content
except json.JSONDecodeError:
continue
return content
else:
response_data = await response.json()
return response_data["choices"][0]["message"]["content"]
async def main():
pass
if __name__ == "__main__":
asyncio.run(main())