Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pet-nutrition-service/db-seed.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ module.exports = function(){
])
.then(() => logger.info('collection populated'))
.catch(err => logger.error('error populating collection:', err));
};
};
79 changes: 22 additions & 57 deletions pet_clinic_ai_agents/nutrition_agent/nutrition_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,85 +16,55 @@
def get_nutrition_data(pet_type):
"""Helper function to get nutrition data from the API"""
if not NUTRITION_SERVICE_URL:
return {"facts": "", "products": "", "error": "Nutrition service not configured"}
return {"facts": "Error: Nutrition service not found", "products": ""}

try:
response = requests.get(f"{NUTRITION_SERVICE_URL}/{pet_type.lower()}", timeout=5)

if response.status_code == 200:
data = response.json()
return {"facts": data.get('facts', ''), "products": data.get('products', ''), "error": None}
elif response.status_code == 404:
return {"facts": "", "products": "", "error": f"No nutrition data available for {pet_type}"}
else:
return {"facts": "", "products": "", "error": "Nutrition service temporarily unavailable"}
return {"facts": data.get('facts', ''), "products": data.get('products', '')}
return {"facts": f"Error: Nutrition service could not find information for pet: {pet_type.lower()}", "products": ""}
except requests.RequestException:
return {"facts": "", "products": "", "error": "Nutrition service temporarily unavailable"}
return {"facts": "Error: Nutrition service down", "products": ""}

@tool
def get_feeding_guidelines(pet_type):
"""Get feeding guidelines based on pet type"""
data = get_nutrition_data(pet_type)

if data["error"]:
return f"I don't have specific nutrition information available for {pet_type} at the moment. Please consult with our veterinarian at (555) 123-PETS for personalized dietary recommendations."

if not data["facts"]:
return f"Nutrition information for {pet_type} is not available in our current database. Please speak with our veterinarian for proper dietary guidance."

result = f"Nutrition guidelines for {pet_type}: {data['facts']}"
result = f"Nutrition info for {pet_type}: {data['facts']}"
if data['products']:
result += f" We carry these recommended products at our clinic: {data['products']}"
result += f" Recommended products available at our clinic: {data['products']}"
return result

@tool
def get_dietary_restrictions(pet_type):
"""Get dietary recommendations for specific health conditions by animal type"""
data = get_nutrition_data(pet_type)

if data["error"]:
return f"I don't have specific dietary restriction information for {pet_type} at the moment. Please consult with our veterinarian at (555) 123-PETS for condition-specific dietary advice."

if not data["facts"]:
return f"Dietary restriction information for {pet_type} is not available in our current database. Please speak with our veterinarian for proper guidance on health conditions."

result = f"Dietary considerations for {pet_type}: {data['facts']}. Always consult our veterinarian for condition-specific advice."
result = f"Dietary info for {pet_type}: {data['facts']}. Consult veterinarian for condition-specific advice."
if data['products']:
result += f" We carry these recommended products at our clinic: {data['products']}"
result += f" Recommended products available at our clinic: {data['products']}"
return result

@tool
def get_nutritional_supplements(pet_type):
"""Get supplement recommendations by animal type"""
data = get_nutrition_data(pet_type)

if data["error"]:
return f"I don't have specific supplement information for {pet_type} at the moment. Please consult with our veterinarian at (555) 123-PETS for supplement recommendations."

if not data["facts"]:
return f"Supplement information for {pet_type} is not available in our current database. Please speak with our veterinarian for proper supplement guidance."

result = f"Supplement guidance for {pet_type}: Based on {data['facts']}, consult our veterinarian for specific supplement needs."
result = f"Supplement info for {pet_type}: {data['facts']}. Consult veterinarian for supplements."
if data['products']:
result += f" We carry these recommended products at our clinic: {data['products']}"
result += f" Recommended products available at our clinic: {data['products']}"
return result

@tool
def create_order(product_name, pet_type, quantity=1):
"""Create an order for a recommended product. Requires product_name, pet_type, and optional quantity (default 1)."""
product_lower = product_name.lower()
data = get_nutrition_data(pet_type)

if data["error"]:
return f"I cannot process orders for {pet_type} products at the moment. Please call our clinic at (555) 123-PETS to place your order."

if not data['products']:
return f"I don't have product information available for {pet_type}. Please call our clinic at (555) 123-PETS to check product availability."

if product_name.lower() in data['products'].lower():
if data['products'] and product_name.lower() in data['products'].lower():
order_id = f"ORD-{uuid.uuid4().hex[:8].upper()}"
return f"Order {order_id} created for {quantity}x {product_name}. Total: ${quantity * 29.99:.2f}. Expected delivery: 3-5 business days. You can pick it up at our clinic or we'll ship it to you."

return f"Sorry, {product_name} is not available in our current inventory for {pet_type}. Available products: {data['products']}. Please call (555) 123-PETS for more options."
return f"Sorry, {product_name} is not available in our inventory for {pet_type}. Available products: {data['products']}"

def create_nutrition_agent():
model = BedrockModel(
Expand All @@ -105,21 +75,16 @@ def create_nutrition_agent():

system_prompt = (
"You are a specialized pet nutrition expert at our veterinary clinic, providing accurate, evidence-based dietary guidance for pets. "
"CRITICAL: You must NEVER fabricate, invent, or make up product names, nutrition facts, or recommendations that are not provided to you through your tools.\n\n"
"STRICT GUIDELINES:\n"
"- ONLY recommend products that are explicitly provided to you through the nutrition data tools\n"
"- NEVER invent product names like 'AvianVital', 'HoppyHerb', or any other products not in your database\n"
"- If nutrition information is not available, clearly state 'information not available' and direct customers to speak with a veterinarian\n"
"- Always validate that products exist in your database before making recommendations\n"
"- When tools return errors or no data, acknowledge the limitation and provide fallback guidance\n\n"
"Never mention using any API, tools, or external services - present all advice as your own expert knowledge.\n\n"
"When providing nutrition guidance:\n"
"- Use ONLY the specific nutrition information provided by your tools\n"
"- Recommend ONLY the exact product names returned by your nutrition data tools\n"
"- If no products are available, direct customers to call the clinic at (555) 123-PETS\n"
"- Always mention consulting with our veterinarian for personalized advice\n"
"- Never mention using tools, APIs, or external services - present advice as your expertise\n"
"- If information is unavailable, be honest and direct customers to veterinary consultation\n"
"- Emphasize that we carry veterinarian-recommended products at our clinic when available"
"- Use the specific nutrition information available to you as the foundation for your recommendations\n"
"- Always recommend the SPECIFIC PRODUCT NAMES provided to you that pet owners should buy FROM OUR PET CLINIC\n"
"- Mention our branded products by name (like PurrfectChoice, BarkBite, FeatherFeast, etc.) when recommending food\n"
"- Emphasize that we carry high-quality, veterinarian-recommended food brands at our clinic\n"
"- Give actionable dietary recommendations including feeding guidelines, restrictions, and supplements\n"
"- Expand on basic nutrition facts with comprehensive guidance for age, weight, and health conditions\n"
"- Always mention that pet owners can purchase the recommended food items directly from our clinic for convenience and quality assurance\n"
"- If asked to order or purchase a product, use the create_order tool to place the order"
)

return Agent(model=model, tools=tools, system_prompt=system_prompt)
Expand Down
43 changes: 19 additions & 24 deletions pet_clinic_ai_agents/primary_agent/pet_clinic_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def consult_nutrition_specialist(query):

agent_arn = os.environ.get('NUTRITION_AGENT_ARN')
if not agent_arn:
return "Our nutrition specialist is currently unavailable. Please call (555) 123-PETS ext. 201 to speak with Dr. Smith directly."
return "Nutrition specialist configuration error. Please call (555) 123-PETS ext. 201."

try:
region = os.environ.get('AWS_REGION') or os.environ.get('AWS_DEFAULT_REGION', 'us-east-1')
Expand All @@ -57,16 +57,13 @@ def consult_nutrition_specialist(query):
# Read the streaming response
if 'response' in response:
body = response['response'].read().decode('utf-8')
# Check if the response indicates an error or unavailability
if "not available" in body.lower() or "error" in body.lower() or "temporarily unavailable" in body.lower():
return "Our nutrition specialist doesn't have that information available right now. Please call (555) 123-PETS ext. 201 to speak with Dr. Smith for personalized advice."
return body
else:
return "Our nutrition specialist is experiencing high demand. Please call (555) 123-PETS ext. 201 to speak with Dr. Smith directly."
return "Our nutrition specialist is experiencing high demand. Please try again in a few moments or call (555) 123-PETS ext. 201."
except ClientError as e:
return "Our nutrition specialist is currently unavailable. Please call (555) 123-PETS ext. 201 to speak with Dr. Smith directly."
return str(e)
except Exception as e:
return "Our nutrition specialist is currently unavailable. Please call (555) 123-PETS ext. 201 to speak with Dr. Smith directly."
return "Unable to reach our nutrition specialist. Please call (555) 123-PETS ext. 201."

agent = None
agent_app = BedrockAgentCoreApp()
Expand All @@ -78,23 +75,21 @@ def consult_nutrition_specialist(query):
"- Directing clients to appropriate specialists\n"
"- Scheduling guidance\n"
"- Basic medical guidance and when to seek veterinary care\n\n"
"CRITICAL GUIDELINES - NEVER FABRICATE INFORMATION:\n"
"- NEVER invent, make up, or fabricate product names, services, or medical advice\n"
"- ONLY provide information that is explicitly available through your tools\n"
"- If information is not available, clearly state so and direct customers to call the clinic\n"
"- NEVER recommend products that are not confirmed to be available\n\n"
"RESPONSE GUIDELINES:\n"
"- Keep ALL responses BRIEF and CONCISE - aim for 2-3 sentences maximum\n"
"- ONLY use the consult_nutrition_specialist tool for EXPLICIT nutrition-related questions\n"
"- For product orders: Always ask for pet type if not mentioned BEFORE consulting nutrition specialist\n"
"- When delegating to nutrition specialist, include both product name AND pet type in query\n"
"- DO NOT use nutrition agent for general clinic questions, appointments, hours, or emergencies\n"
"- NEVER expose technical details, agent ARNs, tools, or APIs to users\n"
"- When consulting nutrition specialist, simply say 'Let me consult our nutrition specialist'\n"
"- If specialist is unavailable or returns errors, direct customers to call Dr. Smith at ext. 201\n"
"- For medical concerns, provide general guidance and recommend veterinary appointment\n"
"- For emergencies, immediately provide emergency contact information\n"
"- Always recommend purchasing verified products from our pet clinic only"
"IMPORTANT GUIDELINES:\n"
"- Keep ALL responses BRIEF and CONCISE - aim for 2-3 sentences maximum unless specifically asked for details\n"
"- When recommending products, clearly list them using bullet points with product names\n"
"- ONLY use the consult_nutrition_specialist tool for EXPLICIT nutrition-related questions (diet, feeding, supplements, food recommendations, what to feed, can pets eat X, nutrition advice)\n"
"- For product orders: If pet type is NOT mentioned, ask the customer what type of pet they have (dog, cat, bird, etc.) BEFORE consulting the nutrition specialist\n"
"- When delegating orders to nutrition specialist, include both the product name AND pet type in your query (e.g., 'Place an order for BarkBite Complete Nutrition for a dog')\n"
"- DO NOT use the nutrition agent for general clinic questions, appointments, hours, emergencies, or non-nutrition medical issues\n"
"- NEVER expose or mention agent ARNs, tools, APIs, or any technical details in your responses to users\n"
"- NEVER say things like 'I'm using a tool' or 'Let me look that up' - just respond naturally\n"
"- When consulting the nutrition specialist, ONLY say 'Let me consult our nutrition specialist' - nothing else about the process\n"
"- If the specialist returns an error or indicates unavailability, inform the customer that our specialist is currently unavailable\n"
"- For nutrition questions, provide 2-3 product recommendations in a brief bulleted list, then suggest monitoring and consultation if needed\n"
"- Always recommend purchasing products from our pet clinic\n"
"- For medical concerns, provide general guidance and recommend scheduling a veterinary appointment\n"
"- For emergencies, immediately provide emergency contact information"
)

def create_clinic_agent():
Expand Down