Files
ALwrity/lib/gpt_providers/text_generation/deepseek_text_gen.py

140 lines
4.7 KiB
Python

import os
import time
import logging
from tenacity import (
retry,
stop_after_attempt,
wait_random_exponential,
)
import openai
import asyncio
# Configure standard logging
logging.basicConfig(level=logging.INFO, format='[%(asctime)s-%(levelname)s-%(module)s-%(lineno)d]- %(message)s')
logger = logging.getLogger(__name__)
@retry(wait=wait_random_exponential(min=1, max=60), stop=stop_after_attempt(6))
def deepseek_text_response(prompt, model, temperature, max_tokens, top_p, n, system_prompt):
"""
Wrapper function for DeepSeek's text generation.
Args:
prompt (str): The input text to generate completion for.
model (str, optional): Model to be used for the completion. Defaults to "deepseek-chat".
temperature (float, optional): Controls randomness. Lower values make responses more deterministic. Defaults to 0.2.
max_tokens (int, optional): Maximum number of tokens to generate. Defaults to 4096.
top_p (float, optional): Controls diversity. Defaults to 0.9.
n (int, optional): Number of completions to generate. Defaults to 1.
Returns:
str: The generated text completion.
Raises:
SystemExit: If an API error, connection error, or rate limit error occurs.
"""
# Wait for 10 seconds to comply with rate limits
for _ in range(10):
time.sleep(1)
try:
client = DeepSeek(api_key=os.getenv('DEEPSEEK_API_KEY'), base_url="https://api.deepseek.com")
response = client.reasoning.create(
model=model,
context=system_prompt,
query=prompt,
max_tokens=max_tokens,
n=n,
top_p=top_p,
stream=True,
temperature=temperature
)
# Create variables to collect the stream of chunks
collected_chunks = []
collected_messages = []
full_reply_content = None
# Iterate through the stream of events
for chunk in response:
collected_chunks.append(chunk) # save the event response
chunk_message = chunk.result # extract the message
collected_messages.append(chunk_message) # save the message
print(chunk.result, end="", flush=True)
# Clean None in collected_messages
collected_messages = [m for m in collected_messages if m is not None]
full_reply_content = ''.join([m for m in collected_messages])
return full_reply_content
except Exception as err:
logger.error(f"DeepSeek error: {err}")
raise SystemExit from err
async def test_deepseek_api_key(api_key: str) -> tuple[bool, str]:
"""
Test if the provided DeepSeek API key is valid.
Args:
api_key (str): The DeepSeek API key to test
Returns:
tuple[bool, str]: A tuple containing (is_valid, message)
"""
try:
# Create OpenAI client with DeepSeek base URL
client = openai.OpenAI(
api_key=api_key,
base_url="https://api.deepseek.com/v1"
)
# Try to list models as a simple API test
models = client.models.list()
# If we get here, the key is valid
return True, "DeepSeek API key is valid"
except openai.AuthenticationError:
return False, "Invalid DeepSeek API key"
except openai.RateLimitError:
return False, "Rate limit exceeded. Please try again later."
except Exception as e:
return False, f"Error testing DeepSeek API key: {str(e)}"
def deepseek_text_gen(prompt, model="deepseek-chat", temperature=0.7, max_tokens=2048):
"""
Generate text using DeepSeek's API.
Args:
prompt (str): The input text to generate completion for
model (str, optional): Model to use. Defaults to "deepseek-chat"
temperature (float, optional): Controls randomness. Defaults to 0.7
max_tokens (int, optional): Maximum number of tokens to generate. Defaults to 2048
Returns:
str: The generated text completion
"""
try:
# Create OpenAI client with DeepSeek base URL
client = openai.OpenAI(
api_key=os.getenv('DEEPSEEK_API_KEY'),
base_url="https://api.deepseek.com/v1"
)
# Generate chat completion
response = client.chat.completions.create(
model=model,
messages=[{
"role": "user",
"content": prompt
}],
temperature=temperature,
max_tokens=max_tokens
)
# Return the generated text
return response.choices[0].message.content
except Exception as e:
logger.error(f"Error in DeepSeek text generation: {e}")
return str(e)