From f408e76e64e1f2e3eb4bf12a1d03fde1dec71b1f Mon Sep 17 00:00:00 2001 From: Andrew Brookins Date: Wed, 16 Sep 2026 13:03:00 -0700 Subject: [PATCH] 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" + ] } } }