diff --git a/content/develop/ai/context-engine/agent-memory/_index.md b/content/develop/ai/context-engine/agent-memory/_index.md index 8fc7f17e7a..79f0baf490 100644 --- a/content/develop/ai/context-engine/agent-memory/_index.md +++ b/content/develop/ai/context-engine/agent-memory/_index.md @@ -141,4 +141,5 @@ For shared integration concepts, identifiers, and authentication, see the [Redis To generate a complete conversational agent that uses Agent Memory, open the [AI agent builder](/content/develop/ai/agent-builder/_index.md) and select **Redis Iris Conversational Assistant**. +To build a conversation list with recent activity and pagination, see [List and sort sessions](/content/develop/ai/context-engine/agent-memory/list-sessions.md). To configure shared memory placement and admission rules, see [Namespace routing](/content/develop/ai/context-engine/agent-memory/namespace-routing.md). diff --git a/content/develop/ai/context-engine/agent-memory/list-sessions.md b/content/develop/ai/context-engine/agent-memory/list-sessions.md new file mode 100644 index 0000000000..9ad7553acd --- /dev/null +++ b/content/develop/ai/context-engine/agent-memory/list-sessions.md @@ -0,0 +1,118 @@ +--- +alwaysopen: false +categories: +- docs +- develop +- ai +description: List session metadata by owner or namespace, sort results, and follow pagination. +hideListLinks: true +linktitle: List sessions +title: List and sort sessions +weight: 10 +--- + +Use session listing to let a user reopen an earlier conversation. The session rows contain IDs and available owner, timestamp, and namespace metadata. They do not contain conversation events or summary text. Retrieve the selected session with `GetSessionMemory` to build the agent's conversation context. + +## Choose a listing operation + +| Result you need | REST endpoint | Python method | TypeScript method | +|:----------------|:--------------|:--------------|:------------------| +| Session IDs | `GET /v1/stores/{storeId}/session-memory` | `list_sessions` | `listSessions` | +| Session rows with sorting | `GET /v1/stores/{storeId}/sessions` | `list_session_summaries` | `listSessionSummaries` | + +The second method's name refers to metadata rows, not generated conversation summaries. The ID-only operation remains available. Both operations return `items`, `total`, and an optional `nextPageToken`. + +For a user's personal conversations, set `filterOwnerId` to the user's authenticated ID. The session owner is the first event's `actorId`. Add `namespaceRef` to require an exact namespace ID as well. It does not include descendants, deprecated namespace labels, or sessions without a namespace resource. Owner and namespace matching is case-sensitive. + +A request without filters must set `includeAll=true`. Do not combine `includeAll=true` with either filter. Authorize store-wide or shared namespace listing in your application before making the request. A filter selects records; it does not establish the caller's right to access them. + +## Sort and paginate session rows + +The default is `sortBy=updatedAt` and `sortOrder=desc`, so recent activity appears first. `sortBy` accepts `sessionId`, `createdAt`, or `updatedAt`. When omitted, `sortOrder` is `asc` for `sessionId` and `desc` for timestamps. `limit` accepts 1–1000 and defaults to 100. + +Install `redis-agent-memory` for Python or `@redis-iris/agent-memory` for TypeScript. Use a service that supports the endpoint. Set `AGENT_MEMORY_URL`, `STORE_ID`, `API_KEY`, and `OWNER_ID` in your shell. See the [developer guide](/content/develop/ai/context-engine/agent-memory/developer-guide.md#connect-to-a-redis-agent-memory-service) for connection details. + +These examples list all pages for one owner, with the most recently updated sessions first: + +{{< multitabs id="sorted-session-list" tab1="Python" tab2="TypeScript" tab3="curl" >}} + +```python +import asyncio +import os + +from redis_agent_memory import AgentMemory + + +async def main(): + async with AgentMemory( + os.environ["AGENT_MEMORY_URL"], + store_id=os.environ["STORE_ID"], + api_key=os.environ["API_KEY"], + ) as agent_memory: + page_token = None + while True: + page = await agent_memory.list_session_summaries_async( + filter_owner_id=os.environ["OWNER_ID"], + sort_by="updatedAt", sort_order="desc", + limit=20, page_token=page_token, + ) + for session in page.items: + print(session.model_dump_json(by_alias=True)) + page_token = page.next_page_token + if not page_token: + break + + +asyncio.run(main()) +``` + +-tab-sep- + +```typescript +import { AgentMemory } from "@redis-iris/agent-memory"; + +async function main() { + const { AGENT_MEMORY_URL, STORE_ID, API_KEY, OWNER_ID } = process.env; + if (!AGENT_MEMORY_URL || !STORE_ID || !API_KEY || !OWNER_ID) { + throw new Error("Set AGENT_MEMORY_URL, STORE_ID, API_KEY, and OWNER_ID."); + } + const agentMemory = new AgentMemory({ + serverURL: AGENT_MEMORY_URL, storeId: STORE_ID, apiKey: API_KEY, + }); + let pageToken: string | undefined; + do { + const page = await agentMemory.listSessionSummaries( + 20, pageToken, OWNER_ID, undefined, undefined, "updatedAt", "desc", + ); + console.dir(page.items, { depth: null }); + pageToken = page.nextPageToken; + } while (pageToken); +} + +main().catch((error) => { console.error(error); process.exitCode = 1; }); +``` + +-tab-sep- + +```sh +page_token='' +while :; do + page=$(curl --fail-with-body --silent --show-error --get \ + --header "Authorization: Bearer $API_KEY" \ + --data-urlencode "filterOwnerId=$OWNER_ID" \ + --data-urlencode 'sortBy=updatedAt' --data-urlencode 'sortOrder=desc' \ + --data-urlencode 'limit=20' --data-urlencode "pageToken=$page_token" \ + "$AGENT_MEMORY_URL/v1/stores/$STORE_ID/sessions") || break + printf '%s\n' "$page" | jq '.items' + page_token=$(printf '%s\n' "$page" | jq -r '.nextPageToken // empty') + [ -n "$page_token" ] || break +done +``` + +{{< /multitabs >}} + +Pass each returned `nextPageToken` as `pageToken`. Keep filters and sort options unchanged; the token is bound to them. Stop when the token is absent. The token is opaque, so URL-encode it in REST requests. Changing a filter or sort requires a new request without the old token. + +Legacy sessions can omit `ownerId`, `createdAt`, or `updatedAt`. Handle those missing values when rendering a conversation list. A row's timestamps describe session metadata; they do not promise that background extraction or summarization has completed. + +TypeScript uses positional arguments. `listSessionSummaries` takes namespace filtering fourth, followed by `includeAll`, `sortBy`, and `sortOrder`. The older `listSessions` method keeps its previous argument order: `includeAll` is fourth, request options fifth, and the new namespace filter sixth. Do not copy one method's argument positions to the other. diff --git a/content/develop/ai/context-engine/agent-memory/rest-api-quickstart.md b/content/develop/ai/context-engine/agent-memory/rest-api-quickstart.md index 9a5d00feab..8c7b05ff80 100644 --- a/content/develop/ai/context-engine/agent-memory/rest-api-quickstart.md +++ b/content/develop/ai/context-engine/agent-memory/rest-api-quickstart.md @@ -51,7 +51,7 @@ Verify that the service is available: ```sh curl --fail-with-body --silent --show-error \ --header "Authorization: Bearer $API_KEY" \ - "$AGENT_MEMORY_URL/health" | jq + "$AGENT_MEMORY_URL/v1/stores/$STORE_ID/health" | jq ``` ## 1. Build conversation context with session memory @@ -94,6 +94,19 @@ The `events` array contains the stored message, its role, actor, and timestamps. > [!NOTE] > **What to expect:** The `events` array contains the travel message. Redis Agent Memory adds an `eventId` and `systemTimestamp`, showing that the application can recover the complete event later using only the session ID. +To find this owner's sessions by recent activity, request session rows: + +```sh +curl --fail-with-body --silent --show-error \ + --header "Authorization: Bearer $API_KEY" \ + "$AGENT_MEMORY_URL/v1/stores/$STORE_ID/sessions?filterOwnerId=$OWNER_ID&limit=20" | jq +``` + +The response includes `sessionId` and the available owner, creation, update, +and namespace details. It defaults to newest `updatedAt` first. Use +`nextPageToken` as `pageToken` with the same filter and sort options for the +next page. The existing `/session-memory` list returns session IDs. See [List and sort sessions](/content/develop/ai/context-engine/agent-memory/list-sessions.md) for Python, TypeScript, and curl pagination examples and filter rules. + ## 2. Recall automatically extracted information Redis Agent Memory processes session events in the background and creates long term memories for information that may be useful in later conversations. You configured the extraction cadence to one minute when you created the service. You do not need to submit a separate memory creation request. diff --git a/content/operate/iris/agent-memory/self-managed/api-examples.md b/content/operate/iris/agent-memory/self-managed/api-examples.md index 5f86c0f3dd..13375a1c2d 100644 --- a/content/operate/iris/agent-memory/self-managed/api-examples.md +++ b/content/operate/iris/agent-memory/self-managed/api-examples.md @@ -329,6 +329,21 @@ curl -sS "$DP_URL/v1/stores/$STORE_ID/session-memory?includeAll=true" \ `filterOwnerId` and `includeAll` are mutually exclusive. +The `/session-memory` list returns session IDs. To get session rows ordered by +recent activity, use `/sessions`: + +```bash +curl -sS "$DP_URL/v1/stores/$STORE_ID/sessions?filterOwnerId=user-001&sortBy=updatedAt&sortOrder=desc&limit=20" \ + -H "Authorization: Bearer $RAM_AGENT_KEY" +``` + +Each row includes `sessionId` and, when known, `ownerId`, `createdAt`, +`updatedAt`, and `namespaceRef`. Older sessions can have no owner or timestamps. +The default order is `updatedAt` descending. You can also sort by `sessionId` +or `createdAt`, each in ascending or descending order. Send `nextPageToken` as +`pageToken` with the same filters and sort options to fetch the next page. +The new route uses the same filter and authorization rules as `/session-memory`. + ### Create long-term memories directly ```bash