diff --git a/docs/api-reference/memory/feedback.mdx b/docs/api-reference/memory/feedback.mdx new file mode 100644 index 00000000..d9bb5d62 --- /dev/null +++ b/docs/api-reference/memory/feedback.mdx @@ -0,0 +1,4 @@ +--- +title: 'Feedback' +openapi: post /v1/feedback/ +--- diff --git a/docs/docs.json b/docs/docs.json index f56c22fe..5c6854d4 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -246,7 +246,8 @@ "api-reference/memory/batch-delete", "api-reference/memory/delete-memories", "api-reference/memory/create-memory-export", - "api-reference/memory/get-memory-export" + "api-reference/memory/get-memory-export", + "api-reference/memory/feedback" ] }, { diff --git a/docs/features/feedback-mechanism.mdx b/docs/features/feedback-mechanism.mdx index dcd40efd..1318b65c 100644 --- a/docs/features/feedback-mechanism.mdx +++ b/docs/features/feedback-mechanism.mdx @@ -17,9 +17,9 @@ You can give feedback on a memory by calling the `feedback` method on the Mem0 c ```python Python -from mem0 import Mem0 +from mem0 import MemoryClient -client = Mem0(api_key="your_api_key") +client = MemoryClient(api_key="your_api_key") client.feedback(memory_id="your-memory-id", feedback="NEGATIVE", feedback_reason="I don't like this memory because it is not relevant.") ``` diff --git a/docs/openapi.json b/docs/openapi.json index 0312e782..ea526d12 100644 --- a/docs/openapi.json +++ b/docs/openapi.json @@ -509,33 +509,33 @@ ] }, "post": { - "tags": [ + "tags": [ "exports" - ], + ], "summary": "Create an export job with schema", "description": "Create a structured export of memories based on a provided schema.", "operationId": "exports_create", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", "required": ["schema"], - "properties": { + "properties": { "schema": { "type": "object", "description": "Schema definition for the export" }, "user_id": { - "type": "string", + "type": "string", "description": "Filter exports by user ID" - }, + }, "run_id": { - "type": "string", + "type": "string", "description": "Filter exports by run ID" - }, + }, "session_id": { - "type": "string", + "type": "string", "description": "Filter exports by session ID" }, "app_id": { @@ -549,28 +549,28 @@ "project_id": { "type": "string", "description": "Filter exports by project ID" - } - } - } - } - }, - "required": true - }, - "responses": { + } + } + } + } + }, + "required": true + }, + "responses": { "201": { "description": "Export created successfully", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { "message": { "type": "string", "example": "Memory export request received. The export will be ready in a few seconds." }, - "id": { - "type": "string", - "format": "uuid", + "id": { + "type": "string", + "format": "uuid", "example": "550e8400-e29b-41d4-a716-446655440000" } }, @@ -587,15 +587,15 @@ "type": "object", "properties": { "message": { - "type": "string", + "type": "string", "example": "Schema is required and must be a valid object" } - } - } - } - } - } - }, + } + } + } + } + } + }, "x-code-samples": [ { "lang": "Python", @@ -622,7 +622,7 @@ "source": "import com.mashape.unirest.http.HttpResponse;\nimport com.mashape.unirest.http.JsonNode;\nimport com.mashape.unirest.http.Unirest;\nimport org.json.JSONObject;\n\nJSONObject data = new JSONObject()\n .put(\"schema\", new JSONObject()) // Your schema here\n .put(\"user_id\", \"your_user_id\");\n\nHttpResponse response = Unirest.post(\"https://api.mem0.ai/v1/exports/\")\n .header(\"Authorization\", \"Token \")\n .header(\"Content-Type\", \"application/json\")\n .body(data.toString())\n .asJson();" } ] - } + } }, "/v1/memories/": { "get": { @@ -2102,6 +2102,95 @@ "x-codegen-request-body-name": "data" } }, + "/v1/feedback/": { + "post": { + "tags": [ + "feedback" + ], + "description": "Submit feedback for a memory.", + "operationId": "submit_feedback", + "requestBody": { + "content": { + "application/json": { + "schema": { + "required": [ + "memory_id" + ], + "type": "object", + "properties": { + "memory_id": { + "type": "string", + "description": "ID of the memory to provide feedback for" + }, + "feedback": { + "type": "string", + "enum": ["POSITIVE", "NEGATIVE", "VERY_NEGATIVE"], + "nullable": true, + "description": "Type of feedback" + }, + "feedback_reason": { + "type": "string", + "nullable": true, + "description": "Reason for the feedback" + } + } + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful operation", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Feedback ID" + }, + "feedback": { + "type": "string", + "enum": ["POSITIVE", "NEGATIVE", "VERY_NEGATIVE"], + "nullable": true, + "description": "Type of feedback" + }, + "feedback_reason": { + "type": "string", + "nullable": true, + "description": "Reason for the feedback" + } + } + } + } + } + }, + "400": { + "description": "Invalid request" + }, + "401": { + "description": "Unauthorized" + } + }, + "x-code-samples": [ + { + "lang": "Python", + "source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\nclient = MemoryClient(api_key=\"your_api_key\")\n\n# Submit feedback for a memory\nfeedback = client.feedback(memory_id=\"memory_id\", feedback=\"POSITIVE\")\nprint(feedback)" + }, + { + "lang": "JavaScript", + "source": "// To use the JavaScript SDK, install the package:\n// npm install mem0ai\n\nimport MemoryClient from 'mem0ai';\n\nconst client = new MemoryClient({ apiKey: 'your-api-key'});\n\nclient.feedback({\n memory_id: \"your-memory-id\", \n feedback: \"NEGATIVE\", \n feedback_reason: \"I don't like this memory because it is not relevant.\"\n})" + }, + { + "lang": "cURL", + "source": "curl --request POST \\\n --url https://api.mem0.ai/v1/feedback/ \\\n --header 'Authorization: Token ' \\\n --header 'Content-Type: application/json' \\\n --data '{\"memory_id\": \"memory_id\", \"feedback\": \"POSITIVE\"}'" + } + ] + } + }, "/api/v1/orgs/organizations/": { "get": { "tags": [ @@ -3140,7 +3229,7 @@ "type": "object", "properties": { "message": { - "type": "string", + "type": "string", "example": "Unauthorized to create projects in this organization." } } @@ -3506,7 +3595,7 @@ "description": "Unauthorized to modify this project", "content": { "application/json": { - "schema": { + "schema": { "type": "object", "properties": { "message": { diff --git a/mem0/client/main.py b/mem0/client/main.py index e89871b3..f444df9c 100644 --- a/mem0/client/main.py +++ b/mem0/client/main.py @@ -3,7 +3,6 @@ import os import warnings from functools import wraps from typing import Any, Dict, List, Optional, Union -from enum import Enum import httpx @@ -618,6 +617,25 @@ class MemoryClient: capture_client_event("client.delete_webhook", self, {"webhook_id": webhook_id}) return response.json() + @api_error_handler + def feedback(self, memory_id: str, feedback: Optional[str] = None, feedback_reason: Optional[str] = None) -> Dict[str, str]: + VALID_FEEDBACK_VALUES = {"POSITIVE", "NEGATIVE", "VERY_NEGATIVE"} + + feedback = feedback.upper() if feedback else None + if feedback is not None and feedback not in VALID_FEEDBACK_VALUES: + raise ValueError(f'feedback must be one of {", ".join(VALID_FEEDBACK_VALUES)} or None') + + data = { + "memory_id": memory_id, + "feedback": feedback, + "feedback_reason": feedback_reason + } + + response = self.client.post("/v1/feedback/", json=data) + response.raise_for_status() + capture_client_event("client.feedback", self, data) + return response.json() + def _prepare_payload( self, messages: Union[str, List[Dict[str, str]], None], kwargs: Dict[str, Any] ) -> Dict[str, Any]: @@ -1007,7 +1025,7 @@ class AsyncMemoryClient: feedback = feedback.upper() if feedback else None if feedback is not None and feedback not in VALID_FEEDBACK_VALUES: raise ValueError(f'feedback must be one of {", ".join(VALID_FEEDBACK_VALUES)} or None') - + data = { "memory_id": memory_id, "feedback": feedback,