Spaces:
Running
Running
Commit ·
bd393e3
1
Parent(s): 8e25b6e
Enhance AI response generation by incorporating company name and updating context builder to return company name along with context string.
Browse files
app/routers/__pycache__/chat.cpython-313.pyc
CHANGED
|
Binary files a/app/routers/__pycache__/chat.cpython-313.pyc and b/app/routers/__pycache__/chat.cpython-313.pyc differ
|
|
|
app/routers/chat.py
CHANGED
|
@@ -44,11 +44,11 @@ async def chat(data: ChatRequest, db: Session = Depends(get_db)):
|
|
| 44 |
ai_messages = [{"role": m.role, "content": m.content} for m in reversed(history)]
|
| 45 |
|
| 46 |
# Fetch relevant live CMS context based on user intent
|
| 47 |
-
context = await build_context(data.message)
|
| 48 |
|
| 49 |
# Generate AI response
|
| 50 |
try:
|
| 51 |
-
ai_response = await generate_ai_response(ai_messages, context)
|
| 52 |
except RateLimitError:
|
| 53 |
raise HTTPException(status_code=429, detail="AI service quota exceeded. Please try again later.")
|
| 54 |
except AuthenticationError:
|
|
|
|
| 44 |
ai_messages = [{"role": m.role, "content": m.content} for m in reversed(history)]
|
| 45 |
|
| 46 |
# Fetch relevant live CMS context based on user intent
|
| 47 |
+
company_name, context = await build_context(data.message)
|
| 48 |
|
| 49 |
# Generate AI response
|
| 50 |
try:
|
| 51 |
+
ai_response = await generate_ai_response(ai_messages, company_name, context)
|
| 52 |
except RateLimitError:
|
| 53 |
raise HTTPException(status_code=429, detail="AI service quota exceeded. Please try again later.")
|
| 54 |
except AuthenticationError:
|
app/services/ai_service.py
CHANGED
|
@@ -6,12 +6,12 @@ load_dotenv()
|
|
| 6 |
|
| 7 |
client = AsyncGroq(api_key=os.getenv("GROQ_API_KEY"))
|
| 8 |
|
| 9 |
-
_BASE_SYSTEM_PROMPT = """You are the AI assistant for
|
| 10 |
|
| 11 |
STRICT RULES:
|
| 12 |
-
1. Only answer questions about
|
| 13 |
2. Use ONLY the company context provided below — never invent information.
|
| 14 |
-
3. If a question is unrelated to the company or automotive services, respond: "I can only help with
|
| 15 |
4. Be concise, helpful, and professional.
|
| 16 |
5. When relevant, suggest booking an appointment or contacting the team.
|
| 17 |
|
|
@@ -19,8 +19,11 @@ STRICT RULES:
|
|
| 19 |
"""
|
| 20 |
|
| 21 |
|
| 22 |
-
async def generate_ai_response(messages: list[dict], context: str) -> str:
|
| 23 |
-
system_prompt = _BASE_SYSTEM_PROMPT.format(
|
|
|
|
|
|
|
|
|
|
| 24 |
|
| 25 |
formatted = [{"role": "system", "content": system_prompt}] + messages
|
| 26 |
|
|
|
|
| 6 |
|
| 7 |
client = AsyncGroq(api_key=os.getenv("GROQ_API_KEY"))
|
| 8 |
|
| 9 |
+
_BASE_SYSTEM_PROMPT = """You are the AI assistant for {company_name}, an automotive repair and maintenance company.
|
| 10 |
|
| 11 |
STRICT RULES:
|
| 12 |
+
1. Only answer questions about {company_name}'s services, pricing, locations, hours, bookings, and general automotive maintenance topics.
|
| 13 |
2. Use ONLY the company context provided below — never invent information.
|
| 14 |
+
3. If a question is unrelated to the company or automotive services, respond: "I can only help with {company_name} services and automotive questions. Is there something specific I can help you with?"
|
| 15 |
4. Be concise, helpful, and professional.
|
| 16 |
5. When relevant, suggest booking an appointment or contacting the team.
|
| 17 |
|
|
|
|
| 19 |
"""
|
| 20 |
|
| 21 |
|
| 22 |
+
async def generate_ai_response(messages: list[dict], company_name: str, context: str) -> str:
|
| 23 |
+
system_prompt = _BASE_SYSTEM_PROMPT.format(
|
| 24 |
+
company_name=company_name,
|
| 25 |
+
context=context,
|
| 26 |
+
)
|
| 27 |
|
| 28 |
formatted = [{"role": "system", "content": system_prompt}] + messages
|
| 29 |
|
app/services/context_builder.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
| 1 |
import asyncio
|
|
|
|
| 2 |
from app.services.cms_service import (
|
| 3 |
get_settings,
|
| 4 |
get_services,
|
|
@@ -116,7 +117,8 @@ def _fmt_faqs(faqs: list[dict]) -> str:
|
|
| 116 |
return "\n".join(lines)
|
| 117 |
|
| 118 |
|
| 119 |
-
async def build_context(message: str) -> str:
|
|
|
|
| 120 |
intents = _detect_intents(message)
|
| 121 |
|
| 122 |
# Decide which CMS calls to make
|
|
@@ -143,12 +145,18 @@ async def build_context(message: str) -> str:
|
|
| 143 |
for k, v in zip(keys, results)
|
| 144 |
}
|
| 145 |
|
| 146 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 147 |
|
| 148 |
# Company info (always present)
|
| 149 |
-
settings = data.get("settings") or {}
|
| 150 |
if settings:
|
| 151 |
-
parts.append(f"Company:
|
| 152 |
if settings.get("phone"):
|
| 153 |
parts.append(f"Phone: {settings['phone']}")
|
| 154 |
if settings.get("contactEmail"):
|
|
@@ -178,4 +186,4 @@ async def build_context(message: str) -> str:
|
|
| 178 |
if data.get("faqs"):
|
| 179 |
parts.append(_fmt_faqs(data["faqs"]))
|
| 180 |
|
| 181 |
-
return "\n\n".join(parts)
|
|
|
|
| 1 |
import asyncio
|
| 2 |
+
import os
|
| 3 |
from app.services.cms_service import (
|
| 4 |
get_settings,
|
| 5 |
get_services,
|
|
|
|
| 117 |
return "\n".join(lines)
|
| 118 |
|
| 119 |
|
| 120 |
+
async def build_context(message: str) -> tuple[str, str]:
|
| 121 |
+
"""Returns (company_name, context_string) — both pulled from CMS."""
|
| 122 |
intents = _detect_intents(message)
|
| 123 |
|
| 124 |
# Decide which CMS calls to make
|
|
|
|
| 145 |
for k, v in zip(keys, results)
|
| 146 |
}
|
| 147 |
|
| 148 |
+
settings = data.get("settings") or {}
|
| 149 |
+
company_name = (
|
| 150 |
+
settings.get("companyName")
|
| 151 |
+
or os.getenv("COMPANY_NAME")
|
| 152 |
+
or "FixinMoto"
|
| 153 |
+
)
|
| 154 |
+
|
| 155 |
+
parts: list[str] = [f"=== {company_name} Company Context ==="]
|
| 156 |
|
| 157 |
# Company info (always present)
|
|
|
|
| 158 |
if settings:
|
| 159 |
+
parts.append(f"Company: {company_name}")
|
| 160 |
if settings.get("phone"):
|
| 161 |
parts.append(f"Phone: {settings['phone']}")
|
| 162 |
if settings.get("contactEmail"):
|
|
|
|
| 186 |
if data.get("faqs"):
|
| 187 |
parts.append(_fmt_faqs(data["faqs"]))
|
| 188 |
|
| 189 |
+
return company_name, "\n\n".join(parts)
|