DocUA commited on
Commit
0c2542b
·
1 Parent(s): a765e3e

feat: Add debug prompt logging functionality with environment variable support

Browse files
config/__init__.py CHANGED
@@ -156,6 +156,11 @@ else:
156
  }
157
  }
158
 
 
 
 
 
 
159
  # Required files - from YAML
160
  REQUIRED_FILES = _get_settings_attr('required_files', [
161
  'docstore_es_filter.json',
@@ -233,6 +238,7 @@ __all__ = [
233
  'GENERATION_TEMPERATURE',
234
  'LEGAL_POSITION_SCHEMA',
235
  'REQUIRED_FILES',
 
236
  'ModelProvider',
237
  'GenerationModelName',
238
  'AnalysisModelName',
 
156
  }
157
  }
158
 
159
+ # Debug prompt logging - env var overrides YAML setting
160
+ _debug_prompts_yaml = _get_settings_attr('app.debug_prompts', False)
161
+ _debug_prompts_env = os.getenv("DEBUG_PROMPTS", "").lower() in ("1", "true", "yes")
162
+ DEBUG_PROMPTS: bool = _debug_prompts_env or bool(_debug_prompts_yaml)
163
+
164
  # Required files - from YAML
165
  REQUIRED_FILES = _get_settings_attr('required_files', [
166
  'docstore_es_filter.json',
 
238
  'GENERATION_TEMPERATURE',
239
  'LEGAL_POSITION_SCHEMA',
240
  'REQUIRED_FILES',
241
+ 'DEBUG_PROMPTS',
242
  'ModelProvider',
243
  'GenerationModelName',
244
  'AnalysisModelName',
config/environments/default.yaml CHANGED
@@ -5,6 +5,7 @@ app:
5
  version: "1.0.0"
6
  debug: false
7
  environment: "production"
 
8
 
9
  # AWS S3 Configuration
10
  aws:
 
5
  version: "1.0.0"
6
  debug: false
7
  environment: "production"
8
+ debug_prompts: false
9
 
10
  # AWS S3 Configuration
11
  aws:
config/environments/development.yaml CHANGED
@@ -3,6 +3,7 @@
3
  app:
4
  debug: true
5
  environment: "development"
 
6
 
7
  # AWS S3 Configuration - use local files in development
8
  aws:
 
3
  app:
4
  debug: true
5
  environment: "development"
6
+ debug_prompts: true
7
 
8
  # AWS S3 Configuration - use local files in development
9
  aws:
config/environments/production.yaml CHANGED
@@ -3,6 +3,7 @@
3
  app:
4
  debug: false
5
  environment: "production"
 
6
 
7
  # AWS S3 Configuration - use production index
8
  aws:
 
3
  app:
4
  debug: false
5
  environment: "production"
6
+ debug_prompts: false
7
 
8
  # AWS S3 Configuration - use production index
9
  aws:
config/settings.py CHANGED
@@ -13,6 +13,7 @@ class AppConfig(BaseModel):
13
  version: str
14
  debug: bool
15
  environment: str
 
16
 
17
 
18
  class AWSConfig(BaseModel):
 
13
  version: str
14
  debug: bool
15
  environment: str
16
+ debug_prompts: bool = False
17
 
18
 
19
  class AWSConfig(BaseModel):
main.py CHANGED
@@ -35,6 +35,7 @@ from config import (
35
  GENERATION_TEMPERATURE,
36
  LEGAL_POSITION_SCHEMA,
37
  REQUIRED_FILES,
 
38
  ModelProvider,
39
  AnalysisModelName,
40
  DEEPSEEK_API_KEY,
@@ -50,6 +51,26 @@ from utils import (
50
  )
51
  from embeddings import GeminiEmbedding
52
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  # Initialize embedding model and settings BEFORE importing components
54
  # Priority: OpenAI > Gemini > None
55
  embed_model = None
@@ -352,6 +373,9 @@ class LLMAnalyzer:
352
  completion_params["verbosity"] = "medium"
353
  completion_params["store"] = False
354
 
 
 
 
355
  # Retry logic for OpenAI analysis
356
  max_retries = 3
357
  last_error = None
@@ -401,6 +425,12 @@ class LLMAnalyzer:
401
  completion_params["response_format"] = {'type': 'json_object'}
402
  completion_params["temperature"] = self.temperature
403
 
 
 
 
 
 
 
404
  # Retry logic for DeepSeek analysis
405
  max_retries = 3
406
  last_error = None
@@ -429,6 +459,7 @@ class LLMAnalyzer:
429
  async def _analyze_with_anthropic(self, prompt: str, response_schema: dict) -> str:
430
  """Analyze text using Anthropic."""
431
  try:
 
432
  response = self.client.messages.create(
433
  model=self.model_name,
434
  max_tokens=self.max_tokens or MAX_TOKENS_ANALYSIS,
@@ -465,6 +496,9 @@ class LLMAnalyzer:
465
 
466
  formatted_prompt = f"{prompt}\n\n{json_instruction}"
467
 
 
 
 
468
  # Use new google.genai API
469
  contents = [
470
  types.Content(
@@ -771,6 +805,9 @@ def generate_legal_position(
771
  # For other reasoning models (gpt-4.1, o1, etc.)
772
  completion_params["reasoning_effort"] = thinking_level.lower()
773
 
 
 
 
774
  # Execute with retries
775
  for attempt in range(max_retries):
776
  try:
@@ -867,6 +904,12 @@ def generate_legal_position(
867
  if not is_reasoning:
868
  completion_params["temperature"] = temperature
869
 
 
 
 
 
 
 
870
  # Execute with retries
871
  for attempt in range(max_retries):
872
  try:
@@ -947,6 +990,9 @@ def generate_legal_position(
947
  }
948
  message_params["temperature"] = 1.0
949
 
 
 
 
950
  # Retry logic for connection errors
951
  max_retries = 3
952
  last_error = None
@@ -1063,6 +1109,9 @@ def generate_legal_position(
1063
 
1064
  generate_content_config = types.GenerateContentConfig(**config_params)
1065
 
 
 
 
1066
  response = client.models.generate_content(
1067
  model=model_name,
1068
  contents=contents,
 
35
  GENERATION_TEMPERATURE,
36
  LEGAL_POSITION_SCHEMA,
37
  REQUIRED_FILES,
38
+ DEBUG_PROMPTS,
39
  ModelProvider,
40
  AnalysisModelName,
41
  DEEPSEEK_API_KEY,
 
51
  )
52
  from embeddings import GeminiEmbedding
53
 
54
+ # ============ Debug Prompt Logging ============
55
+ # DEBUG_PROMPTS is loaded from config (YAML env setting + DEBUG_PROMPTS env var override).
56
+ _PROMPT_SEP = "=" * 80
57
+
58
+
59
+ def _log_prompt(provider: str, model: str, system: str, user: str) -> None:
60
+ """Print full system + user prompts when DEBUG_PROMPTS is enabled."""
61
+ if not DEBUG_PROMPTS:
62
+ return
63
+ print(f"\n{_PROMPT_SEP}")
64
+ print(f"[PROMPT DEBUG] Provider: {provider} | Model: {model}")
65
+ print(f"{_PROMPT_SEP}")
66
+ if system:
67
+ print("[PROMPT DEBUG] ── SYSTEM PROMPT ──────────────────────────────────")
68
+ print(system)
69
+ print("[PROMPT DEBUG] ── USER PROMPT ────────────────────────────────────")
70
+ print(user)
71
+ print(f"{_PROMPT_SEP}\n")
72
+ # ============ End Debug Prompt Logging ============
73
+
74
  # Initialize embedding model and settings BEFORE importing components
75
  # Priority: OpenAI > Gemini > None
76
  embed_model = None
 
373
  completion_params["verbosity"] = "medium"
374
  completion_params["store"] = False
375
 
376
+ # Log full prompts in debug mode
377
+ _log_prompt("openai-analyzer", model_val, SYSTEM_PROMPT, prompt)
378
+
379
  # Retry logic for OpenAI analysis
380
  max_retries = 3
381
  last_error = None
 
425
  completion_params["response_format"] = {'type': 'json_object'}
426
  completion_params["temperature"] = self.temperature
427
 
428
+ # Log full prompts in debug mode
429
+ if is_reasoning:
430
+ _log_prompt("deepseek-analyzer", model_val, "", f"{SYSTEM_PROMPT}\n\n{prompt}")
431
+ else:
432
+ _log_prompt("deepseek-analyzer", model_val, SYSTEM_PROMPT, prompt)
433
+
434
  # Retry logic for DeepSeek analysis
435
  max_retries = 3
436
  last_error = None
 
459
  async def _analyze_with_anthropic(self, prompt: str, response_schema: dict) -> str:
460
  """Analyze text using Anthropic."""
461
  try:
462
+ _log_prompt("anthropic-analyzer", str(self.model_name), SYSTEM_PROMPT, prompt)
463
  response = self.client.messages.create(
464
  model=self.model_name,
465
  max_tokens=self.max_tokens or MAX_TOKENS_ANALYSIS,
 
496
 
497
  formatted_prompt = f"{prompt}\n\n{json_instruction}"
498
 
499
+ # Log full prompts in debug mode
500
+ _log_prompt("gemini-analyzer", str(self.model_name), SYSTEM_PROMPT, formatted_prompt)
501
+
502
  # Use new google.genai API
503
  contents = [
504
  types.Content(
 
805
  # For other reasoning models (gpt-4.1, o1, etc.)
806
  completion_params["reasoning_effort"] = thinking_level.lower()
807
 
808
+ # Log full prompts in debug mode
809
+ _log_prompt("openai", model_name, system_prompt, content)
810
+
811
  # Execute with retries
812
  for attempt in range(max_retries):
813
  try:
 
904
  if not is_reasoning:
905
  completion_params["temperature"] = temperature
906
 
907
+ # Log full prompts in debug mode
908
+ if is_reasoning:
909
+ _log_prompt("deepseek", model_name, "", combined_content)
910
+ else:
911
+ _log_prompt("deepseek", model_name, system_prompt, content)
912
+
913
  # Execute with retries
914
  for attempt in range(max_retries):
915
  try:
 
990
  }
991
  message_params["temperature"] = 1.0
992
 
993
+ # Log full prompts in debug mode
994
+ _log_prompt("anthropic", model_name, system_prompt, content)
995
+
996
  # Retry logic for connection errors
997
  max_retries = 3
998
  last_error = None
 
1109
 
1110
  generate_content_config = types.GenerateContentConfig(**config_params)
1111
 
1112
+ # Log full prompts in debug mode
1113
+ _log_prompt("gemini", model_name, system_prompt, content)
1114
+
1115
  response = client.models.generate_content(
1116
  model=model_name,
1117
  contents=contents,