Skip to content

Commit 366815f

Browse files
feat: Made the SystemPrompt dynamic
1 parent 70f0c1a commit 366815f

File tree

5 files changed

+152
-2
lines changed

5 files changed

+152
-2
lines changed

.env.example

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,12 @@ HITL_ACTIONS=create,update,delete,pause
9595

9696
LIGHTHOUSE_APP_URL='http://localhost:5173'
9797
ENABLE_ALL_METRICS_FROM_CKH='true'
98+
99+
100+
# LangFuse Configuration
101+
ENABLE_LANGFUSE_PROMPTS=true
102+
LANGFUSE_SECRET_KEY=''
103+
LANGFUSE_PUBLIC_KEY=''
104+
LANGFUSE_BASEURL=https://us.cloud.langfuse.com
105+
LANGFUSE_SYSTEM_PROMPT_NAME=AUTOMATIC_VOICE_LANGFUSE_PROMPT
106+
LANGFUSE_SYSTEM_PROMPT_LABEL=automatic_system_langfuse_prompt

app/agents/voice/automatic/prompts/system.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from app.core.logger import logger
33
from app.core.config import ENABLE_SEARCH_GROUNDING, HITL_ENABLE
44
from app.agents.voice.automatic.types import TTSProvider
5+
from app.agents.voice.automatic.services.langfuse import langfuse_service
56

67
SYSTEM_PROMPT = f"""
78
SYSTEM ROLE
@@ -183,11 +184,39 @@ def get_tts_based_instructions(tts_provider: TTSProvider | None) -> str:
183184
"""
184185
return ""
185186

187+
def _process_template_variables(prompt_content: str) -> str:
188+
"""
189+
Replace template variables in the prompt with actual values.
190+
191+
Args:
192+
prompt_content: The prompt content with template variables
193+
194+
Returns:
195+
str: Prompt content with template variables replaced
196+
"""
197+
# Replace {current_time} with actual current date
198+
current_time = datetime.datetime.now().strftime("%B %d, %Y")
199+
prompt_content = prompt_content.replace("{current_time}", current_time)
200+
201+
return prompt_content
202+
203+
186204
def get_system_prompt(user_name: str | None, tts_provider: TTSProvider | None) -> str:
187205
"""
188206
Generates a personalized system prompt based on the user's name and TTS service.
207+
First attempts to fetch from LangFuse, then falls back to hardcoded prompt.
189208
"""
190-
prompt = SYSTEM_PROMPT
209+
# Try to fetch prompt from LangFuse first
210+
langfuse_prompt = langfuse_service.fetch_prompt()
211+
212+
if langfuse_prompt:
213+
logger.info("Using dynamic prompt from LangFuse")
214+
prompt = _process_template_variables(langfuse_prompt)
215+
else:
216+
logger.info("Using fallback hardcoded prompt")
217+
prompt = SYSTEM_PROMPT
218+
219+
# Append dynamic components that are always added locally
191220
prompt += get_tts_based_instructions(tts_provider)
192221
prompt += get_internet_search_instructions()
193222
prompt += get_hitl_security_instructions()
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
"""
2+
LangFuse service for dynamic prompt management.
3+
Handles fetching prompts from LangFuse with error handling.
4+
"""
5+
6+
from typing import Optional
7+
from langfuse import Langfuse
8+
from app.core.logger import logger
9+
from app.core.config import (
10+
ENABLE_LANGFUSE_PROMPTS,
11+
LANGFUSE_SECRET_KEY,
12+
LANGFUSE_PUBLIC_KEY,
13+
LANGFUSE_BASEURL,
14+
LANGFUSE_SYSTEM_PROMPT_NAME,
15+
LANGFUSE_SYSTEM_PROMPT_LABEL
16+
)
17+
18+
19+
class LangFuseService:
20+
"""Service for managing LangFuse prompt operations."""
21+
22+
def __init__(self):
23+
self.client: Optional[Langfuse] = None
24+
self.initialized = False
25+
26+
if ENABLE_LANGFUSE_PROMPTS:
27+
self._initialize_client()
28+
29+
def _initialize_client(self) -> None:
30+
"""Initialize the LangFuse client with error handling."""
31+
try:
32+
if not LANGFUSE_SECRET_KEY or not LANGFUSE_PUBLIC_KEY:
33+
logger.warning("LangFuse credentials not found, using fallback prompts")
34+
return
35+
36+
self.client = Langfuse(
37+
secret_key=LANGFUSE_SECRET_KEY,
38+
public_key=LANGFUSE_PUBLIC_KEY,
39+
host=LANGFUSE_BASEURL
40+
)
41+
self.initialized = True
42+
logger.info("LangFuse client initialized successfully")
43+
44+
except Exception as e:
45+
logger.error(f"Failed to initialize LangFuse client: {e}")
46+
self.client = None
47+
48+
def fetch_prompt(
49+
self,
50+
prompt_name: Optional[str] = None,
51+
label: Optional[str] = None
52+
) -> Optional[str]:
53+
"""
54+
Fetch prompt from LangFuse with error handling.
55+
56+
Args:
57+
prompt_name: Name of the prompt (defaults to config value)
58+
label: Label for the prompt (defaults to config value)
59+
60+
Returns:
61+
str: Prompt content if successful, None if failed
62+
"""
63+
if not ENABLE_LANGFUSE_PROMPTS or not self.initialized or not self.client:
64+
logger.debug("LangFuse not enabled or not initialized, using fallback")
65+
return None
66+
67+
# Use default values if not provided
68+
prompt_name = prompt_name or LANGFUSE_SYSTEM_PROMPT_NAME
69+
label = label or LANGFUSE_SYSTEM_PROMPT_LABEL
70+
71+
# Fetch from LangFuse
72+
try:
73+
logger.info(f"Fetching prompt '{prompt_name}' with label '{label}' from LangFuse")
74+
75+
# Get prompt from LangFuse
76+
prompt = self.client.get_prompt(prompt_name, label=label)
77+
78+
if prompt and hasattr(prompt, 'prompt'):
79+
prompt_content = prompt.prompt
80+
logger.info(f"Successfully fetched prompt from LangFuse (length: {len(prompt_content)} chars)")
81+
return prompt_content
82+
else:
83+
logger.warning(f"Prompt '{prompt_name}' with label '{label}' not found in LangFuse")
84+
return None
85+
86+
except Exception as e:
87+
logger.error(f"Error fetching prompt from LangFuse: {e}")
88+
return None
89+
90+
# Global instance
91+
langfuse_service = LangFuseService()

app/core/config.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,3 +161,16 @@ def get_required_env(var_name: str) -> str:
161161
# HITL Actions Configuration
162162
_hitl_actions_str = os.environ.get("HITL_ACTIONS", "delete")
163163
HITL_ACTIONS = [action.strip().lower() for action in _hitl_actions_str.split(",") if action.strip()]
164+
165+
166+
# LangFuse Configuration
167+
ENABLE_LANGFUSE_PROMPTS = os.environ.get("ENABLE_LANGFUSE_PROMPTS", "true").lower() == "false"
168+
LANGFUSE_SECRET_KEY = os.environ.get("LANGFUSE_SECRET_KEY", "")
169+
LANGFUSE_PUBLIC_KEY = os.environ.get("LANGFUSE_PUBLIC_KEY", "")
170+
LANGFUSE_BASEURL = os.environ.get("LANGFUSE_BASEURL", "https://us.cloud.langfuse.com")
171+
LANGFUSE_SYSTEM_PROMPT_NAME = os.environ.get("LANGFUSE_SYSTEM_PROMPT_NAME", "AUTOMATIC_VOICE_LANGFUSE_PROMPT")
172+
LANGFUSE_SYSTEM_PROMPT_LABEL = os.environ.get("LANGFUSE_SYSTEM_PROMPT_LABEL", "automatic_system_langfuse_prompt")
173+
174+
logger.info(f"LangFuse prompts enabled: {ENABLE_LANGFUSE_PROMPTS}")
175+
if ENABLE_LANGFUSE_PROMPTS:
176+
logger.info(f"LangFuse system prompt: {LANGFUSE_SYSTEM_PROMPT_NAME} (label: {LANGFUSE_SYSTEM_PROMPT_LABEL})")

memory-bank/progress.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,15 @@
2121
- **Enhanced Banner Management:** The current banner management tool supports basic functionality for login and payment page announcements. Future enhancements could include support for more banner types, customization options (colors, icons), scheduling (start/end dates), and targeting specific user segments.
2222
- **Additional Shop Configuration Tools:** Building on the shop configuration utilities, more tools could be developed to manage other aspects of shop configuration, such as theme settings, payment options, or shipping methods.
2323

24-
## 3. Known Issues & Risks
24+
## 3. Recent Improvements (Latest)
25+
26+
- **Dynamic Prompt Management:** Implemented LangFuse integration to make system prompts dynamic instead of hardcoded. Created `LangFuseService` class for fetching prompts from external LangFuse platform.
27+
- **External Prompt Configuration:** Added comprehensive LangFuse configuration in `config.py` with environment variables for credentials, prompt names, and labels, enabling prompt management outside the codebase.
28+
- **Graceful Fallback System:** Modified `get_system_prompt()` to prioritize LangFuse prompts with automatic fallback to hardcoded `SYSTEM_PROMPT` if LangFuse is unavailable or fails.
29+
- **Template Variable Processing:** Added `{{current_time}}` template variable support in LangFuse prompts with dynamic replacement during prompt processing.
30+
- **No-Code Prompt Updates:** System prompts can now be updated through LangFuse interface without code changes or application deployments.
31+
32+
## 4. Known Issues & Risks
2533

2634
- **Sensitive Data Exposure:** As documented in `activeContext.md`, there is a known risk of exposing sensitive information (from tool schemas and results) to the LLM. This remains the most significant risk.
2735
- **Dependency on Remote Server:** While error handling has been improved, the agent's tooling capability is still entirely dependent on the availability and correctness of the remote MCP server.

0 commit comments

Comments
 (0)