99 lines
4.0 KiB
JavaScript
99 lines
4.0 KiB
JavaScript
/**
|
|
* ClinicAgent: An agentic orchestrator for Curio.
|
|
* It uses natural language understanding to map user requests to hospital tools.
|
|
*/
|
|
|
|
const patientManager = require('./patientManager');
|
|
const queueManager = require('./queueManager');
|
|
const pharmacyAgent = require('./pharmacyAgent');
|
|
const configManager = require('./configManager');
|
|
|
|
class ClinicAgent {
|
|
constructor() {
|
|
this.systemPrompt = `
|
|
You are 'Curio AI', the assistant for Curio Health.
|
|
Your goal is to help patients book appointments, manage family members, and check clinic status.
|
|
|
|
TOOLS:
|
|
- list_family: Shows all members linked to the phone.
|
|
- add_member: Registers a new family member name.
|
|
- book_today: Books an appointment for today.
|
|
- check_status: Checks current queue position.
|
|
|
|
RULES:
|
|
1. Always be polite and professional.
|
|
2. If a patient asks for someone not in their family list, offer to add them.
|
|
3. If multiple people have same name, ask for clarification.
|
|
`;
|
|
}
|
|
|
|
async processMessage(phone, message, context = {}) {
|
|
const text = message.toLowerCase();
|
|
console.log(`[Agent] Processing for ${phone}: "${message}"`);
|
|
|
|
// Mock LLM Intent Extraction & Tool Execution
|
|
// In a real app, this would be: const response = await llm.call({ prompt: ..., tools: [...] });
|
|
|
|
const family = patientManager.getProfiles(phone);
|
|
|
|
// Scenario 1: Greeting + Profile Check
|
|
if (text.includes("hi") || text.includes("hello")) {
|
|
if (family.length === 0) {
|
|
return {
|
|
reply: "Hello! I'm Curio AI. I don't see a profile for this number yet. What is your full name so I can get you started?",
|
|
nextStep: "AWAIT_REGISTRATION"
|
|
};
|
|
}
|
|
return {
|
|
reply: `Hello again! I see profiles for ${family.map(p => p.name).join(', ')}. Who can I help you with today?`,
|
|
buttons: [...family.map(p => p.name), "+ Add New Member"]
|
|
};
|
|
}
|
|
|
|
// Scenario 2: Adding a Member
|
|
if (context.lastStep === "AWAIT_REGISTRATION" || text.includes("add new member")) {
|
|
if (text.includes("add new member")) {
|
|
return { reply: "Sure! What is the name of the family member you'd like to add?" };
|
|
}
|
|
const newId = patientManager.addProfile(phone, { name: message, relation: "Family" });
|
|
return {
|
|
reply: `Perfect! I've added ${message} to your family account. Would you like to book an appointment for them today?`,
|
|
buttons: ["Book for Today", "Check Queue"]
|
|
};
|
|
}
|
|
|
|
// Scenario 3: Booking Intent
|
|
if (text.includes("book") || text.includes("today")) {
|
|
return {
|
|
reply: "I can help with that. Which time works best for you?",
|
|
buttons: ["10:00 AM", "11:00 AM", "06:00 PM"]
|
|
};
|
|
}
|
|
|
|
// Scenario 3.5: Medicine Query
|
|
if (text.includes("have") || text.includes("medicine") || text.includes("syrup") || text.includes("tablet")) {
|
|
const pharmacyReply = pharmacyAgent.handlePatientQuery(message);
|
|
return {
|
|
reply: "💊 *Pharmacy Update*: " + pharmacyReply,
|
|
buttons: ["Book for Today", "Check Other Meds"]
|
|
};
|
|
}
|
|
|
|
// Scenario 4: Natural Language Match for Family Members
|
|
const matchedMember = family.find(p => text.includes(p.name.toLowerCase()));
|
|
if (matchedMember) {
|
|
return {
|
|
reply: `I've switched context to ${matchedMember.name}. What would you like to do for them?`,
|
|
buttons: ["Book for Today", "View History"]
|
|
};
|
|
}
|
|
|
|
// Fallback to "Smart" LLM reply
|
|
return {
|
|
reply: "I'm not sure how to help with that yet, but I'm learning! You can ask me to book an appointment or add a family member."
|
|
};
|
|
}
|
|
}
|
|
|
|
module.exports = new ClinicAgent();
|