From f408e76e64e1f2e3eb4bf12a1d03fde1dec71b1f Mon Sep 17 00:00:00 2001 From: Andrew Brookins Date: Wed, 16 Sep 2026 13:03:00 -0700 Subject: [PATCH 1/3] docs: expose namespace routing in the memory API reference --- .../api-reference/openapi-agent-memory.json | 2747 +++++++++++++++-- 1 file changed, 2407 insertions(+), 340 deletions(-) diff --git a/content/develop/ai/context-engine/agent-memory/api-reference/openapi-agent-memory.json b/content/develop/ai/context-engine/agent-memory/api-reference/openapi-agent-memory.json index bbab8e30d1..e6ee18679c 100644 --- a/content/develop/ai/context-engine/agent-memory/api-reference/openapi-agent-memory.json +++ b/content/develop/ai/context-engine/agent-memory/api-reference/openapi-agent-memory.json @@ -117,6 +117,16 @@ } } }, + "423": { + "description": "ResourceSuspendedError 423 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResourceSuspendedErrorResponseContent" + } + } + } + }, "424": { "description": "FailedDependencyError 424 response", "content": { @@ -253,6 +263,16 @@ } } }, + "423": { + "description": "ResourceSuspendedError 423 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResourceSuspendedErrorResponseContent" + } + } + } + }, "424": { "description": "FailedDependencyError 424 response", "content": { @@ -289,7 +309,7 @@ ] }, "post": { - "description": "Creates long-term memories in bulk.", + "description": "Creates long-term memories in bulk. Records without namespace or namespaceRef use automatic routing when the store's routing policy is enabled. If routing is disabled or no destination qualifies, the record is created without a namespace. An explicit namespaceRef must pass destination admission and is never rerouted. Routing and admission failures are reported per record in errors.", "operationId": "BulkCreateLongTermMemories", "requestBody": { "content": { @@ -387,12 +407,22 @@ } } }, + "423": { + "description": "ResourceSuspendedError 423 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResourceSuspendedErrorResponseContent" + } + } + } + }, "424": { - "description": "FailedDependencyError 424 response", + "description": "MemoryFailedDependencyError 424 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/FailedDependencyErrorResponseContent" + "$ref": "#/components/schemas/MemoryFailedDependencyErrorResponseContent" } } } @@ -423,41 +453,42 @@ ] } }, - "/v1/stores/{storeId}/long-term-memory/search": { + "/v1/stores/{storeId}/long-term-memory/move": { "post": { - "description": "Runs a semantic search on long-term memory with filtering options.", - "operationId": "SearchLongTermMemory", + "description": "Moves long-term memories to an explicit namespaceRef or automatically routes each memory when namespaceRef is omitted. If routing is disabled or no destination qualifies, the memory keeps its current placement and receives a per-item error. An explicit destination must pass admission and is never rerouted. Returns 409 when the explicit destination is archived; automatic routing and admission failures are reported per item in errors.", + "operationId": "MoveLongTermMemories", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SearchLongTermMemoryRequestContent" + "$ref": "#/components/schemas/MoveLongTermMemoriesRequestContent" } } - } + }, + "required": true }, "parameters": [ { "name": "storeId", "in": "path", - "description": "The store instance ID.", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes.", "schema": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "The store instance ID." + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes." }, "required": true } ], "responses": { "200": { - "description": "SearchLongTermMemory 200 response", + "description": "MoveLongTermMemories 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SearchLongTermMemoryResponseContent" + "$ref": "#/components/schemas/MoveLongTermMemoriesResponseContent" } } } @@ -512,6 +543,16 @@ } } }, + "409": { + "description": "ConflictError 409 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConflictErrorResponseContent" + } + } + } + }, "413": { "description": "PayloadTooLargeError 413 response", "content": { @@ -522,6 +563,16 @@ } } }, + "423": { + "description": "ResourceSuspendedError 423 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResourceSuspendedErrorResponseContent" + } + } + } + }, "424": { "description": "FailedDependencyError 424 response", "content": { @@ -558,10 +609,19 @@ ] } }, - "/v1/stores/{storeId}/long-term-memory/{memoryId}": { - "get": { - "description": "Returns a long-term memory by its ID.", - "operationId": "GetLongTermMemory", + "/v1/stores/{storeId}/long-term-memory/search": { + "post": { + "description": "Runs a semantic search on long-term memory with filtering options.", + "operationId": "SearchLongTermMemory", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SearchLongTermMemoryRequestContent" + } + } + } + }, "parameters": [ { "name": "storeId", @@ -575,28 +635,15 @@ "description": "The store instance ID." }, "required": true - }, - { - "name": "memoryId", - "in": "path", - "description": "The memory record ID.", - "schema": { - "type": "string", - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-]+$", - "description": "The memory record ID." - }, - "required": true } ], "responses": { "200": { - "description": "GetLongTermMemory 200 response", + "description": "SearchLongTermMemory 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetLongTermMemoryResponseContent" + "$ref": "#/components/schemas/SearchLongTermMemoryResponseContent" } } } @@ -661,12 +708,22 @@ } } }, + "423": { + "description": "ResourceSuspendedError 423 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResourceSuspendedErrorResponseContent" + } + } + } + }, "424": { - "description": "FailedDependencyError 424 response", + "description": "MemoryFailedDependencyError 424 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/FailedDependencyErrorResponseContent" + "$ref": "#/components/schemas/MemoryFailedDependencyErrorResponseContent" } } } @@ -695,19 +752,12 @@ "tags": [ "Long-Term Memory" ] - }, - "patch": { - "description": "Partially updates a long-term memory by its ID.", - "operationId": "UpdateLongTermMemory", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateLongTermMemoryRequestContent" - } - } - } - }, + } + }, + "/v1/stores/{storeId}/long-term-memory/{memoryId}": { + "get": { + "description": "Returns a long-term memory by its ID.", + "operationId": "GetLongTermMemory", "parameters": [ { "name": "storeId", @@ -738,11 +788,11 @@ ], "responses": { "200": { - "description": "UpdateLongTermMemory 200 response", + "description": "GetLongTermMemory 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateLongTermMemoryResponseContent" + "$ref": "#/components/schemas/GetLongTermMemoryResponseContent" } } } @@ -807,6 +857,16 @@ } } }, + "423": { + "description": "ResourceSuspendedError 423 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResourceSuspendedErrorResponseContent" + } + } + } + }, "424": { "description": "FailedDependencyError 424 response", "content": { @@ -841,21 +901,18 @@ "tags": [ "Long-Term Memory" ] - } - }, - "/v1/stores/{storeId}/long-term-memory/{memoryId}/fields": { + }, "patch": { - "description": "Atomically updates a custom-typed long-term memory's text and/or attributes, scoped to the caller's bound memory type. Used by the custom-extraction worker.", - "operationId": "UpdateLongTermMemoryFields", + "description": "Partially updates a long-term memory by its ID. The merged record must pass admission at its destination. Updates never select a different destination automatically.", + "operationId": "UpdateLongTermMemory", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateLongTermMemoryFieldsRequestContent" + "$ref": "#/components/schemas/UpdateLongTermMemoryRequestContent" } } - }, - "required": true + } }, "parameters": [ { @@ -887,7 +944,14 @@ ], "responses": { "200": { - "description": "UpdateLongTermMemoryFields 200 response" + "description": "UpdateLongTermMemory 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateLongTermMemoryResponseContent" + } + } + } }, "400": { "description": "BadRequestError 400 response", @@ -939,12 +1003,42 @@ } } }, + "409": { + "description": "ConflictError 409 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConflictErrorResponseContent" + } + } + } + }, + "413": { + "description": "PayloadTooLargeError 413 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PayloadTooLargeErrorResponseContent" + } + } + } + }, + "423": { + "description": "ResourceSuspendedError 423 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResourceSuspendedErrorResponseContent" + } + } + } + }, "424": { - "description": "FailedDependencyError 424 response", + "description": "MemoryFailedDependencyError 424 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/FailedDependencyErrorResponseContent" + "$ref": "#/components/schemas/MemoryFailedDependencyErrorResponseContent" } } } @@ -975,10 +1069,20 @@ ] } }, - "/v1/stores/{storeId}/session-memory": { - "get": { - "description": "Returns a paginated list of session IDs for a store.", - "operationId": "ListSessions", + "/v1/stores/{storeId}/long-term-memory/{memoryId}/fields": { + "patch": { + "description": "Atomically updates a custom-typed long-term memory's text and/or attributes, scoped to the caller's bound memory type. Used by the custom-extraction worker. New text must pass destination admission before the update is applied.", + "operationId": "UpdateLongTermMemoryFields", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateLongTermMemoryFieldsRequestContent" + } + } + }, + "required": true + }, "parameters": [ { "name": "storeId", @@ -994,59 +1098,22 @@ "required": true }, { - "name": "limit", - "in": "query", - "description": "Maximum number of sessions to return. Defaults to 100. Allowed range: 1-1000.", - "schema": { - "type": "integer", - "default": 100, - "maximum": 1000, - "minimum": 1, - "description": "Maximum number of sessions to return. Defaults to 100. Allowed range: 1-1000.", - "format": "int32" - } - }, - { - "name": "pageToken", - "in": "query", - "description": "Opaque token from a previous response for the next page.", - "schema": { - "type": "string", - "description": "Opaque token from a previous response for the next page." - } - }, - { - "name": "filterOwnerId", - "in": "query", - "description": "Filter sessions by owner. Matching is case-sensitive. Mutually exclusive with includeAll.", + "name": "memoryId", + "in": "path", + "description": "The memory record ID.", "schema": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Filter sessions by owner. Matching is case-sensitive. Mutually exclusive with includeAll." - } - }, - { - "name": "includeAll", - "in": "query", - "description": "Set to true to list all sessions. Required when no filter is given; mutually exclusive with filters.", - "schema": { - "type": "boolean", - "description": "Set to true to list all sessions. Required when no filter is given; mutually exclusive with filters." - } + "description": "The memory record ID." + }, + "required": true } ], "responses": { "200": { - "description": "ListSessions 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ListSessionsResponseContent" - } - } - } + "description": "UpdateLongTermMemoryFields 200 response" }, "400": { "description": "BadRequestError 400 response", @@ -1098,22 +1165,32 @@ } } }, - "413": { - "description": "PayloadTooLargeError 413 response", + "409": { + "description": "ConflictError 409 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PayloadTooLargeErrorResponseContent" + "$ref": "#/components/schemas/ConflictErrorResponseContent" + } + } + } + }, + "423": { + "description": "ResourceSuspendedError 423 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResourceSuspendedErrorResponseContent" } } } }, "424": { - "description": "FailedDependencyError 424 response", + "description": "MemoryFailedDependencyError 424 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/FailedDependencyErrorResponseContent" + "$ref": "#/components/schemas/MemoryFailedDependencyErrorResponseContent" } } } @@ -1140,46 +1217,36 @@ } }, "tags": [ - "Session Memory" + "Long-Term Memory" ] } }, - "/v1/stores/{storeId}/session-memory/events": { - "post": { - "description": "Appends a single event to a session. Creates the session if it does not exist. If sessionId is omitted, the server generates one.", - "operationId": "AddSessionEvent", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AddSessionEventRequestContent" - } - } - }, - "required": true - }, + "/v1/stores/{storeId}/namespace-routing": { + "get": { + "description": "Returns the store's namespace routing policy. An empty disabled policy is returned when none has been saved.", + "operationId": "GetNamespaceRouting", "parameters": [ { "name": "storeId", "in": "path", - "description": "The store instance ID.", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes.", "schema": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "The store instance ID." + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes." }, "required": true } ], "responses": { - "201": { - "description": "AddSessionEvent 201 response", + "200": { + "description": "GetNamespaceRouting 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AddSessionEventResponseContent" + "$ref": "#/components/schemas/GetNamespaceRoutingResponseContent" } } } @@ -1244,6 +1311,16 @@ } } }, + "423": { + "description": "ResourceSuspendedError 423 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResourceSuspendedErrorResponseContent" + } + } + } + }, "424": { "description": "FailedDependencyError 424 response", "content": { @@ -1276,45 +1353,47 @@ } }, "tags": [ - "Session Memory" + "Namespaces" ] - } - }, - "/v1/stores/{storeId}/session-memory/{sessionId}": { - "delete": { - "description": "Deletes the session memory for a session.", - "operationId": "DeleteSessionMemory", + }, + "put": { + "description": "Replaces the store's namespace routing policy. Namespaces remain hierarchy records; routing is an ordered store-level document of plug-in strategies.", + "operationId": "PutNamespaceRouting", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PutNamespaceRoutingRequestContent" + } + } + }, + "required": true + }, "parameters": [ { "name": "storeId", "in": "path", - "description": "The store instance ID.", - "schema": { - "type": "string", - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-]+$", - "description": "The store instance ID." - }, - "required": true - }, - { - "name": "sessionId", - "in": "path", - "description": "The session ID.", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes.", "schema": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "The session ID." + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes." }, "required": true } ], "responses": { - "204": { - "description": "DeleteSessionMemory 204 response" + "200": { + "description": "PutNamespaceRouting 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PutNamespaceRoutingResponseContent" + } + } + } }, "400": { "description": "BadRequestError 400 response", @@ -1366,6 +1445,16 @@ } } }, + "409": { + "description": "ConflictError 409 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConflictErrorResponseContent" + } + } + } + }, "413": { "description": "PayloadTooLargeError 413 response", "content": { @@ -1376,6 +1465,16 @@ } } }, + "423": { + "description": "ResourceSuspendedError 423 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResourceSuspendedErrorResponseContent" + } + } + } + }, "424": { "description": "FailedDependencyError 424 response", "content": { @@ -1408,56 +1507,90 @@ } }, "tags": [ - "Session Memory" + "Namespaces" ] - }, + } + }, + "/v1/stores/{storeId}/namespaces": { "get": { - "description": "Returns the session memory for a session.", - "operationId": "GetSessionMemory", + "description": "Lists namespace roots or direct children.", + "operationId": "ListNamespaces", "parameters": [ { "name": "storeId", "in": "path", - "description": "The store instance ID.", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes.", "schema": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "The store instance ID." + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes." }, "required": true }, { - "name": "sessionId", - "in": "path", - "description": "The session ID.", + "name": "parentId", + "in": "query", + "description": "List direct children of this namespace. Omit to list roots.", "schema": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "The session ID." - }, - "required": true + "description": "List direct children of this namespace. Omit to list roots." + } }, { - "name": "includeSummarisedEvents", + "name": "scope", "in": "query", - "description": "When true, the response includes events that have already been covered by the session summary and have not yet been cleaned up. This flag is not expected to be set under normal usage.", + "description": "Restrict root results to one scope. Cannot be combined with parentId.", "schema": { - "type": "boolean", - "description": "When true, the response includes events that have already been covered by the session summary and have not yet been cleaned up. This flag is not expected to be set under normal usage." + "$ref": "#/components/schemas/NamespaceScope" + } + }, + { + "name": "ownerId", + "in": "query", + "description": "Restrict personal root results to an owner. Cannot be combined with parentId; ignored for shared roots.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Restrict personal root results to an owner. Cannot be combined with parentId; ignored for shared roots." + } + }, + { + "name": "limit", + "in": "query", + "description": "Maximum number of namespaces to return. Defaults to 100. Allowed range: 1-1000.", + "schema": { + "type": "integer", + "default": 100, + "maximum": 1000, + "minimum": 1, + "description": "Maximum number of namespaces to return. Defaults to 100. Allowed range: 1-1000.", + "format": "int32" + } + }, + { + "name": "pageToken", + "in": "query", + "description": "Opaque token from a previous response for the next page.", + "schema": { + "type": "string", + "description": "Opaque token from a previous response for the next page." } } ], "responses": { "200": { - "description": "GetSessionMemory 200 response", + "description": "ListNamespaces 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetSessionMemoryResponseContent" + "$ref": "#/components/schemas/ListNamespacesResponseContent" } } } @@ -1522,6 +1655,16 @@ } } }, + "423": { + "description": "ResourceSuspendedError 423 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResourceSuspendedErrorResponseContent" + } + } + } + }, "424": { "description": "FailedDependencyError 424 response", "content": { @@ -1554,58 +1697,46 @@ } }, "tags": [ - "Session Memory" + "Namespaces" ] - } - }, - "/v1/stores/{storeId}/session-memory/{sessionId}/events/{eventId}": { - "delete": { - "description": "Deletes a single event from a session by event ID.", - "operationId": "DeleteSessionEvent", + }, + "post": { + "description": "Creates a namespace resource as a root, direct child, or explicit hierarchy path. Returns 409 when an active or archived namespace already occupies the requested location.", + "operationId": "CreateNamespace", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateNamespaceRequestContent" + } + } + } + }, "parameters": [ { "name": "storeId", "in": "path", - "description": "The store instance ID.", - "schema": { - "type": "string", - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-]+$", - "description": "The store instance ID." - }, - "required": true - }, - { - "name": "sessionId", - "in": "path", - "description": "The session ID.", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes.", "schema": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "The session ID." - }, - "required": true - }, - { - "name": "eventId", - "in": "path", - "description": "The event ID.", - "schema": { - "type": "string", - "maxLength": 32, - "minLength": 32, - "pattern": "^[a-zA-Z0-9]+$", - "description": "The event ID." + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes." }, "required": true } ], "responses": { - "204": { - "description": "DeleteSessionEvent 204 response" + "201": { + "description": "CreateNamespace 201 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateNamespaceResponseContent" + } + } + } }, "400": { "description": "BadRequestError 400 response", @@ -1657,6 +1788,16 @@ } } }, + "409": { + "description": "ConflictError 409 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConflictErrorResponseContent" + } + } + } + }, "413": { "description": "PayloadTooLargeError 413 response", "content": { @@ -1667,6 +1808,16 @@ } } }, + "423": { + "description": "ResourceSuspendedError 423 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResourceSuspendedErrorResponseContent" + } + } + } + }, "424": { "description": "FailedDependencyError 424 response", "content": { @@ -1699,63 +1850,45 @@ } }, "tags": [ - "Session Memory" + "Namespaces" ] - }, - "get": { - "description": "Returns a single event from a session by event ID.", - "operationId": "GetSessionEvent", + } + }, + "/v1/stores/{storeId}/namespaces/{namespaceId}": { + "delete": { + "description": "Deletes an empty leaf namespace. Returns 409 when the namespace has children or memory placements, or when it changed concurrently.", + "operationId": "DeleteNamespace", "parameters": [ { "name": "storeId", "in": "path", - "description": "The store instance ID.", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes.", "schema": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "The store instance ID." + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes." }, "required": true }, { - "name": "sessionId", + "name": "namespaceId", "in": "path", - "description": "The session ID.", + "description": "Server-generated namespace identifier.", "schema": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "The session ID." - }, - "required": true - }, - { - "name": "eventId", - "in": "path", - "description": "The event ID.", - "schema": { - "type": "string", - "maxLength": 32, - "minLength": 32, - "pattern": "^[a-zA-Z0-9]+$", - "description": "The event ID." + "description": "Server-generated namespace identifier." }, "required": true } ], "responses": { - "200": { - "description": "GetSessionEvent 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/GetSessionEventResponseContent" - } - } - } + "204": { + "description": "DeleteNamespace 204 response" }, "400": { "description": "BadRequestError 400 response", @@ -1807,6 +1940,16 @@ } } }, + "409": { + "description": "ConflictError 409 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConflictErrorResponseContent" + } + } + } + }, "413": { "description": "PayloadTooLargeError 413 response", "content": { @@ -1817,6 +1960,16 @@ } } }, + "423": { + "description": "ResourceSuspendedError 423 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResourceSuspendedErrorResponseContent" + } + } + } + }, "424": { "description": "FailedDependencyError 424 response", "content": { @@ -1849,12 +2002,1275 @@ } }, "tags": [ - "Session Memory" + "Namespaces" ] - } - } - }, - "components": { + }, + "get": { + "description": "Gets one namespace by its canonical ID.", + "operationId": "GetNamespace", + "parameters": [ + { + "name": "storeId", + "in": "path", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes." + }, + "required": true + }, + { + "name": "namespaceId", + "in": "path", + "description": "Server-generated namespace identifier.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Server-generated namespace identifier." + }, + "required": true + } + ], + "responses": { + "200": { + "description": "GetNamespace 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetNamespaceResponseContent" + } + } + } + }, + "400": { + "description": "BadRequestError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BadRequestErrorResponseContent" + } + } + } + }, + "401": { + "description": "AuthenticationError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthenticationErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "408": { + "description": "TimeoutError 408 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TimeoutErrorResponseContent" + } + } + } + }, + "413": { + "description": "PayloadTooLargeError 413 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PayloadTooLargeErrorResponseContent" + } + } + } + }, + "423": { + "description": "ResourceSuspendedError 423 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResourceSuspendedErrorResponseContent" + } + } + } + }, + "424": { + "description": "FailedDependencyError 424 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FailedDependencyErrorResponseContent" + } + } + } + }, + "429": { + "description": "TooManyRequestsError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TooManyRequestsErrorResponseContent" + } + } + } + }, + "500": { + "description": "UnexpectedError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnexpectedErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Namespaces" + ] + }, + "patch": { + "description": "Renames or archives a namespace. Returns 409 when the namespace changed concurrently, an active or archived sibling already uses the requested name, or the namespace is archived.", + "operationId": "UpdateNamespace", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateNamespaceRequestContent" + } + } + } + }, + "parameters": [ + { + "name": "storeId", + "in": "path", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes." + }, + "required": true + }, + { + "name": "namespaceId", + "in": "path", + "description": "Server-generated namespace identifier.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Server-generated namespace identifier." + }, + "required": true + } + ], + "responses": { + "200": { + "description": "UpdateNamespace 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateNamespaceResponseContent" + } + } + } + }, + "400": { + "description": "BadRequestError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BadRequestErrorResponseContent" + } + } + } + }, + "401": { + "description": "AuthenticationError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthenticationErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "408": { + "description": "TimeoutError 408 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TimeoutErrorResponseContent" + } + } + } + }, + "409": { + "description": "ConflictError 409 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConflictErrorResponseContent" + } + } + } + }, + "413": { + "description": "PayloadTooLargeError 413 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PayloadTooLargeErrorResponseContent" + } + } + } + }, + "423": { + "description": "ResourceSuspendedError 423 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResourceSuspendedErrorResponseContent" + } + } + } + }, + "424": { + "description": "FailedDependencyError 424 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FailedDependencyErrorResponseContent" + } + } + } + }, + "429": { + "description": "TooManyRequestsError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TooManyRequestsErrorResponseContent" + } + } + } + }, + "500": { + "description": "UnexpectedError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnexpectedErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Namespaces" + ] + } + }, + "/v1/stores/{storeId}/session-memory": { + "get": { + "description": "Returns a paginated list of session IDs for a store.", + "operationId": "ListSessions", + "parameters": [ + { + "name": "storeId", + "in": "path", + "description": "The store instance ID.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "The store instance ID." + }, + "required": true + }, + { + "name": "limit", + "in": "query", + "description": "Maximum number of sessions to return. Defaults to 100. Allowed range: 1-1000.", + "schema": { + "type": "integer", + "default": 100, + "maximum": 1000, + "minimum": 1, + "description": "Maximum number of sessions to return. Defaults to 100. Allowed range: 1-1000.", + "format": "int32" + } + }, + { + "name": "pageToken", + "in": "query", + "description": "Opaque token from a previous response for the next page.", + "schema": { + "type": "string", + "description": "Opaque token from a previous response for the next page." + } + }, + { + "name": "filterOwnerId", + "in": "query", + "description": "Filter sessions by owner. Matching is case-sensitive. Mutually exclusive with includeAll.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Filter sessions by owner. Matching is case-sensitive. Mutually exclusive with includeAll." + } + }, + { + "name": "namespaceRef", + "in": "query", + "description": "Filter sessions by stable namespace ID. Matching is exact and case-sensitive, excludes deprecated namespace labels and sessions without a namespace resource, and does not include descendants. Combined with filterOwnerId using AND. Mutually exclusive with includeAll.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Filter sessions by stable namespace ID. Matching is exact and case-sensitive, excludes deprecated namespace labels and sessions without a namespace resource, and does not include descendants. Combined with filterOwnerId using AND. Mutually exclusive with includeAll." + } + }, + { + "name": "includeAll", + "in": "query", + "description": "Set to true to list all sessions. Required when no filter is given; mutually exclusive with filters.", + "schema": { + "type": "boolean", + "description": "Set to true to list all sessions. Required when no filter is given; mutually exclusive with filters." + } + } + ], + "responses": { + "200": { + "description": "ListSessions 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListSessionsResponseContent" + } + } + } + }, + "400": { + "description": "BadRequestError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BadRequestErrorResponseContent" + } + } + } + }, + "401": { + "description": "AuthenticationError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthenticationErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "408": { + "description": "TimeoutError 408 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TimeoutErrorResponseContent" + } + } + } + }, + "413": { + "description": "PayloadTooLargeError 413 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PayloadTooLargeErrorResponseContent" + } + } + } + }, + "423": { + "description": "ResourceSuspendedError 423 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResourceSuspendedErrorResponseContent" + } + } + } + }, + "424": { + "description": "FailedDependencyError 424 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FailedDependencyErrorResponseContent" + } + } + } + }, + "429": { + "description": "TooManyRequestsError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TooManyRequestsErrorResponseContent" + } + } + } + }, + "500": { + "description": "UnexpectedError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnexpectedErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Session Memory" + ] + } + }, + "/v1/stores/{storeId}/session-memory/events": { + "post": { + "description": "Appends a single event to a session. Creates the session if it does not exist. If sessionId is omitted, the server generates one.", + "operationId": "AddSessionEvent", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AddSessionEventRequestContent" + } + } + }, + "required": true + }, + "parameters": [ + { + "name": "storeId", + "in": "path", + "description": "The store instance ID.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "The store instance ID." + }, + "required": true + } + ], + "responses": { + "201": { + "description": "AddSessionEvent 201 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AddSessionEventResponseContent" + } + } + } + }, + "400": { + "description": "BadRequestError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BadRequestErrorResponseContent" + } + } + } + }, + "401": { + "description": "AuthenticationError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthenticationErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "408": { + "description": "TimeoutError 408 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TimeoutErrorResponseContent" + } + } + } + }, + "413": { + "description": "PayloadTooLargeError 413 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PayloadTooLargeErrorResponseContent" + } + } + } + }, + "423": { + "description": "ResourceSuspendedError 423 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResourceSuspendedErrorResponseContent" + } + } + } + }, + "424": { + "description": "FailedDependencyError 424 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FailedDependencyErrorResponseContent" + } + } + } + }, + "429": { + "description": "TooManyRequestsError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TooManyRequestsErrorResponseContent" + } + } + } + }, + "500": { + "description": "UnexpectedError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnexpectedErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Session Memory" + ] + } + }, + "/v1/stores/{storeId}/session-memory/{sessionId}": { + "delete": { + "description": "Deletes the session memory for a session.", + "operationId": "DeleteSessionMemory", + "parameters": [ + { + "name": "storeId", + "in": "path", + "description": "The store instance ID.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "The store instance ID." + }, + "required": true + }, + { + "name": "sessionId", + "in": "path", + "description": "The session ID.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "The session ID." + }, + "required": true + } + ], + "responses": { + "204": { + "description": "DeleteSessionMemory 204 response" + }, + "400": { + "description": "BadRequestError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BadRequestErrorResponseContent" + } + } + } + }, + "401": { + "description": "AuthenticationError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthenticationErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "408": { + "description": "TimeoutError 408 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TimeoutErrorResponseContent" + } + } + } + }, + "413": { + "description": "PayloadTooLargeError 413 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PayloadTooLargeErrorResponseContent" + } + } + } + }, + "423": { + "description": "ResourceSuspendedError 423 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResourceSuspendedErrorResponseContent" + } + } + } + }, + "424": { + "description": "FailedDependencyError 424 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FailedDependencyErrorResponseContent" + } + } + } + }, + "429": { + "description": "TooManyRequestsError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TooManyRequestsErrorResponseContent" + } + } + } + }, + "500": { + "description": "UnexpectedError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnexpectedErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Session Memory" + ] + }, + "get": { + "description": "Returns the session memory for a session.", + "operationId": "GetSessionMemory", + "parameters": [ + { + "name": "storeId", + "in": "path", + "description": "The store instance ID.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "The store instance ID." + }, + "required": true + }, + { + "name": "sessionId", + "in": "path", + "description": "The session ID.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "The session ID." + }, + "required": true + }, + { + "name": "includeSummarisedEvents", + "in": "query", + "description": "When true, the response includes events that have already been covered by the session summary and have not yet been cleaned up. This flag is not expected to be set under normal usage.", + "schema": { + "type": "boolean", + "description": "When true, the response includes events that have already been covered by the session summary and have not yet been cleaned up. This flag is not expected to be set under normal usage." + } + } + ], + "responses": { + "200": { + "description": "GetSessionMemory 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetSessionMemoryResponseContent" + } + } + } + }, + "400": { + "description": "BadRequestError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BadRequestErrorResponseContent" + } + } + } + }, + "401": { + "description": "AuthenticationError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthenticationErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "408": { + "description": "TimeoutError 408 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TimeoutErrorResponseContent" + } + } + } + }, + "413": { + "description": "PayloadTooLargeError 413 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PayloadTooLargeErrorResponseContent" + } + } + } + }, + "423": { + "description": "ResourceSuspendedError 423 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResourceSuspendedErrorResponseContent" + } + } + } + }, + "424": { + "description": "FailedDependencyError 424 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FailedDependencyErrorResponseContent" + } + } + } + }, + "429": { + "description": "TooManyRequestsError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TooManyRequestsErrorResponseContent" + } + } + } + }, + "500": { + "description": "UnexpectedError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnexpectedErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Session Memory" + ] + } + }, + "/v1/stores/{storeId}/session-memory/{sessionId}/events/{eventId}": { + "delete": { + "description": "Deletes a single event from a session by event ID.", + "operationId": "DeleteSessionEvent", + "parameters": [ + { + "name": "storeId", + "in": "path", + "description": "The store instance ID.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "The store instance ID." + }, + "required": true + }, + { + "name": "sessionId", + "in": "path", + "description": "The session ID.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "The session ID." + }, + "required": true + }, + { + "name": "eventId", + "in": "path", + "description": "The event ID.", + "schema": { + "type": "string", + "maxLength": 32, + "minLength": 32, + "pattern": "^[a-zA-Z0-9]+$", + "description": "The event ID." + }, + "required": true + } + ], + "responses": { + "204": { + "description": "DeleteSessionEvent 204 response" + }, + "400": { + "description": "BadRequestError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BadRequestErrorResponseContent" + } + } + } + }, + "401": { + "description": "AuthenticationError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthenticationErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "408": { + "description": "TimeoutError 408 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TimeoutErrorResponseContent" + } + } + } + }, + "413": { + "description": "PayloadTooLargeError 413 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PayloadTooLargeErrorResponseContent" + } + } + } + }, + "423": { + "description": "ResourceSuspendedError 423 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResourceSuspendedErrorResponseContent" + } + } + } + }, + "424": { + "description": "FailedDependencyError 424 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FailedDependencyErrorResponseContent" + } + } + } + }, + "429": { + "description": "TooManyRequestsError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TooManyRequestsErrorResponseContent" + } + } + } + }, + "500": { + "description": "UnexpectedError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnexpectedErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Session Memory" + ] + }, + "get": { + "description": "Returns a single event from a session by event ID.", + "operationId": "GetSessionEvent", + "parameters": [ + { + "name": "storeId", + "in": "path", + "description": "The store instance ID.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "The store instance ID." + }, + "required": true + }, + { + "name": "sessionId", + "in": "path", + "description": "The session ID.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "The session ID." + }, + "required": true + }, + { + "name": "eventId", + "in": "path", + "description": "The event ID.", + "schema": { + "type": "string", + "maxLength": 32, + "minLength": 32, + "pattern": "^[a-zA-Z0-9]+$", + "description": "The event ID." + }, + "required": true + } + ], + "responses": { + "200": { + "description": "GetSessionEvent 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetSessionEventResponseContent" + } + } + } + }, + "400": { + "description": "BadRequestError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BadRequestErrorResponseContent" + } + } + } + }, + "401": { + "description": "AuthenticationError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthenticationErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "408": { + "description": "TimeoutError 408 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TimeoutErrorResponseContent" + } + } + } + }, + "413": { + "description": "PayloadTooLargeError 413 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PayloadTooLargeErrorResponseContent" + } + } + } + }, + "423": { + "description": "ResourceSuspendedError 423 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResourceSuspendedErrorResponseContent" + } + } + } + }, + "424": { + "description": "FailedDependencyError 424 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FailedDependencyErrorResponseContent" + } + } + } + }, + "429": { + "description": "TooManyRequestsError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TooManyRequestsErrorResponseContent" + } + } + } + }, + "500": { + "description": "UnexpectedError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnexpectedErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Session Memory" + ] + } + } + }, + "components": { "schemas": { "AddSessionEventRequestContent": { "type": "object", @@ -1878,7 +3294,11 @@ "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Optional namespace for the session, used as the namespace of every long-term memory extracted from it.\n\nLike `ownerId`, this is a session-level value taken from the first event: the value sent with the first event of a session is stored on the session, and values sent with later events are ignored. Omit it to leave extracted memories without a namespace." + "description": "Optional deprecated namespace label for the session. This label does not create or resolve a namespace resource. Do not supply it with namespaceRef.\n\nLike `ownerId`, this is a session-level value taken from the first event: the value sent with the first event of a session is stored on the session, and values sent with later events are ignored. Omit it to leave extracted memories without a namespace.", + "deprecated": true + }, + "namespaceRef": { + "$ref": "#/components/schemas/NamespaceRefInput" }, "role": { "$ref": "#/components/schemas/MessageRole" @@ -2191,6 +3611,45 @@ "id" ] }, + "ConflictErrorResponseContent": { + "type": "object", + "description": "The request conflicts with the current state of the resource.", + "properties": { + "title": { + "type": "string", + "description": "A short, human-readable summary of the problem\n type. It SHOULD NOT change from occurrence to occurrence of the\n problem, except for purposes of localization (e.g., using\n proactive content negotiation; see [RFC7231], Section 3.4)." + }, + "status": { + "type": "integer", + "default": 409, + "description": "The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.", + "format": "int32" + }, + "detail": { + "type": "string", + "description": "A human-readable explanation specific to this occurrence of the problem." + }, + "instance": { + "type": "string", + "description": "A URI reference that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced." + }, + "type": { + "$ref": "#/components/schemas/ConflictErrorType" + } + }, + "required": [ + "status", + "title", + "type" + ] + }, + "ConflictErrorType": { + "type": "string", + "description": "Problem type URI for conflict errors.", + "enum": [ + "/errors/conflict" + ] + }, "Content": { "description": "A single content item in a message. Exactly one member is set.", "oneOf": [ @@ -2252,27 +3711,77 @@ "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Optional namespace for logical grouping (1-64 chars, alphanumeric and dashes). Omit to create the record without a namespace. Records created here are explicit writes, so this value is taken as given; extraction instead inherits the source session's namespace." - }, - "topics": { - "type": "array", - "items": { - "type": "string", - "maxLength": 100, - "minLength": 1, - "description": "Topic name (1-100 chars)." - }, - "maxItems": 50, - "description": "Topic tags for categorization (max 50 topics, each 1-100 chars)." - }, - "attributes": { - "$ref": "#/components/schemas/AttributeMap" + "description": "Optional deprecated namespace label. It does not create or resolve a namespace resource. Do not supply it with namespaceRef. If both fields are omitted, the record uses automatic routing when enabled; if routing is disabled or no destination qualifies, it is created without a namespace.", + "deprecated": true + }, + "namespaceRef": { + "$ref": "#/components/schemas/NamespaceRefInput" + }, + "topics": { + "type": "array", + "items": { + "type": "string", + "maxLength": 100, + "minLength": 1, + "description": "Topic name (1-100 chars)." + }, + "maxItems": 50, + "description": "Topic tags for categorization (max 50 topics, each 1-100 chars)." + }, + "attributes": { + "$ref": "#/components/schemas/AttributeMap" + } + }, + "required": [ + "id", + "ownerId", + "text" + ] + }, + "CreateNamespaceRequestContent": { + "type": "object", + "properties": { + "name": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9_-]+$", + "description": "One namespace segment. Use with scope for a root or parentId for a child." + }, + "path": { + "type": "string", + "maxLength": 1024, + "minLength": 1, + "description": "A complete hierarchy path to create. Missing segments are created as needed. Mutually exclusive with name and parentId. The path does not encode scope." + }, + "scope": { + "$ref": "#/components/schemas/NamespaceScope" + }, + "parentId": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Parent namespace for a direct child." + }, + "ownerId": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Owner for a personal root or path. Required for personal scope; omit for shared roots and children." + } + } + }, + "CreateNamespaceResponseContent": { + "type": "object", + "properties": { + "namespace": { + "$ref": "#/components/schemas/Namespace" } }, "required": [ - "id", - "ownerId", - "text" + "namespace" ] }, "CreatedAtFilter": { @@ -2457,7 +3966,11 @@ "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Namespace for logical grouping. Absent when the record has none: either it was written directly without one, or it was extracted from a session that has no namespace." + "description": "Deprecated namespace label. Absent when the record uses namespaceRef or has no namespace.", + "deprecated": true + }, + "namespaceRef": { + "$ref": "#/components/schemas/NamespaceRef" }, "topics": { "type": "array", @@ -2491,6 +4004,28 @@ "updatedAt" ] }, + "GetNamespaceResponseContent": { + "type": "object", + "properties": { + "namespace": { + "$ref": "#/components/schemas/Namespace" + } + }, + "required": [ + "namespace" + ] + }, + "GetNamespaceRoutingResponseContent": { + "type": "object", + "properties": { + "policy": { + "$ref": "#/components/schemas/NamespaceRoutingPolicy" + } + }, + "required": [ + "policy" + ] + }, "GetSessionEventResponseContent": { "type": "object", "description": "Response containing a single requested session event.", @@ -2526,7 +4061,11 @@ "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "The namespace of the session, set from the namespace of the first event. Absent when the first event did not supply one; long-term memories extracted from this session then carry no namespace." + "description": "Deprecated namespace label for the session, set from the first event. Absent when the session uses namespaceRef or has no namespace.", + "deprecated": true + }, + "namespaceRef": { + "$ref": "#/components/schemas/NamespaceRef" }, "events": { "type": "array", @@ -2564,6 +4103,24 @@ "healthy" ] }, + "ListNamespacesResponseContent": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Namespace" + } + }, + "nextPageToken": { + "type": "string", + "description": "Opaque token for fetching the next page. Omitted when no more results." + } + }, + "required": [ + "items" + ] + }, "ListSessionsResponseContent": { "type": "object", "description": "Paginated list of session IDs for a store.", @@ -2594,6 +4151,20 @@ "total" ] }, + "LlmPromptSpec": { + "type": "object", + "description": "Customer-authored prompt evaluated by the LLM routing strategy.", + "properties": { + "prompt": { + "type": "string", + "maxLength": 2000, + "minLength": 1 + } + }, + "required": [ + "prompt" + ] + }, "LongTermMemoryFilter": { "type": "object", "description": "Grouping of filter conditions for long-term memory search.", @@ -2607,6 +4178,13 @@ "namespace": { "$ref": "#/components/schemas/NamespaceFilter" }, + "namespaceRef": { + "$ref": "#/components/schemas/NamespaceRefFilter" + }, + "unnamespaced": { + "type": "boolean", + "description": "When true, matches only records that have neither a deprecated namespace label nor a namespace resource placement. This scope is always combined with every other filter condition. Do not supply namespace or namespaceRef with this field." + }, "topics": { "$ref": "#/components/schemas/TopicsFilter" }, @@ -2616,140 +4194,399 @@ "createdAt": { "$ref": "#/components/schemas/CreatedAtFilter" }, - "attributes": { - "$ref": "#/components/schemas/AttributeFilterMap" + "attributes": { + "$ref": "#/components/schemas/AttributeFilterMap" + } + } + }, + "MatcherKind": { + "type": "string", + "description": "The matching techniques this API supports.", + "enum": [ + "regex" + ] + }, + "MatcherSpec": { + "type": "object", + "description": "How a detector matches, as a tagged union of techniques.\n\nExactly the block naming the declared kind must be present; a block belonging to\nany other kind is rejected rather than guessed at. Further kinds are additive.", + "properties": { + "kind": { + "$ref": "#/components/schemas/MatcherKind" + }, + "regex": { + "$ref": "#/components/schemas/RegexSpec" + } + }, + "required": [ + "kind" + ] + }, + "MemoryFailedDependencyErrorResponseContent": { + "type": "object", + "description": "A resource or model-provider dependency required by Agent Memory could not complete the request.", + "properties": { + "title": { + "type": "string", + "description": "A short, human-readable summary of the problem\n type. It SHOULD NOT change from occurrence to occurrence of the\n problem, except for purposes of localization (e.g., using\n proactive content negotiation; see [RFC7231], Section 3.4)." + }, + "status": { + "type": "integer", + "default": 424, + "description": "The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.", + "format": "int32" + }, + "detail": { + "type": "string", + "description": "A human-readable explanation specific to this occurrence of the problem." + }, + "instance": { + "type": "string", + "description": "A URI reference that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced." + }, + "type": { + "$ref": "#/components/schemas/MemoryFailedDependencyErrorType" + } + }, + "required": [ + "status", + "title", + "type" + ] + }, + "MemoryFailedDependencyErrorType": { + "type": "string", + "description": "Problem type URI for Agent Memory failed-dependency errors.", + "enum": [ + "/errors/resource-unavailable", + "/errors/database-out-of-memory", + "/errors/invalid-model-credentials", + "/errors/model-quota-exceeded" + ] + }, + "MemoryRecord": { + "type": "object", + "description": "A long-term memory record.", + "properties": { + "id": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Unique memory record ID." + }, + "text": { + "type": "string", + "description": "The memory content." + }, + "memoryType": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z][a-zA-Z0-9_-]*$", + "description": "Type of memory. Built-in or a custom type registered on the store." + }, + "sessionId": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Session ID associated with this memory." + }, + "ownerId": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Owner ID associated with this memory." + }, + "namespace": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Deprecated namespace label. Absent when the record uses namespaceRef or has no namespace.", + "deprecated": true + }, + "namespaceRef": { + "$ref": "#/components/schemas/NamespaceRef" + }, + "topics": { + "type": "array", + "items": { + "type": "string", + "maxLength": 100, + "minLength": 1, + "description": "Topic name (1-100 chars)." + }, + "maxItems": 50, + "description": "Topic tags for categorization." + }, + "attributes": { + "$ref": "#/components/schemas/AttributeMap" + }, + "createdAt": { + "type": "string", + "description": "Timestamp when the memory was created (UTC).", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "description": "Timestamp when the memory was last updated (UTC).", + "format": "date-time" + } + }, + "required": [ + "createdAt", + "id", + "text", + "updatedAt" + ] + }, + "MemoryTypeFilter": { + "type": "object", + "description": "Filter by memory type. Matching is case-insensitive.", + "properties": { + "eq": { + "type": "string", + "description": "Equals the given value." + }, + "ne": { + "type": "string", + "description": "Not equal to the given value." + }, + "in": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Matches any of the given values." + }, + "all": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Matches all of the given values." + } + } + }, + "MessageRole": { + "type": "string", + "description": "Message role for session events.", + "enum": [ + "USER", + "ASSISTANT", + "SYSTEM" + ] + }, + "MoveLongTermMemoriesRequestContent": { + "type": "object", + "properties": { + "memoryIds": { + "type": "array", + "items": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Memory record identifier (1-64 chars, alphanumeric and dashes). Client-provided for idempotent long-term memory creation." + }, + "maxItems": 100, + "minItems": 1 + }, + "namespaceRef": { + "$ref": "#/components/schemas/NamespaceRefInput" + } + }, + "required": [ + "memoryIds" + ] + }, + "MoveLongTermMemoriesResponseContent": { + "type": "object", + "properties": { + "moved": { + "type": "array", + "items": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Memory record identifier (1-64 chars, alphanumeric and dashes). Client-provided for idempotent long-term memory creation." + } + }, + "errors": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BulkOperationError" + } } - } + }, + "required": [ + "moved" + ] }, - "MemoryRecord": { + "Namespace": { "type": "object", - "description": "A long-term memory record.", + "description": "A namespace hierarchy record.", "properties": { - "id": { + "namespaceId": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Unique memory record ID." - }, - "text": { - "type": "string", - "description": "The memory content." + "description": "Server-generated namespace identifier." }, - "memoryType": { + "name": { "type": "string", "maxLength": 64, "minLength": 1, - "pattern": "^[a-zA-Z][a-zA-Z0-9_-]*$", - "description": "Type of memory. Built-in or a custom type registered on the store." + "pattern": "^[a-zA-Z0-9_-]+$", + "description": "One case-sensitive namespace path segment." }, - "sessionId": { + "parentId": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Session ID associated with this memory." + "description": "Server-generated namespace identifier." }, - "ownerId": { + "rootId": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Owner ID associated with this memory." + "description": "Server-generated namespace identifier." }, - "namespace": { + "ownerId": { "type": "string", - "maxLength": 64, "minLength": 1, - "pattern": "^[a-zA-Z0-9-]+$", - "description": "Namespace for logical grouping. Absent when the record has none: either it was written directly without one, or it was extracted from a session that has no namespace." + "description": "An opaque application-user ID selected by the platform for a namespace root." }, - "topics": { - "type": "array", - "items": { - "type": "string", - "maxLength": 100, - "minLength": 1, - "description": "Topic name (1-100 chars)." - }, - "maxItems": 50, - "description": "Topic tags for categorization." + "scope": { + "$ref": "#/components/schemas/NamespaceScope" }, - "attributes": { - "$ref": "#/components/schemas/AttributeMap" + "state": { + "$ref": "#/components/schemas/NamespaceState" + }, + "revision": { + "type": "integer", + "format": "int64" }, "createdAt": { "type": "string", - "description": "Timestamp when the memory was created (UTC).", "format": "date-time" }, "updatedAt": { "type": "string", - "description": "Timestamp when the memory was last updated (UTC).", "format": "date-time" + }, + "path": { + "type": "string", + "maxLength": 1024, + "minLength": 1, + "description": "Current case-sensitive path, derived from the live hierarchy." } }, "required": [ "createdAt", - "id", - "text", + "name", + "namespaceId", + "path", + "revision", + "rootId", + "scope", + "state", "updatedAt" ] }, - "MemoryTypeFilter": { + "NamespaceFilter": { "type": "object", - "description": "Filter by memory type. Matching is case-insensitive.", + "description": "Filter by namespace. Matching is case-insensitive.\n\nNamespace is optional, so records without one need care. The positive operators (`eq`, `in`, `all`) require the field to be present and therefore never match a record that has no namespace \u2014 including memories extracted from a session that has none. `ne` is a plain negation and *does* match those records, so use `eq` or `in` when you need strict namespace isolation rather than `ne` against the namespaces you want to exclude.\n\nOmit this filter to search across every namespace, and use it to keep recall inside one project, workspace, team, environment, or tenant.", "properties": { "eq": { "type": "string", - "description": "Equals the given value." + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Equals the given value.", + "deprecated": true }, "ne": { "type": "string", - "description": "Not equal to the given value." + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Not equal to the given value.", + "deprecated": true }, "in": { "type": "array", "items": { - "type": "string" + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Deprecated flat namespace label for logical grouping. The value is 1-64 alphanumeric characters or dashes and has no hierarchy or scope semantics. Matching through `filter.namespace` is case-insensitive.\n\nThe field remains optional for backward compatibility. New integrations should use `namespaceRef` to reference an existing namespace resource.\n\nRecords produced by extraction inherit the namespace label stored on the session when the session was created.\n\nThis shape is deprecated: Use namespaceRef to reference a namespace resource.", + "deprecated": true }, "description": "Matches any of the given values." }, "all": { "type": "array", "items": { - "type": "string" + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Deprecated flat namespace label for logical grouping. The value is 1-64 alphanumeric characters or dashes and has no hierarchy or scope semantics. Matching through `filter.namespace` is case-insensitive.\n\nThe field remains optional for backward compatibility. New integrations should use `namespaceRef` to reference an existing namespace resource.\n\nRecords produced by extraction inherit the namespace label stored on the session when the session was created.\n\nThis shape is deprecated: Use namespaceRef to reference a namespace resource.", + "deprecated": true }, "description": "Matches all of the given values." } } }, - "MessageRole": { - "type": "string", - "description": "Message role for session events.", - "enum": [ - "USER", - "ASSISTANT", - "SYSTEM" - ] - }, - "NamespaceFilter": { + "NamespaceRef": { "type": "object", - "description": "Filter by namespace. Matching is case-insensitive.\n\nNamespace is optional, so records without one need care. The positive operators (`eq`, `in`, `all`) require the field to be present and therefore never match a record that has no namespace — including memories extracted from a session that has none. `ne` is a plain negation and *does* match those records, so use `eq` or `in` when you need strict namespace isolation rather than `ne` against the namespaces you want to exclude.\n\nOmit this filter to search across every namespace, and use it to keep recall inside one project, workspace, team, environment, or tenant.", + "description": "Reference to a namespace resource with its stable identifier and current display data.", "properties": { - "eq": { + "namespaceId": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Equals the given value." + "description": "Stable namespace resource identifier." }, - "ne": { + "name": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9_-]+$", + "description": "Current namespace name." + }, + "path": { + "type": "string", + "maxLength": 1024, + "minLength": 1, + "description": "Current namespace path." + } + }, + "required": [ + "name", + "namespaceId", + "path" + ] + }, + "NamespaceRefFilter": { + "type": "object", + "description": "Filter by stable namespace resource identifier. Supports exact or any-of matching and matches only resource-backed records, never deprecated namespace labels.", + "properties": { + "eq": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Not equal to the given value." + "description": "Equals the given value." }, "in": { "type": "array", @@ -2758,22 +4595,104 @@ "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Namespace for logical grouping (1-64 chars, alphanumeric and dashes).\n\nThis is the shared namespace format for both session memory and long-term memory: sessions carry it as session-level state, and long-term memory records carry it per record. The same constraints apply everywhere it is used.\n\nNamespace is always optional; a record without one is valid. Applications use it to isolate memories by project, workspace, team, environment, or tenant. See `NamespaceFilter` for how records without a namespace behave under search.\n\nA namespace reaches a record one of two ways. Records written directly carry whatever namespace the caller sets. Records produced by extraction inherit the namespace of the session they were extracted from, which is fixed when that session is created; a session with no namespace yields records with no namespace. Existing records are never backfilled when a namespace is introduced later." + "description": "Server-generated namespace identifier." }, "description": "Matches any of the given values." + } + } + }, + "NamespaceRefInput": { + "type": "object", + "description": "Reference to an existing namespace resource for a write or namespace-scoped operation.", + "properties": { + "namespaceId": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Stable namespace resource identifier." + } + }, + "required": [ + "namespaceId" + ] + }, + "NamespaceRoutingPolicy": { + "type": "object", + "description": "Store-level automatic namespace routing and admission policy. Global rules target shared namespaces only. Accept rules select candidates in list order. All enabled reject rules for a destination apply regardless of their position or how the destination was selected.", + "properties": { + "enabled": { + "type": "boolean" }, - "all": { + "rules": { "type": "array", "items": { - "type": "string", - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-]+$", - "description": "Namespace for logical grouping (1-64 chars, alphanumeric and dashes).\n\nThis is the shared namespace format for both session memory and long-term memory: sessions carry it as session-level state, and long-term memory records carry it per record. The same constraints apply everywhere it is used.\n\nNamespace is always optional; a record without one is valid. Applications use it to isolate memories by project, workspace, team, environment, or tenant. See `NamespaceFilter` for how records without a namespace behave under search.\n\nA namespace reaches a record one of two ways. Records written directly carry whatever namespace the caller sets. Records produced by extraction inherit the namespace of the session they were extracted from, which is fixed when that session is created; a session with no namespace yields records with no namespace. Existing records are never backfilled when a namespace is introduced later." + "$ref": "#/components/schemas/NamespaceRoutingRule" }, - "description": "Matches all of the given values." + "maxItems": 32 } - } + }, + "required": [ + "enabled" + ] + }, + "NamespaceRoutingRule": { + "type": "object", + "description": "One routing or admission rule. action is accept or reject. Strategies run in list order and the first match fires the rule. An accept with no strategies always matches; a reject with no strategies never matches. A matching accept selects a candidate. Every enabled reject for that destination must pass before placement. A veto skips that candidate during automatic routing and fails explicit placement.", + "properties": { + "id": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z][a-zA-Z0-9_-]*$", + "description": "Routing rule identifier (1-64 chars). Published in logs, so it is an identifier rather than free text." + }, + "destination": { + "$ref": "#/components/schemas/NamespaceRefInput" + }, + "enabled": { + "type": "boolean" + }, + "action": { + "$ref": "#/components/schemas/RoutingRuleAction" + }, + "strategies": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RouteCondition" + }, + "maxItems": 8 + } + }, + "required": [ + "action", + "destination", + "enabled", + "id" + ] + }, + "NamespaceScope": { + "type": "string", + "description": "The root scope of a namespace hierarchy.", + "enum": [ + "PERSONAL", + "SHARED" + ] + }, + "NamespaceState": { + "type": "string", + "description": "Whether a namespace accepts new children and placements.", + "enum": [ + "ACTIVE", + "ARCHIVED" + ] + }, + "NamespaceUpdateState": { + "type": "string", + "description": "The archive-only state transition accepted by UpdateNamespace.", + "enum": [ + "ARCHIVED" + ] }, "NotFoundErrorResponseContent": { "type": "object", @@ -2895,6 +4814,116 @@ "/errors/payload-too-large" ] }, + "PutNamespaceRoutingRequestContent": { + "type": "object", + "properties": { + "policy": { + "$ref": "#/components/schemas/NamespaceRoutingPolicy" + } + }, + "required": [ + "policy" + ] + }, + "PutNamespaceRoutingResponseContent": { + "type": "object", + "properties": { + "policy": { + "$ref": "#/components/schemas/NamespaceRoutingPolicy" + } + }, + "required": [ + "policy" + ] + }, + "RegexSpec": { + "type": "object", + "description": "A regular expression to match against.\n\nEvaluated by RE2, which runs in linear time \u2014 so an expensive pattern is not a\ndenial-of-service risk, but lookaround and backreferences are unavailable.\nRejected on write if it does not compile, or if it can match without consuming\ntext: such a pattern matches at every position, so it would exclude every memory\nthe store writes.", + "properties": { + "pattern": { + "type": "string", + "maxLength": 512, + "minLength": 1, + "description": "The pattern, in RE2 syntax." + } + }, + "required": [ + "pattern" + ] + }, + "ResourceSuspendedErrorResponseContent": { + "type": "object", + "description": "The requested resource exists but is suspended by an administrator.", + "properties": { + "title": { + "type": "string", + "description": "A short, human-readable summary of the problem\n type. It SHOULD NOT change from occurrence to occurrence of the\n problem, except for purposes of localization (e.g., using\n proactive content negotiation; see [RFC7231], Section 3.4)." + }, + "status": { + "type": "integer", + "default": 423, + "description": "The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.", + "format": "int32" + }, + "detail": { + "type": "string", + "description": "A human-readable explanation specific to this occurrence of the problem." + }, + "instance": { + "type": "string", + "description": "A URI reference that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced." + }, + "type": { + "$ref": "#/components/schemas/ResourceSuspendedErrorType" + } + }, + "required": [ + "status", + "title", + "type" + ] + }, + "ResourceSuspendedErrorType": { + "type": "string", + "description": "Problem type URI for suspended resources.", + "enum": [ + "/errors/resource-suspended" + ] + }, + "RouteCondition": { + "type": "object", + "description": "One plug-in strategy invocation. Exactly the block naming the declared kind must be present. List order is evaluation order.", + "properties": { + "kind": { + "$ref": "#/components/schemas/RouteStrategyKind" + }, + "llmPrompt": { + "$ref": "#/components/schemas/LlmPromptSpec" + }, + "matcher": { + "$ref": "#/components/schemas/MatcherSpec" + } + }, + "required": [ + "kind" + ] + }, + "RouteStrategyKind": { + "type": "string", + "description": "Routing strategy kinds. Unknown kinds are rejected. New kinds register on the evaluator without changing namespace records.", + "enum": [ + "llm_prompt", + "matcher_spec" + ] + }, + "RoutingRuleAction": { + "type": "string", + "description": "Whether the rule accepts into the destination or rejects that destination.", + "enum": [ + "accept", + "reject" + ] + }, "SearchLongTermMemoryRequestContent": { "type": "object", "description": "Semantic search request for long-term memory records.", @@ -3299,7 +5328,11 @@ "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "The caller's namespace. The update is rejected with 409 unless the record's stored namespace matches exactly.\n\nOmit it to assert that the record has no namespace — an omitted value matches only records stored without one, it does not mean \"any namespace\". The check is applied atomically with the update, so a record cannot be re-filed into another namespace between the check and the write." + "description": "The caller's current deprecated namespace label. The update is rejected with 409 unless the record still stores that label. Do not supply it with namespaceRef.\n\nOmit both namespace and namespaceRef to assert that the record has no namespace placement. Omission does not mean \"any namespace\".", + "deprecated": true + }, + "namespaceRef": { + "$ref": "#/components/schemas/NamespaceRefInput" }, "text": { "type": "string", @@ -3345,7 +5378,11 @@ }, "namespace": { "type": "string", - "description": "Updated namespace. When provided, must be 1-64 chars alphanumeric and dashes; omit the field or send an empty string to clear.\n\nThis is the only way to change the namespace of an existing record, including one produced by extraction: a record inherits its session's namespace at creation and is not revised afterwards, so use this to re-file a record or to add a namespace to one created before the session had any." + "description": "Updated deprecated namespace label. When provided, it must be 1-64 alphanumeric characters or dashes. Send an empty string to clear it.\nDo not supply it with namespaceRef.\n\nThis shape is deprecated: Use namespaceRef to reference a namespace resource.", + "deprecated": true + }, + "namespaceRef": { + "$ref": "#/components/schemas/NamespaceRefInput" }, "ownerId": { "type": "string", @@ -3398,7 +5435,11 @@ "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Namespace for logical grouping. Absent when the record has none: either it was written directly without one, or it was extracted from a session that has no namespace." + "description": "Deprecated namespace label. Absent when the record uses namespaceRef or has no namespace.", + "deprecated": true + }, + "namespaceRef": { + "$ref": "#/components/schemas/NamespaceRef" }, "topics": { "type": "array", @@ -3431,6 +5472,32 @@ "text", "updatedAt" ] + }, + "UpdateNamespaceRequestContent": { + "type": "object", + "properties": { + "name": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9_-]+$", + "description": "One case-sensitive namespace path segment." + }, + "state": { + "$ref": "#/components/schemas/NamespaceUpdateState" + } + } + }, + "UpdateNamespaceResponseContent": { + "type": "object", + "properties": { + "namespace": { + "$ref": "#/components/schemas/Namespace" + } + }, + "required": [ + "namespace" + ] } } } From b4df6ab9353e57121c8bee9cdb34fe72aa49abe9 Mon Sep 17 00:00:00 2001 From: Andrew Brookins Date: Wed, 21 Oct 2026 12:18:54 -0700 Subject: [PATCH 2/3] Keep routing guidance aligned with the beta API --- .../ai/context-engine/agent-memory/_index.md | 2 + .../api-reference/openapi-agent-memory.json | 7850 +++++++++++++---- .../agent-memory/namespace-routing.md | 167 + 3 files changed, 6204 insertions(+), 1815 deletions(-) create mode 100644 content/develop/ai/context-engine/agent-memory/namespace-routing.md diff --git a/content/develop/ai/context-engine/agent-memory/_index.md b/content/develop/ai/context-engine/agent-memory/_index.md index 92a828ae16..8fc7f17e7a 100644 --- a/content/develop/ai/context-engine/agent-memory/_index.md +++ b/content/develop/ai/context-engine/agent-memory/_index.md @@ -140,3 +140,5 @@ After your Redis Agent Memory service is ready, choose a client. Each quickstart For shared integration concepts, identifiers, and authentication, see the [Redis Agent Memory developer guide](/content/develop/ai/context-engine/agent-memory/developer-guide.md). 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 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/api-reference/openapi-agent-memory.json b/content/develop/ai/context-engine/agent-memory/api-reference/openapi-agent-memory.json index e6ee18679c..c3095f3194 100644 --- a/content/develop/ai/context-engine/agent-memory/api-reference/openapi-agent-memory.json +++ b/content/develop/ai/context-engine/agent-memory/api-reference/openapi-agent-memory.json @@ -6,53 +6,50 @@ "description": "API for storing, retrieving, and searching Redis Agent Memory session memory and long-term memory.\n\nAuthentication depends on your deployment. Use the credential issued for your Redis Agent Memory service or store. For self-managed deployments, see the self-managed Redis Agent Memory guide for authentication options.\n" }, "paths": { - "/health": { - "get": { - "description": "Return information about the operational status of the service.", - "operationId": "Health", - "responses": { - "200": { - "description": "Health 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HealthResponseContent" - } + "/v1/stores/{storeId}/document-ingestions": { + "post": { + "description": "Submit one revisioned document for extraction.", + "operationId": "CreateDocumentIngestion", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateDocumentIngestionRequestContent" } } - } + }, + "required": true }, - "tags": [ - "Service Health" - ] - } - }, - "/v1/stores/{storeId}/health": { - "get": { - "description": "Returns read-only health for applicable store-scoped RAM features.", - "operationId": "StoreHealth", "parameters": [ { "name": "storeId", "in": "path", - "description": "The store instance ID.", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes.", "schema": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "The store instance ID." + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes." }, "required": true } ], "responses": { - "200": { - "description": "StoreHealth 200 response", + "202": { + "description": "CreateDocumentIngestion 202 response", + "headers": { + "Location": { + "schema": { + "type": "string" + }, + "required": true + } + }, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/StoreHealthResponseContent" + "$ref": "#/components/schemas/CreateDocumentIngestionResponseContent" } } } @@ -107,6 +104,16 @@ } } }, + "409": { + "description": "ConflictError 409 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConflictErrorResponseContent" + } + } + } + }, "413": { "description": "PayloadTooLargeError 413 response", "content": { @@ -117,6 +124,16 @@ } } }, + "422": { + "description": "IngestionHookStoppedError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IngestionHookStoppedErrorResponseContent" + } + } + } + }, "423": { "description": "ResourceSuspendedError 423 response", "content": { @@ -128,11 +145,11 @@ } }, "424": { - "description": "FailedDependencyError 424 response", + "description": "MemoryFailedDependencyError 424 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/FailedDependencyErrorResponseContent" + "$ref": "#/components/schemas/MemoryFailedDependencyErrorResponseContent" } } } @@ -156,49 +173,58 @@ } } } + }, + "503": { + "description": "IngestionHookRetryError 503 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IngestionHookRetryErrorResponseContent" + } + } + } } - }, - "tags": [ - "Store Health" - ] + } } }, - "/v1/stores/{storeId}/long-term-memory": { - "delete": { - "description": "Deletes long-term memories in bulk by their IDs.", - "operationId": "BulkDeleteLongTermMemories", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/BulkDeleteLongTermMemoriesRequestContent" - } - } - }, - "required": true - }, + "/v1/stores/{storeId}/document-ingestions/{ingestionId}": { + "get": { + "operationId": "GetDocumentIngestion", "parameters": [ { "name": "storeId", "in": "path", - "description": "The store instance ID.", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes.", "schema": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "The store instance ID." + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes." + }, + "required": true + }, + { + "name": "ingestionId", + "in": "path", + "description": "Server-generated document ingestion identifier.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Server-generated document ingestion identifier." }, "required": true } ], "responses": { "200": { - "description": "BulkDeleteLongTermMemories 200 response", + "description": "GetDocumentIngestion 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/BulkDeleteLongTermMemoriesResponseContent" + "$ref": "#/components/schemas/GetDocumentIngestionResponseContent" } } } @@ -253,16 +279,6 @@ } } }, - "413": { - "description": "PayloadTooLargeError 413 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/PayloadTooLargeErrorResponseContent" - } - } - } - }, "423": { "description": "ResourceSuspendedError 423 response", "content": { @@ -283,16 +299,6 @@ } } }, - "429": { - "description": "TooManyRequestsError 429 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TooManyRequestsErrorResponseContent" - } - } - } - }, "500": { "description": "UnexpectedError 500 response", "content": { @@ -303,46 +309,63 @@ } } } - }, - "tags": [ - "Long-Term Memory" - ] - }, - "post": { - "description": "Creates long-term memories in bulk. Records without namespace or namespaceRef use automatic routing when the store's routing policy is enabled. If routing is disabled or no destination qualifies, the record is created without a namespace. An explicit namespaceRef must pass destination admission and is never rerouted. Routing and admission failures are reported per record in errors.", - "operationId": "BulkCreateLongTermMemories", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/BulkCreateLongTermMemoriesRequestContent" - } - } - }, - "required": true - }, + } + } + }, + "/v1/stores/{storeId}/document-ingestions/{ingestionId}/outputs": { + "get": { + "operationId": "ListDocumentIngestionOutputs", "parameters": [ { "name": "storeId", "in": "path", - "description": "The store instance ID.", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes.", "schema": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "The store instance ID." + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes." }, "required": true + }, + { + "name": "ingestionId", + "in": "path", + "description": "Server-generated document ingestion identifier.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Server-generated document ingestion identifier." + }, + "required": true + }, + { + "name": "limit", + "in": "query", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "offset", + "in": "query", + "schema": { + "type": "integer", + "format": "int32" + } } ], "responses": { - "201": { - "description": "BulkCreateLongTermMemories 201 response", + "200": { + "description": "ListDocumentIngestionOutputs 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/BulkCreateLongTermMemoriesResponseContent" + "$ref": "#/components/schemas/ListDocumentIngestionOutputsResponseContent" } } } @@ -397,16 +420,6 @@ } } }, - "413": { - "description": "PayloadTooLargeError 413 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/PayloadTooLargeErrorResponseContent" - } - } - } - }, "423": { "description": "ResourceSuspendedError 423 response", "content": { @@ -418,21 +431,11 @@ } }, "424": { - "description": "MemoryFailedDependencyError 424 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/MemoryFailedDependencyErrorResponseContent" - } - } - } - }, - "429": { - "description": "TooManyRequestsError 429 response", + "description": "FailedDependencyError 424 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/TooManyRequestsErrorResponseContent" + "$ref": "#/components/schemas/FailedDependencyErrorResponseContent" } } } @@ -447,48 +450,35 @@ } } } - }, - "tags": [ - "Long-Term Memory" - ] + } } }, - "/v1/stores/{storeId}/long-term-memory/move": { - "post": { - "description": "Moves long-term memories to an explicit namespaceRef or automatically routes each memory when namespaceRef is omitted. If routing is disabled or no destination qualifies, the memory keeps its current placement and receives a per-item error. An explicit destination must pass admission and is never rerouted. Returns 409 when the explicit destination is archived; automatic routing and admission failures are reported per item in errors.", - "operationId": "MoveLongTermMemories", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/MoveLongTermMemoriesRequestContent" - } - } - }, - "required": true - }, + "/v1/stores/{storeId}/health": { + "get": { + "description": "Returns read-only health for applicable store-scoped RAM features.", + "operationId": "StoreHealth", "parameters": [ { "name": "storeId", "in": "path", - "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes.", + "description": "The store instance ID.", "schema": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes." + "description": "The store instance ID." }, "required": true } ], "responses": { "200": { - "description": "MoveLongTermMemories 200 response", + "description": "StoreHealth 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/MoveLongTermMemoriesResponseContent" + "$ref": "#/components/schemas/StoreHealthResponseContent" } } } @@ -543,16 +533,6 @@ } } }, - "409": { - "description": "ConflictError 409 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ConflictErrorResponseContent" - } - } - } - }, "413": { "description": "PayloadTooLargeError 413 response", "content": { @@ -605,45 +585,54 @@ } }, "tags": [ - "Long-Term Memory" + "Store Health" ] } }, - "/v1/stores/{storeId}/long-term-memory/search": { - "post": { - "description": "Runs a semantic search on long-term memory with filtering options.", - "operationId": "SearchLongTermMemory", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/SearchLongTermMemoryRequestContent" - } - } - } - }, + "/v1/stores/{storeId}/ingestion-hooks/events": { + "get": { + "description": "List hook decisions in stable newest-first order. Pages can be empty after owner filtering; continue while nextCursor is present. Internal run reservations are omitted.", + "operationId": "ListIngestionHookStatuses", "parameters": [ { "name": "storeId", "in": "path", - "description": "The store instance ID.", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes.", "schema": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "The store instance ID." + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes." }, "required": true + }, + { + "name": "limit", + "in": "query", + "schema": { + "type": "integer", + "default": 20, + "maximum": 100, + "minimum": 1, + "format": "int32" + } + }, + { + "name": "cursor", + "in": "query", + "schema": { + "type": "string" + } } ], "responses": { "200": { - "description": "SearchLongTermMemory 200 response", + "description": "ListIngestionHookStatuses 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SearchLongTermMemoryResponseContent" + "$ref": "#/components/schemas/ListIngestionHookStatusesResponseContent" } } } @@ -678,36 +667,6 @@ } } }, - "404": { - "description": "NotFoundError 404 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotFoundErrorResponseContent" - } - } - } - }, - "408": { - "description": "TimeoutError 408 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TimeoutErrorResponseContent" - } - } - } - }, - "413": { - "description": "PayloadTooLargeError 413 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/PayloadTooLargeErrorResponseContent" - } - } - } - }, "423": { "description": "ResourceSuspendedError 423 response", "content": { @@ -728,16 +687,6 @@ } } }, - "429": { - "description": "TooManyRequestsError 429 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TooManyRequestsErrorResponseContent" - } - } - } - }, "500": { "description": "UnexpectedError 500 response", "content": { @@ -750,49 +699,44 @@ } }, "tags": [ - "Long-Term Memory" + "Ingestion Hooks" ] } }, - "/v1/stores/{storeId}/long-term-memory/{memoryId}": { + "/v1/stores/{storeId}/ingestion-hooks/events/{eventId}": { "get": { - "description": "Returns a long-term memory by its ID.", - "operationId": "GetLongTermMemory", + "description": "Read a hook decision and application status. Requires authenticated store access and, when enforced, matching owner scope. Content and secrets are never returned.", + "operationId": "GetIngestionHookStatus", "parameters": [ { "name": "storeId", "in": "path", - "description": "The store instance ID.", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes.", "schema": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "The store instance ID." + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes." }, "required": true }, { - "name": "memoryId", + "name": "eventId", "in": "path", - "description": "The memory record ID.", "schema": { - "type": "string", - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-]+$", - "description": "The memory record ID." + "type": "string" }, "required": true } ], "responses": { "200": { - "description": "GetLongTermMemory 200 response", + "description": "GetIngestionHookStatus 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetLongTermMemoryResponseContent" + "$ref": "#/components/schemas/GetIngestionHookStatusResponseContent" } } } @@ -837,26 +781,6 @@ } } }, - "408": { - "description": "TimeoutError 408 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TimeoutErrorResponseContent" - } - } - } - }, - "413": { - "description": "PayloadTooLargeError 413 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/PayloadTooLargeErrorResponseContent" - } - } - } - }, "423": { "description": "ResourceSuspendedError 423 response", "content": { @@ -868,21 +792,11 @@ } }, "424": { - "description": "FailedDependencyError 424 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/FailedDependencyErrorResponseContent" - } - } - } - }, - "429": { - "description": "TooManyRequestsError 429 response", + "description": "MemoryFailedDependencyError 424 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/TooManyRequestsErrorResponseContent" + "$ref": "#/components/schemas/MemoryFailedDependencyErrorResponseContent" } } } @@ -899,20 +813,23 @@ } }, "tags": [ - "Long-Term Memory" + "Ingestion Hooks" ] - }, - "patch": { - "description": "Partially updates a long-term memory by its ID. The merged record must pass admission at its destination. Updates never select a different destination automatically.", - "operationId": "UpdateLongTermMemory", + } + }, + "/v1/stores/{storeId}/long-term-memory": { + "delete": { + "description": "Deletes long-term memories in bulk by their IDs.", + "operationId": "BulkDeleteLongTermMemories", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateLongTermMemoryRequestContent" + "$ref": "#/components/schemas/BulkDeleteLongTermMemoriesRequestContent" } } - } + }, + "required": true }, "parameters": [ { @@ -927,28 +844,15 @@ "description": "The store instance ID." }, "required": true - }, - { - "name": "memoryId", - "in": "path", - "description": "The memory record ID.", - "schema": { - "type": "string", - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-]+$", - "description": "The memory record ID." - }, - "required": true } ], "responses": { "200": { - "description": "UpdateLongTermMemory 200 response", + "description": "BulkDeleteLongTermMemories 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateLongTermMemoryResponseContent" + "$ref": "#/components/schemas/BulkDeleteLongTermMemoriesResponseContent" } } } @@ -1003,16 +907,6 @@ } } }, - "409": { - "description": "ConflictError 409 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ConflictErrorResponseContent" - } - } - } - }, "413": { "description": "PayloadTooLargeError 413 response", "content": { @@ -1034,11 +928,11 @@ } }, "424": { - "description": "MemoryFailedDependencyError 424 response", + "description": "FailedDependencyError 424 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/MemoryFailedDependencyErrorResponseContent" + "$ref": "#/components/schemas/FailedDependencyErrorResponseContent" } } } @@ -1067,17 +961,15 @@ "tags": [ "Long-Term Memory" ] - } - }, - "/v1/stores/{storeId}/long-term-memory/{memoryId}/fields": { - "patch": { - "description": "Atomically updates a custom-typed long-term memory's text and/or attributes, scoped to the caller's bound memory type. Used by the custom-extraction worker. New text must pass destination admission before the update is applied.", - "operationId": "UpdateLongTermMemoryFields", + }, + "post": { + "description": "Creates long-term memories in bulk. Records without namespace or namespaceRef stay un-namespaced. Automatic routing does not place them in a shared namespace. An explicit namespaceRef must pass destination admission and is never rerouted. Admission failures are reported per record in errors.", + "operationId": "BulkCreateLongTermMemories", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateLongTermMemoryFieldsRequestContent" + "$ref": "#/components/schemas/BulkCreateLongTermMemoriesRequestContent" } } }, @@ -1096,24 +988,18 @@ "description": "The store instance ID." }, "required": true - }, - { - "name": "memoryId", - "in": "path", - "description": "The memory record ID.", - "schema": { - "type": "string", - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-]+$", - "description": "The memory record ID." - }, - "required": true } ], "responses": { - "200": { - "description": "UpdateLongTermMemoryFields 200 response" + "201": { + "description": "BulkCreateLongTermMemories 201 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BulkCreateLongTermMemoriesResponseContent" + } + } + } }, "400": { "description": "BadRequestError 400 response", @@ -1165,12 +1051,22 @@ } } }, - "409": { - "description": "ConflictError 409 response", + "413": { + "description": "PayloadTooLargeError 413 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ConflictErrorResponseContent" + "$ref": "#/components/schemas/PayloadTooLargeErrorResponseContent" + } + } + } + }, + "422": { + "description": "IngestionHookStoppedError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IngestionHookStoppedErrorResponseContent" } } } @@ -1214,6 +1110,16 @@ } } } + }, + "503": { + "description": "IngestionHookRetryError 503 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IngestionHookRetryErrorResponseContent" + } + } + } } }, "tags": [ @@ -1221,10 +1127,20 @@ ] } }, - "/v1/stores/{storeId}/namespace-routing": { - "get": { - "description": "Returns the store's namespace routing policy. An empty disabled policy is returned when none has been saved.", - "operationId": "GetNamespaceRouting", + "/v1/stores/{storeId}/long-term-memory/move": { + "post": { + "description": "Moves long-term memories to an explicit namespaceRef, or automatically routes a memory that is already in a shared namespace when namespaceRef is omitted. Personal and un-namespaced memories are not automatic-routing candidates and keep their current placement with a per-item error. If routing is disabled or no shared destination qualifies, the memory also keeps its current placement and receives a per-item error. An explicit destination must pass admission and is never rerouted. Returns 409 when the explicit destination is archived; automatic routing and admission failures are reported per item in errors.", + "operationId": "MoveLongTermMemories", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MoveLongTermMemoriesRequestContent" + } + } + }, + "required": true + }, "parameters": [ { "name": "storeId", @@ -1242,11 +1158,11 @@ ], "responses": { "200": { - "description": "GetNamespaceRouting 200 response", + "description": "MoveLongTermMemories 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetNamespaceRoutingResponseContent" + "$ref": "#/components/schemas/MoveLongTermMemoriesResponseContent" } } } @@ -1301,6 +1217,16 @@ } } }, + "409": { + "description": "ConflictError 409 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConflictErrorResponseContent" + } + } + } + }, "413": { "description": "PayloadTooLargeError 413 response", "content": { @@ -1353,44 +1279,45 @@ } }, "tags": [ - "Namespaces" + "Long-Term Memory" ] - }, - "put": { - "description": "Replaces the store's namespace routing policy. Namespaces remain hierarchy records; routing is an ordered store-level document of plug-in strategies.", - "operationId": "PutNamespaceRouting", + } + }, + "/v1/stores/{storeId}/long-term-memory/search": { + "post": { + "description": "Runs a semantic search on long-term memory with filtering options.", + "operationId": "SearchLongTermMemory", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PutNamespaceRoutingRequestContent" + "$ref": "#/components/schemas/SearchLongTermMemoryRequestContent" } } - }, - "required": true + } }, "parameters": [ { "name": "storeId", "in": "path", - "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes.", + "description": "The store instance ID.", "schema": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes." + "description": "The store instance ID." }, "required": true } ], "responses": { "200": { - "description": "PutNamespaceRouting 200 response", + "description": "SearchLongTermMemory 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PutNamespaceRoutingResponseContent" + "$ref": "#/components/schemas/SearchLongTermMemoryResponseContent" } } } @@ -1445,16 +1372,6 @@ } } }, - "409": { - "description": "ConflictError 409 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ConflictErrorResponseContent" - } - } - } - }, "413": { "description": "PayloadTooLargeError 413 response", "content": { @@ -1476,11 +1393,11 @@ } }, "424": { - "description": "FailedDependencyError 424 response", + "description": "MemoryFailedDependencyError 424 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/FailedDependencyErrorResponseContent" + "$ref": "#/components/schemas/MemoryFailedDependencyErrorResponseContent" } } } @@ -1507,90 +1424,49 @@ } }, "tags": [ - "Namespaces" + "Long-Term Memory" ] } }, - "/v1/stores/{storeId}/namespaces": { + "/v1/stores/{storeId}/long-term-memory/{memoryId}": { "get": { - "description": "Lists namespace roots or direct children.", - "operationId": "ListNamespaces", + "description": "Returns a long-term memory by its ID.", + "operationId": "GetLongTermMemory", "parameters": [ { "name": "storeId", "in": "path", - "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes.", + "description": "The store instance ID.", "schema": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes." + "description": "The store instance ID." }, "required": true }, { - "name": "parentId", - "in": "query", - "description": "List direct children of this namespace. Omit to list roots.", - "schema": { - "type": "string", - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-]+$", - "description": "List direct children of this namespace. Omit to list roots." - } - }, - { - "name": "scope", - "in": "query", - "description": "Restrict root results to one scope. Cannot be combined with parentId.", - "schema": { - "$ref": "#/components/schemas/NamespaceScope" - } - }, - { - "name": "ownerId", - "in": "query", - "description": "Restrict personal root results to an owner. Cannot be combined with parentId; ignored for shared roots.", + "name": "memoryId", + "in": "path", + "description": "The memory record ID.", "schema": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Restrict personal root results to an owner. Cannot be combined with parentId; ignored for shared roots." - } - }, - { - "name": "limit", - "in": "query", - "description": "Maximum number of namespaces to return. Defaults to 100. Allowed range: 1-1000.", - "schema": { - "type": "integer", - "default": 100, - "maximum": 1000, - "minimum": 1, - "description": "Maximum number of namespaces to return. Defaults to 100. Allowed range: 1-1000.", - "format": "int32" - } - }, - { - "name": "pageToken", - "in": "query", - "description": "Opaque token from a previous response for the next page.", - "schema": { - "type": "string", - "description": "Opaque token from a previous response for the next page." - } + "description": "The memory record ID." + }, + "required": true } ], "responses": { "200": { - "description": "ListNamespaces 200 response", + "description": "GetLongTermMemory 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListNamespacesResponseContent" + "$ref": "#/components/schemas/GetLongTermMemoryResponseContent" } } } @@ -1697,17 +1573,17 @@ } }, "tags": [ - "Namespaces" + "Long-Term Memory" ] }, - "post": { - "description": "Creates a namespace resource as a root, direct child, or explicit hierarchy path. Returns 409 when an active or archived namespace already occupies the requested location.", - "operationId": "CreateNamespace", + "patch": { + "description": "Partially updates a long-term memory by its ID. The merged record must pass admission at its destination. Updates never select a different destination automatically.", + "operationId": "UpdateLongTermMemory", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateNamespaceRequestContent" + "$ref": "#/components/schemas/UpdateLongTermMemoryRequestContent" } } } @@ -1716,24 +1592,37 @@ { "name": "storeId", "in": "path", - "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes.", + "description": "The store instance ID.", "schema": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes." + "description": "The store instance ID." + }, + "required": true + }, + { + "name": "memoryId", + "in": "path", + "description": "The memory record ID.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "The memory record ID." }, "required": true } ], "responses": { - "201": { - "description": "CreateNamespace 201 response", + "200": { + "description": "UpdateLongTermMemory 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateNamespaceResponseContent" + "$ref": "#/components/schemas/UpdateLongTermMemoryResponseContent" } } } @@ -1819,11 +1708,11 @@ } }, "424": { - "description": "FailedDependencyError 424 response", + "description": "MemoryFailedDependencyError 424 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/FailedDependencyErrorResponseContent" + "$ref": "#/components/schemas/MemoryFailedDependencyErrorResponseContent" } } } @@ -1850,45 +1739,55 @@ } }, "tags": [ - "Namespaces" + "Long-Term Memory" ] } }, - "/v1/stores/{storeId}/namespaces/{namespaceId}": { - "delete": { - "description": "Deletes an empty leaf namespace. Returns 409 when the namespace has children or memory placements, or when it changed concurrently.", - "operationId": "DeleteNamespace", + "/v1/stores/{storeId}/long-term-memory/{memoryId}/fields": { + "patch": { + "description": "Atomically updates a custom-typed long-term memory's text and/or attributes, scoped to the caller's bound memory type. Used by the custom-extraction worker. New text must pass destination admission before the update is applied.", + "operationId": "UpdateLongTermMemoryFields", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateLongTermMemoryFieldsRequestContent" + } + } + }, + "required": true + }, "parameters": [ { "name": "storeId", "in": "path", - "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes.", + "description": "The store instance ID.", "schema": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes." + "description": "The store instance ID." }, "required": true }, { - "name": "namespaceId", + "name": "memoryId", "in": "path", - "description": "Server-generated namespace identifier.", + "description": "The memory record ID.", "schema": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Server-generated namespace identifier." + "description": "The memory record ID." }, "required": true } ], "responses": { - "204": { - "description": "DeleteNamespace 204 response" + "200": { + "description": "UpdateLongTermMemoryFields 200 response" }, "400": { "description": "BadRequestError 400 response", @@ -1950,16 +1849,6 @@ } } }, - "413": { - "description": "PayloadTooLargeError 413 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/PayloadTooLargeErrorResponseContent" - } - } - } - }, "423": { "description": "ResourceSuspendedError 423 response", "content": { @@ -1971,11 +1860,11 @@ } }, "424": { - "description": "FailedDependencyError 424 response", + "description": "MemoryFailedDependencyError 424 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/FailedDependencyErrorResponseContent" + "$ref": "#/components/schemas/MemoryFailedDependencyErrorResponseContent" } } } @@ -2002,12 +1891,14 @@ } }, "tags": [ - "Namespaces" + "Long-Term Memory" ] - }, + } + }, + "/v1/stores/{storeId}/long-term-memory/{memoryId}/sources": { "get": { - "description": "Gets one namespace by its canonical ID.", - "operationId": "GetNamespace", + "description": "Pages source links for one long-term memory. Tokens bind this query and expire.", + "operationId": "ListMemorySourceLinks", "parameters": [ { "name": "storeId", @@ -2023,26 +1914,43 @@ "required": true }, { - "name": "namespaceId", + "name": "memoryId", "in": "path", - "description": "Server-generated namespace identifier.", + "description": "Memory record identifier (1-64 chars, alphanumeric and dashes). Client-provided for idempotent long-term memory creation.", "schema": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Server-generated namespace identifier." + "description": "Memory record identifier (1-64 chars, alphanumeric and dashes). Client-provided for idempotent long-term memory creation." }, "required": true + }, + { + "name": "limit", + "in": "query", + "schema": { + "type": "integer", + "maximum": 100, + "minimum": 1, + "format": "int32" + } + }, + { + "name": "pageToken", + "in": "query", + "schema": { + "type": "string" + } } ], "responses": { "200": { - "description": "GetNamespace 200 response", + "description": "ListMemorySourceLinks 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetNamespaceResponseContent" + "$ref": "#/components/schemas/ListMemorySourceLinksResponseContent" } } } @@ -2097,16 +2005,6 @@ } } }, - "413": { - "description": "PayloadTooLargeError 413 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/PayloadTooLargeErrorResponseContent" - } - } - } - }, "423": { "description": "ResourceSuspendedError 423 response", "content": { @@ -2127,16 +2025,6 @@ } } }, - "429": { - "description": "TooManyRequestsError 429 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TooManyRequestsErrorResponseContent" - } - } - } - }, "500": { "description": "UnexpectedError 500 response", "content": { @@ -2149,21 +2037,14 @@ } }, "tags": [ - "Namespaces" + "Long-Term Memory" ] - }, - "patch": { - "description": "Renames or archives a namespace. Returns 409 when the namespace changed concurrently, an active or archived sibling already uses the requested name, or the namespace is archived.", - "operationId": "UpdateNamespace", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateNamespaceRequestContent" - } - } - } - }, + } + }, + "/v1/stores/{storeId}/long-term-memory/{memoryId}/sources/{sourceId}/evidence": { + "get": { + "description": "Pages extraction evidence for one source of a memory, in append order. Tokens bind the store, current owner, memory and source, and expire.", + "operationId": "ListMemorySourceEvidence", "parameters": [ { "name": "storeId", @@ -2179,26 +2060,56 @@ "required": true }, { - "name": "namespaceId", + "name": "memoryId", "in": "path", - "description": "Server-generated namespace identifier.", + "description": "Memory record identifier (1-64 chars, alphanumeric and dashes). Client-provided for idempotent long-term memory creation.", "schema": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Server-generated namespace identifier." + "description": "Memory record identifier (1-64 chars, alphanumeric and dashes). Client-provided for idempotent long-term memory creation." }, "required": true - } - ], + }, + { + "name": "sourceId", + "in": "path", + "description": "Stable source identifier for one revisioned origin in a store.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Stable source identifier for one revisioned origin in a store." + }, + "required": true + }, + { + "name": "limit", + "in": "query", + "schema": { + "type": "integer", + "maximum": 100, + "minimum": 1, + "format": "int32" + } + }, + { + "name": "pageToken", + "in": "query", + "schema": { + "type": "string" + } + } + ], "responses": { "200": { - "description": "UpdateNamespace 200 response", + "description": "ListMemorySourceEvidence 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateNamespaceResponseContent" + "$ref": "#/components/schemas/ListMemorySourceEvidenceResponseContent" } } } @@ -2253,26 +2164,6 @@ } } }, - "409": { - "description": "ConflictError 409 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ConflictErrorResponseContent" - } - } - } - }, - "413": { - "description": "PayloadTooLargeError 413 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/PayloadTooLargeErrorResponseContent" - } - } - } - }, "423": { "description": "ResourceSuspendedError 423 response", "content": { @@ -2293,16 +2184,6 @@ } } }, - "429": { - "description": "TooManyRequestsError 429 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TooManyRequestsErrorResponseContent" - } - } - } - }, "500": { "description": "UnexpectedError 500 response", "content": { @@ -2315,91 +2196,36 @@ } }, "tags": [ - "Namespaces" + "Long-Term Memory" ] } }, - "/v1/stores/{storeId}/session-memory": { + "/v1/stores/{storeId}/namespace-routing": { "get": { - "description": "Returns a paginated list of session IDs for a store.", - "operationId": "ListSessions", + "description": "Returns the store's namespace routing policy. An empty disabled policy is returned when none has been saved.", + "operationId": "GetNamespaceRouting", "parameters": [ { "name": "storeId", "in": "path", - "description": "The store instance ID.", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes.", "schema": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "The store instance ID." + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes." }, "required": true - }, - { - "name": "limit", - "in": "query", - "description": "Maximum number of sessions to return. Defaults to 100. Allowed range: 1-1000.", - "schema": { - "type": "integer", - "default": 100, - "maximum": 1000, - "minimum": 1, - "description": "Maximum number of sessions to return. Defaults to 100. Allowed range: 1-1000.", - "format": "int32" - } - }, - { - "name": "pageToken", - "in": "query", - "description": "Opaque token from a previous response for the next page.", - "schema": { - "type": "string", - "description": "Opaque token from a previous response for the next page." - } - }, - { - "name": "filterOwnerId", - "in": "query", - "description": "Filter sessions by owner. Matching is case-sensitive. Mutually exclusive with includeAll.", - "schema": { - "type": "string", - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-]+$", - "description": "Filter sessions by owner. Matching is case-sensitive. Mutually exclusive with includeAll." - } - }, - { - "name": "namespaceRef", - "in": "query", - "description": "Filter sessions by stable namespace ID. Matching is exact and case-sensitive, excludes deprecated namespace labels and sessions without a namespace resource, and does not include descendants. Combined with filterOwnerId using AND. Mutually exclusive with includeAll.", - "schema": { - "type": "string", - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-]+$", - "description": "Filter sessions by stable namespace ID. Matching is exact and case-sensitive, excludes deprecated namespace labels and sessions without a namespace resource, and does not include descendants. Combined with filterOwnerId using AND. Mutually exclusive with includeAll." - } - }, - { - "name": "includeAll", - "in": "query", - "description": "Set to true to list all sessions. Required when no filter is given; mutually exclusive with filters.", - "schema": { - "type": "boolean", - "description": "Set to true to list all sessions. Required when no filter is given; mutually exclusive with filters." - } } ], "responses": { "200": { - "description": "ListSessions 200 response", + "description": "GetNamespaceRouting 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListSessionsResponseContent" + "$ref": "#/components/schemas/GetNamespaceRoutingResponseContent" } } } @@ -2506,19 +2332,17 @@ } }, "tags": [ - "Session Memory" + "Namespaces" ] - } - }, - "/v1/stores/{storeId}/session-memory/events": { - "post": { - "description": "Appends a single event to a session. Creates the session if it does not exist. If sessionId is omitted, the server generates one.", - "operationId": "AddSessionEvent", + }, + "put": { + "description": "Replaces the store's namespace routing policy. Namespaces remain hierarchy records; routing is an ordered store-level document of plug-in strategies.", + "operationId": "PutNamespaceRouting", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AddSessionEventRequestContent" + "$ref": "#/components/schemas/PutNamespaceRoutingRequestContent" } } }, @@ -2528,24 +2352,24 @@ { "name": "storeId", "in": "path", - "description": "The store instance ID.", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes.", "schema": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "The store instance ID." + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes." }, "required": true } ], "responses": { - "201": { - "description": "AddSessionEvent 201 response", + "200": { + "description": "PutNamespaceRouting 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AddSessionEventResponseContent" + "$ref": "#/components/schemas/PutNamespaceRoutingResponseContent" } } } @@ -2600,6 +2424,16 @@ } } }, + "409": { + "description": "ConflictError 409 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConflictErrorResponseContent" + } + } + } + }, "413": { "description": "PayloadTooLargeError 413 response", "content": { @@ -2652,45 +2486,109 @@ } }, "tags": [ - "Session Memory" + "Namespaces" ] } }, - "/v1/stores/{storeId}/session-memory/{sessionId}": { - "delete": { - "description": "Deletes the session memory for a session.", - "operationId": "DeleteSessionMemory", + "/v1/stores/{storeId}/namespaces": { + "get": { + "description": "Lists namespace roots or direct children.", + "operationId": "ListNamespaces", "parameters": [ { "name": "storeId", "in": "path", - "description": "The store instance ID.", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes.", "schema": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "The store instance ID." + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes." }, "required": true }, { - "name": "sessionId", - "in": "path", - "description": "The session ID.", + "name": "parentId", + "in": "query", + "description": "List direct children of this namespace. Omit to list roots.", "schema": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "The session ID." - }, - "required": true + "description": "List direct children of this namespace. Omit to list roots." + } + }, + { + "name": "scope", + "in": "query", + "description": "Restrict root results to one scope. Cannot be combined with parentId.", + "schema": { + "$ref": "#/components/schemas/NamespaceScope" + } + }, + { + "name": "ownerId", + "in": "query", + "description": "Restrict personal root results to an owner. Cannot be combined with parentId; ignored for shared roots.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Restrict personal root results to an owner. Cannot be combined with parentId; ignored for shared roots." + } + }, + { + "name": "sortBy", + "in": "query", + "description": "Field to sort by. Defaults to id. Name sorts by the indexed display name using Redis text collation, not the namespace path. Equal values are ordered by ID ascending.", + "schema": { + "$ref": "#/components/schemas/NamespaceSortBy" + } + }, + { + "name": "sortOrder", + "in": "query", + "description": "Sort direction. Defaults to asc. Use the same sort options for each page; concurrent changes can shift offset-based pages.", + "schema": { + "$ref": "#/components/schemas/NamespaceSortOrder" + } + }, + { + "name": "limit", + "in": "query", + "description": "Maximum number of namespaces to return. Defaults to 100. Allowed range: 1-1000.", + "schema": { + "type": "integer", + "default": 100, + "maximum": 1000, + "minimum": 1, + "description": "Maximum number of namespaces to return. Defaults to 100. Allowed range: 1-1000.", + "format": "int32" + } + }, + { + "name": "pageToken", + "in": "query", + "description": "Opaque token from a previous response for the next page.", + "schema": { + "type": "string", + "description": "Opaque token from a previous response for the next page." + } } ], "responses": { - "204": { - "description": "DeleteSessionMemory 204 response" + "200": { + "description": "ListNamespaces 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListNamespacesResponseContent" + } + } + } }, "400": { "description": "BadRequestError 400 response", @@ -2794,56 +2692,43 @@ } }, "tags": [ - "Session Memory" + "Namespaces" ] }, - "get": { - "description": "Returns the session memory for a session.", - "operationId": "GetSessionMemory", + "post": { + "description": "Creates a namespace resource as a root, direct child, or explicit hierarchy path. Returns 409 when an active or archived namespace already occupies the requested location.", + "operationId": "CreateNamespace", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateNamespaceRequestContent" + } + } + } + }, "parameters": [ { "name": "storeId", "in": "path", - "description": "The store instance ID.", - "schema": { - "type": "string", - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-]+$", - "description": "The store instance ID." - }, - "required": true - }, - { - "name": "sessionId", - "in": "path", - "description": "The session ID.", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes.", "schema": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "The session ID." + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes." }, "required": true - }, - { - "name": "includeSummarisedEvents", - "in": "query", - "description": "When true, the response includes events that have already been covered by the session summary and have not yet been cleaned up. This flag is not expected to be set under normal usage.", - "schema": { - "type": "boolean", - "description": "When true, the response includes events that have already been covered by the session summary and have not yet been cleaned up. This flag is not expected to be set under normal usage." - } } ], "responses": { - "200": { - "description": "GetSessionMemory 200 response", + "201": { + "description": "CreateNamespace 201 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetSessionMemoryResponseContent" + "$ref": "#/components/schemas/CreateNamespaceResponseContent" } } } @@ -2898,6 +2783,16 @@ } } }, + "409": { + "description": "ConflictError 409 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConflictErrorResponseContent" + } + } + } + }, "413": { "description": "PayloadTooLargeError 413 response", "content": { @@ -2950,58 +2845,45 @@ } }, "tags": [ - "Session Memory" + "Namespaces" ] } }, - "/v1/stores/{storeId}/session-memory/{sessionId}/events/{eventId}": { + "/v1/stores/{storeId}/namespaces/{namespaceId}": { "delete": { - "description": "Deletes a single event from a session by event ID.", - "operationId": "DeleteSessionEvent", + "description": "Deletes an empty leaf namespace. Returns 409 when the namespace has children or memory placements, or when it changed concurrently.", + "operationId": "DeleteNamespace", "parameters": [ { "name": "storeId", "in": "path", - "description": "The store instance ID.", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes.", "schema": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "The store instance ID." + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes." }, "required": true }, { - "name": "sessionId", + "name": "namespaceId", "in": "path", - "description": "The session ID.", + "description": "Server-generated namespace identifier.", "schema": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "The session ID." - }, - "required": true - }, - { - "name": "eventId", - "in": "path", - "description": "The event ID.", - "schema": { - "type": "string", - "maxLength": 32, - "minLength": 32, - "pattern": "^[a-zA-Z0-9]+$", - "description": "The event ID." + "description": "Server-generated namespace identifier." }, "required": true } ], "responses": { "204": { - "description": "DeleteSessionEvent 204 response" + "description": "DeleteNamespace 204 response" }, "400": { "description": "BadRequestError 400 response", @@ -3053,6 +2935,16 @@ } } }, + "409": { + "description": "ConflictError 409 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConflictErrorResponseContent" + } + } + } + }, "413": { "description": "PayloadTooLargeError 413 response", "content": { @@ -3105,60 +2997,47 @@ } }, "tags": [ - "Session Memory" + "Namespaces" ] }, "get": { - "description": "Returns a single event from a session by event ID.", - "operationId": "GetSessionEvent", + "description": "Gets one namespace by its canonical ID.", + "operationId": "GetNamespace", "parameters": [ { "name": "storeId", "in": "path", - "description": "The store instance ID.", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes.", "schema": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "The store instance ID." + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes." }, "required": true }, { - "name": "sessionId", + "name": "namespaceId", "in": "path", - "description": "The session ID.", + "description": "Server-generated namespace identifier.", "schema": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "The session ID." - }, - "required": true - }, - { - "name": "eventId", - "in": "path", - "description": "The event ID.", - "schema": { - "type": "string", - "maxLength": 32, - "minLength": 32, - "pattern": "^[a-zA-Z0-9]+$", - "description": "The event ID." + "description": "Server-generated namespace identifier." }, "required": true } ], "responses": { "200": { - "description": "GetSessionEvent 200 response", + "description": "GetNamespace 200 response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetSessionEventResponseContent" + "$ref": "#/components/schemas/GetNamespaceResponseContent" } } } @@ -3265,155 +3144,3979 @@ } }, "tags": [ - "Session Memory" - ] - } - } - }, - "components": { - "schemas": { - "AddSessionEventRequestContent": { - "type": "object", - "properties": { - "sessionId": { - "type": "string", - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-]+$", - "description": "Optional session ID. If omitted, the server generates a unique ID." - }, - "actorId": { - "type": "string", - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-]+$", - "description": "Unique actor identifier (1-255 chars). Can represent a user, agent, or any participant." - }, - "namespace": { - "type": "string", - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-]+$", - "description": "Optional deprecated namespace label for the session. This label does not create or resolve a namespace resource. Do not supply it with namespaceRef.\n\nLike `ownerId`, this is a session-level value taken from the first event: the value sent with the first event of a session is stored on the session, and values sent with later events are ignored. Omit it to leave extracted memories without a namespace.", - "deprecated": true - }, - "namespaceRef": { - "$ref": "#/components/schemas/NamespaceRefInput" - }, - "role": { - "$ref": "#/components/schemas/MessageRole" - }, - "content": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Content" - }, - "description": "The message content as an array of typed content parts." - }, - "createdAt": { - "type": "string", - "description": "Client-supplied timestamp for when the event happened (UTC).", - "format": "date-time" - }, - "metadata": { - "description": "Optional metadata as any valid JSON value." - } - }, - "required": [ - "actorId", - "content", - "createdAt", - "role" + "Namespaces" ] }, - "AddSessionEventResponseContent": { - "type": "object", - "description": "Response returned after appending a session event.", - "properties": { - "event": { - "$ref": "#/components/schemas/SessionEvent" + "patch": { + "description": "Renames or archives a namespace. Returns 409 when the namespace changed concurrently, an active or archived sibling already uses the requested name, or the namespace is archived.", + "operationId": "UpdateNamespace", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateNamespaceRequestContent" + } + } } }, - "required": [ - "event" - ] - }, - "AttributeFilterClause": { - "description": "Filter clause for a single record attribute. Exactly one member is set; the member must match the attribute's declared field type.", - "oneOf": [ + "parameters": [ { - "type": "object", - "title": "string", - "properties": { - "string": { - "type": "string", - "description": "Match a string attribute equal to this value." - } + "name": "storeId", + "in": "path", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes." }, - "required": [ - "string" - ] + "required": true }, { - "type": "object", - "title": "number", - "properties": { - "number": { - "type": "number", - "description": "Match a numeric attribute equal to this value.", - "format": "double" - } + "name": "namespaceId", + "in": "path", + "description": "Server-generated namespace identifier.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Server-generated namespace identifier." }, - "required": [ - "number" - ] - }, - { - "type": "object", - "title": "boolean", - "properties": { - "boolean": { - "type": "boolean", - "description": "Match a boolean attribute equal to this value." + "required": true + } + ], + "responses": { + "200": { + "description": "UpdateNamespace 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateNamespaceResponseContent" + } + } + } + }, + "400": { + "description": "BadRequestError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BadRequestErrorResponseContent" + } + } + } + }, + "401": { + "description": "AuthenticationError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthenticationErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "408": { + "description": "TimeoutError 408 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TimeoutErrorResponseContent" + } + } + } + }, + "409": { + "description": "ConflictError 409 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConflictErrorResponseContent" + } + } + } + }, + "413": { + "description": "PayloadTooLargeError 413 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PayloadTooLargeErrorResponseContent" + } + } + } + }, + "423": { + "description": "ResourceSuspendedError 423 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResourceSuspendedErrorResponseContent" + } + } + } + }, + "424": { + "description": "FailedDependencyError 424 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FailedDependencyErrorResponseContent" + } + } + } + }, + "429": { + "description": "TooManyRequestsError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TooManyRequestsErrorResponseContent" + } + } + } + }, + "500": { + "description": "UnexpectedError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnexpectedErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Namespaces" + ] + } + }, + "/v1/stores/{storeId}/session-memory": { + "get": { + "description": "Returns a paginated list of session IDs for a store.", + "operationId": "ListSessions", + "parameters": [ + { + "name": "storeId", + "in": "path", + "description": "The store instance ID.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "The store instance ID." + }, + "required": true + }, + { + "name": "limit", + "in": "query", + "description": "Maximum number of sessions to return. Defaults to 100. Allowed range: 1-1000.", + "schema": { + "type": "integer", + "default": 100, + "maximum": 1000, + "minimum": 1, + "description": "Maximum number of sessions to return. Defaults to 100. Allowed range: 1-1000.", + "format": "int32" + } + }, + { + "name": "pageToken", + "in": "query", + "description": "Opaque token from a previous response for the next page.", + "schema": { + "type": "string", + "description": "Opaque token from a previous response for the next page." + } + }, + { + "name": "filterOwnerId", + "in": "query", + "description": "Filter sessions by owner. The owner of a session is the actorId of its first event. Matching is exact and case-sensitive. Mutually exclusive with includeAll.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Filter sessions by owner. The owner of a session is the actorId of its first event. Matching is exact and case-sensitive. Mutually exclusive with includeAll." + } + }, + { + "name": "namespaceRef", + "in": "query", + "description": "Filter sessions by stable namespace ID. Matching is exact and case-sensitive, excludes deprecated namespace labels and sessions without a namespace resource, and does not include descendants. Combined with filterOwnerId using AND. Mutually exclusive with includeAll.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Filter sessions by stable namespace ID. Matching is exact and case-sensitive, excludes deprecated namespace labels and sessions without a namespace resource, and does not include descendants. Combined with filterOwnerId using AND. Mutually exclusive with includeAll." + } + }, + { + "name": "includeAll", + "in": "query", + "description": "Set to true to list all sessions. Required when no filter is given; mutually exclusive with filters.", + "schema": { + "type": "boolean", + "description": "Set to true to list all sessions. Required when no filter is given; mutually exclusive with filters." + } + } + ], + "responses": { + "200": { + "description": "ListSessions 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListSessionsResponseContent" + } + } + } + }, + "400": { + "description": "BadRequestError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BadRequestErrorResponseContent" + } + } + } + }, + "401": { + "description": "AuthenticationError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthenticationErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } } + } + }, + "408": { + "description": "TimeoutError 408 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TimeoutErrorResponseContent" + } + } + } + }, + "413": { + "description": "PayloadTooLargeError 413 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PayloadTooLargeErrorResponseContent" + } + } + } + }, + "423": { + "description": "ResourceSuspendedError 423 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResourceSuspendedErrorResponseContent" + } + } + } + }, + "424": { + "description": "FailedDependencyError 424 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FailedDependencyErrorResponseContent" + } + } + } + }, + "429": { + "description": "TooManyRequestsError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TooManyRequestsErrorResponseContent" + } + } + } + }, + "500": { + "description": "UnexpectedError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnexpectedErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Session Memory" + ] + } + }, + "/v1/stores/{storeId}/session-memory/events": { + "post": { + "description": "Appends a single event to a session. Creates the session if it does not exist. If sessionId is omitted, the server generates one.", + "operationId": "AddSessionEvent", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AddSessionEventRequestContent" + } + } + }, + "required": true + }, + "parameters": [ + { + "name": "storeId", + "in": "path", + "description": "The store instance ID.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "The store instance ID." + }, + "required": true + } + ], + "responses": { + "201": { + "description": "AddSessionEvent 201 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AddSessionEventResponseContent" + } + } + } + }, + "400": { + "description": "BadRequestError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BadRequestErrorResponseContent" + } + } + } + }, + "401": { + "description": "AuthenticationError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthenticationErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "408": { + "description": "TimeoutError 408 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TimeoutErrorResponseContent" + } + } + } + }, + "413": { + "description": "PayloadTooLargeError 413 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PayloadTooLargeErrorResponseContent" + } + } + } + }, + "422": { + "description": "IngestionHookStoppedError 422 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IngestionHookStoppedErrorResponseContent" + } + } + } + }, + "423": { + "description": "ResourceSuspendedError 423 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResourceSuspendedErrorResponseContent" + } + } + } + }, + "424": { + "description": "FailedDependencyError 424 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FailedDependencyErrorResponseContent" + } + } + } + }, + "429": { + "description": "TooManyRequestsError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TooManyRequestsErrorResponseContent" + } + } + } + }, + "500": { + "description": "UnexpectedError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnexpectedErrorResponseContent" + } + } + } + }, + "503": { + "description": "IngestionHookRetryError 503 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IngestionHookRetryErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Session Memory" + ] + } + }, + "/v1/stores/{storeId}/session-memory/{sessionId}": { + "delete": { + "description": "Deletes the session memory for a session.", + "operationId": "DeleteSessionMemory", + "parameters": [ + { + "name": "storeId", + "in": "path", + "description": "The store instance ID.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "The store instance ID." + }, + "required": true + }, + { + "name": "sessionId", + "in": "path", + "description": "The session ID.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "The session ID." + }, + "required": true + } + ], + "responses": { + "204": { + "description": "DeleteSessionMemory 204 response" + }, + "400": { + "description": "BadRequestError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BadRequestErrorResponseContent" + } + } + } + }, + "401": { + "description": "AuthenticationError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthenticationErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "408": { + "description": "TimeoutError 408 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TimeoutErrorResponseContent" + } + } + } + }, + "413": { + "description": "PayloadTooLargeError 413 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PayloadTooLargeErrorResponseContent" + } + } + } + }, + "423": { + "description": "ResourceSuspendedError 423 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResourceSuspendedErrorResponseContent" + } + } + } + }, + "424": { + "description": "FailedDependencyError 424 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FailedDependencyErrorResponseContent" + } + } + } + }, + "429": { + "description": "TooManyRequestsError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TooManyRequestsErrorResponseContent" + } + } + } + }, + "500": { + "description": "UnexpectedError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnexpectedErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Session Memory" + ] + }, + "get": { + "description": "Returns the session memory for a session.", + "operationId": "GetSessionMemory", + "parameters": [ + { + "name": "storeId", + "in": "path", + "description": "The store instance ID.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "The store instance ID." + }, + "required": true + }, + { + "name": "sessionId", + "in": "path", + "description": "The session ID.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "The session ID." + }, + "required": true + }, + { + "name": "includeSummarisedEvents", + "in": "query", + "description": "When true, the response includes events that have already been covered by the session summary and have not yet been cleaned up. This flag is not expected to be set under normal usage.", + "schema": { + "type": "boolean", + "description": "When true, the response includes events that have already been covered by the session summary and have not yet been cleaned up. This flag is not expected to be set under normal usage." + } + } + ], + "responses": { + "200": { + "description": "GetSessionMemory 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetSessionMemoryResponseContent" + } + } + } + }, + "400": { + "description": "BadRequestError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BadRequestErrorResponseContent" + } + } + } + }, + "401": { + "description": "AuthenticationError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthenticationErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "408": { + "description": "TimeoutError 408 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TimeoutErrorResponseContent" + } + } + } + }, + "413": { + "description": "PayloadTooLargeError 413 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PayloadTooLargeErrorResponseContent" + } + } + } + }, + "423": { + "description": "ResourceSuspendedError 423 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResourceSuspendedErrorResponseContent" + } + } + } + }, + "424": { + "description": "FailedDependencyError 424 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FailedDependencyErrorResponseContent" + } + } + } + }, + "429": { + "description": "TooManyRequestsError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TooManyRequestsErrorResponseContent" + } + } + } + }, + "500": { + "description": "UnexpectedError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnexpectedErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Session Memory" + ] + } + }, + "/v1/stores/{storeId}/session-memory/{sessionId}/events/{eventId}": { + "delete": { + "description": "Deletes a single event from a session by event ID.", + "operationId": "DeleteSessionEvent", + "parameters": [ + { + "name": "storeId", + "in": "path", + "description": "The store instance ID.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "The store instance ID." + }, + "required": true + }, + { + "name": "sessionId", + "in": "path", + "description": "The session ID.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "The session ID." + }, + "required": true + }, + { + "name": "eventId", + "in": "path", + "description": "The event ID.", + "schema": { + "type": "string", + "maxLength": 32, + "minLength": 32, + "pattern": "^[a-zA-Z0-9]+$", + "description": "The event ID." + }, + "required": true + } + ], + "responses": { + "204": { + "description": "DeleteSessionEvent 204 response" + }, + "400": { + "description": "BadRequestError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BadRequestErrorResponseContent" + } + } + } + }, + "401": { + "description": "AuthenticationError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthenticationErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "408": { + "description": "TimeoutError 408 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TimeoutErrorResponseContent" + } + } + } + }, + "413": { + "description": "PayloadTooLargeError 413 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PayloadTooLargeErrorResponseContent" + } + } + } + }, + "423": { + "description": "ResourceSuspendedError 423 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResourceSuspendedErrorResponseContent" + } + } + } + }, + "424": { + "description": "FailedDependencyError 424 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FailedDependencyErrorResponseContent" + } + } + } + }, + "429": { + "description": "TooManyRequestsError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TooManyRequestsErrorResponseContent" + } + } + } + }, + "500": { + "description": "UnexpectedError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnexpectedErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Session Memory" + ] + }, + "get": { + "description": "Returns a single event from a session by event ID.", + "operationId": "GetSessionEvent", + "parameters": [ + { + "name": "storeId", + "in": "path", + "description": "The store instance ID.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "The store instance ID." + }, + "required": true + }, + { + "name": "sessionId", + "in": "path", + "description": "The session ID.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "The session ID." + }, + "required": true + }, + { + "name": "eventId", + "in": "path", + "description": "The event ID.", + "schema": { + "type": "string", + "maxLength": 32, + "minLength": 32, + "pattern": "^[a-zA-Z0-9]+$", + "description": "The event ID." + }, + "required": true + } + ], + "responses": { + "200": { + "description": "GetSessionEvent 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetSessionEventResponseContent" + } + } + } + }, + "400": { + "description": "BadRequestError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BadRequestErrorResponseContent" + } + } + } + }, + "401": { + "description": "AuthenticationError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthenticationErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "408": { + "description": "TimeoutError 408 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TimeoutErrorResponseContent" + } + } + } + }, + "413": { + "description": "PayloadTooLargeError 413 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PayloadTooLargeErrorResponseContent" + } + } + } + }, + "423": { + "description": "ResourceSuspendedError 423 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResourceSuspendedErrorResponseContent" + } + } + } + }, + "424": { + "description": "FailedDependencyError 424 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FailedDependencyErrorResponseContent" + } + } + } + }, + "429": { + "description": "TooManyRequestsError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TooManyRequestsErrorResponseContent" + } + } + } + }, + "500": { + "description": "UnexpectedError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnexpectedErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Session Memory" + ] + } + }, + "/v1/stores/{storeId}/sessions": { + "get": { + "description": "Returns paginated session rows with metadata and caller-selected order. The ID-only ListSessions operation remains unchanged.", + "operationId": "ListSessionSummaries", + "parameters": [ + { + "name": "storeId", + "in": "path", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes." + }, + "required": true + }, + { + "name": "limit", + "in": "query", + "description": "Maximum number of sessions to return. Defaults to 100. Allowed range: 1-1000.", + "schema": { + "type": "integer", + "default": 100, + "maximum": 1000, + "minimum": 1, + "description": "Maximum number of sessions to return. Defaults to 100. Allowed range: 1-1000.", + "format": "int32" + } + }, + { + "name": "pageToken", + "in": "query", + "description": "Opaque token from a previous response for the next page. Bound to the effective filters and sort.", + "schema": { + "type": "string", + "description": "Opaque token from a previous response for the next page. Bound to the effective filters and sort." + } + }, + { + "name": "filterOwnerId", + "in": "query", + "description": "Filter sessions by owner. The owner of a session is the actorId of its first event. Matching is exact and case-sensitive. Combined with namespaceRef using AND. Mutually exclusive with includeAll.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Filter sessions by owner. The owner of a session is the actorId of its first event. Matching is exact and case-sensitive. Combined with namespaceRef using AND. Mutually exclusive with includeAll." + } + }, + { + "name": "namespaceRef", + "in": "query", + "description": "Filter by stable namespace ID. Combined with filterOwnerId using AND. Mutually exclusive with includeAll.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Filter by stable namespace ID. Combined with filterOwnerId using AND. Mutually exclusive with includeAll." + } + }, + { + "name": "includeAll", + "in": "query", + "description": "Set to true to list all visible sessions. Required when no filter is given; mutually exclusive with filters.", + "schema": { + "type": "boolean", + "description": "Set to true to list all visible sessions. Required when no filter is given; mutually exclusive with filters." + } + }, + { + "name": "sortBy", + "in": "query", + "description": "Sort field. Defaults to updatedAt.", + "schema": { + "$ref": "#/components/schemas/SessionListSortBy" + } + }, + { + "name": "sortOrder", + "in": "query", + "description": "Sort direction. Defaults to desc for timestamps and asc for sessionId.", + "schema": { + "$ref": "#/components/schemas/SessionListSortOrder" + } + } + ], + "responses": { + "200": { + "description": "ListSessionSummaries 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListSessionSummariesResponseContent" + } + } + } + }, + "400": { + "description": "BadRequestError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BadRequestErrorResponseContent" + } + } + } + }, + "401": { + "description": "AuthenticationError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthenticationErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "408": { + "description": "TimeoutError 408 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TimeoutErrorResponseContent" + } + } + } + }, + "413": { + "description": "PayloadTooLargeError 413 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PayloadTooLargeErrorResponseContent" + } + } + } + }, + "423": { + "description": "ResourceSuspendedError 423 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResourceSuspendedErrorResponseContent" + } + } + } + }, + "424": { + "description": "FailedDependencyError 424 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FailedDependencyErrorResponseContent" + } + } + } + }, + "429": { + "description": "TooManyRequestsError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TooManyRequestsErrorResponseContent" + } + } + } + }, + "500": { + "description": "UnexpectedError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnexpectedErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Session Memory" + ] + } + }, + "/v1/stores/{storeId}/sources/{sourceId}/memories": { + "get": { + "description": "Pages memories linked to one source. A source link does not grant access to a memory in another owner or namespace.", + "operationId": "ListSourceMemories", + "parameters": [ + { + "name": "storeId", + "in": "path", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes." + }, + "required": true + }, + { + "name": "sourceId", + "in": "path", + "description": "Stable source identifier for one revisioned origin in a store.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Stable source identifier for one revisioned origin in a store." + }, + "required": true + }, + { + "name": "ownerId", + "in": "query", + "description": "Actor/owner identifier (1-64 chars, alphanumeric and dashes). Used for users, agents, or other participants.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Actor/owner identifier (1-64 chars, alphanumeric and dashes). Used for users, agents, or other participants." + }, + "required": true + }, + { + "name": "limit", + "in": "query", + "schema": { + "type": "integer", + "maximum": 100, + "minimum": 1, + "format": "int32" + } + }, + { + "name": "pageToken", + "in": "query", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "ListSourceMemories 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListSourceMemoriesResponseContent" + } + } + } + }, + "400": { + "description": "BadRequestError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BadRequestErrorResponseContent" + } + } + } + }, + "401": { + "description": "AuthenticationError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthenticationErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "408": { + "description": "TimeoutError 408 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TimeoutErrorResponseContent" + } + } + } + }, + "423": { + "description": "ResourceSuspendedError 423 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResourceSuspendedErrorResponseContent" + } + } + } + }, + "424": { + "description": "FailedDependencyError 424 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FailedDependencyErrorResponseContent" + } + } + } + }, + "500": { + "description": "UnexpectedError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnexpectedErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Long-Term Memory" + ] + } + }, + "/v1/stores/{storeId}/summary-views": { + "get": { + "description": "Lists Summary View definitions and high-level state. Partition values are not included.", + "operationId": "ListSummaryViews", + "parameters": [ + { + "name": "storeId", + "in": "path", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes." + }, + "required": true + }, + { + "name": "limit", + "in": "query", + "schema": { + "type": "integer", + "default": 100, + "maximum": 100, + "minimum": 1, + "format": "int32" + } + }, + { + "name": "pageToken", + "in": "query", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "ListSummaryViews 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListSummaryViewsResponseContent" + } + } + } + }, + "400": { + "description": "BadRequestError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BadRequestErrorResponseContent" + } + } + } + }, + "401": { + "description": "AuthenticationError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthenticationErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "408": { + "description": "TimeoutError 408 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TimeoutErrorResponseContent" + } + } + } + }, + "424": { + "description": "FailedDependencyError 424 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FailedDependencyErrorResponseContent" + } + } + } + }, + "429": { + "description": "TooManyRequestsError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TooManyRequestsErrorResponseContent" + } + } + } + }, + "500": { + "description": "UnexpectedError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnexpectedErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Summary Views" + ] + }, + "post": { + "description": "Creates a Summary View definition and asynchronously enqueues its initial reconciliation.", + "operationId": "CreateSummaryView", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateSummaryViewRequestContent" + } + } + }, + "required": true + }, + "parameters": [ + { + "name": "storeId", + "in": "path", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes." + }, + "required": true + } + ], + "responses": { + "201": { + "description": "CreateSummaryView 201 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateSummaryViewResponseContent" + } + } + } + }, + "400": { + "description": "BadRequestError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BadRequestErrorResponseContent" + } + } + } + }, + "401": { + "description": "AuthenticationError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthenticationErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "408": { + "description": "TimeoutError 408 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TimeoutErrorResponseContent" + } + } + } + }, + "409": { + "description": "SummaryViewConflictError 409 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SummaryViewConflictErrorResponseContent" + } + } + } + }, + "413": { + "description": "PayloadTooLargeError 413 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PayloadTooLargeErrorResponseContent" + } + } + } + }, + "424": { + "description": "FailedDependencyError 424 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FailedDependencyErrorResponseContent" + } + } + } + }, + "429": { + "description": "SummaryViewQuotaError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SummaryViewQuotaErrorResponseContent" + } + } + } + }, + "500": { + "description": "UnexpectedError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnexpectedErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Summary Views" + ] + } + }, + "/v1/stores/{storeId}/summary-views/{viewId}": { + "delete": { + "description": "Marks a Summary View deleting and asynchronously removes its schedule and materializations in bounded batches. Repeated requests are idempotent.", + "operationId": "DeleteSummaryView", + "parameters": [ + { + "name": "storeId", + "in": "path", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes." + }, + "required": true + }, + { + "name": "viewId", + "in": "path", + "description": "Server-generated Summary View identifier.", + "schema": { + "type": "string", + "maxLength": 32, + "minLength": 32, + "pattern": "^[a-zA-Z0-9]+$", + "description": "Server-generated Summary View identifier." + }, + "required": true + } + ], + "responses": { + "202": { + "description": "DeleteSummaryView 202 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeleteSummaryViewResponseContent" + } + } + } + }, + "400": { + "description": "BadRequestError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BadRequestErrorResponseContent" + } + } + } + }, + "401": { + "description": "AuthenticationError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthenticationErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "408": { + "description": "TimeoutError 408 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TimeoutErrorResponseContent" + } + } + } + }, + "409": { + "description": "SummaryViewConflictError 409 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SummaryViewConflictErrorResponseContent" + } + } + } + }, + "424": { + "description": "FailedDependencyError 424 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FailedDependencyErrorResponseContent" + } + } + } + }, + "429": { + "description": "TooManyRequestsError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TooManyRequestsErrorResponseContent" + } + } + } + }, + "500": { + "description": "UnexpectedError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnexpectedErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Summary Views" + ] + }, + "get": { + "description": "Returns one Summary View definition without partition values.", + "operationId": "GetSummaryView", + "parameters": [ + { + "name": "storeId", + "in": "path", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes." + }, + "required": true + }, + { + "name": "viewId", + "in": "path", + "description": "Server-generated Summary View identifier.", + "schema": { + "type": "string", + "maxLength": 32, + "minLength": 32, + "pattern": "^[a-zA-Z0-9]+$", + "description": "Server-generated Summary View identifier." + }, + "required": true + } + ], + "responses": { + "200": { + "description": "GetSummaryView 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetSummaryViewResponseContent" + } + } + } + }, + "400": { + "description": "BadRequestError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BadRequestErrorResponseContent" + } + } + } + }, + "401": { + "description": "AuthenticationError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthenticationErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "408": { + "description": "TimeoutError 408 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TimeoutErrorResponseContent" + } + } + } + }, + "424": { + "description": "FailedDependencyError 424 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FailedDependencyErrorResponseContent" + } + } + } + }, + "429": { + "description": "TooManyRequestsError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TooManyRequestsErrorResponseContent" + } + } + } + }, + "500": { + "description": "UnexpectedError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnexpectedErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Summary Views" + ] + }, + "patch": { + "description": "Updates mutable Summary View fields. Source is immutable. Material changes increment definitionVersion; name- or description-only changes do not enqueue refresh work.", + "operationId": "UpdateSummaryView", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateSummaryViewRequestContent" + } + } + } + }, + "parameters": [ + { + "name": "storeId", + "in": "path", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes." + }, + "required": true + }, + { + "name": "viewId", + "in": "path", + "description": "Server-generated Summary View identifier.", + "schema": { + "type": "string", + "maxLength": 32, + "minLength": 32, + "pattern": "^[a-zA-Z0-9]+$", + "description": "Server-generated Summary View identifier." + }, + "required": true + } + ], + "responses": { + "200": { + "description": "UpdateSummaryView 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateSummaryViewResponseContent" + } + } + } + }, + "400": { + "description": "BadRequestError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BadRequestErrorResponseContent" + } + } + } + }, + "401": { + "description": "AuthenticationError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthenticationErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "408": { + "description": "TimeoutError 408 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TimeoutErrorResponseContent" + } + } + } + }, + "409": { + "description": "SummaryViewConflictError 409 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SummaryViewConflictErrorResponseContent" + } + } + } + }, + "413": { + "description": "PayloadTooLargeError 413 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PayloadTooLargeErrorResponseContent" + } + } + } + }, + "424": { + "description": "FailedDependencyError 424 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FailedDependencyErrorResponseContent" + } + } + } + }, + "429": { + "description": "SummaryViewQuotaError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SummaryViewQuotaErrorResponseContent" + } + } + } + }, + "500": { + "description": "UnexpectedError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnexpectedErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Summary Views" + ] + } + }, + "/v1/stores/{storeId}/summary-views/{viewId}/refresh": { + "post": { + "description": "Asynchronously enqueues one exact partition refresh or a complete view reconciliation. It never performs generation synchronously.", + "operationId": "RefreshSummaryView", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RefreshSummaryViewRequestContent" + } + } + }, + "required": true + }, + "parameters": [ + { + "name": "storeId", + "in": "path", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes." + }, + "required": true + }, + { + "name": "viewId", + "in": "path", + "description": "Server-generated Summary View identifier.", + "schema": { + "type": "string", + "maxLength": 32, + "minLength": 32, + "pattern": "^[a-zA-Z0-9]+$", + "description": "Server-generated Summary View identifier." + }, + "required": true + } + ], + "responses": { + "202": { + "description": "RefreshSummaryView 202 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RefreshSummaryViewResponseContent" + } + } + } + }, + "400": { + "description": "BadRequestError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BadRequestErrorResponseContent" + } + } + } + }, + "401": { + "description": "AuthenticationError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthenticationErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "408": { + "description": "TimeoutError 408 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TimeoutErrorResponseContent" + } + } + } + }, + "409": { + "description": "SummaryViewConflictError 409 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SummaryViewConflictErrorResponseContent" + } + } + } + }, + "424": { + "description": "FailedDependencyError 424 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FailedDependencyErrorResponseContent" + } + } + } + }, + "429": { + "description": "SummaryViewQuotaError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SummaryViewQuotaErrorResponseContent" + } + } + } + }, + "500": { + "description": "UnexpectedError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnexpectedErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Summary Views" + ] + } + }, + "/v1/stores/{storeId}/summary-views/{viewId}/result": { + "get": { + "description": "Returns one authorized exact Summary View partition after validating its contributing source records. Invalid output is withheld while repair is pending.", + "operationId": "GetSummaryViewResult", + "parameters": [ + { + "name": "storeId", + "in": "path", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Store identifier (1-64 chars, alphanumeric and dashes). Generated store IDs are typically 32-character UUIDs without dashes." + }, + "required": true + }, + { + "name": "viewId", + "in": "path", + "description": "Server-generated Summary View identifier.", + "schema": { + "type": "string", + "maxLength": 32, + "minLength": 32, + "pattern": "^[a-zA-Z0-9]+$", + "description": "Server-generated Summary View identifier." + }, + "required": true + }, + { + "name": "ownerId", + "in": "query", + "description": "Actor/owner identifier (1-64 chars, alphanumeric and dashes). Used for users, agents, or other participants.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Actor/owner identifier (1-64 chars, alphanumeric and dashes). Used for users, agents, or other participants." + } + }, + { + "name": "sessionId", + "in": "query", + "description": "Session identifier (1-64 chars, alphanumeric and dashes). When the server generates one, it uses a 32-character UUID without dashes.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Session identifier (1-64 chars, alphanumeric and dashes). When the server generates one, it uses a 32-character UUID without dashes." + } + }, + { + "name": "namespaceRef", + "in": "query", + "description": "Server-generated namespace identifier.", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Server-generated namespace identifier." + } + }, + { + "name": "memoryType", + "in": "query", + "description": "Identifier of a long-term memory type.\n\nBuilt-in types include `semantic`, `episodic`, `message`, and `session_summary_view`.\nStores may also register custom memory types; this open string accepts any\nregistered type name.\n\nConstraints: 1-64 chars, must start with a letter, followed by letters, digits,\nunderscores, or dashes.\n", + "schema": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z][a-zA-Z0-9_-]*$", + "description": "Identifier of a long-term memory type.\n\nBuilt-in types include `semantic`, `episodic`, `message`, and `session_summary_view`.\nStores may also register custom memory types; this open string accepts any\nregistered type name.\n\nConstraints: 1-64 chars, must start with a letter, followed by letters, digits,\nunderscores, or dashes." + } + }, + { + "name": "includeSourceMemoryIds", + "in": "query", + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "description": "GetSummaryViewResult 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetSummaryViewResultResponseContent" + } + } + } + }, + "400": { + "description": "BadRequestError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BadRequestErrorResponseContent" + } + } + } + }, + "401": { + "description": "AuthenticationError 401 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthenticationErrorResponseContent" + } + } + } + }, + "403": { + "description": "ForbiddenError 403 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForbiddenErrorResponseContent" + } + } + } + }, + "404": { + "description": "NotFoundError 404 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotFoundErrorResponseContent" + } + } + } + }, + "408": { + "description": "TimeoutError 408 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TimeoutErrorResponseContent" + } + } + } + }, + "409": { + "description": "SummaryViewConflictError 409 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SummaryViewConflictErrorResponseContent" + } + } + } + }, + "424": { + "description": "FailedDependencyError 424 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FailedDependencyErrorResponseContent" + } + } + } + }, + "429": { + "description": "TooManyRequestsError 429 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TooManyRequestsErrorResponseContent" + } + } + } + }, + "500": { + "description": "UnexpectedError 500 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnexpectedErrorResponseContent" + } + } + } + } + }, + "tags": [ + "Summary Views" + ] + } + } + }, + "components": { + "schemas": { + "AddSessionEventRequestContent": { + "type": "object", + "properties": { + "idempotencyKey": { + "type": "string", + "maxLength": 128, + "minLength": 1, + "pattern": "^[ -~]+$", + "description": "Required when the store selects session.append input hooks. Reuse this key only for an identical request; accepted retries reuse the saved decision and event identity." + }, + "sessionId": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Optional session ID. If omitted, the server generates a unique ID." + }, + "actorId": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Unique actor identifier (1-255 chars). Can represent a user, agent, or any participant." + }, + "namespace": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Optional deprecated namespace label for the session. This label does not create or resolve a namespace resource. Do not supply it with namespaceRef.\n\nLike `ownerId`, this is a session-level value taken from the first event: the value sent with the first event of a session is stored on the session, and values sent with later events are ignored. Omit it to leave extracted memories without a namespace.", + "deprecated": true + }, + "namespaceRef": { + "$ref": "#/components/schemas/NamespaceRefInput" + }, + "role": { + "$ref": "#/components/schemas/MessageRole" + }, + "content": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Content" + }, + "description": "The message content as an array of typed content parts." + }, + "createdAt": { + "type": "string", + "description": "Client-supplied timestamp for when the event happened (UTC).", + "format": "date-time" + }, + "metadata": { + "description": "Optional metadata as any valid JSON value." + } + }, + "required": [ + "actorId", + "content", + "createdAt", + "role" + ] + }, + "AddSessionEventResponseContent": { + "type": "object", + "description": "Response returned after appending a session event.", + "properties": { + "event": { + "$ref": "#/components/schemas/SessionEvent" + } + }, + "required": [ + "event" + ] + }, + "AttributeFilterClause": { + "description": "Filter clause for a single record attribute. Exactly one member is set; the member must match the attribute's declared field type.", + "oneOf": [ + { + "type": "object", + "title": "string", + "properties": { + "string": { + "type": "string", + "description": "Match a string attribute equal to this value." + } + }, + "required": [ + "string" + ] + }, + { + "type": "object", + "title": "number", + "properties": { + "number": { + "type": "number", + "description": "Match a numeric attribute equal to this value.", + "format": "double" + } + }, + "required": [ + "number" + ] + }, + { + "type": "object", + "title": "boolean", + "properties": { + "boolean": { + "type": "boolean", + "description": "Match a boolean attribute equal to this value." + } + }, + "required": [ + "boolean" + ] + }, + { + "type": "object", + "title": "list", + "properties": { + "list": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Match a list attribute that contains all of these values." + } + }, + "required": [ + "list" + ] + } + ] + }, + "AttributeFilterMap": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/AttributeFilterClause" + }, + "description": "Per-attribute filter clauses keyed by the custom memory type's field name." + }, + "AttributeMap": { + "type": "object", + "additionalProperties": {}, + "description": "Structured record attributes: a map from the custom memory type's field name to that field's value. Values are arbitrary JSON matching the field's declared type (str, int, float, bool, list[str], list[float], or object)." + }, + "AuthenticationErrorResponseContent": { + "type": "object", + "description": "Authentication credentials are missing, malformed, or invalid.", + "properties": { + "title": { + "type": "string", + "description": "A short, human-readable summary of the problem\n type. It SHOULD NOT change from occurrence to occurrence of the\n problem, except for purposes of localization (e.g., using\n proactive content negotiation; see [RFC7231], Section 3.4)." + }, + "status": { + "type": "integer", + "default": 401, + "description": "The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.", + "format": "int32" + }, + "detail": { + "type": "string", + "description": "A human-readable explanation specific to this occurrence of the problem." + }, + "instance": { + "type": "string", + "description": "A URI reference that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced." + }, + "type": { + "$ref": "#/components/schemas/AuthenticationErrorType" + } + }, + "required": [ + "status", + "title", + "type" + ] + }, + "AuthenticationErrorType": { + "type": "string", + "description": "Problem type URI for authentication errors.", + "enum": [ + "/errors/authentication-failed" + ] + }, + "BadRequestErrorResponseContent": { + "type": "object", + "description": "Request validation or input decoding failed.", + "properties": { + "title": { + "type": "string", + "description": "A short, human-readable summary of the problem\n type. It SHOULD NOT change from occurrence to occurrence of the\n problem, except for purposes of localization (e.g., using\n proactive content negotiation; see [RFC7231], Section 3.4)." + }, + "status": { + "type": "integer", + "default": 400, + "description": "The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.", + "format": "int32" + }, + "detail": { + "type": "string", + "description": "A human-readable explanation specific to this occurrence of the problem." + }, + "instance": { + "type": "string", + "description": "A URI reference that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced." + }, + "type": { + "$ref": "#/components/schemas/BadRequestErrorType" + }, + "fields": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FieldError" + }, + "description": "Optional field-level validation errors." + } + }, + "required": [ + "status", + "title", + "type" + ] + }, + "BadRequestErrorType": { + "type": "string", + "description": "Problem type URI for bad request errors.", + "enum": [ + "/errors/invalid-data" + ] + }, + "BulkCreateLongTermMemoriesRequestContent": { + "type": "object", + "description": "Bulk create request for long-term memory records.", + "properties": { + "idempotencyKey": { + "type": "string", + "maxLength": 128, + "minLength": 1, + "pattern": "^[ -~]+$", + "description": "Required when the memory.create input hook is selected. Reuse the same key and original request to resume its saved decision." + }, + "memories": { + "type": "array", + "items": { + "$ref": "#/components/schemas/CreateMemoryRecord" + }, + "maxItems": 100, + "minItems": 1, + "description": "List of memory records to create." + } + }, + "required": [ + "memories" + ] + }, + "BulkCreateLongTermMemoriesResponseContent": { + "type": "object", + "description": "Bulk create result for long-term memory records.", + "properties": { + "created": { + "type": "array", + "items": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Memory record identifier (1-64 chars, alphanumeric and dashes). Client-provided for idempotent long-term memory creation." + }, + "description": "IDs of successfully created memory records. Always returned; empty when no records were created." + }, + "errors": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BulkOperationError" + }, + "description": "Errors for memory records that failed to be created." + } + }, + "required": [ + "created" + ] + }, + "BulkDeleteLongTermMemoriesRequestContent": { + "type": "object", + "description": "Bulk delete request for long-term memory records.", + "properties": { + "memoryIds": { + "type": "array", + "items": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Memory record identifier (1-64 chars, alphanumeric and dashes). Client-provided for idempotent long-term memory creation." + }, + "maxItems": 100, + "minItems": 1, + "description": "List of memory record IDs to delete (1-100 IDs)." + } + }, + "required": [ + "memoryIds" + ] + }, + "BulkDeleteLongTermMemoriesResponseContent": { + "type": "object", + "description": "Bulk delete result for long-term memory records.", + "properties": { + "deleted": { + "type": "array", + "items": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Memory record identifier (1-64 chars, alphanumeric and dashes). Client-provided for idempotent long-term memory creation." + }, + "description": "IDs of successfully deleted memory records. Always returned; empty when no records were deleted." + }, + "errors": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BulkOperationError" + }, + "description": "Errors for memory records that failed to be deleted." + } + }, + "required": [ + "deleted" + ] + }, + "BulkOperationError": { + "type": "object", + "description": "Error detail for a single item in a bulk operation.", + "properties": { + "id": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Memory record ID of the item that failed." + }, + "error": { + "type": "string", + "description": "Error message describing the failure." + } + }, + "required": [ + "error", + "id" + ] + }, + "ConflictErrorResponseContent": { + "type": "object", + "description": "The request conflicts with the current state of the resource.", + "properties": { + "title": { + "type": "string", + "description": "A short, human-readable summary of the problem\n type. It SHOULD NOT change from occurrence to occurrence of the\n problem, except for purposes of localization (e.g., using\n proactive content negotiation; see [RFC7231], Section 3.4)." + }, + "status": { + "type": "integer", + "default": 409, + "description": "The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.", + "format": "int32" + }, + "detail": { + "type": "string", + "description": "A human-readable explanation specific to this occurrence of the problem." + }, + "instance": { + "type": "string", + "description": "A URI reference that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced." + }, + "type": { + "$ref": "#/components/schemas/ConflictErrorType" + } + }, + "required": [ + "status", + "title", + "type" + ] + }, + "ConflictErrorType": { + "type": "string", + "description": "Problem type URI for conflict errors.", + "enum": [ + "/errors/conflict" + ] + }, + "Content": { + "description": "A single content item in a message. Exactly one member is set.", + "oneOf": [ + { + "type": "object", + "title": "text", + "properties": { + "text": { + "type": "string", + "description": "Text content." + } + }, + "required": [ + "text" + ] + } + ] + }, + "CreateDocumentIngestionRequestContent": { + "type": "object", + "properties": { + "documentId": { + "type": "string", + "maxLength": 512, + "minLength": 1, + "description": "Customer-controlled logical document ID. Opaque and case-sensitive." + }, + "revision": { + "type": "string", + "maxLength": 512, + "minLength": 1, + "description": "Customer-controlled immutable revision token. Opaque and case-sensitive." + }, + "content": { + "type": "string", + "format": "byte" + }, + "mediaType": { + "$ref": "#/components/schemas/DocumentMediaType" + }, + "ownerId": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Actor/owner identifier (1-64 chars, alphanumeric and dashes). Used for users, agents, or other participants." + }, + "extractorId": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Extractor identifier (1-64 chars, alphanumeric and dashes)." + }, + "idempotencyKey": { + "type": "string", + "maxLength": 128, + "minLength": 1, + "description": "Customer idempotency key for one document submission." + } + }, + "required": [ + "content", + "documentId", + "extractorId", + "idempotencyKey", + "mediaType", + "ownerId", + "revision" + ] + }, + "CreateDocumentIngestionResponseContent": { + "type": "object", + "properties": { + "ingestionId": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Server-generated document ingestion identifier." + }, + "status": { + "$ref": "#/components/schemas/DocumentIngestionStatus" + } + }, + "required": [ + "ingestionId", + "status" + ] + }, + "CreateMemoryRecord": { + "type": "object", + "description": "A memory record to create.", + "properties": { + "id": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Client-provided memory record ID for idempotent creation." + }, + "text": { + "type": "string", + "maxLength": 50000, + "minLength": 1, + "description": "The memory content (1-50000 chars)." + }, + "memoryType": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z][a-zA-Z0-9_-]*$", + "description": "Type of memory. Built-in or a custom type registered on the store." + }, + "sessionId": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Session ID associated with this memory (1-64 chars, alphanumeric and dashes)." + }, + "ownerId": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Owner ID associated with this memory (1-64 chars, alphanumeric and dashes)." + }, + "namespace": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Optional deprecated namespace label. It does not create or resolve a namespace resource. Do not supply it with namespaceRef. If both fields are omitted, the record is created without a namespace. Automatic routing does not place an un-namespaced record in a shared namespace.", + "deprecated": true + }, + "namespaceRef": { + "$ref": "#/components/schemas/NamespaceRefInput" + }, + "topics": { + "type": "array", + "items": { + "type": "string", + "maxLength": 100, + "minLength": 1, + "description": "Topic name (1-100 chars)." + }, + "maxItems": 50, + "description": "Topic tags for categorization (max 50 topics, each 1-100 chars)." + }, + "attributes": { + "$ref": "#/components/schemas/AttributeMap" + } + }, + "required": [ + "id", + "ownerId", + "text" + ] + }, + "CreateNamespaceRequestContent": { + "type": "object", + "properties": { + "name": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9_-]+$", + "description": "One namespace segment. Use with scope for a root or parentId for a child." + }, + "path": { + "type": "string", + "maxLength": 1024, + "minLength": 1, + "description": "A complete hierarchy path to create. Missing segments are created as needed. Mutually exclusive with name and parentId. The path does not encode scope." + }, + "scope": { + "$ref": "#/components/schemas/NamespaceScope" + }, + "parentId": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Parent namespace for a direct child." + }, + "ownerId": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Owner for a personal root or path. Required for personal scope; omit for shared roots and children." + } + } + }, + "CreateNamespaceResponseContent": { + "type": "object", + "properties": { + "namespace": { + "$ref": "#/components/schemas/Namespace" + } + }, + "required": [ + "namespace" + ] + }, + "CreateSummaryViewRequestContent": { + "type": "object", + "properties": { + "visibility": { + "$ref": "#/components/schemas/SummaryViewVisibility" + }, + "name": { + "type": "string", + "maxLength": 100, + "minLength": 1, + "description": "Customer-visible Summary View name (1-100 characters)." + }, + "description": { + "type": "string", + "maxLength": 200, + "description": "Optional Summary View description (up to 200 characters)." + }, + "source": { + "$ref": "#/components/schemas/SummaryViewSource" + }, + "filter": { + "$ref": "#/components/schemas/LongTermMemoryFilter" + }, + "filterOp": { + "$ref": "#/components/schemas/FilterConjunction" + }, + "groupBy": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SummaryViewGroupField" + }, + "maxItems": 4 + }, + "evictionPolicy": { + "$ref": "#/components/schemas/SummaryViewEvictionPolicy" + }, + "timeWindowSeconds": { + "type": "integer", + "minimum": 1, + "format": "int64" + }, + "output": { + "$ref": "#/components/schemas/SummaryViewOutputConfig" + }, + "refreshPolicy": { + "$ref": "#/components/schemas/SummaryViewRefreshPolicy" + } + }, + "required": [ + "groupBy", + "name", + "output", + "refreshPolicy", + "source" + ] + }, + "CreateSummaryViewResponseContent": { + "type": "object", + "description": "An owned Summary View definition. Results are separate derived state and never enter long-term-memory search.", + "properties": { + "id": { + "type": "string", + "maxLength": 32, + "minLength": 32, + "pattern": "^[a-zA-Z0-9]+$", + "description": "Server-generated Summary View identifier." + }, + "ownerId": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Immutable canonical user ID assigned by the server. Clients cannot set ownership." + }, + "visibility": { + "$ref": "#/components/schemas/SummaryViewVisibility" + }, + "name": { + "type": "string", + "maxLength": 100, + "minLength": 1, + "description": "Customer-visible Summary View name (1-100 characters)." + }, + "description": { + "type": "string", + "maxLength": 200, + "description": "Optional Summary View description (up to 200 characters)." + }, + "source": { + "$ref": "#/components/schemas/SummaryViewSource" + }, + "filter": { + "$ref": "#/components/schemas/LongTermMemoryFilter" + }, + "filterOp": { + "$ref": "#/components/schemas/FilterConjunction" + }, + "groupBy": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SummaryViewGroupField" + }, + "maxItems": 4 + }, + "evictionPolicy": { + "$ref": "#/components/schemas/SummaryViewEvictionPolicy" + }, + "timeWindowSeconds": { + "type": "integer", + "minimum": 1, + "format": "int64" + }, + "output": { + "$ref": "#/components/schemas/SummaryViewOutputConfig" + }, + "refreshPolicy": { + "$ref": "#/components/schemas/SummaryViewRefreshPolicy" + }, + "definitionVersion": { + "type": "integer", + "minimum": 1, + "format": "int64" + }, + "state": { + "$ref": "#/components/schemas/SummaryViewState" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + } + }, + "required": [ + "createdAt", + "definitionVersion", + "filterOp", + "groupBy", + "id", + "name", + "output", + "ownerId", + "refreshPolicy", + "source", + "state", + "updatedAt", + "visibility" + ] + }, + "CreatedAtFilter": { + "type": "object", + "description": "Filter by creation timestamp.", + "properties": { + "gt": { + "type": "string", + "description": "After the given timestamp.", + "format": "date-time" + }, + "gte": { + "type": "string", + "description": "At or after the given timestamp.", + "format": "date-time" + }, + "lt": { + "type": "string", + "description": "Before the given timestamp.", + "format": "date-time" + }, + "lte": { + "type": "string", + "description": "At or before the given timestamp.", + "format": "date-time" + }, + "eq": { + "type": "string", + "description": "Exactly at the given timestamp.", + "format": "date-time" + } + } + }, + "DeleteSummaryViewResponseContent": { + "type": "object", + "properties": { + "viewId": { + "type": "string", + "maxLength": 32, + "minLength": 32, + "pattern": "^[a-zA-Z0-9]+$", + "description": "Server-generated Summary View identifier." + }, + "state": { + "$ref": "#/components/schemas/SummaryViewState" + } + }, + "required": [ + "state", + "viewId" + ] + }, + "DocumentIngestionCleanupState": { + "type": "string", + "enum": [ + "pending", + "deleted", + "failed" + ] + }, + "DocumentIngestionProcessingState": { + "type": "string", + "enum": [ + "queued", + "running", + "succeeded", + "failed", + "partial" + ] + }, + "DocumentIngestionRecord": { + "type": "object", + "properties": { + "ingestionId": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Server-generated document ingestion identifier." + }, + "status": { + "$ref": "#/components/schemas/DocumentIngestionStatus" + } + }, + "required": [ + "ingestionId", + "status" + ] + }, + "DocumentIngestionStatus": { + "type": "object", + "properties": { + "processing": { + "$ref": "#/components/schemas/DocumentIngestionProcessingState" + }, + "cleanup": { + "$ref": "#/components/schemas/DocumentIngestionCleanupState" + }, + "extractorId": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Extractor identifier (1-64 chars, alphanumeric and dashes)." + }, + "extractorRevision": { + "type": "integer", + "format": "int64" + }, + "completedChunks": { + "type": "integer", + "format": "int32" + }, + "totalChunks": { + "type": "integer", + "format": "int32" + }, + "createdCount": { + "type": "integer", + "format": "int32" + }, + "filteredCount": { + "type": "integer", + "format": "int32" + }, + "error": { + "type": "string" + }, + "retentionDeadline": { + "type": "number", + "format": "double" + }, + "deletedAt": { + "type": "number", + "format": "double" + } + }, + "required": [ + "cleanup", + "processing" + ] + }, + "DocumentMediaType": { + "type": "string", + "enum": [ + "text/plain", + "text/markdown" + ] + }, + "DocumentSourceIdentity": { + "type": "object", + "properties": { + "documentId": { + "type": "string", + "maxLength": 512, + "minLength": 1, + "description": "Customer-controlled logical document ID. Opaque and case-sensitive." + }, + "revision": { + "type": "string", + "maxLength": 512, + "minLength": 1, + "description": "Customer-controlled immutable revision token. Opaque and case-sensitive." + } + }, + "required": [ + "documentId", + "revision" + ] + }, + "EvidenceProducer": { + "type": "object", + "properties": { + "name": { + "type": "string", + "maxLength": 128, + "minLength": 1 + } + }, + "required": [ + "name" + ] + }, + "FailedDependencyErrorResponseContent": { + "type": "object", + "description": "A dependent resource required to process the request is unavailable or unhealthy.", + "properties": { + "title": { + "type": "string", + "description": "A short, human-readable summary of the problem\n type. It SHOULD NOT change from occurrence to occurrence of the\n problem, except for purposes of localization (e.g., using\n proactive content negotiation; see [RFC7231], Section 3.4)." + }, + "status": { + "type": "integer", + "default": 424, + "description": "The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.", + "format": "int32" + }, + "detail": { + "type": "string", + "description": "A human-readable explanation specific to this occurrence of the problem." + }, + "instance": { + "type": "string", + "description": "A URI reference that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced." + }, + "type": { + "$ref": "#/components/schemas/FailedDependencyErrorType" + } + }, + "required": [ + "status", + "title", + "type" + ] + }, + "FailedDependencyErrorType": { + "type": "string", + "description": "Problem type URI for failed-dependency errors.", + "enum": [ + "/errors/resource-unavailable", + "/errors/database-out-of-memory" + ] + }, + "FieldError": { + "type": "object", + "description": "Validation error details for a single request field.", + "properties": { + "field": { + "type": "string", + "description": "Name of the invalid request field." + }, + "rule": { + "type": "string", + "description": "Validation rule that was violated." + }, + "message": { + "type": "string", + "description": "Human-readable validation error message." + } + }, + "required": [ + "field", + "message", + "rule" + ] + }, + "FilterConjunction": { + "type": "string", + "description": "Filter conjunction mode.", + "enum": [ + "all", + "any" + ] + }, + "ForbiddenErrorResponseContent": { + "type": "object", + "description": "The caller is authenticated but not allowed to access the requested resource.", + "properties": { + "title": { + "type": "string", + "description": "A short, human-readable summary of the problem\n type. It SHOULD NOT change from occurrence to occurrence of the\n problem, except for purposes of localization (e.g., using\n proactive content negotiation; see [RFC7231], Section 3.4)." + }, + "status": { + "type": "integer", + "default": 403, + "description": "The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.", + "format": "int32" + }, + "detail": { + "type": "string", + "description": "A human-readable explanation specific to this occurrence of the problem." + }, + "instance": { + "type": "string", + "description": "A URI reference that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced." + }, + "type": { + "$ref": "#/components/schemas/ForbiddenErrorType" + } + }, + "required": [ + "status", + "title", + "type" + ] + }, + "ForbiddenErrorType": { + "type": "string", + "description": "Problem type URI for authorization errors.", + "enum": [ + "/errors/insufficient-permissions" + ] + }, + "GetDocumentIngestionResponseContent": { + "type": "object", + "properties": { + "ingestion": { + "$ref": "#/components/schemas/DocumentIngestionRecord" + } + }, + "required": [ + "ingestion" + ] + }, + "GetIngestionHookStatusResponseContent": { + "type": "object", + "properties": { + "status": { + "$ref": "#/components/schemas/IngestionHookStatus" + } + }, + "required": [ + "status" + ] + }, + "GetLongTermMemoryResponseContent": { + "type": "object", + "description": "A long-term memory record.", + "properties": { + "id": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Unique memory record ID." + }, + "text": { + "type": "string", + "description": "The memory content." + }, + "memoryType": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z][a-zA-Z0-9_-]*$", + "description": "Type of memory. Built-in or a custom type registered on the store." + }, + "sessionId": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Session ID associated with this memory." + }, + "ownerId": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Owner ID associated with this memory." + }, + "namespace": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Deprecated namespace label. Absent when the record uses namespaceRef or has no namespace.", + "deprecated": true + }, + "namespaceRef": { + "$ref": "#/components/schemas/NamespaceRef" + }, + "topics": { + "type": "array", + "items": { + "type": "string", + "maxLength": 100, + "minLength": 1, + "description": "Topic name (1-100 chars)." + }, + "maxItems": 50, + "description": "Topic tags for categorization." + }, + "attributes": { + "$ref": "#/components/schemas/AttributeMap" + }, + "createdAt": { + "type": "string", + "description": "Timestamp when the memory was created (UTC).", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "description": "Timestamp when the memory was last updated (UTC).", + "format": "date-time" + }, + "sources": { + "type": "array", + "items": { + "$ref": "#/components/schemas/MemorySourceLink" + }, + "description": "Generic source links for this memory. Document sources include the customer document ID and revision that produced the memory." + }, + "sourcesNextPageToken": { + "type": "string", + "description": "Opaque token for additional source links when this response truncated attribution. Absent when every link is included." + }, + "documentManaged": { + "type": "boolean", + "description": "True when this memory was created by document ingestion and is protected from generic overwrite." + } + }, + "required": [ + "createdAt", + "id", + "text", + "updatedAt" + ] + }, + "GetNamespaceResponseContent": { + "type": "object", + "properties": { + "namespace": { + "$ref": "#/components/schemas/Namespace" + } + }, + "required": [ + "namespace" + ] + }, + "GetNamespaceRoutingResponseContent": { + "type": "object", + "properties": { + "policy": { + "$ref": "#/components/schemas/NamespaceRoutingPolicy" + } + }, + "required": [ + "policy" + ] + }, + "GetSessionEventResponseContent": { + "type": "object", + "description": "Response containing a single requested session event.", + "properties": { + "event": { + "$ref": "#/components/schemas/SessionEvent" + } + }, + "required": [ + "event" + ] + }, + "GetSessionMemoryResponseContent": { + "type": "object", + "description": "Session memory state for a session.", + "properties": { + "sessionId": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "The session ID." + }, + "ownerId": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "The owner of the session, set from the actorId of the first event." + }, + "namespace": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Deprecated namespace label for the session, set from the first event. Absent when the session uses namespaceRef or has no namespace.", + "deprecated": true + }, + "namespaceRef": { + "$ref": "#/components/schemas/NamespaceRef" + }, + "events": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SessionEvent" }, - "required": [ - "boolean" - ] + "description": "Conversation events retained for this session. When summarization is enabled, events already covered by the summary are excluded unless `includeSummarisedEvents` is set; the compacted summary is returned separately in `summary`." }, - { - "type": "object", - "title": "list", - "properties": { - "list": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Match a list attribute that contains all of these values." - } + "summary": { + "$ref": "#/components/schemas/SessionSummary" + } + }, + "required": [ + "events", + "ownerId", + "sessionId" + ] + }, + "GetSummaryViewResponseContent": { + "type": "object", + "description": "An owned Summary View definition. Results are separate derived state and never enter long-term-memory search.", + "properties": { + "id": { + "type": "string", + "maxLength": 32, + "minLength": 32, + "pattern": "^[a-zA-Z0-9]+$", + "description": "Server-generated Summary View identifier." + }, + "ownerId": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Immutable canonical user ID assigned by the server. Clients cannot set ownership." + }, + "visibility": { + "$ref": "#/components/schemas/SummaryViewVisibility" + }, + "name": { + "type": "string", + "maxLength": 100, + "minLength": 1, + "description": "Customer-visible Summary View name (1-100 characters)." + }, + "description": { + "type": "string", + "maxLength": 200, + "description": "Optional Summary View description (up to 200 characters)." + }, + "source": { + "$ref": "#/components/schemas/SummaryViewSource" + }, + "filter": { + "$ref": "#/components/schemas/LongTermMemoryFilter" + }, + "filterOp": { + "$ref": "#/components/schemas/FilterConjunction" + }, + "groupBy": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SummaryViewGroupField" }, - "required": [ - "list" - ] + "maxItems": 4 + }, + "evictionPolicy": { + "$ref": "#/components/schemas/SummaryViewEvictionPolicy" + }, + "timeWindowSeconds": { + "type": "integer", + "minimum": 1, + "format": "int64" + }, + "output": { + "$ref": "#/components/schemas/SummaryViewOutputConfig" + }, + "refreshPolicy": { + "$ref": "#/components/schemas/SummaryViewRefreshPolicy" + }, + "definitionVersion": { + "type": "integer", + "minimum": 1, + "format": "int64" + }, + "state": { + "$ref": "#/components/schemas/SummaryViewState" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" } + }, + "required": [ + "createdAt", + "definitionVersion", + "filterOp", + "groupBy", + "id", + "name", + "output", + "ownerId", + "refreshPolicy", + "source", + "state", + "updatedAt", + "visibility" ] }, - "AttributeFilterMap": { + "GetSummaryViewResultResponseContent": { "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/AttributeFilterClause" + "properties": { + "viewId": { + "type": "string", + "maxLength": 32, + "minLength": 32, + "pattern": "^[a-zA-Z0-9]+$", + "description": "Server-generated Summary View identifier." + }, + "scope": { + "$ref": "#/components/schemas/SummaryViewScope" + }, + "status": { + "$ref": "#/components/schemas/SummaryViewResultStatus" + }, + "stale": { + "type": "boolean" + }, + "format": { + "$ref": "#/components/schemas/SummaryViewOutputFormat" + }, + "value": { + "$ref": "#/components/schemas/SummaryViewResultValue" + }, + "sourceMemoryCount": { + "type": "integer", + "minimum": 0, + "description": "Number of matching source memories. When selection stops early, a separate count query measures the matching total without reading the remaining source pages. Concurrent writes can change the source set between queries; the count is never less than the number of records already observed.", + "format": "int64" + }, + "summarizedMemoryCount": { + "type": "integer", + "minimum": 0, + "description": "Number of matching source memories included in the generated value after bounded deterministic selection.", + "format": "int64" + }, + "truncated": { + "type": "boolean", + "description": "Combined signal for sourcesOmitted or sourceContentTruncated." + }, + "sourcesOmitted": { + "type": "boolean", + "description": "True when matching source memories were excluded from generation, including when further source pages were not read after reaching an input budget." + }, + "sourceContentTruncated": { + "type": "boolean", + "description": "True when content from an included source memory was clipped to fit a source or generation input budget. This can be true even when sourceMemoryCount equals summarizedMemoryCount." + }, + "sourceMemoryIds": { + "type": "array", + "items": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Memory record identifier (1-64 chars, alphanumeric and dashes). Client-provided for idempotent long-term memory creation." + }, + "description": "The memory IDs selected for the materialized value. Included only when requested with includeSourceMemoryIds=true." + }, + "sourceUpdatedAt": { + "type": "string", + "format": "date-time" + }, + "computedAt": { + "type": "string", + "format": "date-time" + }, + "definitionVersion": { + "type": "integer", + "minimum": 1, + "format": "int64" + }, + "errorCode": { + "$ref": "#/components/schemas/SummaryViewResultErrorCode" + } }, - "description": "Per-attribute filter clauses keyed by the custom memory type's field name." + "required": [ + "definitionVersion", + "format", + "scope", + "sourceContentTruncated", + "sourceMemoryCount", + "sourcesOmitted", + "stale", + "status", + "summarizedMemoryCount", + "truncated", + "viewId" + ] }, - "AttributeMap": { + "HookStatusSource": { "type": "object", - "additionalProperties": {}, - "description": "Structured record attributes: a map from the custom memory type's field name to that field's value. Values are arbitrary JSON matching the field's declared type (str, int, float, bool, list[str], list[float], or object)." + "additionalProperties": { + "type": "string" + } }, - "AuthenticationErrorResponseContent": { + "IngestionHookRetryErrorResponseContent": { "type": "object", - "description": "Authentication credentials are missing, malformed, or invalid.", + "description": "A saved ingestion hook decision is waiting for its next bounded attempt.", "properties": { "title": { "type": "string", @@ -3421,7 +7124,7 @@ }, "status": { "type": "integer", - "default": 401, + "default": 503, "description": "The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.", "format": "int32" }, @@ -3434,25 +7137,116 @@ "description": "A URI reference that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced." }, "type": { - "$ref": "#/components/schemas/AuthenticationErrorType" + "$ref": "#/components/schemas/IngestionHookRetryErrorType" + }, + "retryAt": { + "type": "string", + "format": "date-time" } }, "required": [ + "retryAt", "status", "title", "type" ] }, - "AuthenticationErrorType": { + "IngestionHookRetryErrorType": { "type": "string", - "description": "Problem type URI for authentication errors.", "enum": [ - "/errors/authentication-failed" + "/errors/ingestion-hook-retry" ] }, - "BadRequestErrorResponseContent": { + "IngestionHookStatus": { "type": "object", - "description": "Request validation or input decoding failed.", + "description": "Compact hook metadata, retained for seven days after completion or expiry. Application state is independent of the decision state; earlier writes may have completed before a later failure.", + "properties": { + "eventId": { + "type": "string" + }, + "ingestionOperationId": { + "type": "string" + }, + "phase": { + "type": "string" + }, + "path": { + "type": "string" + }, + "ownerId": { + "type": "string" + }, + "source": { + "$ref": "#/components/schemas/HookStatusSource" + }, + "configRevision": { + "type": "integer", + "format": "int64" + }, + "state": { + "type": "string" + }, + "applyState": { + "type": "string" + }, + "attempts": { + "type": "integer", + "format": "int32" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + }, + "deadline": { + "type": "string", + "format": "date-time" + }, + "nextAttemptAt": { + "type": "string", + "format": "date-time" + }, + "lastError": { + "type": "string" + }, + "applied": { + "type": "integer", + "format": "int32" + }, + "filtered": { + "type": "integer", + "format": "int32" + }, + "conflicts": { + "type": "integer", + "format": "int32" + } + }, + "required": [ + "applied", + "applyState", + "attempts", + "configRevision", + "conflicts", + "createdAt", + "deadline", + "eventId", + "filtered", + "ingestionOperationId", + "ownerId", + "path", + "phase", + "source", + "state", + "updatedAt" + ] + }, + "IngestionHookStoppedErrorResponseContent": { + "type": "object", + "description": "The ingestion hook stopped this operation without applying unapproved content.", "properties": { "title": { "type": "string", @@ -3460,7 +7254,7 @@ }, "status": { "type": "integer", - "default": 400, + "default": 422, "description": "The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.", "format": "int32" }, @@ -3473,147 +7267,292 @@ "description": "A URI reference that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced." }, "type": { - "$ref": "#/components/schemas/BadRequestErrorType" + "$ref": "#/components/schemas/IngestionHookStoppedErrorType" }, - "fields": { + "state": { + "$ref": "#/components/schemas/IngestionHookStoppedState" + } + }, + "required": [ + "state", + "status", + "title", + "type" + ] + }, + "IngestionHookStoppedErrorType": { + "type": "string", + "enum": [ + "/errors/ingestion-hook-stopped" + ] + }, + "IngestionHookStoppedState": { + "type": "string", + "enum": [ + "rejected", + "failed", + "expired", + "cancelled", + "conflict" + ] + }, + "ListDocumentIngestionOutputsResponseContent": { + "type": "object", + "properties": { + "memoryIds": { + "type": "array", + "items": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Memory record identifier (1-64 chars, alphanumeric and dashes). Client-provided for idempotent long-term memory creation." + } + } + }, + "required": [ + "memoryIds" + ] + }, + "ListIngestionHookStatusesResponseContent": { + "type": "object", + "properties": { + "statuses": { "type": "array", "items": { - "$ref": "#/components/schemas/FieldError" - }, - "description": "Optional field-level validation errors." + "$ref": "#/components/schemas/IngestionHookStatus" + } + }, + "nextCursor": { + "type": "string" } }, "required": [ - "status", - "title", - "type" + "statuses" ] }, - "BadRequestErrorType": { - "type": "string", - "description": "Problem type URI for bad request errors.", - "enum": [ - "/errors/invalid-data" + "ListMemorySourceEvidenceResponseContent": { + "type": "object", + "properties": { + "source": { + "$ref": "#/components/schemas/MemorySourceLink" + } + }, + "required": [ + "source" ] }, - "BulkCreateLongTermMemoriesRequestContent": { + "ListMemorySourceLinksResponseContent": { "type": "object", - "description": "Bulk create request for long-term memory records.", "properties": { - "memories": { + "items": { "type": "array", "items": { - "$ref": "#/components/schemas/CreateMemoryRecord" - }, - "maxItems": 100, - "minItems": 1, - "description": "List of memory records to create." + "$ref": "#/components/schemas/MemorySourceLink" + } + }, + "nextPageToken": { + "type": "string" } }, "required": [ - "memories" + "items" ] }, - "BulkCreateLongTermMemoriesResponseContent": { + "ListNamespacesResponseContent": { "type": "object", - "description": "Bulk create result for long-term memory records.", "properties": { - "created": { + "items": { "type": "array", "items": { - "type": "string", - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-]+$", - "description": "Memory record identifier (1-64 chars, alphanumeric and dashes). Client-provided for idempotent long-term memory creation." - }, - "description": "IDs of successfully created memory records. Always returned; empty when no records were created." + "$ref": "#/components/schemas/Namespace" + } }, - "errors": { + "nextPageToken": { + "type": "string", + "description": "Opaque token for fetching the next page. Omitted when no more results." + } + }, + "required": [ + "items" + ] + }, + "ListSessionSummariesResponseContent": { + "type": "object", + "description": "Paginated session rows for a store.", + "properties": { + "items": { "type": "array", "items": { - "$ref": "#/components/schemas/BulkOperationError" - }, - "description": "Errors for memory records that failed to be created." + "$ref": "#/components/schemas/SessionListItem" + } + }, + "total": { + "type": "integer", + "format": "int32" + }, + "nextPageToken": { + "type": "string" } }, "required": [ - "created" + "items", + "total" ] }, - "BulkDeleteLongTermMemoriesRequestContent": { + "ListSessionsResponseContent": { "type": "object", - "description": "Bulk delete request for long-term memory records.", + "description": "Paginated list of session IDs for a store.", "properties": { - "memoryIds": { + "items": { "type": "array", "items": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Memory record identifier (1-64 chars, alphanumeric and dashes). Client-provided for idempotent long-term memory creation." + "description": "Session identifier (1-64 chars, alphanumeric and dashes). When the server generates one, it uses a 32-character UUID without dashes." }, - "maxItems": 100, - "minItems": 1, - "description": "List of memory record IDs to delete (1-100 IDs)." + "description": "List of session IDs. Always returned; empty when the store has no sessions." + }, + "total": { + "type": "integer", + "description": "Total number of matching sessions.", + "format": "int32" + }, + "nextPageToken": { + "type": "string", + "description": "Opaque token for fetching the next page. Omitted when no more results." } }, "required": [ - "memoryIds" + "items", + "total" ] }, - "BulkDeleteLongTermMemoriesResponseContent": { + "ListSourceMemoriesResponseContent": { "type": "object", - "description": "Bulk delete result for long-term memory records.", "properties": { - "deleted": { + "items": { "type": "array", "items": { - "type": "string", - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-]+$", - "description": "Memory record identifier (1-64 chars, alphanumeric and dashes). Client-provided for idempotent long-term memory creation." - }, - "description": "IDs of successfully deleted memory records. Always returned; empty when no records were deleted." + "$ref": "#/components/schemas/MemoryRecord" + } }, - "errors": { + "nextPageToken": { + "type": "string" + } + }, + "required": [ + "items" + ] + }, + "ListSummaryViewsResponseContent": { + "type": "object", + "properties": { + "items": { "type": "array", "items": { - "$ref": "#/components/schemas/BulkOperationError" - }, - "description": "Errors for memory records that failed to be deleted." + "$ref": "#/components/schemas/SummaryView" + } + }, + "nextPageToken": { + "type": "string" } }, "required": [ - "deleted" + "items" ] }, - "BulkOperationError": { + "LlmPromptSpec": { "type": "object", - "description": "Error detail for a single item in a bulk operation.", + "description": "Customer-authored prompt evaluated by the LLM routing strategy.", "properties": { - "id": { + "prompt": { "type": "string", - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-]+$", - "description": "Memory record ID of the item that failed." + "maxLength": 2000, + "minLength": 1 + } + }, + "required": [ + "prompt" + ] + }, + "LongTermMemoryFilter": { + "type": "object", + "description": "Grouping of filter conditions for long-term memory search.", + "properties": { + "sessionId": { + "$ref": "#/components/schemas/SessionIdFilter" }, - "error": { - "type": "string", - "description": "Error message describing the failure." + "ownerId": { + "$ref": "#/components/schemas/OwnerIdFilter" + }, + "namespace": { + "$ref": "#/components/schemas/NamespaceFilter" + }, + "namespaceRef": { + "$ref": "#/components/schemas/NamespaceRefFilter" + }, + "unnamespaced": { + "type": "boolean", + "description": "When true, matches only records that have neither a deprecated namespace label nor a namespace resource placement. This scope is always combined with every other filter condition. Do not supply namespace or namespaceRef with this field." + }, + "topics": { + "$ref": "#/components/schemas/TopicsFilter" + }, + "memoryType": { + "$ref": "#/components/schemas/MemoryTypeFilter" + }, + "createdAt": { + "$ref": "#/components/schemas/CreatedAtFilter" + }, + "attributes": { + "$ref": "#/components/schemas/AttributeFilterMap" + } + } + }, + "LongTermMemorySearchSortBy": { + "type": "string", + "description": "Timestamp field used to order long-term memory search results.", + "enum": [ + "createdAt", + "updatedAt" + ] + }, + "LongTermMemorySearchSortOrder": { + "type": "string", + "description": "Direction used to order long-term memory search results.", + "enum": [ + "asc", + "desc" + ] + }, + "MatcherKind": { + "type": "string", + "description": "The matching techniques this API supports.", + "enum": [ + "regex" + ] + }, + "MatcherSpec": { + "type": "object", + "description": "How a detector matches, as a tagged union of techniques.\n\nExactly the block naming the declared kind must be present; a block belonging to\nany other kind is rejected rather than guessed at. Further kinds are additive.", + "properties": { + "kind": { + "$ref": "#/components/schemas/MatcherKind" + }, + "regex": { + "$ref": "#/components/schemas/RegexSpec" } }, "required": [ - "error", - "id" + "kind" ] }, - "ConflictErrorResponseContent": { + "MemoryFailedDependencyErrorResponseContent": { "type": "object", - "description": "The request conflicts with the current state of the resource.", + "description": "A resource or model-provider dependency required by Agent Memory could not complete the request.", "properties": { "title": { "type": "string", @@ -3621,7 +7560,7 @@ }, "status": { "type": "integer", - "default": 409, + "default": 424, "description": "The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.", "format": "int32" }, @@ -3634,7 +7573,7 @@ "description": "A URI reference that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced." }, "type": { - "$ref": "#/components/schemas/ConflictErrorType" + "$ref": "#/components/schemas/MemoryFailedDependencyErrorType" } }, "required": [ @@ -3643,47 +7582,30 @@ "type" ] }, - "ConflictErrorType": { - "type": "string", - "description": "Problem type URI for conflict errors.", - "enum": [ - "/errors/conflict" - ] - }, - "Content": { - "description": "A single content item in a message. Exactly one member is set.", - "oneOf": [ - { - "type": "object", - "title": "text", - "properties": { - "text": { - "type": "string", - "description": "Text content." - } - }, - "required": [ - "text" - ] - } + "MemoryFailedDependencyErrorType": { + "type": "string", + "description": "Problem type URI for Agent Memory failed-dependency errors.", + "enum": [ + "/errors/resource-unavailable", + "/errors/database-out-of-memory", + "/errors/invalid-model-credentials", + "/errors/model-quota-exceeded" ] }, - "CreateMemoryRecord": { + "MemoryRecord": { "type": "object", - "description": "A memory record to create.", + "description": "A long-term memory record.", "properties": { "id": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Client-provided memory record ID for idempotent creation." + "description": "Unique memory record ID." }, "text": { "type": "string", - "maxLength": 50000, - "minLength": 1, - "description": "The memory content (1-50000 chars)." + "description": "The memory content." }, "memoryType": { "type": "string", @@ -3697,25 +7619,25 @@ "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Session ID associated with this memory (1-64 chars, alphanumeric and dashes)." + "description": "Session ID associated with this memory." }, "ownerId": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Owner ID associated with this memory (1-64 chars, alphanumeric and dashes)." + "description": "Owner ID associated with this memory." }, "namespace": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Optional deprecated namespace label. It does not create or resolve a namespace resource. Do not supply it with namespaceRef. If both fields are omitted, the record uses automatic routing when enabled; if routing is disabled or no destination qualifies, it is created without a namespace.", + "description": "Deprecated namespace label. Absent when the record uses namespaceRef or has no namespace.", "deprecated": true }, "namespaceRef": { - "$ref": "#/components/schemas/NamespaceRefInput" + "$ref": "#/components/schemas/NamespaceRef" }, "topics": { "type": "array", @@ -3726,504 +7648,513 @@ "description": "Topic name (1-100 chars)." }, "maxItems": 50, - "description": "Topic tags for categorization (max 50 topics, each 1-100 chars)." + "description": "Topic tags for categorization." }, "attributes": { "$ref": "#/components/schemas/AttributeMap" + }, + "createdAt": { + "type": "string", + "description": "Timestamp when the memory was created (UTC).", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "description": "Timestamp when the memory was last updated (UTC).", + "format": "date-time" + }, + "sources": { + "type": "array", + "items": { + "$ref": "#/components/schemas/MemorySourceLink" + }, + "description": "Generic source links for this memory. Document sources include the customer document ID and revision that produced the memory." + }, + "sourcesNextPageToken": { + "type": "string", + "description": "Opaque token for additional source links when this response truncated attribution. Absent when every link is included." + }, + "documentManaged": { + "type": "boolean", + "description": "True when this memory was created by document ingestion and is protected from generic overwrite." } }, "required": [ + "createdAt", "id", - "ownerId", - "text" + "text", + "updatedAt" ] }, - "CreateNamespaceRequestContent": { + "MemorySourceEvidence": { "type": "object", "properties": { - "name": { + "evidenceId": { "type": "string", - "maxLength": 64, + "maxLength": 128, "minLength": 1, - "pattern": "^[a-zA-Z0-9_-]+$", - "description": "One namespace segment. Use with scope for a root or parentId for a child." + "description": "Identity of a logical extraction occurrence. Delivery retries retain this ID; a new extraction receives a new ID. Absent on legacy evidence." }, - "path": { + "schemaVersion": { + "type": "integer", + "description": "Version of the evidence metadata contract, currently 1. Absent on legacy evidence.", + "format": "int32" + }, + "capturedAt": { "type": "string", - "maxLength": 1024, - "minLength": 1, - "description": "A complete hierarchy path to create. Missing segments are created as needed. Mutually exclusive with name and parentId. The path does not encode scope." + "description": "UTC time when the producer prepared the input for extraction, before model invocation. Preserved through checkpoint replay. This is not the source event time.", + "format": "date-time" }, - "scope": { - "$ref": "#/components/schemas/NamespaceScope" + "producer": { + "$ref": "#/components/schemas/EvidenceProducer" }, - "parentId": { + "ingestionId": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Parent namespace for a direct child." + "description": "Server-generated document ingestion identifier." }, - "ownerId": { - "type": "string", - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-]+$", - "description": "Owner for a personal root or path. Required for personal scope; omit for shared roots and children." - } - } - }, - "CreateNamespaceResponseContent": { - "type": "object", - "properties": { - "namespace": { - "$ref": "#/components/schemas/Namespace" + "chunkId": { + "type": "string" + }, + "start": { + "type": "integer", + "format": "int32" + }, + "end": { + "type": "integer", + "format": "int32" } }, "required": [ - "namespace" + "chunkId", + "ingestionId" ] }, - "CreatedAtFilter": { + "MemorySourceKind": { + "type": "string", + "enum": [ + "document", + "session" + ] + }, + "MemorySourceLink": { "type": "object", - "description": "Filter by creation timestamp.", "properties": { - "gt": { - "type": "string", - "description": "After the given timestamp.", - "format": "date-time" + "sourceId": { + "type": "string" }, - "gte": { - "type": "string", - "description": "At or after the given timestamp.", - "format": "date-time" + "kind": { + "$ref": "#/components/schemas/MemorySourceKind" }, - "lt": { - "type": "string", - "description": "Before the given timestamp.", - "format": "date-time" + "identity": { + "$ref": "#/components/schemas/DocumentSourceIdentity" }, - "lte": { - "type": "string", - "description": "At or before the given timestamp.", - "format": "date-time" + "session": { + "$ref": "#/components/schemas/SessionSourceIdentity" }, - "eq": { + "evidence": { + "type": "array", + "items": { + "$ref": "#/components/schemas/MemorySourceEvidence" + } + }, + "sessionEvidence": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SessionSourceEvidence" + } + }, + "evidenceNextPageToken": { "type": "string", - "description": "Exactly at the given timestamp.", - "format": "date-time" + "description": "Opaque token for GET /v1/stores/{storeId}/long-term-memory/{memoryId}/sources/{sourceId}/evidence. Continues evidence or sessionEvidence for this source; absent when every item is included." } - } + }, + "required": [ + "kind", + "sourceId" + ] }, - "FailedDependencyErrorResponseContent": { + "MemoryTypeFilter": { "type": "object", - "description": "A dependent resource required to process the request is unavailable or unhealthy.", + "description": "Filter by memory type. Matching is case-insensitive.", "properties": { - "title": { + "eq": { "type": "string", - "description": "A short, human-readable summary of the problem\n type. It SHOULD NOT change from occurrence to occurrence of the\n problem, except for purposes of localization (e.g., using\n proactive content negotiation; see [RFC7231], Section 3.4)." - }, - "status": { - "type": "integer", - "default": 424, - "description": "The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.", - "format": "int32" + "description": "Equals the given value." }, - "detail": { + "ne": { "type": "string", - "description": "A human-readable explanation specific to this occurrence of the problem." + "description": "Not equal to the given value." }, - "instance": { - "type": "string", - "description": "A URI reference that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced." + "in": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Matches any of the given values." }, - "type": { - "$ref": "#/components/schemas/FailedDependencyErrorType" + "all": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Matches all of the given values." } - }, - "required": [ - "status", - "title", - "type" - ] + } }, - "FailedDependencyErrorType": { + "MessageRole": { "type": "string", - "description": "Problem type URI for failed-dependency errors.", + "description": "Message role for session events.", "enum": [ - "/errors/resource-unavailable", - "/errors/database-out-of-memory" + "USER", + "ASSISTANT", + "SYSTEM" ] }, - "FieldError": { + "MoveLongTermMemoriesRequestContent": { "type": "object", - "description": "Validation error details for a single request field.", "properties": { - "field": { - "type": "string", - "description": "Name of the invalid request field." - }, - "rule": { - "type": "string", - "description": "Validation rule that was violated." + "memoryIds": { + "type": "array", + "items": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Memory record identifier (1-64 chars, alphanumeric and dashes). Client-provided for idempotent long-term memory creation." + }, + "maxItems": 100, + "minItems": 1 }, - "message": { - "type": "string", - "description": "Human-readable validation error message." + "namespaceRef": { + "$ref": "#/components/schemas/NamespaceRefInput" } }, "required": [ - "field", - "message", - "rule" - ] - }, - "FilterConjunction": { - "type": "string", - "description": "Filter conjunction mode.", - "enum": [ - "all", - "any" + "memoryIds" ] }, - "ForbiddenErrorResponseContent": { + "MoveLongTermMemoriesResponseContent": { "type": "object", - "description": "The caller is authenticated but not allowed to access the requested resource.", "properties": { - "title": { - "type": "string", - "description": "A short, human-readable summary of the problem\n type. It SHOULD NOT change from occurrence to occurrence of the\n problem, except for purposes of localization (e.g., using\n proactive content negotiation; see [RFC7231], Section 3.4)." - }, - "status": { - "type": "integer", - "default": 403, - "description": "The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.", - "format": "int32" - }, - "detail": { - "type": "string", - "description": "A human-readable explanation specific to this occurrence of the problem." - }, - "instance": { - "type": "string", - "description": "A URI reference that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced." + "moved": { + "type": "array", + "items": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Memory record identifier (1-64 chars, alphanumeric and dashes). Client-provided for idempotent long-term memory creation." + } }, - "type": { - "$ref": "#/components/schemas/ForbiddenErrorType" + "errors": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BulkOperationError" + } } }, "required": [ - "status", - "title", - "type" + "moved" ] }, - "ForbiddenErrorType": { + "MutableSummaryViewState": { "type": "string", - "description": "Problem type URI for authorization errors.", + "description": "States a caller may set directly. Deleting is entered only by the delete operation.", "enum": [ - "/errors/insufficient-permissions" + "active", + "disabled" ] }, - "GetLongTermMemoryResponseContent": { + "Namespace": { "type": "object", - "description": "A long-term memory record.", + "description": "A namespace hierarchy record.", "properties": { - "id": { + "namespaceId": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Unique memory record ID." - }, - "text": { - "type": "string", - "description": "The memory content." + "description": "Server-generated namespace identifier." }, - "memoryType": { + "name": { "type": "string", "maxLength": 64, "minLength": 1, - "pattern": "^[a-zA-Z][a-zA-Z0-9_-]*$", - "description": "Type of memory. Built-in or a custom type registered on the store." + "pattern": "^[a-zA-Z0-9_-]+$", + "description": "One case-sensitive namespace path segment." }, - "sessionId": { + "parentId": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Session ID associated with this memory." + "description": "Server-generated namespace identifier." }, - "ownerId": { + "rootId": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Owner ID associated with this memory." + "description": "Server-generated namespace identifier." }, - "namespace": { + "ownerId": { "type": "string", - "maxLength": 64, "minLength": 1, - "pattern": "^[a-zA-Z0-9-]+$", - "description": "Deprecated namespace label. Absent when the record uses namespaceRef or has no namespace.", - "deprecated": true + "description": "An opaque application-user ID selected by the platform for a namespace root." }, - "namespaceRef": { - "$ref": "#/components/schemas/NamespaceRef" + "scope": { + "$ref": "#/components/schemas/NamespaceScope" }, - "topics": { - "type": "array", - "items": { - "type": "string", - "maxLength": 100, - "minLength": 1, - "description": "Topic name (1-100 chars)." - }, - "maxItems": 50, - "description": "Topic tags for categorization." + "state": { + "$ref": "#/components/schemas/NamespaceState" }, - "attributes": { - "$ref": "#/components/schemas/AttributeMap" + "revision": { + "type": "integer", + "format": "int64" }, "createdAt": { "type": "string", - "description": "Timestamp when the memory was created (UTC).", "format": "date-time" }, "updatedAt": { "type": "string", - "description": "Timestamp when the memory was last updated (UTC).", "format": "date-time" + }, + "path": { + "type": "string", + "maxLength": 1024, + "minLength": 1, + "description": "Current case-sensitive path, derived from the live hierarchy." } }, "required": [ "createdAt", - "id", - "text", + "name", + "namespaceId", + "path", + "revision", + "rootId", + "scope", + "state", "updatedAt" ] }, - "GetNamespaceResponseContent": { - "type": "object", - "properties": { - "namespace": { - "$ref": "#/components/schemas/Namespace" - } - }, - "required": [ - "namespace" - ] - }, - "GetNamespaceRoutingResponseContent": { - "type": "object", - "properties": { - "policy": { - "$ref": "#/components/schemas/NamespaceRoutingPolicy" - } - }, - "required": [ - "policy" - ] - }, - "GetSessionEventResponseContent": { - "type": "object", - "description": "Response containing a single requested session event.", - "properties": { - "event": { - "$ref": "#/components/schemas/SessionEvent" - } - }, - "required": [ - "event" - ] - }, - "GetSessionMemoryResponseContent": { + "NamespaceFilter": { "type": "object", - "description": "Session memory state for a session.", + "description": "Filter by namespace. Matching is case-insensitive.\n\nNamespace is optional, so records without one need care. The positive operators (`eq`, `in`, `all`) require the field to be present and therefore never match a record that has no namespace \u2014 including memories extracted from a session that has none. `ne` is a plain negation and *does* match those records, so use `eq` or `in` when you need strict namespace isolation rather than `ne` against the namespaces you want to exclude.\n\nOmit this filter to search across every namespace, and use it to keep recall inside one project, workspace, team, environment, or tenant.", "properties": { - "sessionId": { - "type": "string", - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-]+$", - "description": "The session ID." - }, - "ownerId": { + "eq": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "The owner of the session, set from the actorId of the first event." + "description": "Equals the given value.", + "deprecated": true }, - "namespace": { + "ne": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Deprecated namespace label for the session, set from the first event. Absent when the session uses namespaceRef or has no namespace.", + "description": "Not equal to the given value.", "deprecated": true }, - "namespaceRef": { - "$ref": "#/components/schemas/NamespaceRef" - }, - "events": { + "in": { "type": "array", "items": { - "$ref": "#/components/schemas/SessionEvent" + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Deprecated flat namespace label for logical grouping. The value is 1-64 alphanumeric characters or dashes and has no hierarchy or scope semantics. Matching through `filter.namespace` is case-insensitive.\n\nThe field remains optional for backward compatibility. New integrations should use `namespaceRef` to reference an existing namespace resource.\n\nRecords produced by extraction inherit the namespace label stored on the session when the session was created.\n\nThis shape is deprecated: Use namespaceRef to reference a namespace resource.", + "deprecated": true }, - "description": "Conversation events retained for this session. When summarization is enabled, events already covered by the summary are excluded unless `includeSummarisedEvents` is set; the compacted summary is returned separately in `summary`." + "description": "Matches any of the given values." }, - "summary": { - "$ref": "#/components/schemas/SessionSummary" - } - }, - "required": [ - "events", - "ownerId", - "sessionId" - ] - }, - "HealthResponseContent": { - "type": "object", - "description": "Health check response.", - "properties": { - "status": { - "$ref": "#/components/schemas/HealthStatus" + "all": { + "type": "array", + "items": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Deprecated flat namespace label for logical grouping. The value is 1-64 alphanumeric characters or dashes and has no hierarchy or scope semantics. Matching through `filter.namespace` is case-insensitive.\n\nThe field remains optional for backward compatibility. New integrations should use `namespaceRef` to reference an existing namespace resource.\n\nRecords produced by extraction inherit the namespace label stored on the session when the session was created.\n\nThis shape is deprecated: Use namespaceRef to reference a namespace resource.", + "deprecated": true + }, + "description": "Matches all of the given values." } - }, - "required": [ - "status" - ] - }, - "HealthStatus": { - "type": "string", - "description": "Health status returned by the /health endpoint.", - "enum": [ - "healthy" - ] + } }, - "ListNamespacesResponseContent": { + "NamespaceRef": { "type": "object", + "description": "Reference to a namespace resource with its stable identifier and current display data.", "properties": { - "items": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Namespace" - } + "namespaceId": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Stable namespace resource identifier." }, - "nextPageToken": { + "name": { "type": "string", - "description": "Opaque token for fetching the next page. Omitted when no more results." + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9_-]+$", + "description": "Current namespace name." + }, + "path": { + "type": "string", + "maxLength": 1024, + "minLength": 1, + "description": "Current namespace path." } }, "required": [ - "items" + "name", + "namespaceId", + "path" ] }, - "ListSessionsResponseContent": { + "NamespaceRefFilter": { "type": "object", - "description": "Paginated list of session IDs for a store.", + "description": "Filter by stable namespace resource identifier. Supports exact or any-of matching and matches only resource-backed records, never deprecated namespace labels.", "properties": { - "items": { + "eq": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Equals the given value." + }, + "in": { "type": "array", "items": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Session identifier (1-64 chars, alphanumeric and dashes). When the server generates one, it uses a 32-character UUID without dashes." + "description": "Server-generated namespace identifier." }, - "description": "List of session IDs. Always returned; empty when the store has no sessions." - }, - "total": { - "type": "integer", - "description": "Total number of matching sessions.", - "format": "int32" - }, - "nextPageToken": { + "description": "Matches any of the given values." + } + } + }, + "NamespaceRefInput": { + "type": "object", + "description": "Reference to an existing namespace resource for a write or namespace-scoped operation.", + "properties": { + "namespaceId": { "type": "string", - "description": "Opaque token for fetching the next page. Omitted when no more results." + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Stable namespace resource identifier." } }, "required": [ - "items", - "total" + "namespaceId" ] }, - "LlmPromptSpec": { + "NamespaceRoutingPolicy": { "type": "object", - "description": "Customer-authored prompt evaluated by the LLM routing strategy.", + "description": "Store-level automatic namespace routing and admission policy. Global rules target shared namespaces only. Accept rules select candidates in list order. All enabled reject rules for a destination apply regardless of their position or how the destination was selected.", "properties": { - "prompt": { - "type": "string", - "maxLength": 2000, - "minLength": 1 + "enabled": { + "type": "boolean" + }, + "rules": { + "type": "array", + "items": { + "$ref": "#/components/schemas/NamespaceRoutingRule" + }, + "maxItems": 32 } }, "required": [ - "prompt" + "enabled" ] }, - "LongTermMemoryFilter": { + "NamespaceRoutingRule": { "type": "object", - "description": "Grouping of filter conditions for long-term memory search.", + "description": "One routing or admission rule. action is accept or reject. Strategies run in list order and the first match fires the rule. An accept with no strategies always matches; a reject with no strategies never matches. A matching accept selects a candidate. Every enabled reject for that destination must pass before placement. A veto skips that candidate during automatic routing and fails explicit placement.", "properties": { - "sessionId": { - "$ref": "#/components/schemas/SessionIdFilter" - }, - "ownerId": { - "$ref": "#/components/schemas/OwnerIdFilter" - }, - "namespace": { - "$ref": "#/components/schemas/NamespaceFilter" - }, - "namespaceRef": { - "$ref": "#/components/schemas/NamespaceRefFilter" - }, - "unnamespaced": { - "type": "boolean", - "description": "When true, matches only records that have neither a deprecated namespace label nor a namespace resource placement. This scope is always combined with every other filter condition. Do not supply namespace or namespaceRef with this field." + "id": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z][a-zA-Z0-9_-]*$", + "description": "Routing rule identifier (1-64 chars). Published in logs, so it is an identifier rather than free text." }, - "topics": { - "$ref": "#/components/schemas/TopicsFilter" + "destination": { + "$ref": "#/components/schemas/NamespaceRefInput" }, - "memoryType": { - "$ref": "#/components/schemas/MemoryTypeFilter" + "enabled": { + "type": "boolean" }, - "createdAt": { - "$ref": "#/components/schemas/CreatedAtFilter" + "action": { + "$ref": "#/components/schemas/RoutingRuleAction" }, - "attributes": { - "$ref": "#/components/schemas/AttributeFilterMap" + "strategies": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RouteCondition" + }, + "maxItems": 8 } - } + }, + "required": [ + "action", + "destination", + "enabled", + "id" + ] }, - "MatcherKind": { + "NamespaceScope": { "type": "string", - "description": "The matching techniques this API supports.", + "description": "The root scope of a namespace hierarchy.", "enum": [ - "regex" + "PERSONAL", + "SHARED" ] }, - "MatcherSpec": { - "type": "object", - "description": "How a detector matches, as a tagged union of techniques.\n\nExactly the block naming the declared kind must be present; a block belonging to\nany other kind is rejected rather than guessed at. Further kinds are additive.", - "properties": { - "kind": { - "$ref": "#/components/schemas/MatcherKind" - }, - "regex": { - "$ref": "#/components/schemas/RegexSpec" - } - }, - "required": [ - "kind" + "NamespaceSortBy": { + "type": "string", + "enum": [ + "id", + "name", + "createdAt", + "updatedAt" ] }, - "MemoryFailedDependencyErrorResponseContent": { + "NamespaceSortOrder": { + "type": "string", + "enum": [ + "asc", + "desc" + ] + }, + "NamespaceState": { + "type": "string", + "description": "Whether a namespace accepts new children and placements.", + "enum": [ + "ACTIVE", + "ARCHIVED" + ] + }, + "NamespaceUpdateState": { + "type": "string", + "description": "The archive-only state transition accepted by UpdateNamespace.", + "enum": [ + "ARCHIVED" + ] + }, + "NotFoundErrorResponseContent": { "type": "object", - "description": "A resource or model-provider dependency required by Agent Memory could not complete the request.", + "description": "The requested resource does not exist.", "properties": { "title": { "type": "string", @@ -4231,7 +8162,7 @@ }, "status": { "type": "integer", - "default": 424, + "default": 404, "description": "The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.", "format": "int32" }, @@ -4244,7 +8175,7 @@ "description": "A URI reference that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced." }, "type": { - "$ref": "#/components/schemas/MemoryFailedDependencyErrorType" + "$ref": "#/components/schemas/NotFoundErrorType" } }, "required": [ @@ -4253,272 +8184,382 @@ "type" ] }, - "MemoryFailedDependencyErrorType": { + "NotFoundErrorType": { "type": "string", - "description": "Problem type URI for Agent Memory failed-dependency errors.", + "description": "Problem type URI for not-found errors.", "enum": [ - "/errors/resource-unavailable", - "/errors/database-out-of-memory", - "/errors/invalid-model-credentials", - "/errors/model-quota-exceeded" + "/errors/resource-not-found" ] }, - "MemoryRecord": { + "OwnerIdFilter": { "type": "object", - "description": "A long-term memory record.", + "description": "Filter by the long-term memory ownerId field. Matching is case-sensitive.", "properties": { - "id": { - "type": "string", - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-]+$", - "description": "Unique memory record ID." - }, - "text": { - "type": "string", - "description": "The memory content." - }, - "memoryType": { - "type": "string", - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z][a-zA-Z0-9_-]*$", - "description": "Type of memory. Built-in or a custom type registered on the store." - }, - "sessionId": { - "type": "string", - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-]+$", - "description": "Session ID associated with this memory." - }, - "ownerId": { + "eq": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Owner ID associated with this memory." + "description": "Equals the given value." }, - "namespace": { + "ne": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Deprecated namespace label. Absent when the record uses namespaceRef or has no namespace.", - "deprecated": true + "description": "Not equal to the given value." }, - "namespaceRef": { - "$ref": "#/components/schemas/NamespaceRef" + "in": { + "type": "array", + "items": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Actor/owner identifier (1-64 chars, alphanumeric and dashes). Used for users, agents, or other participants." + }, + "description": "Matches any of the given values." }, - "topics": { + "all": { "type": "array", "items": { "type": "string", - "maxLength": 100, + "maxLength": 64, "minLength": 1, - "description": "Topic name (1-100 chars)." + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Actor/owner identifier (1-64 chars, alphanumeric and dashes). Used for users, agents, or other participants." }, - "maxItems": 50, - "description": "Topic tags for categorization." + "description": "Matches all of the given values." + } + } + }, + "PayloadTooLargeErrorResponseContent": { + "type": "object", + "description": "The request payload exceeds the maximum supported size.", + "properties": { + "title": { + "type": "string", + "description": "A short, human-readable summary of the problem\n type. It SHOULD NOT change from occurrence to occurrence of the\n problem, except for purposes of localization (e.g., using\n proactive content negotiation; see [RFC7231], Section 3.4)." }, - "attributes": { - "$ref": "#/components/schemas/AttributeMap" + "status": { + "type": "integer", + "default": 413, + "description": "The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.", + "format": "int32" }, - "createdAt": { + "detail": { + "type": "string", + "description": "A human-readable explanation specific to this occurrence of the problem." + }, + "instance": { + "type": "string", + "description": "A URI reference that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced." + }, + "type": { + "$ref": "#/components/schemas/PayloadTooLargeErrorType" + } + }, + "required": [ + "status", + "title", + "type" + ] + }, + "PayloadTooLargeErrorType": { + "type": "string", + "description": "Problem type URI for payload-too-large errors.", + "enum": [ + "/errors/payload-too-large" + ] + }, + "PutNamespaceRoutingRequestContent": { + "type": "object", + "properties": { + "policy": { + "$ref": "#/components/schemas/NamespaceRoutingPolicy" + } + }, + "required": [ + "policy" + ] + }, + "PutNamespaceRoutingResponseContent": { + "type": "object", + "properties": { + "policy": { + "$ref": "#/components/schemas/NamespaceRoutingPolicy" + } + }, + "required": [ + "policy" + ] + }, + "RefreshSummaryViewRequestContent": { + "type": "object", + "properties": { + "target": { + "$ref": "#/components/schemas/SummaryViewRefreshTarget" + }, + "scope": { + "$ref": "#/components/schemas/SummaryViewScope" + } + }, + "required": [ + "target" + ] + }, + "RefreshSummaryViewResponseContent": { + "type": "object", + "properties": { + "viewId": { "type": "string", - "description": "Timestamp when the memory was created (UTC).", - "format": "date-time" + "maxLength": 32, + "minLength": 32, + "pattern": "^[a-zA-Z0-9]+$", + "description": "Server-generated Summary View identifier." }, - "updatedAt": { + "target": { + "$ref": "#/components/schemas/SummaryViewRefreshTarget" + }, + "accepted": { + "type": "boolean" + } + }, + "required": [ + "accepted", + "target", + "viewId" + ] + }, + "RegexSpec": { + "type": "object", + "description": "A regular expression to match against.\n\nEvaluated by RE2, which runs in linear time \u2014 so an expensive pattern is not a\ndenial-of-service risk, but lookaround and backreferences are unavailable.\nRejected on write if it does not compile, or if it can match without consuming\ntext: such a pattern matches at every position, so it would exclude every memory\nthe store writes.", + "properties": { + "pattern": { "type": "string", - "description": "Timestamp when the memory was last updated (UTC).", - "format": "date-time" + "maxLength": 512, + "minLength": 1, + "description": "The pattern, in RE2 syntax." } }, "required": [ - "createdAt", - "id", - "text", - "updatedAt" + "pattern" ] }, - "MemoryTypeFilter": { + "ResourceSuspendedErrorResponseContent": { "type": "object", - "description": "Filter by memory type. Matching is case-insensitive.", + "description": "The requested resource exists but is suspended by an administrator.", "properties": { - "eq": { + "title": { "type": "string", - "description": "Equals the given value." + "description": "A short, human-readable summary of the problem\n type. It SHOULD NOT change from occurrence to occurrence of the\n problem, except for purposes of localization (e.g., using\n proactive content negotiation; see [RFC7231], Section 3.4)." }, - "ne": { + "status": { + "type": "integer", + "default": 423, + "description": "The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.", + "format": "int32" + }, + "detail": { "type": "string", - "description": "Not equal to the given value." + "description": "A human-readable explanation specific to this occurrence of the problem." }, - "in": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Matches any of the given values." + "instance": { + "type": "string", + "description": "A URI reference that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced." }, - "all": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Matches all of the given values." + "type": { + "$ref": "#/components/schemas/ResourceSuspendedErrorType" } - } + }, + "required": [ + "status", + "title", + "type" + ] }, - "MessageRole": { + "ResourceSuspendedErrorType": { "type": "string", - "description": "Message role for session events.", + "description": "Problem type URI for suspended resources.", "enum": [ - "USER", - "ASSISTANT", - "SYSTEM" + "/errors/resource-suspended" ] }, - "MoveLongTermMemoriesRequestContent": { + "RouteCondition": { "type": "object", + "description": "One plug-in strategy invocation. Exactly the block naming the declared kind must be present. List order is evaluation order.", "properties": { - "memoryIds": { - "type": "array", - "items": { - "type": "string", - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-]+$", - "description": "Memory record identifier (1-64 chars, alphanumeric and dashes). Client-provided for idempotent long-term memory creation." - }, - "maxItems": 100, - "minItems": 1 + "kind": { + "$ref": "#/components/schemas/RouteStrategyKind" }, - "namespaceRef": { - "$ref": "#/components/schemas/NamespaceRefInput" + "llmPrompt": { + "$ref": "#/components/schemas/LlmPromptSpec" + }, + "matcher": { + "$ref": "#/components/schemas/MatcherSpec" } }, "required": [ - "memoryIds" + "kind" ] }, - "MoveLongTermMemoriesResponseContent": { + "RouteStrategyKind": { + "type": "string", + "description": "Routing strategy kinds. Unknown kinds are rejected. New kinds register on the evaluator without changing namespace records.", + "enum": [ + "llm_prompt", + "matcher_spec" + ] + }, + "RoutingRuleAction": { + "type": "string", + "description": "Whether the rule accepts into the destination or rejects that destination.", + "enum": [ + "accept", + "reject" + ] + }, + "SearchLongTermMemoryRequestContent": { "type": "object", + "description": "Semantic search request for long-term memory records.", "properties": { - "moved": { - "type": "array", - "items": { - "type": "string", - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-]+$", - "description": "Memory record identifier (1-64 chars, alphanumeric and dashes). Client-provided for idempotent long-term memory creation." - } + "text": { + "type": "string", + "description": "Text to use for semantic search." }, - "errors": { + "similarityThreshold": { + "type": "number", + "maximum": 1, + "minimum": 0, + "description": "The minimum similarity threshold for vector search results (normalized cosine similarity). Allowed range: 0-1.", + "format": "float" + }, + "filter": { + "$ref": "#/components/schemas/LongTermMemoryFilter" + }, + "excludeDocumentManaged": { + "type": "boolean", + "description": "When true, omit document-managed memories from results. Automatic session reconciliation uses this; public search omits it so document memories remain visible." + }, + "filterOp": { + "$ref": "#/components/schemas/FilterConjunction" + }, + "sortBy": { + "$ref": "#/components/schemas/LongTermMemorySearchSortBy" + }, + "sortOrder": { + "$ref": "#/components/schemas/LongTermMemorySearchSortOrder" + }, + "limit": { + "type": "integer", + "default": 10, + "maximum": 100, + "minimum": 1, + "description": "Maximum number of results to return. Defaults to 10. Allowed range: 1-100.", + "format": "int32" + }, + "pageToken": { + "type": "string", + "description": "Opaque token from a previous response for the next page." + } + } + }, + "SearchLongTermMemoryResponseContent": { + "type": "object", + "description": "Semantic search result for long-term memory records.", + "properties": { + "items": { "type": "array", "items": { - "$ref": "#/components/schemas/BulkOperationError" - } + "$ref": "#/components/schemas/MemoryRecord" + }, + "description": "List of matching memory records. Always returned; empty when no records match." + }, + "nextPageToken": { + "type": "string", + "description": "Opaque token for fetching the next page. Omitted when no more results." } }, "required": [ - "moved" + "items" ] }, - "Namespace": { + "SessionEvent": { "type": "object", - "description": "A namespace hierarchy record.", + "description": "A single event in the session history.", "properties": { - "namespaceId": { - "type": "string", - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-]+$", - "description": "Server-generated namespace identifier." - }, - "name": { + "eventId": { "type": "string", - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9_-]+$", - "description": "One case-sensitive namespace path segment." + "maxLength": 32, + "minLength": 32, + "pattern": "^[a-zA-Z0-9]+$", + "description": "Auto-generated event ID." }, - "parentId": { + "actorId": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Server-generated namespace identifier." + "description": "Unique actor identifier (1-255 chars). Can represent a user, agent, or any participant." }, - "rootId": { + "sessionId": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Server-generated namespace identifier." - }, - "ownerId": { - "type": "string", - "minLength": 1, - "description": "An opaque application-user ID selected by the platform for a namespace root." - }, - "scope": { - "$ref": "#/components/schemas/NamespaceScope" + "description": "Session identifier (client-provided or server-generated)." }, - "state": { - "$ref": "#/components/schemas/NamespaceState" + "role": { + "$ref": "#/components/schemas/MessageRole" }, - "revision": { - "type": "integer", - "format": "int64" + "content": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Content" + }, + "description": "The message content as an array of typed content parts." }, "createdAt": { "type": "string", + "description": "Client-supplied timestamp for when the event happened (UTC).", "format": "date-time" }, - "updatedAt": { + "systemTimestamp": { "type": "string", + "description": "Server-set timestamp for when the dataplane ingested the event (UTC).", "format": "date-time" }, - "path": { - "type": "string", - "maxLength": 1024, - "minLength": 1, - "description": "Current case-sensitive path, derived from the live hierarchy." + "metadata": { + "description": "Optional metadata as any valid JSON value." } }, - "required": [ - "createdAt", - "name", - "namespaceId", - "path", - "revision", - "rootId", - "scope", - "state", - "updatedAt" + "required": [ + "actorId", + "content", + "createdAt", + "eventId", + "role", + "sessionId", + "systemTimestamp" ] }, - "NamespaceFilter": { + "SessionIdFilter": { "type": "object", - "description": "Filter by namespace. Matching is case-insensitive.\n\nNamespace is optional, so records without one need care. The positive operators (`eq`, `in`, `all`) require the field to be present and therefore never match a record that has no namespace \u2014 including memories extracted from a session that has none. `ne` is a plain negation and *does* match those records, so use `eq` or `in` when you need strict namespace isolation rather than `ne` against the namespaces you want to exclude.\n\nOmit this filter to search across every namespace, and use it to keep recall inside one project, workspace, team, environment, or tenant.", + "description": "Filter by the long-term memory sessionId field. Matching is case-sensitive.", "properties": { "eq": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Equals the given value.", - "deprecated": true + "description": "Equals the given value." }, "ne": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Not equal to the given value.", - "deprecated": true + "description": "Not equal to the given value." }, "in": { "type": "array", @@ -4527,8 +8568,7 @@ "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Deprecated flat namespace label for logical grouping. The value is 1-64 alphanumeric characters or dashes and has no hierarchy or scope semantics. Matching through `filter.namespace` is case-insensitive.\n\nThe field remains optional for backward compatibility. New integrations should use `namespaceRef` to reference an existing namespace resource.\n\nRecords produced by extraction inherit the namespace label stored on the session when the session was created.\n\nThis shape is deprecated: Use namespaceRef to reference a namespace resource.", - "deprecated": true + "description": "Session identifier (1-64 chars, alphanumeric and dashes). When the server generates one, it uses a 32-character UUID without dashes." }, "description": "Matches any of the given values." }, @@ -4539,245 +8579,307 @@ "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Deprecated flat namespace label for logical grouping. The value is 1-64 alphanumeric characters or dashes and has no hierarchy or scope semantics. Matching through `filter.namespace` is case-insensitive.\n\nThe field remains optional for backward compatibility. New integrations should use `namespaceRef` to reference an existing namespace resource.\n\nRecords produced by extraction inherit the namespace label stored on the session when the session was created.\n\nThis shape is deprecated: Use namespaceRef to reference a namespace resource.", - "deprecated": true + "description": "Session identifier (1-64 chars, alphanumeric and dashes). When the server generates one, it uses a 32-character UUID without dashes." }, "description": "Matches all of the given values." } } }, - "NamespaceRef": { + "SessionListItem": { "type": "object", - "description": "Reference to a namespace resource with its stable identifier and current display data.", + "description": "One session row without events or summary text. Owner ID and timestamps are absent when unknown on legacy sessions.", "properties": { - "namespaceId": { + "sessionId": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Stable namespace resource identifier." + "description": "Session identifier (1-64 chars, alphanumeric and dashes). When the server generates one, it uses a 32-character UUID without dashes." }, - "name": { + "ownerId": { "type": "string", "maxLength": 64, "minLength": 1, - "pattern": "^[a-zA-Z0-9_-]+$", - "description": "Current namespace name." + "pattern": "^[a-zA-Z0-9-]+$", + "description": "The owner of the session, set from the actorId of the first event. Absent for a legacy session that has no recorded owner." }, - "path": { + "createdAt": { "type": "string", - "maxLength": 1024, - "minLength": 1, - "description": "Current namespace path." + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + }, + "namespaceRef": { + "$ref": "#/components/schemas/NamespaceRef" } }, "required": [ - "name", - "namespaceId", - "path" + "sessionId" ] }, - "NamespaceRefFilter": { + "SessionListSortBy": { + "type": "string", + "enum": [ + "sessionId", + "createdAt", + "updatedAt" + ] + }, + "SessionListSortOrder": { + "type": "string", + "enum": [ + "asc", + "desc" + ] + }, + "SessionSourceEvidence": { "type": "object", - "description": "Filter by stable namespace resource identifier. Supports exact or any-of matching and matches only resource-backed records, never deprecated namespace labels.", "properties": { - "eq": { + "evidenceId": { "type": "string", - "maxLength": 64, + "maxLength": 128, "minLength": 1, - "pattern": "^[a-zA-Z0-9-]+$", - "description": "Equals the given value." + "description": "Identity of a logical extraction occurrence. Delivery retries retain this ID; a new extraction receives a new ID. Absent on legacy evidence." }, - "in": { + "schemaVersion": { + "type": "integer", + "description": "Version of the evidence metadata contract, currently 1. Absent on legacy evidence.", + "format": "int32" + }, + "capturedAt": { + "type": "string", + "description": "UTC time when the producer prepared the input for extraction, before model invocation. Preserved through checkpoint replay. This is not the source event time.", + "format": "date-time" + }, + "producer": { + "$ref": "#/components/schemas/EvidenceProducer" + }, + "eventIds": { "type": "array", "items": { "type": "string", - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-]+$", - "description": "Server-generated namespace identifier." + "maxLength": 32, + "minLength": 32, + "pattern": "^[a-zA-Z0-9]+$", + "description": "Server-generated event identifier (exactly 32 alphanumeric characters, UUID without dashes)." }, - "description": "Matches any of the given values." + "description": "Ordered IDs of events whose content was supplied to one model request. Input attribution, not fact citations." } - } + }, + "required": [ + "eventIds" + ] }, - "NamespaceRefInput": { + "SessionSourceIdentity": { "type": "object", - "description": "Reference to an existing namespace resource for a write or namespace-scoped operation.", "properties": { - "namespaceId": { + "sessionId": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Stable namespace resource identifier." - } - }, - "required": [ - "namespaceId" - ] - }, - "NamespaceRoutingPolicy": { - "type": "object", - "description": "Store-level automatic namespace routing and admission policy. Global rules target shared namespaces only. Accept rules select candidates in list order. All enabled reject rules for a destination apply regardless of their position or how the destination was selected.", - "properties": { - "enabled": { - "type": "boolean" + "description": "Session identifier (1-64 chars, alphanumeric and dashes). When the server generates one, it uses a 32-character UUID without dashes." }, - "rules": { - "type": "array", - "items": { - "$ref": "#/components/schemas/NamespaceRoutingRule" - }, - "maxItems": 32 + "ownerId": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Actor/owner identifier (1-64 chars, alphanumeric and dashes). Used for users, agents, or other participants." } }, "required": [ - "enabled" + "ownerId", + "sessionId" ] }, - "NamespaceRoutingRule": { + "SessionSummary": { "type": "object", - "description": "One routing or admission rule. action is accept or reject. Strategies run in list order and the first match fires the rule. An accept with no strategies always matches; a reject with no strategies never matches. A matching accept selects a candidate. Every enabled reject for that destination must pass before placement. A veto skips that candidate during automatic routing and fails explicit placement.", + "description": "Compacted summary of older session history for a session.\n\nThis is derived session state maintained by the background summarization workflow, not a conversation event. It is present only after at least one summarization cycle has completed.", "properties": { - "id": { + "text": { "type": "string", - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z][a-zA-Z0-9_-]*$", - "description": "Routing rule identifier (1-64 chars). Published in logs, so it is an identifier rather than free text." + "description": "The summary text, a single coherent block." }, - "destination": { - "$ref": "#/components/schemas/NamespaceRefInput" + "summarizedUpToEventId": { + "type": "string", + "maxLength": 32, + "minLength": 32, + "pattern": "^[a-zA-Z0-9]+$", + "description": "Boundary event ID. This event and all events before it (by array position) are covered by the summary; `events` contains the retained turns after this boundary." }, - "enabled": { - "type": "boolean" + "createdAt": { + "type": "string", + "description": "Timestamp when the summary was first created (UTC). Preserved across re-summarization cycles.", + "format": "date-time" }, - "action": { - "$ref": "#/components/schemas/RoutingRuleAction" + "updatedAt": { + "type": "string", + "description": "Timestamp when the summary was last regenerated (UTC). Updated on every summarization cycle. Equal to createdAt on the first cycle.", + "format": "date-time" }, - "strategies": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RouteCondition" - }, - "maxItems": 8 + "metadata": { + "description": "Metadata as a JSON object (e.g., model name, token count). Always present; defaults to an empty object when no metadata was supplied." + }, + "summarizedEvents": { + "type": "integer", + "minimum": 1, + "description": "Cumulative number of session events folded into this summary across all summarization cycles. Always positive. A value of 1 may indicate a summary created before this field was tracked; it self-corrects to a real count on the next summarization cycle.", + "format": "int64" } }, "required": [ - "action", - "destination", - "enabled", - "id" - ] - }, - "NamespaceScope": { - "type": "string", - "description": "The root scope of a namespace hierarchy.", - "enum": [ - "PERSONAL", - "SHARED" + "createdAt", + "metadata", + "summarizedEvents", + "summarizedUpToEventId", + "text", + "updatedAt" ] }, - "NamespaceState": { - "type": "string", - "description": "Whether a namespace accepts new children and placements.", - "enum": [ - "ACTIVE", - "ARCHIVED" + "StoreHealthFeature": { + "type": "object", + "description": "Feature-level store health.", + "properties": { + "status": { + "$ref": "#/components/schemas/StoreHealthStatus" + } + }, + "required": [ + "status" ] }, - "NamespaceUpdateState": { - "type": "string", - "description": "The archive-only state transition accepted by UpdateNamespace.", - "enum": [ - "ARCHIVED" - ] + "StoreHealthFeatureMap": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/StoreHealthFeature" + } }, - "NotFoundErrorResponseContent": { + "StoreHealthResponseContent": { "type": "object", - "description": "The requested resource does not exist.", + "description": "Store-scoped RAM feature health.", "properties": { - "title": { - "type": "string", - "description": "A short, human-readable summary of the problem\n type. It SHOULD NOT change from occurrence to occurrence of the\n problem, except for purposes of localization (e.g., using\n proactive content negotiation; see [RFC7231], Section 3.4)." - }, "status": { - "type": "integer", - "default": 404, - "description": "The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.", - "format": "int32" - }, - "detail": { - "type": "string", - "description": "A human-readable explanation specific to this occurrence of the problem." - }, - "instance": { - "type": "string", - "description": "A URI reference that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced." + "$ref": "#/components/schemas/StoreHealthStatus" }, - "type": { - "$ref": "#/components/schemas/NotFoundErrorType" + "features": { + "$ref": "#/components/schemas/StoreHealthFeatureMap" } }, "required": [ - "status", - "title", - "type" + "features", + "status" ] }, - "NotFoundErrorType": { + "StoreHealthStatus": { "type": "string", - "description": "Problem type URI for not-found errors.", + "description": "Store health status.", "enum": [ - "/errors/resource-not-found" + "healthy", + "degraded", + "unavailable" ] }, - "OwnerIdFilter": { + "SummaryView": { "type": "object", - "description": "Filter by the long-term memory ownerId field. Matching is case-sensitive.", + "description": "An owned Summary View definition. Results are separate derived state and never enter long-term-memory search.", "properties": { - "eq": { + "id": { + "type": "string", + "maxLength": 32, + "minLength": 32, + "pattern": "^[a-zA-Z0-9]+$", + "description": "Server-generated Summary View identifier." + }, + "ownerId": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Equals the given value." + "description": "Immutable canonical user ID assigned by the server. Clients cannot set ownership." }, - "ne": { + "visibility": { + "$ref": "#/components/schemas/SummaryViewVisibility" + }, + "name": { "type": "string", - "maxLength": 64, + "maxLength": 100, "minLength": 1, - "pattern": "^[a-zA-Z0-9-]+$", - "description": "Not equal to the given value." + "description": "Customer-visible Summary View name (1-100 characters)." }, - "in": { - "type": "array", - "items": { - "type": "string", - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-]+$", - "description": "Actor/owner identifier (1-64 chars, alphanumeric and dashes). Used for users, agents, or other participants." - }, - "description": "Matches any of the given values." + "description": { + "type": "string", + "maxLength": 200, + "description": "Optional Summary View description (up to 200 characters)." }, - "all": { + "source": { + "$ref": "#/components/schemas/SummaryViewSource" + }, + "filter": { + "$ref": "#/components/schemas/LongTermMemoryFilter" + }, + "filterOp": { + "$ref": "#/components/schemas/FilterConjunction" + }, + "groupBy": { "type": "array", "items": { - "type": "string", - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-]+$", - "description": "Actor/owner identifier (1-64 chars, alphanumeric and dashes). Used for users, agents, or other participants." + "$ref": "#/components/schemas/SummaryViewGroupField" }, - "description": "Matches all of the given values." + "maxItems": 4 + }, + "evictionPolicy": { + "$ref": "#/components/schemas/SummaryViewEvictionPolicy" + }, + "timeWindowSeconds": { + "type": "integer", + "minimum": 1, + "format": "int64" + }, + "output": { + "$ref": "#/components/schemas/SummaryViewOutputConfig" + }, + "refreshPolicy": { + "$ref": "#/components/schemas/SummaryViewRefreshPolicy" + }, + "definitionVersion": { + "type": "integer", + "minimum": 1, + "format": "int64" + }, + "state": { + "$ref": "#/components/schemas/SummaryViewState" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" } - } + }, + "required": [ + "createdAt", + "definitionVersion", + "filterOp", + "groupBy", + "id", + "name", + "output", + "ownerId", + "refreshPolicy", + "source", + "state", + "updatedAt", + "visibility" + ] }, - "PayloadTooLargeErrorResponseContent": { + "SummaryViewConflictErrorResponseContent": { "type": "object", - "description": "The request payload exceeds the maximum supported size.", + "description": "A Summary View operation conflicts with the current definition or partition state.", "properties": { "title": { "type": "string", @@ -4785,7 +8887,7 @@ }, "status": { "type": "integer", - "default": 413, + "default": 409, "description": "The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.", "format": "int32" }, @@ -4798,7 +8900,7 @@ "description": "A URI reference that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced." }, "type": { - "$ref": "#/components/schemas/PayloadTooLargeErrorType" + "$ref": "#/components/schemas/SummaryViewConflictErrorType" } }, "required": [ @@ -4807,53 +8909,117 @@ "type" ] }, - "PayloadTooLargeErrorType": { + "SummaryViewConflictErrorType": { "type": "string", - "description": "Problem type URI for payload-too-large errors.", + "description": "Problem type URI for Summary View conflicts.", "enum": [ - "/errors/payload-too-large" + "/errors/summary-view-conflict" ] }, - "PutNamespaceRoutingRequestContent": { + "SummaryViewEvictionPolicy": { "type": "object", + "description": "Selects the bounded set of grouped results. Matching long-term-memory mutations make a scope recent.", "properties": { - "policy": { - "$ref": "#/components/schemas/NamespaceRoutingPolicy" + "maxPartitions": { + "type": "integer", + "minimum": 1, + "format": "int32" } }, "required": [ - "policy" + "maxPartitions" ] }, - "PutNamespaceRoutingResponseContent": { + "SummaryViewField": { "type": "object", + "description": "A field in a bounded structured Summary View result. All fields are optional in generated results.", "properties": { - "policy": { - "$ref": "#/components/schemas/NamespaceRoutingPolicy" + "name": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z][a-zA-Z0-9_-]*$" + }, + "description": { + "type": "string", + "maxLength": 200, + "minLength": 1 + }, + "type": { + "$ref": "#/components/schemas/SummaryViewFieldType" } }, "required": [ - "policy" + "description", + "name", + "type" ] }, - "RegexSpec": { + "SummaryViewFieldType": { + "type": "string", + "description": "Supported structured-output field types. This matches the custom-memory field vocabulary.", + "enum": [ + "str", + "int", + "float", + "bool", + "list[str]", + "list[float]", + "object" + ] + }, + "SummaryViewGroupField": { + "type": "string", + "description": "A deterministic source field used to partition a Summary View.", + "enum": [ + "ownerId", + "sessionId", + "namespaceRef", + "memoryType" + ] + }, + "SummaryViewOutputConfig": { "type": "object", - "description": "A regular expression to match against.\n\nEvaluated by RE2, which runs in linear time \u2014 so an expensive pattern is not a\ndenial-of-service risk, but lookaround and backreferences are unavailable.\nRejected on write if it does not compile, or if it can match without consuming\ntext: such a pattern matches at every position, so it would exclude every memory\nthe store writes.", + "description": "Text or structured generation configuration. Schema is required exactly when format is structured.", "properties": { - "pattern": { + "format": { + "$ref": "#/components/schemas/SummaryViewOutputFormat" + }, + "instructions": { "type": "string", - "maxLength": 512, - "minLength": 1, - "description": "The pattern, in RE2 syntax." + "maxLength": 10000, + "description": "Customer-authored generation instructions. Prompt-security validation is enforced by the service." + }, + "schema": { + "$ref": "#/components/schemas/SummaryViewSchema" } }, "required": [ - "pattern" + "format" ] }, - "ResourceSuspendedErrorResponseContent": { + "SummaryViewOutputFormat": { + "type": "string", + "description": "Summary View output format.", + "enum": [ + "text", + "structured" + ] + }, + "SummaryViewQuotaCode": { + "type": "string", + "description": "Stable machine-readable Summary View quota code.", + "enum": [ + "DEFINITION_LIMIT_EXCEEDED", + "PARTITION_LIMIT_EXCEEDED", + "SOURCE_LIMIT_EXCEEDED", + "SCHEDULED_GENERATION_LIMIT_EXCEEDED", + "CONCURRENCY_LIMIT_EXCEEDED" + ] + }, + "SummaryViewQuotaErrorResponseContent": { "type": "object", - "description": "The requested resource exists but is suspended by an administrator.", + "description": "A Summary View operation exceeded an enabled store quota. Exact ceilings are deployment configuration established from benchmark evidence.", "properties": { "title": { "type": "string", @@ -4861,7 +9027,7 @@ }, "status": { "type": "integer", - "default": 423, + "default": 429, "description": "The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.", "format": "int32" }, @@ -4874,297 +9040,187 @@ "description": "A URI reference that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced." }, "type": { - "$ref": "#/components/schemas/ResourceSuspendedErrorType" + "$ref": "#/components/schemas/SummaryViewQuotaErrorType" + }, + "code": { + "$ref": "#/components/schemas/SummaryViewQuotaCode" } }, "required": [ + "code", "status", "title", "type" ] }, - "ResourceSuspendedErrorType": { + "SummaryViewQuotaErrorType": { "type": "string", - "description": "Problem type URI for suspended resources.", + "description": "Problem type URI for Summary View quota errors.", "enum": [ - "/errors/resource-suspended" + "/errors/summary-view-quota-exceeded" ] }, - "RouteCondition": { + "SummaryViewRefreshMode": { + "type": "string", + "description": "Summary View refresh mode.", + "enum": [ + "manual", + "continuous" + ] + }, + "SummaryViewRefreshPolicy": { "type": "object", - "description": "One plug-in strategy invocation. Exactly the block naming the declared kind must be present. List order is evaluation order.", + "description": "Refresh policy. Continuous views require reconcileIntervalSeconds; manual views omit both interval fields.", "properties": { - "kind": { - "$ref": "#/components/schemas/RouteStrategyKind" + "mode": { + "$ref": "#/components/schemas/SummaryViewRefreshMode" }, - "llmPrompt": { - "$ref": "#/components/schemas/LlmPromptSpec" + "debounceSeconds": { + "type": "integer", + "minimum": 1, + "format": "int32" }, - "matcher": { - "$ref": "#/components/schemas/MatcherSpec" + "reconcileIntervalSeconds": { + "type": "integer", + "minimum": 1, + "format": "int32" } }, "required": [ - "kind" + "mode" ] }, - "RouteStrategyKind": { + "SummaryViewRefreshTarget": { "type": "string", - "description": "Routing strategy kinds. Unknown kinds are rejected. New kinds register on the evaluator without changing namespace records.", + "description": "Manual refresh target. Partition refreshes require an exact configured scope; full refreshes reconcile every current and prior partition.", "enum": [ - "llm_prompt", - "matcher_spec" + "partition", + "full" ] }, - "RoutingRuleAction": { + "SummaryViewResultErrorCode": { "type": "string", - "description": "Whether the rule accepts into the destination or rejects that destination.", + "description": "Customer-safe refresh failure code. Provider details and source content are never returned.", "enum": [ - "accept", - "reject" + "SOURCE_LIMIT_EXCEEDED", + "GENERATION_FAILED", + "OUTPUT_VALIDATION_FAILED", + "REFRESH_RETRIES_EXHAUSTED", + "INTERNAL_ERROR" ] }, - "SearchLongTermMemoryRequestContent": { - "type": "object", - "description": "Semantic search request for long-term memory records.", - "properties": { - "text": { - "type": "string", - "description": "Text to use for semantic search." - }, - "similarityThreshold": { - "type": "number", - "maximum": 1, - "minimum": 0, - "description": "The minimum similarity threshold for vector search results (normalized cosine similarity). Allowed range: 0-1.", - "format": "float" - }, - "filter": { - "$ref": "#/components/schemas/LongTermMemoryFilter" - }, - "filterOp": { - "$ref": "#/components/schemas/FilterConjunction" - }, - "limit": { - "type": "integer", - "default": 10, - "maximum": 100, - "minimum": 1, - "description": "Maximum number of results to return. Defaults to 10. Allowed range: 1-100.", - "format": "int32" - }, - "pageToken": { - "type": "string", - "description": "Opaque token from a previous response for the next page." - } - } - }, - "SearchLongTermMemoryResponseContent": { - "type": "object", - "description": "Semantic search result for long-term memory records.", - "properties": { - "items": { - "type": "array", - "items": { - "$ref": "#/components/schemas/MemoryRecord" - }, - "description": "List of matching memory records. Always returned; empty when no records match." - }, - "nextPageToken": { - "type": "string", - "description": "Opaque token for fetching the next page. Omitted when no more results." - } - }, - "required": [ - "items" + "SummaryViewResultStatus": { + "type": "string", + "description": "Materialization refresh state.", + "enum": [ + "cold", + "pending", + "ready", + "empty", + "refreshing", + "failed" ] }, - "SessionEvent": { - "type": "object", - "description": "A single event in the session history.", - "properties": { - "eventId": { - "type": "string", - "maxLength": 32, - "minLength": 32, - "pattern": "^[a-zA-Z0-9]+$", - "description": "Auto-generated event ID." - }, - "actorId": { - "type": "string", - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-]+$", - "description": "Unique actor identifier (1-255 chars). Can represent a user, agent, or any participant." - }, - "sessionId": { - "type": "string", - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-]+$", - "description": "Session identifier (client-provided or server-generated)." - }, - "role": { - "$ref": "#/components/schemas/MessageRole" + "SummaryViewResultValue": { + "description": "Exactly one generated result value. It is omitted for cold, pending, and empty results, and may be omitted for failed results with no last good value.", + "oneOf": [ + { + "type": "object", + "title": "text", + "properties": { + "text": { + "type": "string" + } + }, + "required": [ + "text" + ] }, - "content": { + { + "type": "object", + "title": "data", + "properties": { + "data": {} + }, + "required": [ + "data" + ] + } + ] + }, + "SummaryViewSchema": { + "type": "object", + "description": "Bounded structured-output schema. Nested object schemas, required fields, and arbitrary JSON Schema are not supported in the MVP.", + "properties": { + "fields": { "type": "array", "items": { - "$ref": "#/components/schemas/Content" + "$ref": "#/components/schemas/SummaryViewField" }, - "description": "The message content as an array of typed content parts." - }, - "createdAt": { - "type": "string", - "description": "Client-supplied timestamp for when the event happened (UTC).", - "format": "date-time" - }, - "systemTimestamp": { - "type": "string", - "description": "Server-set timestamp for when the dataplane ingested the event (UTC).", - "format": "date-time" - }, - "metadata": { - "description": "Optional metadata as any valid JSON value." + "maxItems": 50, + "minItems": 1 } }, "required": [ - "actorId", - "content", - "createdAt", - "eventId", - "role", - "sessionId", - "systemTimestamp" + "fields" ] }, - "SessionIdFilter": { + "SummaryViewScope": { "type": "object", - "description": "Filter by the long-term memory sessionId field. Matching is case-sensitive.", + "description": "An exact partition scope. The service requires exactly the fields configured by groupBy; singleton views accept none.", "properties": { - "eq": { + "ownerId": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Equals the given value." + "description": "Actor/owner identifier (1-64 chars, alphanumeric and dashes). Used for users, agents, or other participants." }, - "ne": { + "sessionId": { "type": "string", "maxLength": 64, "minLength": 1, "pattern": "^[a-zA-Z0-9-]+$", - "description": "Not equal to the given value." - }, - "in": { - "type": "array", - "items": { - "type": "string", - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-]+$", - "description": "Session identifier (1-64 chars, alphanumeric and dashes). When the server generates one, it uses a 32-character UUID without dashes." - }, - "description": "Matches any of the given values." - }, - "all": { - "type": "array", - "items": { - "type": "string", - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-]+$", - "description": "Session identifier (1-64 chars, alphanumeric and dashes). When the server generates one, it uses a 32-character UUID without dashes." - }, - "description": "Matches all of the given values." - } - } - }, - "SessionSummary": { - "type": "object", - "description": "Compacted summary of older session history for a session.\n\nThis is derived session state maintained by the background summarization workflow, not a conversation event. It is present only after at least one summarization cycle has completed.", - "properties": { - "text": { - "type": "string", - "description": "The summary text, a single coherent block." + "description": "Session identifier (1-64 chars, alphanumeric and dashes). When the server generates one, it uses a 32-character UUID without dashes." }, - "summarizedUpToEventId": { - "type": "string", - "maxLength": 32, - "minLength": 32, - "pattern": "^[a-zA-Z0-9]+$", - "description": "Boundary event ID. This event and all events before it (by array position) are covered by the summary; `events` contains the retained turns after this boundary." - }, - "createdAt": { + "namespaceRef": { "type": "string", - "description": "Timestamp when the summary was first created (UTC). Preserved across re-summarization cycles.", - "format": "date-time" + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Server-generated namespace identifier." }, - "updatedAt": { + "memoryType": { "type": "string", - "description": "Timestamp when the summary was last regenerated (UTC). Updated on every summarization cycle. Equal to createdAt on the first cycle.", - "format": "date-time" - }, - "metadata": { - "description": "Metadata as a JSON object (e.g., model name, token count). Always present; defaults to an empty object when no metadata was supplied." - }, - "summarizedEvents": { - "type": "integer", - "minimum": 1, - "description": "Cumulative number of session events folded into this summary across all summarization cycles. Always positive. A value of 1 may indicate a summary created before this field was tracked; it self-corrects to a real count on the next summarization cycle.", - "format": "int64" + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z][a-zA-Z0-9_-]*$", + "description": "Identifier of a long-term memory type.\n\nBuilt-in types include `semantic`, `episodic`, `message`, and `session_summary_view`.\nStores may also register custom memory types; this open string accepts any\nregistered type name.\n\nConstraints: 1-64 chars, must start with a letter, followed by letters, digits,\nunderscores, or dashes." } - }, - "required": [ - "createdAt", - "metadata", - "summarizedEvents", - "summarizedUpToEventId", - "text", - "updatedAt" - ] + } }, - "StoreHealthFeature": { - "type": "object", - "description": "Feature-level store health.", - "properties": { - "status": { - "$ref": "#/components/schemas/StoreHealthStatus" - } - }, - "required": [ - "status" + "SummaryViewSource": { + "type": "string", + "description": "The source record family summarized by a Summary View. The MVP supports long-term memory only.", + "enum": [ + "long_term" ] }, - "StoreHealthFeatureMap": { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/StoreHealthFeature" - } - }, - "StoreHealthResponseContent": { - "type": "object", - "description": "Store-scoped RAM feature health.", - "properties": { - "status": { - "$ref": "#/components/schemas/StoreHealthStatus" - }, - "features": { - "$ref": "#/components/schemas/StoreHealthFeatureMap" - } - }, - "required": [ - "features", - "status" + "SummaryViewState": { + "type": "string", + "description": "Summary View definition lifecycle state.", + "enum": [ + "active", + "disabled", + "deleting" ] }, - "StoreHealthStatus": { + "SummaryViewVisibility": { "type": "string", - "description": "Store health status.", + "description": "The immutable audience of a Summary View.", "enum": [ - "healthy", - "degraded", - "unavailable" + "PRIVATE", + "SHARED" ] }, "TimeoutErrorResponseContent": { @@ -5464,6 +9520,21 @@ "type": "string", "description": "Timestamp when the memory was last updated (UTC).", "format": "date-time" + }, + "sources": { + "type": "array", + "items": { + "$ref": "#/components/schemas/MemorySourceLink" + }, + "description": "Generic source links for this memory. Document sources include the customer document ID and revision that produced the memory." + }, + "sourcesNextPageToken": { + "type": "string", + "description": "Opaque token for additional source links when this response truncated attribution. Absent when every link is included." + }, + "documentManaged": { + "type": "boolean", + "description": "True when this memory was created by document ingestion and is protected from generic overwrite." } }, "required": [ @@ -5498,6 +9569,155 @@ "required": [ "namespace" ] + }, + "UpdateSummaryViewRequestContent": { + "type": "object", + "properties": { + "name": { + "type": "string", + "maxLength": 100, + "minLength": 1, + "description": "Customer-visible Summary View name (1-100 characters)." + }, + "description": { + "type": "string", + "maxLength": 200, + "description": "New description. Send an empty string to clear it." + }, + "filter": { + "$ref": "#/components/schemas/LongTermMemoryFilter" + }, + "clearFilter": { + "type": "boolean", + "description": "Clear the saved filter. Mutually exclusive with filter." + }, + "filterOp": { + "$ref": "#/components/schemas/FilterConjunction" + }, + "groupBy": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SummaryViewGroupField" + }, + "maxItems": 4 + }, + "evictionPolicy": { + "$ref": "#/components/schemas/SummaryViewEvictionPolicy" + }, + "timeWindowSeconds": { + "type": "integer", + "minimum": 1, + "format": "int64" + }, + "clearTimeWindow": { + "type": "boolean", + "description": "Clear the rolling time window. Mutually exclusive with timeWindowSeconds." + }, + "output": { + "$ref": "#/components/schemas/SummaryViewOutputConfig" + }, + "refreshPolicy": { + "$ref": "#/components/schemas/SummaryViewRefreshPolicy" + }, + "state": { + "$ref": "#/components/schemas/MutableSummaryViewState" + } + } + }, + "UpdateSummaryViewResponseContent": { + "type": "object", + "description": "An owned Summary View definition. Results are separate derived state and never enter long-term-memory search.", + "properties": { + "id": { + "type": "string", + "maxLength": 32, + "minLength": 32, + "pattern": "^[a-zA-Z0-9]+$", + "description": "Server-generated Summary View identifier." + }, + "ownerId": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-]+$", + "description": "Immutable canonical user ID assigned by the server. Clients cannot set ownership." + }, + "visibility": { + "$ref": "#/components/schemas/SummaryViewVisibility" + }, + "name": { + "type": "string", + "maxLength": 100, + "minLength": 1, + "description": "Customer-visible Summary View name (1-100 characters)." + }, + "description": { + "type": "string", + "maxLength": 200, + "description": "Optional Summary View description (up to 200 characters)." + }, + "source": { + "$ref": "#/components/schemas/SummaryViewSource" + }, + "filter": { + "$ref": "#/components/schemas/LongTermMemoryFilter" + }, + "filterOp": { + "$ref": "#/components/schemas/FilterConjunction" + }, + "groupBy": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SummaryViewGroupField" + }, + "maxItems": 4 + }, + "evictionPolicy": { + "$ref": "#/components/schemas/SummaryViewEvictionPolicy" + }, + "timeWindowSeconds": { + "type": "integer", + "minimum": 1, + "format": "int64" + }, + "output": { + "$ref": "#/components/schemas/SummaryViewOutputConfig" + }, + "refreshPolicy": { + "$ref": "#/components/schemas/SummaryViewRefreshPolicy" + }, + "definitionVersion": { + "type": "integer", + "minimum": 1, + "format": "int64" + }, + "state": { + "$ref": "#/components/schemas/SummaryViewState" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + } + }, + "required": [ + "createdAt", + "definitionVersion", + "filterOp", + "groupBy", + "id", + "name", + "output", + "ownerId", + "refreshPolicy", + "source", + "state", + "updatedAt", + "visibility" + ] } } } diff --git a/content/develop/ai/context-engine/agent-memory/namespace-routing.md b/content/develop/ai/context-engine/agent-memory/namespace-routing.md new file mode 100644 index 0000000000..5f64f14fa3 --- /dev/null +++ b/content/develop/ai/context-engine/agent-memory/namespace-routing.md @@ -0,0 +1,167 @@ +--- +alwaysopen: false +categories: +- docs +- develop +- ai +description: Configure shared namespace routing and admission rules for long-term memories. +hideListLinks: true +linktitle: Namespace routing +title: Namespace routing +weight: 14 +--- + +Namespace routing selects a shared namespace for an eligible memory. Admission rules check whether a memory can enter a destination. Use routing to organize shared memories by content, and admission rules to reject content that does not belong in a namespace. + +The policy applies to one store. It targets existing shared namespace resources, using their stable `namespaceId` values. It does not create namespaces or change access permissions. Your service must support namespace routing and have it enabled. The beta software development kits (SDKs) expose these operations in Python `0.5.0b1` and TypeScript `0.4.0-beta.1`; installing an SDK does not enable routing on the service. + +## Understand placement and admission + +| Request | Behavior | +|:--------|:---------| +| Create a memory with `namespaceRef` | Use that destination after admission checks. The service never chooses another destination. | +| Create a memory without `namespace` or `namespaceRef` | Create it without a namespace. Automatic routing does not place it in a shared namespace. | +| Move a memory with `namespaceRef` | Use that destination after admission checks. | +| Move a memory without `namespaceRef` | Evaluate automatic routing only if the memory is already in a shared namespace. | +| Update a memory | Check the merged record against admission at its current destination. An update never chooses another destination. | + +An automatic move keeps the current placement and returns a per-item error if routing is disabled, no destination qualifies, or the memory is personal or has no namespace. Inspect both `moved` and `errors` in a move response. Bulk creation also reports failures per record in `errors`. An explicit move to an archived namespace returns `409 Conflict`. + +An enabled `accept` rule selects a candidate destination. Accept rules run in list order. Every enabled `reject` rule for that destination applies, including rules later in the list. A matching reject vetoes the candidate. Automatic routing then tries another candidate; explicit placement fails rather than choosing another namespace. + +Strategies within a rule run in list order; the first match fires the rule. An accept rule with no strategies always matches. A reject rule with no strategies never matches. Use `matcher_spec` with a `regex` matcher for text patterns, or `llm_prompt` with `llmPrompt` for a model-evaluated instruction. Each strategy must contain only the block for its declared `kind`. + +## Configure a policy + +Create a shared namespace with `CreateNamespace`, and save its returned ID as `SHARED_NAMESPACE_ID`. Use `scope: "SHARED"` and omit `ownerId`. Install the beta SDK for your language, then set `AGENT_MEMORY_URL`, `STORE_ID`, and `API_KEY` as described in the [developer guide](/content/develop/ai/context-engine/agent-memory/developer-guide.md#connect-to-a-redis-agent-memory-service). + +This example accepts text containing `travel` into that namespace. The regular expression is case-insensitive. **PUT replaces the entire policy**, so read the current policy first and retain any rules you still need. + +{{< multitabs id="namespace-routing-policy" 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: + current = await agent_memory.get_namespace_routing_async() + print(current.model_dump_json(by_alias=True, indent=2)) + result = await agent_memory.put_namespace_routing_async(policy={ + "enabled": True, + "rules": [{ + "id": "travel", + "enabled": True, + "action": "accept", + "destination": {"namespace_id": os.environ["SHARED_NAMESPACE_ID"]}, + "strategies": [{ + "kind": "matcher_spec", + "matcher": {"kind": "regex", "regex": {"pattern": "(?i)travel"}}, + }], + }], + }) + print(result.model_dump_json(by_alias=True, indent=2)) + + +asyncio.run(main()) +``` + +-tab-sep- + +```typescript +import { AgentMemory } from "@redis-iris/agent-memory"; + +async function main() { + const { AGENT_MEMORY_URL, STORE_ID, API_KEY, SHARED_NAMESPACE_ID } = process.env; + if (!AGENT_MEMORY_URL || !STORE_ID || !API_KEY || !SHARED_NAMESPACE_ID) { + throw new Error("Set AGENT_MEMORY_URL, STORE_ID, API_KEY, and SHARED_NAMESPACE_ID."); + } + const agentMemory = new AgentMemory({ + serverURL: AGENT_MEMORY_URL, storeId: STORE_ID, apiKey: API_KEY, + }); + console.dir(await agentMemory.getNamespaceRouting(), { depth: null }); + const result = await agentMemory.putNamespaceRouting({ + policy: { + enabled: true, + rules: [{ + id: "travel", enabled: true, action: "accept", + destination: { namespaceId: SHARED_NAMESPACE_ID }, + strategies: [{ + kind: "matcher_spec", + matcher: { kind: "regex", regex: { pattern: "(?i)travel" } }, + }], + }], + }, + }); + console.dir(result, { depth: null }); +} + +main().catch((error) => { console.error(error); process.exitCode = 1; }); +``` + +-tab-sep- + +```sh +curl --fail-with-body --silent --show-error \ + --header "Authorization: Bearer $API_KEY" \ + "$AGENT_MEMORY_URL/v1/stores/$STORE_ID/namespace-routing" | jq + +curl --fail-with-body --silent --show-error \ + --request PUT \ + --header "Authorization: Bearer $API_KEY" \ + --header 'Content-Type: application/json' \ + --data "$(jq -n --arg ns "$SHARED_NAMESPACE_ID" \ + '{policy: {enabled: true, rules: [{id: "travel", enabled: true, + action: "accept", destination: {namespaceId: $ns}, strategies: [{ + kind: "matcher_spec", matcher: {kind: "regex", regex: {pattern: "(?i)travel"}} + }]}]}}')" \ + "$AGENT_MEMORY_URL/v1/stores/$STORE_ID/namespace-routing" | jq +``` + +{{< /multitabs >}} + +A store without a saved policy returns an empty, disabled policy. Regular expressions use RE2 syntax. Lookaround, backreferences, invalid expressions, and patterns that can match empty text are not supported. A policy supports up to 32 rules and 8 strategies per rule. See [`PutNamespaceRouting`](/content/develop/ai/context-engine/agent-memory/api-reference.md#operation/PutNamespaceRouting) for validation and error responses. + +## Move memories with the policy + +To evaluate the policy for an existing shared memory, omit the destination from `MoveLongTermMemories`. Use IDs returned by a previous create or search request: + +{{< multitabs id="namespace-routing-move" tab1="Python" tab2="TypeScript" tab3="curl" >}} + +```python + moved = await agent_memory.move_long_term_memories_async( + memory_ids=[os.environ["MEMORY_ID"]], + ) + print(moved.model_dump_json(by_alias=True, indent=2)) +``` + +-tab-sep- + +```typescript + const memoryId = process.env.MEMORY_ID; + if (!memoryId) throw new Error("Set MEMORY_ID to an existing shared memory ID."); + const moved = await agentMemory.moveLongTermMemories({ memoryIds: [memoryId] }); + console.dir(moved, { depth: null }); +``` + +-tab-sep- + +```sh +curl --fail-with-body --silent --show-error \ + --request POST \ + --header "Authorization: Bearer $API_KEY" \ + --header 'Content-Type: application/json' \ + --data "$(jq -n --arg id "$MEMORY_ID" '{memoryIds: [$id]}')" \ + "$AGENT_MEMORY_URL/v1/stores/$STORE_ID/long-term-memory/move" | jq +``` + +{{< /multitabs >}} + +Add the SDK snippet inside the client block or `main` function from [Configure a policy](/content/develop/ai/context-engine/agent-memory/namespace-routing.md#configure-a-policy). Set `MEMORY_ID` before running it. The example memory must already belong to a shared namespace and contain matching text. The request accepts 1–100 IDs. To choose a destination explicitly, also pass `namespace_ref={"namespace_id": ""}` in Python or `namespaceRef: { namespaceId: "" }` in TypeScript or the request body. Explicit placement still runs admission checks. From a56a107c6324b39b0fc6e4157e40063b70ca724e Mon Sep 17 00:00:00 2001 From: Andrew Brookins Date: Wed, 21 Oct 2026 13:30:41 -0700 Subject: [PATCH 3/3] Write routing setup for stable publication --- .../ai/context-engine/agent-memory/namespace-routing.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/develop/ai/context-engine/agent-memory/namespace-routing.md b/content/develop/ai/context-engine/agent-memory/namespace-routing.md index 5f64f14fa3..68b3b26acb 100644 --- a/content/develop/ai/context-engine/agent-memory/namespace-routing.md +++ b/content/develop/ai/context-engine/agent-memory/namespace-routing.md @@ -13,7 +13,7 @@ weight: 14 Namespace routing selects a shared namespace for an eligible memory. Admission rules check whether a memory can enter a destination. Use routing to organize shared memories by content, and admission rules to reject content that does not belong in a namespace. -The policy applies to one store. It targets existing shared namespace resources, using their stable `namespaceId` values. It does not create namespaces or change access permissions. Your service must support namespace routing and have it enabled. The beta software development kits (SDKs) expose these operations in Python `0.5.0b1` and TypeScript `0.4.0-beta.1`; installing an SDK does not enable routing on the service. +The policy applies to one store. It targets existing shared namespace resources, using their stable `namespaceId` values. It does not create namespaces or change access permissions. Your service must support namespace routing and have it enabled. ## Understand placement and admission @@ -33,7 +33,7 @@ Strategies within a rule run in list order; the first match fires the rule. An a ## Configure a policy -Create a shared namespace with `CreateNamespace`, and save its returned ID as `SHARED_NAMESPACE_ID`. Use `scope: "SHARED"` and omit `ownerId`. Install the beta SDK for your language, then set `AGENT_MEMORY_URL`, `STORE_ID`, and `API_KEY` as described in the [developer guide](/content/develop/ai/context-engine/agent-memory/developer-guide.md#connect-to-a-redis-agent-memory-service). +Create a shared namespace with `CreateNamespace`, and save its returned ID as `SHARED_NAMESPACE_ID`. Use `scope: "SHARED"` and omit `ownerId`. Install the software development kit (SDK) for your language, then set `AGENT_MEMORY_URL`, `STORE_ID`, and `API_KEY` as described in the [developer guide](/content/develop/ai/context-engine/agent-memory/developer-guide.md#connect-to-a-redis-agent-memory-service). This example accepts text containing `travel` into that namespace. The regular expression is case-insensitive. **PUT replaces the entire policy**, so read the current policy first and retain any rules you still need.