{"id":34066252,"url":"https://github.com/recallrai/sdk-python","last_synced_at":"2026-01-21T21:01:58.327Z","repository":{"id":285118772,"uuid":"912416197","full_name":"recallrai/sdk-python","owner":"recallrai","description":"Official Python SDK for RecallrAI – a revolutionary contextual memory system that enables AI assistants to form meaningful connections between conversations, just like human memory.","archived":false,"fork":false,"pushed_at":"2026-01-18T08:33:26.000Z","size":148,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-18T15:54:10.674Z","etag":null,"topics":["ai","cognee","contextual-memory","getzep","halucination","long-term-memory","longmemeval","mem0","mem0ai","memora","memory","recallrai"],"latest_commit_sha":null,"homepage":"https://recallrai.com","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/recallrai.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-01-05T14:15:31.000Z","updated_at":"2026-01-18T08:33:29.000Z","dependencies_parsed_at":null,"dependency_job_id":"89989c48-62e4-4200-aaaf-6bd7b67a55a9","html_url":"https://github.com/recallrai/sdk-python","commit_stats":null,"previous_names":["recallrai/sdk-python"],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/recallrai/sdk-python","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/recallrai%2Fsdk-python","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/recallrai%2Fsdk-python/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/recallrai%2Fsdk-python/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/recallrai%2Fsdk-python/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/recallrai","download_url":"https://codeload.github.com/recallrai/sdk-python/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/recallrai%2Fsdk-python/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28642697,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-21T18:04:35.752Z","status":"ssl_error","status_checked_at":"2026-01-21T18:03:55.054Z","response_time":86,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","cognee","contextual-memory","getzep","halucination","long-term-memory","longmemeval","mem0","mem0ai","memora","memory","recallrai"],"created_at":"2025-12-14T06:26:08.469Z","updated_at":"2026-01-21T21:01:58.320Z","avatar_url":"https://github.com/recallrai.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# RecallrAI Python SDK\n\nOfficial Python SDK for RecallrAI – a revolutionary contextual memory system that enables AI assistants to form meaningful connections between conversations, just like human memory.\n\n**Note:** All datetime objects returned by the SDK are in UTC timezone.\n\n## Installation\n\nInstall the SDK via Poetry or pip:\n\n```bash\npoetry add recallrai\n# or\npip install recallrai\n```\n\n## Async Support\n\nThe SDK provides full async/await support for all operations! Use `AsyncRecallrAI`, `AsyncUser`, and `AsyncSession` for async applications. All usage patterns are identical to the sync versions, just with `await` keywords.\n\n## Initialization\n\nCreate a client instance with your API key and project ID:\n\n```python\nfrom recallrai import RecallrAI\n\nclient = RecallrAI(\n    api_key=\"rai_yourapikey\",\n    project_id=\"project-uuid\",\n    base_url=\"https://api.recallrai.com\",  # custom endpoint if applicable\n    timeout=60,  # seconds\n)\n```\n\n## User Management\n\n### Create a User\n\n```python\nfrom recallrai.exceptions import UserAlreadyExistsError\ntry:\n    user = client.create_user(user_id=\"user123\", metadata={\"name\": \"John Doe\"})\n    print(f\"Created user: {user.user_id}\")\n    print(f\"User metadata: {user.metadata}\")\n    print(f\"Created at: {user.created_at}\")\nexcept UserAlreadyExistsError as e:\n    print(f\"Error: {e}\")\n```\n\n### Get a User\n\n```python\nfrom recallrai.exceptions import UserNotFoundError\ntry:\n    user = client.get_user(\"user123\")\n    print(f\"User metadata: {user.metadata}\")\n    print(f\"Last active: {user.last_active_at}\")\nexcept UserNotFoundError as e:\n    print(f\"Error: {e}\")\n```\n\n### List Users\n\n```python\nuser_list = client.list_users(offset=0, limit=10, metadata_filter={\"role\": \"admin\"})\nprint(f\"Total users: {user_list.total}\")\nprint(f\"Has more users: {user_list.has_more}\")\nprint(\"---\")\n\nfor u in user_list.users:\n    print(f\"User ID: {u.user_id}\")\n    print(f\"Metadata: {u.metadata}\")\n    print(f\"Created at: {u.created_at}\")\n    print(f\"Last active: {u.last_active_at}\")\n    print(\"---\")\n```\n\n### Update a User\n\n```python\nfrom recallrai.exceptions import UserNotFoundError, UserAlreadyExistsError\ntry:\n    user = client.get_user(\"user123\")\n    # update() mutates the instance; no value is returned\n    user.update(\n        new_metadata={\"name\": \"John Doe\", \"role\": \"admin\"},\n        new_user_id=\"john_doe\"\n    )\n    print(f\"Updated user ID: {user.user_id}\")\n    print(f\"Updated metadata: {user.metadata}\")\n    print(f\"Last active: {user.last_active_at}\")\nexcept UserNotFoundError as e:\n    print(f\"Error: {e}\")\nexcept UserAlreadyExistsError as e:\n    print(f\"Error: {e}\")\n```\n\n### Refresh User Instance\n\n```python\nfrom recallrai.exceptions import UserNotFoundError\ntry:\n    user = client.get_user(\"john_doe\")\n    user.refresh()\n    print(f\"Refreshed user metadata: {user.metadata}\")\n    print(f\"Last active: {user.last_active_at}\")\nexcept UserNotFoundError as e:\n    print(f\"Error: {e}\")\n```\n\n### Delete a User\n\n```python\nfrom recallrai.exceptions import UserNotFoundError\ntry:\n    user = client.get_user(\"john_doe\")\n    user.delete()\n    print(\"User deleted successfully\")\nexcept UserNotFoundError as e:\n    print(f\"Error: {e}\")\n```\n\n## Session Management\n\n### Create a Session\n\n```python\nfrom recallrai.exceptions import UserNotFoundError\nfrom recallrai.session import Session\n\ntry:\n    # First, get the user\n    user = client.get_user(\"user123\")\n    \n    # Create a session for the user.\n    session: Session = user.create_session(\n        auto_process_after_seconds=600,\n        metadata={\"type\": \"chat\"}\n    )\n    print(\"Created session id:\", session.session_id)\nexcept UserNotFoundError as e:\n    print(f\"Error: {e}\")\n```\n\n### Get an Existing Session\n\n```python\nfrom recallrai.exceptions import UserNotFoundError, SessionNotFoundError\n\ntry:\n    # First, get the user\n    user = client.get_user(\"user123\")\n    \n    # Retrieve an existing session by its ID\n    session = user.get_session(session_id=\"session-uuid\")\n    print(\"Session status:\", session.status)\n    print(\"Session metadata:\", session.metadata)\nexcept UserNotFoundError as e:\n    print(f\"Error: {e}\")\nexcept SessionNotFoundError as e:\n    print(f\"Error: {e}\")\n```\n\n### Update a Session\n\n```python\nfrom recallrai.exceptions import UserNotFoundError, SessionNotFoundError\ntry:\n    # First, get the user\n    user = client.get_user(\"user123\")\n    \n    # Retrieve an existing session by its ID\n    session = user.get_session(session_id=\"session-uuid\")\n    \n    # Update session metadata\n    session.update(new_metadata={\"type\": \"support_chat\"})\n    print(\"Updated session metadata:\", session.metadata)\nexcept UserNotFoundError as e:\n    print(f\"Error: {e}\")\nexcept SessionNotFoundError as e:\n    print(f\"Error: {e}\")\n```\n\n### Refresh a Session\n\n```python\nfrom recallrai.exceptions import UserNotFoundError, SessionNotFoundError\ntry:\n    # First, get the user\n    user = client.get_user(\"user123\")\n\n    # Retrieve an existing session by its ID\n    session = user.get_session(session_id=\"session-uuid\")\n\n    # Refresh session data from the server\n    session.refresh()\n    print(\"Session status:\", session.status)\n    print(\"Refreshed session metadata:\", session.metadata)\nexcept UserNotFoundError as e:\n    print(f\"Error: {e}\")\nexcept SessionNotFoundError as e:\n    print(f\"Error: {e}\")\n```\n\n### List Sessions\n\n```python\nfrom recallrai.models import SessionStatus\nfrom recallrai.exceptions import UserNotFoundError\n\ntry:\n    # First, get the user\n    user = client.get_user(\"user123\")\n    \n    # List sessions for this user with optional filters\n    session_list = user.list_sessions(\n        offset=0,\n        limit=10,\n        metadata_filter={\"type\": \"chat\"},           # optional: filter by session metadata\n        status_filter=[SessionStatus.PENDING, SessionStatus.PROCESSING]     # optional: filter by session status\n    )\n    print(f\"Total sessions: {session_list.total}\")\n    print(f\"Has more sessions: {session_list.has_more}\")\n    for s in session_list.sessions:\n        print(s.session_id, s.status, s.metadata)\nexcept UserNotFoundError as e:\n    print(f\"Error: {e}\")\n```\n\n### Session – Adding Messages\n\n```python\nfrom recallrai.exceptions import UserNotFoundError, SessionNotFoundError, InvalidSessionStateError\nfrom recallrai.models import MessageRole\n\ntry:\n    # Add a user message\n    session.add_message(role=MessageRole.USER, content=\"Hello! How are you?\")\n    \n    # Add an assistant message\n    session.add_message(role=MessageRole.ASSISTANT, content=\"I'm an assistant. How can I help you?\")\n    \n    # Available message roles:\n    # - MessageRole.USER: Messages from the user/human\n    # - MessageRole.ASSISTANT: Messages from the AI assistant\nexcept UserNotFoundError as e:\n    print(f\"Error: {e}\")\nexcept SessionNotFoundError as e:\n    print(f\"Error: {e}\")\nexcept InvalidSessionStateError as e:\n    print(f\"Error: {e}\")\n```\n\n### Session – Retrieving Context\n\n```python\nfrom recallrai.exceptions import UserNotFoundError, SessionNotFoundError\nfrom recallrai.models import RecallStrategy\n\ntry:\n    # Get context with default parameters\n    context = session.get_context()\n    print(\"Context:\", context.context)\n    \n    # Get context with specific recall strategy\n    context = session.get_context(recall_strategy=RecallStrategy.LOW_LATENCY)\n    print(\"Context:\", context.context)\n    \n    # Get context with custom memory retrieval parameters\n    context = session.get_context(\n        recall_strategy=RecallStrategy.BALANCED,\n        min_top_k=10,\n        max_top_k=100,\n        memories_threshold=0.6,\n        summaries_threshold=0.5,\n        last_n_messages=20,\n        last_n_summaries=5,\n        timezone=\"America/Los_Angeles\"  # Optional: timezone for timestamp formatting, None for UTC\n    )\n    print(\"Context:\", context.context)\n    \n    # Available recall strategies:\n    # - RecallStrategy.LOW_LATENCY: Fast retrieval with basic relevance\n    # - RecallStrategy.BALANCED: Good balance of speed and quality (default)\n    # - RecallStrategy.AGENTIC: Agentic exploration for complex queries\n    \n    # Parameters:\n    # - min_top_k: Minimum number of memories to return (default: 15, range: 5-50)\n    # - max_top_k: Maximum number of memories to return (default: 50, range: 10-100)\n    # - memories_threshold: Similarity threshold for memories (default: 0.6, range: 0.2-0.8)\n    # - summaries_threshold: Similarity threshold for summaries (default: 0.5, range: 0.2-0.8)\n    # - last_n_messages: Number of last messages to include in context (optional, range: 1-100)\n    # - last_n_summaries: Number of last summaries to include in context (optional, range: 1-20)\n    # - timezone: Timezone for formatting timestamps (optional, e.g., 'America/New_York', None for UTC)\n    # - include_system_prompt: Whether to include the default system prompt of Recallr AI (default: True)\nexcept UserNotFoundError as e:\n    print(f\"Error: {e}\")\nexcept SessionNotFoundError as e:\n    print(f\"Error: {e}\")\n```\n\n### Session – Process Session\n\n```python\nfrom recallrai.exceptions import UserNotFoundError, SessionNotFoundError, InvalidSessionStateError\n\ntry:\n    session.process()\nexcept UserNotFoundError as e:\n    print(f\"Error: {e}\")\nexcept SessionNotFoundError as e:\n    print(f\"Error: {e}\")\nexcept InvalidSessionStateError as e:\n    print(f\"Error: {e}\")\n```\n\n### Session – List Messages\n\n```python\nfrom recallrai.exceptions import UserNotFoundError, SessionNotFoundError\n\ntry:\n    # Paginated retrieval\n    messages = session.get_messages(offset=0, limit=50)\n    for msg in messages.messages:\n        print(f\"{msg.role.value.upper()} (at {msg.timestamp}): {msg.content}\")\n    print(f\"Has more?: {messages.has_more}\")\n    print(f\"Total messages: {messages.total}\")\nexcept UserNotFoundError as e:\n    print(f\"Error: {e}\")\nexcept SessionNotFoundError as e:\n    print(f\"Error: {e}\")\n```\n\n## User Memories\n\n### List User Memories (with optional category filters)\n\n```python\nfrom recallrai.exceptions import UserNotFoundError, InvalidCategoriesError\n\ntry:\n    user = client.get_user(\"user123\")\n    \n    # List memories with all available options\n    memories = user.list_memories(\n        categories=[\"food_preferences\", \"allergies\"],  # optional: filter by categories\n        session_id_filter=[\"session-uuid-1\", \"session-uuid-2\"],  # optional: filter by specific sessions\n        session_metadata_filter={\"environment\": \"production\"},  # optional: filter by session metadata\n        offset=0,\n        limit=20,  # max 200\n        include_previous_versions=True,  # default: True - include version history\n        include_connected_memories=True,  # default: True - include related memories\n    )\n    \n    for mem in memories.items:\n        print(f\"Memory ID: {mem.memory_id}\")\n        print(f\"Categories: {mem.categories}\")\n        print(f\"Content: {mem.content}\")\n        print(f\"Created at: {mem.created_at}\")\n        print(f\"Session ID: {mem.session_id}\")\n        \n        # Version information\n        print(f\"Version: {mem.version_number} of {mem.total_versions}\")\n        print(f\"Has previous versions: {mem.has_previous_versions}\")\n        \n        # Previous versions (if included)\n        if mem.previous_versions:\n            print(f\"Previous versions: {len(mem.previous_versions)}\")\n            for version in mem.previous_versions:\n                print(f\"  - Version {version.version_number}: {version.content}\")\n                print(f\"    Created: {version.created_at}, Expired: {version.expired_at}\")\n                print(f\"    Expiration reason: {version.expiration_reason}\")\n        \n        # Connected memories (if included)\n        if mem.connected_memories:\n            print(f\"Connected memories: {len(mem.connected_memories)}\")\n            for connected in mem.connected_memories:\n                print(f\"  - {connected.memory_id}: {connected.content}\")\n        \n        # Merge conflict status\n        print(f\"Merge conflict in progress: {mem.merge_conflict_in_progress}\")\n        print(\"---\")\n    \n    print(f\"Has more?: {memories.has_more}\")\n    print(f\"Total memories: {memories.total}\")\n    \nexcept UserNotFoundError as e:\n    print(f\"Error: {e}\")\nexcept InvalidCategoriesError as e:\n    print(f\"Invalid categories: {e.invalid_categories}\")\n    print(f\"Error: {e}\")\n```\n\n#### Memory Item Fields\n\nEach memory item returned contains the following information:\n\n- **memory_id**: Unique identifier for the current/latest version of the memory\n- **categories**: List of category strings the memory belongs to\n- **content**: The current version's content text\n- **created_at**: Timestamp when the latest version was created\n- **session_id**: ID of the session that created this version\n- **version_number**: Which version this is (e.g., 3 means this is the 3rd version)\n- **total_versions**: Total number of versions that exist for this memory\n- **has_previous_versions**: Boolean indicating if `total_versions \u003e 1`\n- **previous_versions** (optional): List of `MemoryVersionInfo` objects containing:\n  - `version_number`: Sequential version number (1 = oldest)\n  - `content`: Content of that version\n  - `created_at`: When this version was created\n  - `expired_at`: When this version expired\n  - `expiration_reason`: Why it expired (e.g., new version created)\n- **connected_memories** (optional): List of `MemoryRelationship` objects containing:\n  - `memory_id`: ID of the connected memory\n  - `content`: Brief content for context\n- **merge_conflict_in_progress**: Boolean indicating if this memory has an active merge conflict\n\n## User Messages\n\n### Get Last N Messages\n\nRetrieve the most recent messages for a user across all their sessions. This is particularly useful for chatbot applications where you need conversation context, such as WhatsApp support bots where you want to pass the last few messages to understand the ongoing conversation.\n\n```python\nfrom recallrai.exceptions import UserNotFoundError\n\ntry:\n    user = client.get_user(\"user123\")\n    \n    # Fetch last N messages (e.g., last 5)\n    messages = user.get_last_n_messages(n=5)\n    \n    for msg in messages.messages:\n        print(f\"Session ID: {msg.session_id}\")\n        print(f\"{msg.role.upper()} (at {msg.timestamp}): {msg.content}\")\n        print(\"---\")\n\nexcept UserNotFoundError as e:\n    print(f\"Error: {e}\")\n```\n\n## Merge Conflict Management\n\nWhen RecallrAI processes sessions, it may detect conflicts between new memories and existing ones. The SDK provides comprehensive tools to handle these merge conflicts, allowing you to guide the resolution process through clarifying questions.\n\n### List Merge Conflicts\n\n```python\nfrom recallrai.exceptions import UserNotFoundError\nfrom recallrai.models import MergeConflictStatus\n\ntry:\n    user = client.get_user(\"user123\")\n    \n    # List all merge conflicts (with optional status filter)\n    conflicts = user.list_merge_conflicts(\n        offset=0,\n        limit=10,\n        status=MergeConflictStatus.PENDING,  # optional: filter by status\n        sort_by=\"created_at\",  # created_at, resolved_at\n        sort_order=\"desc\",  # asc, desc\n    )\n    \n    print(f\"Total conflicts: {conflicts.total}\")\n    print(f\"Has more: {conflicts.has_more}\")\n    \n    for conf in conflicts.conflicts:\n        print(f\"Conflict ID: {conf.conflict_id}\")\n        print(f\"Status: {conf.status}\")\n        print(f\"New memory: {conf.new_memory_content}\")\n        print(f\"Conflicting memories: {len(conf.conflicting_memories)}\")\n        print(f\"Questions: {len(conf.clarifying_questions)}\")\n        print(f\"Created at: {conf.created_at}\")\n        print(\"---\")\n        \nexcept UserNotFoundError as e:\n    print(f\"Error: {e}\")\n```\n\n### Get a Specific Merge Conflict\n\n```python\nfrom recallrai.exceptions import UserNotFoundError, MergeConflictNotFoundError\n\ntry:\n    user = client.get_user(\"user123\")\n    conflict = user.get_merge_conflict(\"conflict-uuid\")\n    \n    print(f\"Conflict ID: {conflict.conflict_id}\")\n    print(f\"Status: {conflict.status.value}\")\n    print(f\"New memory content: {conflict.new_memory_content}\")\n    \n    # Examine conflicting memories\n    print(\"\\nConflicting memories:\")\n    for mem in conflict.conflicting_memories:\n        print(f\"  Content: {mem.content}\")\n        print(f\"  Reason: {mem.reason}\")\n        print()\n    \n    # View clarifying questions\n    print(\"Clarifying questions:\")\n    for ques in conflict.clarifying_questions:\n        print(f\"  Question: {ques.question}\")\n        print(f\"  Options: {ques.options}\")\n        print()\n        \nexcept UserNotFoundError as e:\n    print(f\"Error: {e}\")\nexcept MergeConflictNotFoundError as e:\n    print(f\"Error: {e}\")\n```\n\n### Resolve a Merge Conflict\n\n```python\nfrom recallrai.exceptions import (\n    UserNotFoundError, \n    MergeConflictNotFoundError,\n    MergeConflictAlreadyResolvedError,\n    MergeConflictInvalidQuestionsError,\n    MergeConflictMissingAnswersError,\n    MergeConflictInvalidAnswerError,\n    ValidationError\n)\nfrom recallrai.models import MergeConflictAnswer\n\ntry:\n    user = client.get_user(\"user123\")\n    conflict = user.get_merge_conflict(\"conflict-uuid\")\n    \n    # Prepare answers to the clarifying questions\n    answers = []\n    for ques in conflict.clarifying_questions:\n        print(f\"  Question: {ques.question}\")\n        print(f\"  Options: {ques.options}\")\n        print()\n\n        answer = MergeConflictAnswer(\n            question=ques.question,\n            answer=ques.options[0],  # Select first option\n            message=\"User prefers this option based on recent conversation\"\n        )\n        answers.append(answer)\n    \n    # Resolve the conflict\n    conflict.resolve(answers)\n    print(f\"Conflict resolved! Status: {conflict.status}\")\n    print(f\"Resolved at: {conflict.resolved_at}\")\n    \n    if conflict.resolution_data:\n        print(f\"Resolution data: {conflict.resolution_data}\")\n        \nexcept UserNotFoundError as e:\n    print(f\"Error: {e}\")\nexcept MergeConflictNotFoundError as e:\n    print(f\"Error: {e}\")\nexcept MergeConflictAlreadyResolvedError as e:\n    print(f\"Error: {e}\")\nexcept MergeConflictInvalidQuestionsError as e:\n    print(f\"Error: {e}\")\n    if e.invalid_questions:\n        print(f\"Invalid questions: {e.invalid_questions}\")\nexcept MergeConflictMissingAnswersError as e:\n    print(f\"Error: {e}\")\n    if e.missing_questions:\n        print(f\"Missing answers for: {e.missing_questions}\")\nexcept MergeConflictInvalidAnswerError as e:\n    print(f\"Error: {e}\")\n    if e.question and e.valid_options:\n        print(f\"Question: {e.question}\")\n        print(f\"Valid options: {e.valid_options}\")\nexcept ValidationError as e:\n    print(f\"Error: {e}\")\n```\n\n### Refresh Merge Conflict Data\n\n```python\nfrom recallrai.exceptions import UserNotFoundError, MergeConflictNotFoundError\n\ntry:\n    user = client.get_user(\"user123\")\n    conflict = user.get_merge_conflict(\"conflict-uuid\")\n    \n    # Refresh to get latest status from server\n    conflict.refresh()\n    print(f\"Current status: {conflict.status}\")\n    print(f\"Last updated: {conflict.resolved_at}\")\n    \nexcept UserNotFoundError as e:\n    print(f\"Error: {e}\")\nexcept MergeConflictNotFoundError as e:\n    print(f\"Error: {e}\")\n```\n\n### Working with Merge Conflict Statuses\n\nThe merge conflict system uses several status values to track the lifecycle of conflicts:\n\n- **PENDING**: Conflict detected and waiting for resolution\n- **IN_QUEUE**: Conflict is queued for automated processing  \n- **RESOLVING**: Conflict is being processed\n- **RESOLVED**: Conflict has been successfully resolved\n- **FAILED**: Conflict resolution failed\n\n## Example Usage with LLMs\n\n```python\nimport openai\nfrom recallrai import RecallrAI\nfrom recallrai.exceptions import UserNotFoundError\nfrom recallrai.models import MessageRole\n\n# Initialize RecallrAI and OpenAI clients\nrai_client = RecallrAI(\n    api_key=\"rai_yourapikey\", \n    project_id=\"your-project-uuid\"\n)\noai_client = openai.OpenAI(api_key=\"your-openai-api-key\")\n\ndef chat_with_memory(user_id, session_id=None):\n    # Get or create user\n    try:\n        user = rai_client.get_user(user_id)\n    except UserNotFoundError:\n        user = rai_client.create_user(user_id)\n    \n    # Create a new session or get an existing one\n    if session_id:\n        session = user.get_session(session_id=session_id)\n    else:\n    session = user.create_session(auto_process_after_seconds=1800)\n        print(f\"Created new session: {session.session_id}\")\n    \n    print(\"Chat session started. Type 'exit' to end the conversation.\")\n    \n    while True:\n        # Get user input\n        user_message = input(\"You: \")\n        if user_message.lower() == 'exit':\n            break\n        \n        # Add the user message to RecallrAI\n        session.add_message(role=MessageRole.USER, content=user_message)\n        \n        # Get context from RecallrAI after adding the user message\n        # You can specify a recall strategy for different performance/quality trade-offs\n        # Additional parameters like min_top_k, max_top_k, memories_threshold, summaries_threshold, last_n_messages, last_n_summaries are available\n        context = session.get_context()  # Uses default BALANCED strategy\n        \n        # Create a system prompt that includes the context\n        system_prompt = \"You are a helpful assistant\" + context.context\n        \n        # Get previous messages\n        messages = session.get_messages(offset=0, limit=50)\n        previous_messages = [{\"role\": message.role, \"content\": message.content} for message in messages.messages]\n\n        # Call the LLM with the system prompt and conversation history\n        response = oai_client.chat.completions.create(\n            model=\"gpt-4o-mini\",\n            messages=[\n                {\"role\": \"system\", \"content\": system_prompt},\n                **previous_messages,\n            ],\n            temperature=0.7\n        )\n        \n        assistant_message = response.choices[0].message.content\n        \n        # Print the assistant's response\n        print(f\"Assistant: {assistant_message}\")\n        \n        # Add the assistant's response to RecallrAI\n        session.add_message(role=MessageRole.ASSISTANT, content=assistant_message)\n    \n    # Process the session at the end of the conversation\n    print(\"Processing session to update memory...\")\n    session.process()\n    print(f\"Session ended. Session ID: {session.session_id}\")\n    return session.session_id\n\n# Example usage\nif __name__ == \"__main__\":\n    user_id = \"user123\"\n    # To continue a previous session, uncomment below and provide the session ID\n    # previous_session_id = \"previously-saved-session-uuid\"\n    # session_id = chat_with_memory(user_id, previous_session_id)\n    \n    # Start a new session\n    session_id = chat_with_memory(user_id)\n    print(f\"To continue this conversation later, use session ID: {session_id}\")\n```\n\n## Exception Handling\n\nThe RecallrAI SDK implements a comprehensive exception hierarchy to help you handle different error scenarios gracefully:\n\n### Base Exception\n\n- **RecallrAIError**: The base exception for all SDK-specific errors. All other exceptions inherit from this.\n\n### Authentication Errors\n\n- **AuthenticationError**: Raised when there's an issue with your API key or project ID authentication.\n\n### Network-Related Errors\n\n- **TimeoutError**: Occurs when a request takes too long to complete.\n- **ConnectionError**: Happens when the SDK cannot establish a connection to the RecallrAI API.\n\n### Server Errors\n\n- **InternalServerError**: Raised when the RecallrAI API returns a 5xx error code.\n- **RateLimitError**: Raised when the API rate limit has been exceeded (HTTP 429). When available, the `retry_after` value is provided in the exception details.\n\n### User-Related Errors\n\n- **UserNotFoundError**: Raised when attempting to access a user that doesn't exist.\n- **UserAlreadyExistsError**: Occurs when creating a user with an ID that already exists.\n- **InvalidCategoriesError**: Raised when filtering user memories by categories that do not exist in the project. The exception contains the list of invalid categories in `e.invalid_categories`.\n\n### Session-Related Errors\n\n- **SessionNotFoundError**: Raised when attempting to access a non-existent session.\n- **InvalidSessionStateError**: Occurs when performing an operation that's not valid for the current session state (e.g., adding a message to a processed session).\n\n### Merge Conflict-Related Errors\n\n- **MergeConflictError**: Base class for merge conflict-related exceptions.\n- **MergeConflictNotFoundError**: Raised when attempting to access a merge conflict that doesn't exist.\n- **MergeConflictAlreadyResolvedError**: Occurs when trying to resolve a merge conflict that has already been processed.\n- **MergeConflictInvalidQuestionsError**: Raised when the provided questions don't match the original clarifying questions.\n- **MergeConflictMissingAnswersError**: Occurs when not all required clarifying questions have been answered.\n- **MergeConflictInvalidAnswerError**: Raised when an answer is not one of the valid options for a question.\n\n### Input Validation Errors\n\n- **ValidationError**: Raised when provided data doesn't meet the required format or constraints.\n\n### Importing Exceptions\n\nYou can import exceptions directly from the `recallrai.exceptions` module:\n\n```python\n# Import specific exceptions\nfrom recallrai.exceptions import (\n    UserNotFoundError, \n    SessionNotFoundError,\n    InvalidCategoriesError,\n    MergeConflictNotFoundError,\n    MergeConflictAlreadyResolvedError,\n    MergeConflictInvalidQuestionsError,\n    MergeConflictMissingAnswersError,\n    MergeConflictInvalidAnswerError,\n)\n\n# Import all exceptions\nfrom recallrai.exceptions import (\n    RecallrAIError,\n    AuthenticationError,\n    TimeoutError,\n    ConnectionError,\n    InternalServerError,\n    RateLimitError,\n    SessionNotFoundError, \n    InvalidSessionStateError,\n    UserNotFoundError, \n    UserAlreadyExistsError,\n    InvalidCategoriesError,\n    ValidationError,\n    MergeConflictError,\n    MergeConflictNotFoundError,\n    MergeConflictAlreadyResolvedError,\n    MergeConflictInvalidQuestionsError,\n    MergeConflictMissingAnswersError,\n    MergeConflictInvalidAnswerError,\n)\n```\n\n### Exception Hierarchy Diagram\n\n```mermaid\nflowchart LR\n    %% Title\n    title[Errors and Exceptions Hierarchy]\n    style title fill:none,stroke:none\n    \n    %% Base exception class\n    Exception[Exception]\n    RecallrAIError[RecallrAIError]\n    \n    %% First level exceptions\n    AuthenticationError[AuthenticationError]\n    NetworkError[NetworkError]\n    ServerError[ServerError]\n    UserError[UserError]\n    SessionError[SessionError]\n    MergeConflictError[MergeConflictError]\n    ValidationError[ValidationError]\n    \n    %% Second level exceptions - NetworkError children\n    TimeoutError[TimeoutError]\n    ConnectionError[ConnectionError]\n    \n    %% Second level exceptions - ServerError children\n    InternalServerError[Internal ServerError]\n    RateLimitError[RateLimitError]\n    \n    %% Second level exceptions - UserError children\n    UserNotFoundError[User NotFound Error]\n    UserAlreadyExistsError[User AlreadyExists Error]\n    \n    %% Second level exceptions - SessionError children\n    InvalidSessionStateError[Invalid SessionState Error]\n    SessionNotFoundError[Session NotFound Error]\n    \n    %% Second level exceptions - MergeConflictError children\n    MergeConflictNotFoundError[MergeConflict NotFound Error]\n    MergeConflictAlreadyResolvedError[MergeConflict AlreadyResolved Error]\n    MergeConflictInvalidQuestionsError[MergeConflict InvalidQuestions Error]\n    MergeConflictMissingAnswersError[MergeConflict MissingAnswers Error]\n    MergeConflictInvalidAnswerError[MergeConflict InvalidAnswer Error]\n    \n    %% Connect parent to base\n    Exception --\u003e RecallrAIError\n    \n    %% Connect base to first level\n    RecallrAIError --\u003e AuthenticationError\n    RecallrAIError --\u003e NetworkError\n    RecallrAIError --\u003e ServerError\n    RecallrAIError --\u003e UserError\n    RecallrAIError --\u003e SessionError\n    RecallrAIError --\u003e MergeConflictError\n    RecallrAIError --\u003e ValidationError\n    \n    %% Connect first level to second level\n    NetworkError --\u003e TimeoutError\n    NetworkError --\u003e ConnectionError\n    ServerError --\u003e InternalServerError\n    ServerError --\u003e RateLimitError\n    UserError --\u003e UserNotFoundError\n    UserError --\u003e UserAlreadyExistsError\n    SessionError --\u003e InvalidSessionStateError\n    SessionError --\u003e SessionNotFoundError\n    MergeConflictError --\u003e MergeConflictNotFoundError\n    MergeConflictError --\u003e MergeConflictAlreadyResolvedError\n    MergeConflictError --\u003e MergeConflictInvalidQuestionsError\n    MergeConflictError --\u003e MergeConflictMissingAnswersError\n    MergeConflictError --\u003e MergeConflictInvalidAnswerError\n```\n\n### Best Practices for Error Handling\n\nWhen implementing error handling with the RecallrAI SDK, consider these best practices:\n\n1. **Handle specific exceptions first**: Catch more specific exceptions before general ones.\n\n   ```python\n   try:\n       # SDK operation\n   except UserNotFoundError:\n       # Specific handling\n   except RecallrAIError:\n       # General fallback\n   ```\n\n2. **Implement retry logic for transient errors**: Network and timeout errors might be temporary.\n\n3. **Log detailed error information**: Exceptions contain useful information for debugging.\n\n4. **Handle common user flows**: For example, check if a user exists before operations, or create them if they don't:\n\n   ```python\n   try:\n       user = client.get_user(user_id)\n   except UserNotFoundError:\n       user = client.create_user(user_id)\n   ```\n\nFor more detailed information on specific exceptions, refer to the API documentation.\n\n## Conclusion\n\nThis README outlines the basic usage of the RecallrAI SDK functions for user and session management. For additional documentation and advanced usage, please see the [official documentation](https://docs.recallrai.com) or the source code repository on [GitHub](https://github.com/recallrai/sdk-python).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frecallrai%2Fsdk-python","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frecallrai%2Fsdk-python","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frecallrai%2Fsdk-python/lists"}