> ## Documentation Index
> Fetch the complete documentation index at: https://docs.recallrai.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Merge Conflict Resolution

> Handle and resolve memory merge conflicts

## Overview

When RecallrAI processes sessions, it may detect conflicts between new memories and existing ones. The SDK provides comprehensive tools to handle these merge conflicts through clarifying questions.

## MergeConflict Class

The `MergeConflict` class represents a conflict between memories that requires resolution.

### Properties

<ResponseField name="conflict_id" type="string">
  Unique identifier for the merge conflict.
</ResponseField>

<ResponseField name="user_id" type="string">
  ID of the user this conflict belongs to.
</ResponseField>

<ResponseField name="status" type="MergeConflictStatus">
  Current status: `PENDING`, `IN_QUEUE`, `RESOLVING`, `RESOLVED`, or `FAILED`
</ResponseField>

<ResponseField name="proposed_memory_content" type="string">
  Content of the proposed memory that conflicts with existing ones.
</ResponseField>

<ResponseField name="conflicting_memories" type="list">
  List of existing memories that conflict with the new memory. Each contains:

  * `content`: Memory content
  * `reason`: Explanation of why it conflicts
</ResponseField>

<ResponseField name="clarifying_questions" type="list">
  List of questions to help resolve the conflict. Each contains:

  * `question`: The question text
  * `options`: List of possible answers
</ResponseField>

<ResponseField name="created_at" type="datetime">
  UTC timestamp when the conflict was created.
</ResponseField>

<ResponseField name="resolved_at" type="datetime | None">
  UTC timestamp when resolved, or None if not yet resolved.
</ResponseField>

<ResponseField name="resolution_data" type="dict | None">
  Additional data about the resolution, or None if not resolved.
</ResponseField>

## List Merge Conflicts

List merge conflicts for a user with optional filtering.

```python theme={null}
from recallrai.models import MergeConflictStatus

user = client.get_user("user123")

conflicts = user.list_merge_conflicts(
    offset=0,
    limit=10,
    status=MergeConflictStatus.PENDING,
    sort_by="created_at",
    sort_order="desc"
)

print(f"Total conflicts: {conflicts.total}")
print(f"Has more: {conflicts.has_more}")

for conf in conflicts.conflicts:
    print(f"Conflict ID: {conf.conflict_id}")
    print(f"Status: {conf.status}")
    print(f"New memory: {conf.proposed_memory_content}")
    print(f"Conflicting memories: {len(conf.conflicting_memories)}")
    print(f"Questions: {len(conf.clarifying_questions)}")
```

<ParamField path="offset" type="integer">
  Number of conflicts to skip. Default: `0`
</ParamField>

<ParamField path="limit" type="integer">
  Maximum number of conflicts to return. Default: `10`
</ParamField>

<ParamField path="status" type="MergeConflictStatus">
  Filter by status. Options:

  * `PENDING`: Conflict detected and waiting for resolution
  * `IN_QUEUE`: Queued for automated processing
  * `RESOLVING`: Being processed
  * `RESOLVED`: Successfully resolved
  * `FAILED`: Resolution failed
</ParamField>

<ParamField path="sort_by" type="string">
  Sort field: `created_at` or `resolved_at`. Default: `created_at`
</ParamField>

<ParamField path="sort_order" type="string">
  Sort order: `asc` or `desc`. Default: `desc`
</ParamField>

**Returns:** `MergeConflictList` object with `conflicts`, `total`, and `has_more` fields

## Get a Specific Merge Conflict

Retrieve detailed information about a specific merge conflict.

```python theme={null}
from recallrai.exceptions import MergeConflictNotFoundError

try:
    user = client.get_user("user123")
    conflict = user.get_merge_conflict("conflict-uuid")
    
    print(f"Status: {conflict.status.value}")
    print(f"New memory: {conflict.proposed_memory_content}")
    
    # Examine conflicting memories
    print("\nConflicting memories:")
    for mem in conflict.conflicting_memories:
        print(f"  Content: {mem.content}")
        print(f"  Reason: {mem.reason}")
    
    # View clarifying questions
    print("\nClarifying questions:")
    for ques in conflict.clarifying_questions:
        print(f"  Question: {ques.question}")
        print(f"  Options: {ques.options}")
        
except MergeConflictNotFoundError as e:
    print(f"Error: {e}")
```

<ParamField path="conflict_id" type="string" required>
  The UUID of the merge conflict to retrieve.
</ParamField>

**Returns:** `MergeConflict` object

**Raises:** `UserNotFoundError`, `MergeConflictNotFoundError`

## Resolve a Merge Conflict

Resolve a merge conflict by answering the clarifying questions.

```python theme={null}
from recallrai.exceptions import (
    MergeConflictNotFoundError,
    MergeConflictAlreadyResolvedError,
    MergeConflictInvalidQuestionsError,
    MergeConflictMissingAnswersError,
    MergeConflictInvalidAnswerError,
)
from recallrai.models import MergeConflictAnswer

try:
    user = client.get_user("user123")
    conflict = user.get_merge_conflict("conflict-uuid")
    
    # Prepare answers to the clarifying questions
    answers = []
    for ques in conflict.clarifying_questions:
        print(f"Question: {ques.question}")
        print(f"Options: {ques.options}")
        
        # Select an option (in this example, we select the first one)
        answer = MergeConflictAnswer(
            question=ques.question,
            answer=ques.options[0],
            message="User prefers this option based on recent conversation"
        )
        answers.append(answer)
    
    # Resolve the conflict
    conflict.resolve(answers)
    
    print(f"Conflict resolved! Status: {conflict.status}")
    print(f"Resolved at: {conflict.resolved_at}")
    
    if conflict.resolution_data:
        print(f"Resolution data: {conflict.resolution_data}")
        
except MergeConflictNotFoundError as e:
    print(f"Conflict not found: {e}")
except MergeConflictAlreadyResolvedError as e:
    print(f"Conflict already resolved: {e}")
except MergeConflictInvalidQuestionsError as e:
    print(f"Invalid questions provided: {e}")
    if e.invalid_questions:
        print(f"Invalid questions: {e.invalid_questions}")
except MergeConflictMissingAnswersError as e:
    print(f"Missing answers: {e}")
    if e.missing_questions:
        print(f"Missing answers for: {e.missing_questions}")
except MergeConflictInvalidAnswerError as e:
    print(f"Invalid answer: {e}")
    if e.question and e.valid_options:
        print(f"Question: {e.question}")
        print(f"Valid options: {e.valid_options}")
```

### resolve() Method

<ParamField path="answers" type="list[MergeConflictAnswer]" required>
  List of answers to the clarifying questions. Each answer must include:

  * `question`: The question text (must match exactly)
  * `answer`: Selected option (must be one of the valid options)
  * `message`: Optional explanation for the choice
</ParamField>

**Returns:** None (updates the instance in place)

**Raises:**

* `MergeConflictNotFoundError`: Conflict doesn't exist
* `MergeConflictAlreadyResolvedError`: Conflict already processed
* `MergeConflictInvalidQuestionsError`: Questions don't match original questions
* `MergeConflictMissingAnswersError`: Not all questions have been answered
* `MergeConflictInvalidAnswerError`: Answer is not a valid option

<Warning>
  All clarifying questions must be answered, and each answer must match one of the provided options exactly.
</Warning>

## Refresh Merge Conflict

Refresh the merge conflict instance to get the latest status from the server.

```python theme={null}
user = client.get_user("user123")
conflict = user.get_merge_conflict("conflict-uuid")

# Refresh to get latest status
conflict.refresh()
print(f"Current status: {conflict.status}")
print(f"Resolved at: {conflict.resolved_at}")
```

**Returns:** None (updates the instance in place)

**Raises:** `UserNotFoundError`, `MergeConflictNotFoundError`

## MergeConflictAnswer Model

When resolving conflicts, you need to create `MergeConflictAnswer` objects:

```python theme={null}
from recallrai.models import MergeConflictAnswer

answer = MergeConflictAnswer(
    question="Which food preference is correct?",
    answer="User prefers vegetarian meals",
    message="User explicitly mentioned being vegetarian in last conversation"
)
```

<ParamField path="question" type="string" required>
  The exact question text from the conflict's clarifying questions.
</ParamField>

<ParamField path="answer" type="string" required>
  The selected option. Must be one of the valid options from the question.
</ParamField>

<ParamField path="message" type="string">
  Optional explanation for why this answer was selected.
</ParamField>

## Merge Conflict Statuses

<AccordionGroup>
  <Accordion title="PENDING">
    Conflict has been detected and is waiting for resolution. You can call `resolve()` to provide answers.
  </Accordion>

  <Accordion title="IN_QUEUE">
    Conflict is queued for automated processing by the system.
  </Accordion>

  <Accordion title="RESOLVING">
    Conflict is currently being processed.
  </Accordion>

  <Accordion title="RESOLVED">
    Conflict has been successfully resolved. The memories have been updated accordingly.
  </Accordion>

  <Accordion title="FAILED">
    Conflict resolution failed. You may need to contact support or try resolving again.
  </Accordion>
</AccordionGroup>

## Async Merge Conflicts

For async applications, all merge conflict methods support async/await:

```python theme={null}
from recallrai import AsyncRecallrAI

client = AsyncRecallrAI(api_key="rai_yourapikey", project_id="project-uuid")
user = await client.get_user("user123")

# All methods are the same, just use await
conflicts = await user.list_merge_conflicts(status=MergeConflictStatus.PENDING)
conflict = await user.get_merge_conflict("conflict-uuid")
await conflict.resolve(answers)
await conflict.refresh()
```

## Best Practices

<Tip>
  **Regular Monitoring**: Check for pending merge conflicts regularly, especially after processing sessions with important conversations.
</Tip>

<Tip>
  **Contextual Answers**: When resolving conflicts, use the `message` field to provide context about why you selected a particular answer. This helps improve the accuracy of future memory updates.
</Tip>

<Tip>
  **Error Handling**: Always handle the specific merge conflict exceptions to provide appropriate user feedback and recovery options.
</Tip>
