DocUA commited on
Commit
558b73f
·
1 Parent(s): 39e57fa

Improve DeepSeek compatibility (R1/reasoner support) and fix lint errors in main.py

Browse files
Files changed (1) hide show
  1. main.py +52 -31
main.py CHANGED
@@ -4,7 +4,7 @@ import json
4
  import time
5
  import boto3
6
  from pathlib import Path
7
- from typing import Dict, List, Optional, Tuple
8
  from anthropic import Anthropic
9
  import openai
10
  from openai import OpenAI
@@ -244,7 +244,7 @@ class RetrieverEvent(Event):
244
  class LLMAnalyzer:
245
  """Class for handling different LLM providers."""
246
 
247
- def __init__(self, provider: "ModelProvider", model_name: "AnalysisModelName"):
248
  self.provider = provider
249
  self.model_name = model_name
250
 
@@ -323,29 +323,36 @@ class LLMAnalyzer:
323
 
324
  async def _analyze_with_deepseek(self, prompt: str) -> str:
325
  """Analyze text using DeepSeek."""
326
- messages = [
327
- ChatMessage(role="system", content=SYSTEM_PROMPT),
328
- ChatMessage(role="user", content=prompt)
329
- ]
330
-
331
- response_format = {
332
- 'type': 'json_object'
333
- }
 
 
334
 
335
  try:
336
- response = self.client.chat.completions.create(
337
- model=self.model_name,
338
- messages=[{"role": m.role, "content": m.content} for m in messages],
339
- response_format=response_format,
340
- temperature=0
341
- )
 
 
 
 
 
342
  response_text = response.choices[0].message.content
343
 
344
  # Verify and clean JSON
345
  json_data = extract_json_from_text(response_text)
346
  return json.dumps(json_data, ensure_ascii=False) if json_data else response_text
347
  except Exception as e:
348
- raise RuntimeError(f"Error in DeepSeek analysis: {str(e)}")
349
 
350
  async def _analyze_with_anthropic(self, prompt: str, response_schema: dict) -> str:
351
  """Analyze text using Anthropic."""
@@ -451,8 +458,8 @@ class LLMAnalyzer:
451
  class PrecedentAnalysisWorkflow(Workflow):
452
  """Workflow for analyzing legal precedents."""
453
 
454
- def __init__(self, provider: ModelProvider = ModelProvider.OPENAI,
455
- model_name: AnalysisModelName = AnalysisModelName.GPT4o_MINI):
456
  super().__init__()
457
  self.analyzer = LLMAnalyzer(provider, model_name)
458
 
@@ -670,29 +677,43 @@ def generate_legal_position(
670
  client = OpenAI(api_key=DEEPSEEK_API_KEY, base_url="https://api.deepseek.com")
671
  try:
672
  print(f"[DEBUG] DeepSeek Generation - Model: {model_name}")
673
- response = client.chat.completions.create(
674
- model=model_name,
675
- messages=[
676
- {"role": "system", "content": system_prompt},
677
- {"role": "user", "content": content},
678
- ],
679
- temperature=GENERATION_TEMPERATURE,
680
- max_tokens=MAX_TOKENS_CONFIG["deepseek"],
681
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
682
  response_text = response.choices[0].message.content
683
- print(f"[DEBUG] DeepSeek response length: {len(response_text)}")
684
 
685
  json_response = extract_json_from_text(response_text)
686
  if json_response and all(key in json_response for key in ["title", "text", "proceeding", "category"]):
687
  return json_response
688
  else:
689
- print(f"[WARNING] Invalid JSON structure from DeepSeek. Text: {response_text[:300]}...")
690
  raise ValueError("Invalid JSON structure")
691
  except Exception as e:
692
  print(f"[ERROR] DeepSeek generation/parsing failed: {e}")
693
  return {
694
  "title": "Автоматично сформований заголовок (DeepSeek)",
695
- "text": response_text.strip() if 'response_text' in locals() else "Помилка при отриманні відповіді від DeepSeek",
696
  "proceeding": "Не визначено",
697
  "category": "Помилка API/Парсингу"
698
  }
 
4
  import time
5
  import boto3
6
  from pathlib import Path
7
+ from typing import Dict, List, Optional, Tuple, Any
8
  from anthropic import Anthropic
9
  import openai
10
  from openai import OpenAI
 
244
  class LLMAnalyzer:
245
  """Class for handling different LLM providers."""
246
 
247
+ def __init__(self, provider: Any, model_name: Any):
248
  self.provider = provider
249
  self.model_name = model_name
250
 
 
323
 
324
  async def _analyze_with_deepseek(self, prompt: str) -> str:
325
  """Analyze text using DeepSeek."""
326
+ model_val = self.model_name.value if hasattr(self.model_name, "value") else str(self.model_name)
327
+ is_reasoning = "reasoner" in model_val.lower()
328
+
329
+ messages = []
330
+ if is_reasoning:
331
+ # DeepSeek R1 does not support system role, combine with user
332
+ messages.append(ChatMessage(role="user", content=f"{SYSTEM_PROMPT}\n\n{prompt}"))
333
+ else:
334
+ messages.append(ChatMessage(role="system", content=SYSTEM_PROMPT))
335
+ messages.append(ChatMessage(role="user", content=prompt))
336
 
337
  try:
338
+ completion_params = {
339
+ "model": model_val,
340
+ "messages": [{"role": m.role, "content": m.content} for m in messages],
341
+ }
342
+
343
+ # Use JSON mode and temperature only for non-reasoning models
344
+ if not is_reasoning:
345
+ completion_params["response_format"] = {'type': 'json_object'}
346
+ completion_params["temperature"] = 0
347
+
348
+ response = self.client.chat.completions.create(**completion_params)
349
  response_text = response.choices[0].message.content
350
 
351
  # Verify and clean JSON
352
  json_data = extract_json_from_text(response_text)
353
  return json.dumps(json_data, ensure_ascii=False) if json_data else response_text
354
  except Exception as e:
355
+ raise RuntimeError(f"Error in DeepSeek analysis ({model_val}): {str(e)}")
356
 
357
  async def _analyze_with_anthropic(self, prompt: str, response_schema: dict) -> str:
358
  """Analyze text using Anthropic."""
 
458
  class PrecedentAnalysisWorkflow(Workflow):
459
  """Workflow for analyzing legal precedents."""
460
 
461
+ def __init__(self, provider: Any = ModelProvider.OPENAI,
462
+ model_name: Any = AnalysisModelName.GPT4o_MINI):
463
  super().__init__()
464
  self.analyzer = LLMAnalyzer(provider, model_name)
465
 
 
677
  client = OpenAI(api_key=DEEPSEEK_API_KEY, base_url="https://api.deepseek.com")
678
  try:
679
  print(f"[DEBUG] DeepSeek Generation - Model: {model_name}")
680
+
681
+ # Check for reasoning model (DeepSeek R1)
682
+ is_reasoning = "reasoner" in model_name.lower()
683
+
684
+ messages = []
685
+ if is_reasoning:
686
+ # R1 does not support system role, combine with user
687
+ combined_content = f"{system_prompt}\n\n{content}"
688
+ messages.append({"role": "user", "content": combined_content})
689
+ else:
690
+ messages.append({"role": "system", "content": system_prompt})
691
+ messages.append({"role": "user", "content": content})
692
+
693
+ completion_params = {
694
+ "model": model_name,
695
+ "messages": messages,
696
+ "max_tokens": MAX_TOKENS_CONFIG["deepseek"],
697
+ }
698
+
699
+ if not is_reasoning:
700
+ completion_params["temperature"] = GENERATION_TEMPERATURE
701
+
702
+ response = client.chat.completions.create(**completion_params)
703
  response_text = response.choices[0].message.content
704
+ print(f"[DEBUG] DeepSeek response length: {len(response_text) if response_text else 0}")
705
 
706
  json_response = extract_json_from_text(response_text)
707
  if json_response and all(key in json_response for key in ["title", "text", "proceeding", "category"]):
708
  return json_response
709
  else:
710
+ print(f"[WARNING] Invalid JSON structure from DeepSeek. Text: {response_text[:300] if response_text else 'None'}...")
711
  raise ValueError("Invalid JSON structure")
712
  except Exception as e:
713
  print(f"[ERROR] DeepSeek generation/parsing failed: {e}")
714
  return {
715
  "title": "Автоматично сформований заголовок (DeepSeek)",
716
+ "text": response_text.strip() if 'response_text' in locals() and response_text else f"Помилка при отриманні відповіді від DeepSeek: {str(e)}",
717
  "proceeding": "Не визначено",
718
  "category": "Помилка API/Парсингу"
719
  }