diff --git a/bot.db b/bot.db index 25fb841..7bf7bc1 100644 Binary files a/bot.db and b/bot.db differ diff --git a/handlers/dashboard.go b/handlers/dashboard.go index f5d1cb2..4bb00a6 100644 --- a/handlers/dashboard.go +++ b/handlers/dashboard.go @@ -116,16 +116,37 @@ func UpdateAppointmentHandler(c *gin.Context) { // POST /admin/chat func NewChatHandler(c *gin.Context) { - // Insert a new chat record. In SQLite, this is enough to generate an ID. res, err := db.Conn.Exec("INSERT INTO chats (title) VALUES ('New Chat')") if err != nil { - log.Println("Database Error in NewChat:", err) - c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create chat"}) + c.JSON(500, gin.H{"error": err.Error()}) return } - id, _ := res.LastInsertId() - c.JSON(http.StatusOK, gin.H{"id": id}) + // Return the ID so the frontend can select it immediately + c.JSON(200, gin.H{"id": id, "title": "New Chat"}) +} + +// DELETE /admin/chat/:id +func DeleteChatHandler(c *gin.Context) { + id := c.Param("id") + // Delete messages first (foreign key cleanup usually, but we'll do manual for SQLite safety) + db.Conn.Exec("DELETE FROM messages WHERE chat_id = ?", id) + db.Conn.Exec("DELETE FROM chats WHERE id = ?", id) + c.Status(200) +} + +// PUT /admin/chat/:id/rename +func RenameChatHandler(c *gin.Context) { + id := c.Param("id") + var body struct { + Title string `json:"title"` + } + if err := c.BindJSON(&body); err != nil { + c.Status(400) + return + } + db.Conn.Exec("UPDATE chats SET title = ? WHERE id = ?", body.Title, id) + c.Status(200) } // GET /admin/chat/:id/messages diff --git a/main.go b/main.go index 6718443..573754a 100644 --- a/main.go +++ b/main.go @@ -33,7 +33,9 @@ func main() { r.POST("/admin/appointment", handlers.CreateAppointmentHandler) r.PUT("/admin/appointment/:id", handlers.UpdateAppointmentHandler) - r.POST("/admin/chat", handlers.NewChatHandler) // THE BUTTON HITS THIS + r.POST("/admin/chat", handlers.NewChatHandler) // THE BUTTON HITS THIS + r.DELETE("/admin/chat/:id", handlers.DeleteChatHandler) // <--- ADD THIS + r.PUT("/admin/chat/:id/rename", handlers.RenameChatHandler) // <--- ADD THIS r.GET("/admin/chat/:id/messages", handlers.GetMessagesHandler) r.POST("/admin/chat/:id/message", handlers.PostMessageHandler) diff --git a/services/openrouter.go b/services/openrouter.go index 485955b..001eb01 100644 --- a/services/openrouter.go +++ b/services/openrouter.go @@ -8,6 +8,7 @@ import ( "net/http" "os" "strings" + "time" "whatsapp-bot/db" ) @@ -41,28 +42,50 @@ func StreamAIResponse(chatHistory []Message, onToken func(string)) (string, erro apiKey := os.Getenv("OPENROUTER_API_KEY") url := "https://openrouter.ai/api/v1/chat/completions" + // 1. Get Current Time for the LLM + currentTime := time.Now().Format("Monday, 2006-01-02 15:04") + + // 2. Strict System Prompt + systemPrompt := fmt.Sprintf(` +You are a helpful scheduler assistant for a business in Chile. +Current Date/Time: %s + +RULES FOR BOOKING: +1. You MUST get three things from the user before booking: + - The Date (day/month) + - The Time (hour) + - The Phone Number +2. If any of these are missing, ASK for them. Do NOT assume or guess. +3. If the user says "tomorrow" or "next Friday", calculate the date based on the Current Date/Time above. +4. Only when you have all details, use the 'create_appointment' tool. +`, currentTime) + + // 3. Prepend System Prompt to History fullMessages := append([]Message{ - { - Role: "system", - Content: "You are a helpful business assistant. You can book appointments. If the user mentions scheduling an appointment always ask for his phone number and the time and date of the appointment, if the user wants to schedule something before doing it, it is requiered to have a phone number and a date, use the create_appointment tool. Be concise and polite.", - }, + {Role: "system", Content: systemPrompt}, }, chatHistory...) payload := map[string]interface{}{ - "model": "arcee-ai/trinity-large-preview:free", // arcee-ai/trinity-large-preview:free, stepfun/step-3.5-flash:free + "model": "arcee-ai/trinity-large-preview:free", // stepfun/step-3.5-flash:free, arcee-ai/trinity-large-preview:free "messages": fullMessages, - "stream": true, // <--- THIS IS KEY + "stream": true, "tools": []map[string]interface{}{ { "type": "function", "function": map[string]interface{}{ "name": "create_appointment", - "description": "Schedules a new appointment", + "description": "Schedules a new appointment. ONLY use this when you have a confirm date, time, and phone number.", "parameters": map[string]interface{}{ "type": "object", "properties": map[string]interface{}{ - "customer_phone": map[string]string{"type": "string"}, - "date": map[string]string{"type": "string"}, + "customer_phone": map[string]string{ + "type": "string", + "description": "The user's phone number (e.g., +569...)", + }, + "date": map[string]string{ + "type": "string", + "description": "The full date and time in YYYY-MM-DD HH:MM format", + }, }, "required": []string{"customer_phone", "date"}, }, diff --git a/templates/dashboard.html b/templates/dashboard.html index 14a21aa..e28a0bd 100644 --- a/templates/dashboard.html +++ b/templates/dashboard.html @@ -1,275 +1,434 @@ {{ define "dashboard.html" }} - + + SekiBot | Dashboard + -