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

# Multi-Party Conversations

> Build memory for group discussions and meetings with per-participant attribution

Group chats and meetings have many speakers. EverOS attributes memory to each
participant via their `sender_id`, and extracts the discussion into **shared
episodes** that every participant can recall. This guide builds memory for team
discussions and meeting notes.

## How multi-party memory works

* **One session, many senders.** Put the whole conversation in a single
  `session_id`; each message carries the `sender_id` of who spoke, with
  `role: "user"`.
* **Shared episodes.** Extraction produces episodes tagged with *all* the
  participants involved (`sender_ids`), summarizing what the group discussed and
  who committed to what.
* **Retrieve as any participant.** `search` takes exactly one `user_id`. Query
  as any participant and you get the shared discussion episodes they were part
  of. Each participant also accumulates their own consolidated **profile**.

<Note>
  There's no separate "group id" or group registration in v2. The session plus
  per-message `sender_id` is all EverOS needs. A group conversation's memory is
  reached through any of its participants.
</Note>

## Setup

```bash theme={null}
pip install everos-cloud
export EVEROS_API_KEY="your_api_key"
```

```python theme={null}
from everos_cloud import EverOS

client = EverOS()  # reads EVEROS_API_KEY
```

## Store a group discussion

Every message names its speaker with `sender_id`. Names are inferred, so you don't
register participants ahead of time.

```python theme={null}
client.add(
    session_id="team_engineering_2026_07",
    async_mode=False,
    messages=[
        {"sender_id": "user_alice", "role": "user",
         "content": "We need to pick a database for the new service. I'd lean PostgreSQL."},
        {"sender_id": "user_bob", "role": "user",
         "content": "Agreed on Postgres — it's what we know, and we already have monitoring for it."},
        {"sender_id": "user_carol", "role": "user",
         "content": "Works for me. Alice owns the schema, Bob takes migrations?"},
        {"sender_id": "user_alice", "role": "user",
         "content": "Yes. I'll have a schema draft by Friday."},
    ],
)

# Extract the discussion when the topic wraps up
client.flush("team_engineering_2026_07")
```

## Retrieve the discussion

Search as any participant to recall what the team decided. The returned episode
lists every `sender_id` it involved.

```python theme={null}
results = client.search(
    "database decision and who owns what",
    user_id="user_alice",      # any participant reaches the shared episode
    method="hybrid",
    top_k=5,
)

for ep in (results.episodes or []):
    print("participants:", ep.sender_ids)
    print("summary:     ", ep.summary)
# participants: ['user_alice', 'user_bob', 'user_carol']
# summary:      The team decided to use PostgreSQL; Alice owns the schema
#               (draft by Friday) and Bob owns migrations.
```

<Tip>
  Bob and Carol can retrieve the same decision from their own `user_id`. The
  episode belongs to everyone who was in the conversation. Use each participant's
  **profile** (`include_profile=True`) for their individual, consolidated traits.
</Tip>

## Use case: meeting memory bot

A bot that records a meeting and can surface relevant past discussion on demand.

```python theme={null}
from everos_cloud import EverOS

client = EverOS()


class MeetingMemoryBot:
    def __init__(self, meeting_id: str):
        self.session_id = f"meeting_{meeting_id}"

    def record(self, speaker_id: str, content: str):
        """Record one thing a participant said."""
        client.add(
            session_id=self.session_id,
            messages=[{"sender_id": speaker_id, "role": "user", "content": content}],
        )

    def relevant_context(self, participant_id: str, topic: str) -> str:
        """Surface past discussion relevant to the current topic."""
        results = client.search(
            topic, user_id=participant_id, method="hybrid", top_k=5,
        )
        eps = results.episodes or []
        if not eps:
            return "No relevant past discussion found."
        return "\n".join(f"- {e.summary}" for e in eps)

    def end_meeting(self):
        """Force extraction so the notes are recallable right away."""
        client.flush(self.session_id)


bot = MeetingMemoryBot("sprint_planning_2026_q3")

bot.record("user_alice", "Let's prioritize the auth refactor this sprint.")
bot.record("user_bob", "Agreed — I'll take the backend portion.")
bot.end_meeting()

print(bot.relevant_context("user_alice", "authentication work"))
```

## Best practices

<AccordionGroup>
  <Accordion title="One session per conversation or meeting">
    Keep a discussion in a single `session_id` so it extracts as one coherent,
    shared episode. Use descriptive ids: `meeting_sprint_planning_2026_q3`.
  </Accordion>

  <Accordion title="Message format">
    Each message needs a `sender_id`, `role: "user"`, and `content`. `timestamp`
    (unix ms) defaults to now; set it when backfilling a past meeting so the
    ordering is preserved.
  </Accordion>

  <Accordion title="Flush at topic boundaries">
    Call `client.flush(session_id)` when a topic wraps up or the meeting ends, so
    EverOS extracts a clean episode and participants can recall it immediately.
  </Accordion>
</AccordionGroup>

## Next steps

<CardGroup cols={2}>
  <Card title="Customer Support" icon="headset" href="/cookbook/customer-support">
    Per-user memory and clean agent handoffs.
  </Card>

  <Card title="Batch Processing" icon="layer-group" href="/cookbook/batch-processing">
    Import existing chat history at scale.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.