From 815b034c2d0defbc0b7916c7a00995263d1573ae Mon Sep 17 00:00:00 2001 From: Vito Sansevero Date: Thu, 29 May 2025 06:47:36 -0700 Subject: [PATCH 1/2] feat(api): add endpoint to add tags to prompts --- py/api.py | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/py/api.py b/py/api.py index 02cfb25..dedb2ca 100644 --- a/py/api.py +++ b/py/api.py @@ -186,6 +186,10 @@ class PromptManagerAPI: async def remove_tag_route(request): return await self.remove_prompt_tag(request) + @routes.post("/prompt_manager/prompts/tags") + async def add_tags_to_prompt_route(request): + return await self.add_tags_to_prompt(request) + # Bulk operations @routes.post("/prompt_manager/bulk/delete") async def bulk_delete_route(request): @@ -786,6 +790,74 @@ class PromptManagerAPI: {"success": False, "error": f"Failed to add tag: {str(e)}"}, status=500 ) + async def add_tags_to_prompt(self, request): + """Add multiple tags to a single prompt.""" + try: + data = await request.json() + prompt_id = data.get("prompt_id") + new_tags = data.get("tags", []) + + if not prompt_id: + return web.json_response( + {"success": False, "error": "Prompt ID is required"}, status=400 + ) + + if not new_tags or not isinstance(new_tags, list): + return web.json_response( + {"success": False, "error": "Tags must be a non-empty list"}, status=400 + ) + + # Get current prompt + prompt = self.db.get_prompt_by_id(prompt_id) + if not prompt: + return web.json_response( + {"success": False, "error": "Prompt not found"}, status=404 + ) + + # Get current tags + current_tags = prompt.get("tags", []) + if not isinstance(current_tags, list): + current_tags = [] + + # Add new tags if not already present + tags_added = 0 + for new_tag in new_tags: + new_tag = new_tag.strip() + if new_tag and new_tag not in current_tags: + current_tags.append(new_tag) + tags_added += 1 + + # Update database if any tags were added + if tags_added > 0: + with self.db.model.get_connection() as conn: + cursor = conn.execute( + "UPDATE prompts SET tags = ?, updated_at = ? WHERE id = ?", + ( + json.dumps(current_tags), + datetime.datetime.now(datetime.timezone.utc).isoformat(), + prompt_id, + ), + ) + conn.commit() + + message = f"{tags_added} tag(s) added successfully" + if tags_added == 0: + message = "No new tags to add (all tags already exist)" + + return web.json_response( + {"success": True, "message": message, "tags_added": tags_added} + ) + + except ValueError: + return web.json_response( + {"success": False, "error": "Invalid prompt ID"}, status=400 + ) + except Exception as e: + self.logger.error(f"Add tags error: {e}") + return web.json_response( + {"success": False, "error": f"Failed to add tags: {str(e)}"}, status=500 + ) + async def remove_prompt_tag(self, request): """Remove tag from prompt.""" try: From 0cd92f9c36fcdccf6fb99f803242b8c088b32c4b Mon Sep 17 00:00:00 2001 From: Vito Sansevero Date: Thu, 29 May 2025 06:47:50 -0700 Subject: [PATCH 2/2] feat(tags): Add individual tag modal functionality --- web/admin.html | 58 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 50 insertions(+), 8 deletions(-) diff --git a/web/admin.html b/web/admin.html index 3c8fbda..907b25b 100644 --- a/web/admin.html +++ b/web/admin.html @@ -328,6 +328,30 @@ + + + @@ -1322,25 +1350,39 @@ } } - async addTag(promptId) { - const tag = prompt("Enter new tag:"); - if (!tag) return; + addTag(promptId) { + // Store the prompt ID for later use + this.currentTagPromptId = promptId; + // Clear the input and show the modal + document.getElementById("individualTagInput").value = ""; + this.showModal("individualTagModal"); + } + + async confirmIndividualTag() { + const tags = document.getElementById("individualTagInput").value.split(",") + .map((tag) => tag.trim()).filter((tag) => tag); + + if (tags.length === 0) return; try { - const response = await fetch(`/prompt_manager/prompts/${promptId}/tags`, { + const response = await fetch("/prompt_manager/prompts/tags", { method: "POST", headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ tag: tag.trim() }), + body: JSON.stringify({ + prompt_id: this.currentTagPromptId, + tags: tags, + }), }); if (response.ok) { - this.showNotification("Tag added", "success"); + this.showNotification(`Tags added to prompt`, "success"); + this.hideModal("individualTagModal"); // Refresh both stats and results await this.loadStatistics(); this.search(); } } catch (error) { - this.showNotification("Failed to add tag", "error"); + this.showNotification("Failed to add tags", "error"); } }