diff --git a/docs/ContextInput.md b/docs/ContextInput.md index 510582b..14b1f55 100644 --- a/docs/ContextInput.md +++ b/docs/ContextInput.md @@ -1,6 +1,6 @@ # ContextInput -Request body of `POST /api/v2/memory/context`. The same fields as the `/search` request, except that `method` is fixed to `\"context\"`, `min_score` is not supported, and `radius`, `enable_llm_rerank` and `with_readable_episode` are not accepted. +Request body of `POST /api/v2/memory/context`. The same fields as the `/search` request, except that `user_id` is required and `agent_id` is not accepted (user memories only), `method` is fixed to `\"context\"`, `min_score` is not supported, and `radius`, `enable_llm_rerank` and `with_readable_episode` are not accepted. ## Properties @@ -8,8 +8,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **app_id** | **str** | Scope to search in, defaulting to \"default\". Must match the pair used on write. | [optional] [default to 'default'] **project_id** | **str** | Second half of the scope, defaulting to \"default\". | [optional] [default to 'default'] -**user_id** | **str** | | [optional] -**agent_id** | **str** | | [optional] +**user_id** | **str** | Required. The user whose memories are searched — matched against the messages' `sender_id`. `agent_id` is not accepted here (422); use /search for agent memories. | **query** | **str** | The question to retrieve for. The loop keeps searching until it judges the evidence sufficient to answer it, so pass the whole question, not keywords. | **method** | **str** | Fixed to `\"context\"`; may be omitted. Any other value is a 422. | [optional] [default to 'context'] **top_k** | **int** | Maximum number of episodes returned. Either -1 (the default, letting the engine decide) or a value from 1 to 100; anything else is rejected with 422. | [optional] [default to -1] diff --git a/docs/MemoryApi.md b/docs/MemoryApi.md index 44f1262..e638c6f 100644 --- a/docs/MemoryApi.md +++ b/docs/MemoryApi.md @@ -867,7 +867,7 @@ Name | Type | Description | Notes Request a memory-space purge (step 1 of 2) [Cloud-only] -**Permanent — there is no undo.** Step 1 of 2: asks for a purge and returns a `nonce`. Nothing is deleted yet. - `scope: \"space\"` purges the whole memory space; `\"app\"` one app (`app_id`); `\"project\"` one project of one app (`app_id` + `project_id`). - Confirm with `POST /purge/confirm` before `expires_at` (5 minutes). The nonce is single use and only valid for the same memory space and API key. What is deleted: memories, sessions, messages, memory cells, feedback, events and (space scope only) senders and engine knowledge bases, from every index. Not deleted: files uploaded through `/object/sign`, and data of the separate knowledge-base service. +**Permanent — there is no undo.** Step 1 of 2: asks for a purge and returns a `nonce`. Nothing is deleted yet. - `scope: \"space\"` purges the whole memory space; `\"app\"` one app (`app_id`); `\"project\"` one project of one app (`app_id` + `project_id`). - Confirm with `POST /purge/confirm` before `expires_at` (5 minutes). The nonce is single use and only valid for the same memory space and API key. What is deleted: memories, sessions, messages, memory cells, feedback, events and (space scope only) senders and knowledge bases (`/api/v2/knowledge_bases`: categories, documents, topics), from every index. Left in object storage, no longer reachable through the API: files uploaded through `/object/sign`, and (space scope) the stored text of knowledge base topics. ### Example @@ -951,7 +951,7 @@ Name | Type | Description | Notes Context Retrieval [Cloud-only] -Retrieve memories with a multi-round, LLM-driven search loop. An LLM plans and runs several searches over the owner's memories — keyword, semantic, hybrid, topic-cluster, and reading the surrounding conversation or a whole session — and keeps searching until it judges the evidence sufficient to answer `query`. The memories it found are returned. **The response contains memories, not an answer**: the model's own answer is discarded. Use it for questions a single search answers poorly: multi-hop, temporal, or spread across several conversations. For simple lookups, `/search` is faster and cheaper. **Request** — the same body as `/search`, except: - `method` is fixed to `\"context\"`. It can be omitted; any other value is a 422. - `min_score` is not supported (422): results are ranked by rank fusion, not by a similarity score. - `radius`, `enable_llm_rerank` and `with_readable_episode` are not accepted (422): the loop does not use them. **Response** — the same `SearchData` shape as `/search`: - The loop returns its memories in `episodes`, for a `user_id` owner only; for an `agent_id` owner `episodes`, `agent_cases` and `agent_skills` are empty. `profiles` (`include_profile`) and `unprocessed_messages` (a top-level `session_id` filter) are filled exactly as on `/search`. - `episodes[].cited` is `true` for memories the model named as the ones its answer rested on. - `episodes[].score` is a rank-fusion score, not a similarity: roughly 0.01–0.05, plus 1.0 for a cited memory, so cited memories come first. It is not comparable with `/search` scores. **Limits** — by default at most 5 LLM rounds and 45 seconds per request. Reaching a limit is not an error: the memories found so far are returned. **Latency** — several LLM calls per request, so noticeably slower than `/search`. +Retrieve memories with a multi-round, LLM-driven search loop. An LLM plans and runs several searches over the owner's memories — keyword, semantic, hybrid, topic-cluster, and reading the surrounding conversation or a whole session — and keeps searching until it judges the evidence sufficient to answer `query`. The memories it found are returned. **The response contains memories, not an answer**: the model's own answer is discarded. Use it for questions a single search answers poorly: multi-hop, temporal, or spread across several conversations. For simple lookups, `/search` is faster and cheaper. **Request** — the same body as `/search`, except: - `user_id` is required and `agent_id` is not accepted (422): the loop searches a user's memories only. Use `/search` for agent memories. - `method` is fixed to `\"context\"`. It can be omitted; any other value is a 422. - `min_score` is not supported (422): results are ranked by rank fusion, not by a similarity score. - `radius`, `enable_llm_rerank` and `with_readable_episode` are not accepted (422): the loop does not use them. **Response** — the same `SearchData` shape as `/search`: - The loop returns its memories in `episodes`. `profiles` (`include_profile`) and `unprocessed_messages` (a top-level `session_id` filter) are filled exactly as on `/search`. - `episodes[].cited` is `true` for memories the model named as the ones its answer rested on. - `episodes[].score` is a rank-fusion score, not a similarity: roughly 0.01–0.05, plus 1.0 for a cited memory, so cited memories come first. It is not comparable with `/search` scores. **Limits** — by default at most 5 LLM rounds and 45 seconds per request. Reaching a limit is not an error: the memories found so far are returned. **Latency** — several LLM calls per request, so noticeably slower than `/search`. ### Example diff --git a/everos_cloud/__init__.py b/everos_cloud/__init__.py index 906b9f1..747cc41 100644 --- a/everos_cloud/__init__.py +++ b/everos_cloud/__init__.py @@ -15,7 +15,7 @@ """ # noqa: E501 -__version__ = "1.3.0-rc2" +__version__ = "1.3.0-rc3" # import apis into sdk package from everos_cloud.api.knowledge_api import KnowledgeApi diff --git a/everos_cloud/api/memory_api.py b/everos_cloud/api/memory_api.py index 8382d24..f601ff4 100644 --- a/everos_cloud/api/memory_api.py +++ b/everos_cloud/api/memory_api.py @@ -2965,7 +2965,7 @@ def request_purge( ) -> SuccessEnvelopePurgeRequestData: """Request a memory-space purge (step 1 of 2) [Cloud-only] - **Permanent — there is no undo.** Step 1 of 2: asks for a purge and returns a `nonce`. Nothing is deleted yet. - `scope: \"space\"` purges the whole memory space; `\"app\"` one app (`app_id`); `\"project\"` one project of one app (`app_id` + `project_id`). - Confirm with `POST /purge/confirm` before `expires_at` (5 minutes). The nonce is single use and only valid for the same memory space and API key. What is deleted: memories, sessions, messages, memory cells, feedback, events and (space scope only) senders and engine knowledge bases, from every index. Not deleted: files uploaded through `/object/sign`, and data of the separate knowledge-base service. + **Permanent — there is no undo.** Step 1 of 2: asks for a purge and returns a `nonce`. Nothing is deleted yet. - `scope: \"space\"` purges the whole memory space; `\"app\"` one app (`app_id`); `\"project\"` one project of one app (`app_id` + `project_id`). - Confirm with `POST /purge/confirm` before `expires_at` (5 minutes). The nonce is single use and only valid for the same memory space and API key. What is deleted: memories, sessions, messages, memory cells, feedback, events and (space scope only) senders and knowledge bases (`/api/v2/knowledge_bases`: categories, documents, topics), from every index. Left in object storage, no longer reachable through the API: files uploaded through `/object/sign`, and (space scope) the stored text of knowledge base topics. :param purge_request_input: (required) :type purge_request_input: PurgeRequestInput @@ -3037,7 +3037,7 @@ def request_purge_with_http_info( ) -> ApiResponse[SuccessEnvelopePurgeRequestData]: """Request a memory-space purge (step 1 of 2) [Cloud-only] - **Permanent — there is no undo.** Step 1 of 2: asks for a purge and returns a `nonce`. Nothing is deleted yet. - `scope: \"space\"` purges the whole memory space; `\"app\"` one app (`app_id`); `\"project\"` one project of one app (`app_id` + `project_id`). - Confirm with `POST /purge/confirm` before `expires_at` (5 minutes). The nonce is single use and only valid for the same memory space and API key. What is deleted: memories, sessions, messages, memory cells, feedback, events and (space scope only) senders and engine knowledge bases, from every index. Not deleted: files uploaded through `/object/sign`, and data of the separate knowledge-base service. + **Permanent — there is no undo.** Step 1 of 2: asks for a purge and returns a `nonce`. Nothing is deleted yet. - `scope: \"space\"` purges the whole memory space; `\"app\"` one app (`app_id`); `\"project\"` one project of one app (`app_id` + `project_id`). - Confirm with `POST /purge/confirm` before `expires_at` (5 minutes). The nonce is single use and only valid for the same memory space and API key. What is deleted: memories, sessions, messages, memory cells, feedback, events and (space scope only) senders and knowledge bases (`/api/v2/knowledge_bases`: categories, documents, topics), from every index. Left in object storage, no longer reachable through the API: files uploaded through `/object/sign`, and (space scope) the stored text of knowledge base topics. :param purge_request_input: (required) :type purge_request_input: PurgeRequestInput @@ -3109,7 +3109,7 @@ def request_purge_without_preload_content( ) -> RESTResponseType: """Request a memory-space purge (step 1 of 2) [Cloud-only] - **Permanent — there is no undo.** Step 1 of 2: asks for a purge and returns a `nonce`. Nothing is deleted yet. - `scope: \"space\"` purges the whole memory space; `\"app\"` one app (`app_id`); `\"project\"` one project of one app (`app_id` + `project_id`). - Confirm with `POST /purge/confirm` before `expires_at` (5 minutes). The nonce is single use and only valid for the same memory space and API key. What is deleted: memories, sessions, messages, memory cells, feedback, events and (space scope only) senders and engine knowledge bases, from every index. Not deleted: files uploaded through `/object/sign`, and data of the separate knowledge-base service. + **Permanent — there is no undo.** Step 1 of 2: asks for a purge and returns a `nonce`. Nothing is deleted yet. - `scope: \"space\"` purges the whole memory space; `\"app\"` one app (`app_id`); `\"project\"` one project of one app (`app_id` + `project_id`). - Confirm with `POST /purge/confirm` before `expires_at` (5 minutes). The nonce is single use and only valid for the same memory space and API key. What is deleted: memories, sessions, messages, memory cells, feedback, events and (space scope only) senders and knowledge bases (`/api/v2/knowledge_bases`: categories, documents, topics), from every index. Left in object storage, no longer reachable through the API: files uploaded through `/object/sign`, and (space scope) the stored text of knowledge base topics. :param purge_request_input: (required) :type purge_request_input: PurgeRequestInput @@ -3254,7 +3254,7 @@ def retrieve_context( ) -> SuccessEnvelopeSearchData: """Context Retrieval [Cloud-only] - Retrieve memories with a multi-round, LLM-driven search loop. An LLM plans and runs several searches over the owner's memories — keyword, semantic, hybrid, topic-cluster, and reading the surrounding conversation or a whole session — and keeps searching until it judges the evidence sufficient to answer `query`. The memories it found are returned. **The response contains memories, not an answer**: the model's own answer is discarded. Use it for questions a single search answers poorly: multi-hop, temporal, or spread across several conversations. For simple lookups, `/search` is faster and cheaper. **Request** — the same body as `/search`, except: - `method` is fixed to `\"context\"`. It can be omitted; any other value is a 422. - `min_score` is not supported (422): results are ranked by rank fusion, not by a similarity score. - `radius`, `enable_llm_rerank` and `with_readable_episode` are not accepted (422): the loop does not use them. **Response** — the same `SearchData` shape as `/search`: - The loop returns its memories in `episodes`, for a `user_id` owner only; for an `agent_id` owner `episodes`, `agent_cases` and `agent_skills` are empty. `profiles` (`include_profile`) and `unprocessed_messages` (a top-level `session_id` filter) are filled exactly as on `/search`. - `episodes[].cited` is `true` for memories the model named as the ones its answer rested on. - `episodes[].score` is a rank-fusion score, not a similarity: roughly 0.01–0.05, plus 1.0 for a cited memory, so cited memories come first. It is not comparable with `/search` scores. **Limits** — by default at most 5 LLM rounds and 45 seconds per request. Reaching a limit is not an error: the memories found so far are returned. **Latency** — several LLM calls per request, so noticeably slower than `/search`. + Retrieve memories with a multi-round, LLM-driven search loop. An LLM plans and runs several searches over the owner's memories — keyword, semantic, hybrid, topic-cluster, and reading the surrounding conversation or a whole session — and keeps searching until it judges the evidence sufficient to answer `query`. The memories it found are returned. **The response contains memories, not an answer**: the model's own answer is discarded. Use it for questions a single search answers poorly: multi-hop, temporal, or spread across several conversations. For simple lookups, `/search` is faster and cheaper. **Request** — the same body as `/search`, except: - `user_id` is required and `agent_id` is not accepted (422): the loop searches a user's memories only. Use `/search` for agent memories. - `method` is fixed to `\"context\"`. It can be omitted; any other value is a 422. - `min_score` is not supported (422): results are ranked by rank fusion, not by a similarity score. - `radius`, `enable_llm_rerank` and `with_readable_episode` are not accepted (422): the loop does not use them. **Response** — the same `SearchData` shape as `/search`: - The loop returns its memories in `episodes`. `profiles` (`include_profile`) and `unprocessed_messages` (a top-level `session_id` filter) are filled exactly as on `/search`. - `episodes[].cited` is `true` for memories the model named as the ones its answer rested on. - `episodes[].score` is a rank-fusion score, not a similarity: roughly 0.01–0.05, plus 1.0 for a cited memory, so cited memories come first. It is not comparable with `/search` scores. **Limits** — by default at most 5 LLM rounds and 45 seconds per request. Reaching a limit is not an error: the memories found so far are returned. **Latency** — several LLM calls per request, so noticeably slower than `/search`. :param context_input: (required) :type context_input: ContextInput @@ -3326,7 +3326,7 @@ def retrieve_context_with_http_info( ) -> ApiResponse[SuccessEnvelopeSearchData]: """Context Retrieval [Cloud-only] - Retrieve memories with a multi-round, LLM-driven search loop. An LLM plans and runs several searches over the owner's memories — keyword, semantic, hybrid, topic-cluster, and reading the surrounding conversation or a whole session — and keeps searching until it judges the evidence sufficient to answer `query`. The memories it found are returned. **The response contains memories, not an answer**: the model's own answer is discarded. Use it for questions a single search answers poorly: multi-hop, temporal, or spread across several conversations. For simple lookups, `/search` is faster and cheaper. **Request** — the same body as `/search`, except: - `method` is fixed to `\"context\"`. It can be omitted; any other value is a 422. - `min_score` is not supported (422): results are ranked by rank fusion, not by a similarity score. - `radius`, `enable_llm_rerank` and `with_readable_episode` are not accepted (422): the loop does not use them. **Response** — the same `SearchData` shape as `/search`: - The loop returns its memories in `episodes`, for a `user_id` owner only; for an `agent_id` owner `episodes`, `agent_cases` and `agent_skills` are empty. `profiles` (`include_profile`) and `unprocessed_messages` (a top-level `session_id` filter) are filled exactly as on `/search`. - `episodes[].cited` is `true` for memories the model named as the ones its answer rested on. - `episodes[].score` is a rank-fusion score, not a similarity: roughly 0.01–0.05, plus 1.0 for a cited memory, so cited memories come first. It is not comparable with `/search` scores. **Limits** — by default at most 5 LLM rounds and 45 seconds per request. Reaching a limit is not an error: the memories found so far are returned. **Latency** — several LLM calls per request, so noticeably slower than `/search`. + Retrieve memories with a multi-round, LLM-driven search loop. An LLM plans and runs several searches over the owner's memories — keyword, semantic, hybrid, topic-cluster, and reading the surrounding conversation or a whole session — and keeps searching until it judges the evidence sufficient to answer `query`. The memories it found are returned. **The response contains memories, not an answer**: the model's own answer is discarded. Use it for questions a single search answers poorly: multi-hop, temporal, or spread across several conversations. For simple lookups, `/search` is faster and cheaper. **Request** — the same body as `/search`, except: - `user_id` is required and `agent_id` is not accepted (422): the loop searches a user's memories only. Use `/search` for agent memories. - `method` is fixed to `\"context\"`. It can be omitted; any other value is a 422. - `min_score` is not supported (422): results are ranked by rank fusion, not by a similarity score. - `radius`, `enable_llm_rerank` and `with_readable_episode` are not accepted (422): the loop does not use them. **Response** — the same `SearchData` shape as `/search`: - The loop returns its memories in `episodes`. `profiles` (`include_profile`) and `unprocessed_messages` (a top-level `session_id` filter) are filled exactly as on `/search`. - `episodes[].cited` is `true` for memories the model named as the ones its answer rested on. - `episodes[].score` is a rank-fusion score, not a similarity: roughly 0.01–0.05, plus 1.0 for a cited memory, so cited memories come first. It is not comparable with `/search` scores. **Limits** — by default at most 5 LLM rounds and 45 seconds per request. Reaching a limit is not an error: the memories found so far are returned. **Latency** — several LLM calls per request, so noticeably slower than `/search`. :param context_input: (required) :type context_input: ContextInput @@ -3398,7 +3398,7 @@ def retrieve_context_without_preload_content( ) -> RESTResponseType: """Context Retrieval [Cloud-only] - Retrieve memories with a multi-round, LLM-driven search loop. An LLM plans and runs several searches over the owner's memories — keyword, semantic, hybrid, topic-cluster, and reading the surrounding conversation or a whole session — and keeps searching until it judges the evidence sufficient to answer `query`. The memories it found are returned. **The response contains memories, not an answer**: the model's own answer is discarded. Use it for questions a single search answers poorly: multi-hop, temporal, or spread across several conversations. For simple lookups, `/search` is faster and cheaper. **Request** — the same body as `/search`, except: - `method` is fixed to `\"context\"`. It can be omitted; any other value is a 422. - `min_score` is not supported (422): results are ranked by rank fusion, not by a similarity score. - `radius`, `enable_llm_rerank` and `with_readable_episode` are not accepted (422): the loop does not use them. **Response** — the same `SearchData` shape as `/search`: - The loop returns its memories in `episodes`, for a `user_id` owner only; for an `agent_id` owner `episodes`, `agent_cases` and `agent_skills` are empty. `profiles` (`include_profile`) and `unprocessed_messages` (a top-level `session_id` filter) are filled exactly as on `/search`. - `episodes[].cited` is `true` for memories the model named as the ones its answer rested on. - `episodes[].score` is a rank-fusion score, not a similarity: roughly 0.01–0.05, plus 1.0 for a cited memory, so cited memories come first. It is not comparable with `/search` scores. **Limits** — by default at most 5 LLM rounds and 45 seconds per request. Reaching a limit is not an error: the memories found so far are returned. **Latency** — several LLM calls per request, so noticeably slower than `/search`. + Retrieve memories with a multi-round, LLM-driven search loop. An LLM plans and runs several searches over the owner's memories — keyword, semantic, hybrid, topic-cluster, and reading the surrounding conversation or a whole session — and keeps searching until it judges the evidence sufficient to answer `query`. The memories it found are returned. **The response contains memories, not an answer**: the model's own answer is discarded. Use it for questions a single search answers poorly: multi-hop, temporal, or spread across several conversations. For simple lookups, `/search` is faster and cheaper. **Request** — the same body as `/search`, except: - `user_id` is required and `agent_id` is not accepted (422): the loop searches a user's memories only. Use `/search` for agent memories. - `method` is fixed to `\"context\"`. It can be omitted; any other value is a 422. - `min_score` is not supported (422): results are ranked by rank fusion, not by a similarity score. - `radius`, `enable_llm_rerank` and `with_readable_episode` are not accepted (422): the loop does not use them. **Response** — the same `SearchData` shape as `/search`: - The loop returns its memories in `episodes`. `profiles` (`include_profile`) and `unprocessed_messages` (a top-level `session_id` filter) are filled exactly as on `/search`. - `episodes[].cited` is `true` for memories the model named as the ones its answer rested on. - `episodes[].score` is a rank-fusion score, not a similarity: roughly 0.01–0.05, plus 1.0 for a cited memory, so cited memories come first. It is not comparable with `/search` scores. **Limits** — by default at most 5 LLM rounds and 45 seconds per request. Reaching a limit is not an error: the memories found so far are returned. **Latency** — several LLM calls per request, so noticeably slower than `/search`. :param context_input: (required) :type context_input: ContextInput diff --git a/everos_cloud/api_client.py b/everos_cloud/api_client.py index 836876a..269cc44 100644 --- a/everos_cloud/api_client.py +++ b/everos_cloud/api_client.py @@ -91,7 +91,7 @@ def __init__( self.default_headers[header_name] = header_value self.cookie = cookie # Set default User-Agent. - self.user_agent = 'OpenAPI-Generator/1.3.0-rc2/python' + self.user_agent = 'OpenAPI-Generator/1.3.0-rc3/python' self.client_side_validation = configuration.client_side_validation def __enter__(self): diff --git a/everos_cloud/configuration.py b/everos_cloud/configuration.py index 42720d0..3fc0045 100644 --- a/everos_cloud/configuration.py +++ b/everos_cloud/configuration.py @@ -504,7 +504,7 @@ def to_debug_report(self) -> str: "OS: {env}\n"\ "Python Version: {pyversion}\n"\ "Version of the API: 2.0.0\n"\ - "SDK Package Version: 1.3.0-rc2".\ + "SDK Package Version: 1.3.0-rc3".\ format(env=sys.platform, pyversion=sys.version) def get_host_settings(self) -> List[HostSetting]: diff --git a/everos_cloud/models/context_input.py b/everos_cloud/models/context_input.py index 5a13c36..bcd66b2 100644 --- a/everos_cloud/models/context_input.py +++ b/everos_cloud/models/context_input.py @@ -27,12 +27,11 @@ class ContextInput(BaseModel): """ - Request body of `POST /api/v2/memory/context`. The same fields as the `/search` request, except that `method` is fixed to `\"context\"`, `min_score` is not supported, and `radius`, `enable_llm_rerank` and `with_readable_episode` are not accepted. + Request body of `POST /api/v2/memory/context`. The same fields as the `/search` request, except that `user_id` is required and `agent_id` is not accepted (user memories only), `method` is fixed to `\"context\"`, `min_score` is not supported, and `radius`, `enable_llm_rerank` and `with_readable_episode` are not accepted. """ # noqa: E501 app_id: Optional[Annotated[str, Field(strict=True, max_length=128)]] = Field(default='default', description="Scope to search in, defaulting to \"default\". Must match the pair used on write.") project_id: Optional[Annotated[str, Field(strict=True, max_length=128)]] = Field(default='default', description="Second half of the scope, defaulting to \"default\".") - user_id: Optional[Annotated[str, Field(min_length=1, strict=True, max_length=256)]] = None - agent_id: Optional[Annotated[str, Field(min_length=1, strict=True, max_length=256)]] = None + user_id: Annotated[str, Field(min_length=1, strict=True, max_length=256)] = Field(description="Required. The user whose memories are searched — matched against the messages' `sender_id`. `agent_id` is not accepted here (422); use /search for agent memories.") query: Annotated[str, Field(min_length=1, strict=True)] = Field(description="The question to retrieve for. The loop keeps searching until it judges the evidence sufficient to answer it, so pass the whole question, not keywords.") method: Optional[StrictStr] = Field(default='context', description="Fixed to `\"context\"`; may be omitted. Any other value is a 422.") top_k: Optional[StrictInt] = Field(default=-1, description="Maximum number of episodes returned. Either -1 (the default, letting the engine decide) or a value from 1 to 100; anything else is rejected with 422.") @@ -40,7 +39,7 @@ class ContextInput(BaseModel): include_profile: Optional[StrictBool] = Field(default=False, description="Also return the user's profile alongside the episodes, as on /search.") filters: Optional[FilterNode] = None additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["app_id", "project_id", "user_id", "agent_id", "query", "method", "top_k", "min_score", "include_profile", "filters"] + __properties: ClassVar[List[str]] = ["app_id", "project_id", "user_id", "query", "method", "top_k", "min_score", "include_profile", "filters"] @field_validator('method') def method_validate_enum(cls, value): @@ -101,16 +100,6 @@ def to_dict(self) -> Dict[str, Any]: for _key, _value in self.additional_properties.items(): _dict[_key] = _value - # set to None if user_id (nullable) is None - # and model_fields_set contains the field - if self.user_id is None and "user_id" in self.model_fields_set: - _dict['user_id'] = None - - # set to None if agent_id (nullable) is None - # and model_fields_set contains the field - if self.agent_id is None and "agent_id" in self.model_fields_set: - _dict['agent_id'] = None - # set to None if min_score (nullable) is None # and model_fields_set contains the field if self.min_score is None and "min_score" in self.model_fields_set: @@ -136,7 +125,6 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: "app_id": obj.get("app_id") if obj.get("app_id") is not None else 'default', "project_id": obj.get("project_id") if obj.get("project_id") is not None else 'default', "user_id": obj.get("user_id"), - "agent_id": obj.get("agent_id"), "query": obj.get("query"), "method": obj.get("method") if obj.get("method") is not None else 'context', "top_k": obj.get("top_k") if obj.get("top_k") is not None else -1, diff --git a/openapi.json b/openapi.json index 44c8542..a61ddae 100644 --- a/openapi.json +++ b/openapi.json @@ -113,7 +113,7 @@ "Memory" ], "summary": "Context Retrieval [Cloud-only]", - "description": "Retrieve memories with a multi-round, LLM-driven search loop.\n\nAn LLM plans and runs several searches over the owner's memories \u2014 keyword, semantic, hybrid, topic-cluster, and reading the surrounding conversation or a whole session \u2014 and keeps searching until it judges the evidence sufficient to answer `query`. The memories it found are returned. **The response contains memories, not an answer**: the model's own answer is discarded.\n\nUse it for questions a single search answers poorly: multi-hop, temporal, or spread across several conversations. For simple lookups, `/search` is faster and cheaper.\n\n**Request** \u2014 the same body as `/search`, except:\n- `method` is fixed to `\"context\"`. It can be omitted; any other value is a 422.\n- `min_score` is not supported (422): results are ranked by rank fusion, not by a similarity score.\n- `radius`, `enable_llm_rerank` and `with_readable_episode` are not accepted (422): the loop does not use them.\n\n**Response** \u2014 the same `SearchData` shape as `/search`:\n- The loop returns its memories in `episodes`, for a `user_id` owner only; for an `agent_id` owner `episodes`, `agent_cases` and `agent_skills` are empty. `profiles` (`include_profile`) and `unprocessed_messages` (a top-level `session_id` filter) are filled exactly as on `/search`.\n- `episodes[].cited` is `true` for memories the model named as the ones its answer rested on.\n- `episodes[].score` is a rank-fusion score, not a similarity: roughly 0.01\u20130.05, plus 1.0 for a cited memory, so cited memories come first. It is not comparable with `/search` scores.\n\n**Limits** \u2014 by default at most 5 LLM rounds and 45 seconds per request. Reaching a limit is not an error: the memories found so far are returned.\n\n**Latency** \u2014 several LLM calls per request, so noticeably slower than `/search`.", + "description": "Retrieve memories with a multi-round, LLM-driven search loop.\n\nAn LLM plans and runs several searches over the owner's memories \u2014 keyword, semantic, hybrid, topic-cluster, and reading the surrounding conversation or a whole session \u2014 and keeps searching until it judges the evidence sufficient to answer `query`. The memories it found are returned. **The response contains memories, not an answer**: the model's own answer is discarded.\n\nUse it for questions a single search answers poorly: multi-hop, temporal, or spread across several conversations. For simple lookups, `/search` is faster and cheaper.\n\n**Request** \u2014 the same body as `/search`, except:\n- `user_id` is required and `agent_id` is not accepted (422): the loop searches a user's memories only. Use `/search` for agent memories.\n- `method` is fixed to `\"context\"`. It can be omitted; any other value is a 422.\n- `min_score` is not supported (422): results are ranked by rank fusion, not by a similarity score.\n- `radius`, `enable_llm_rerank` and `with_readable_episode` are not accepted (422): the loop does not use them.\n\n**Response** \u2014 the same `SearchData` shape as `/search`:\n- The loop returns its memories in `episodes`. `profiles` (`include_profile`) and `unprocessed_messages` (a top-level `session_id` filter) are filled exactly as on `/search`.\n- `episodes[].cited` is `true` for memories the model named as the ones its answer rested on.\n- `episodes[].score` is a rank-fusion score, not a similarity: roughly 0.01\u20130.05, plus 1.0 for a cited memory, so cited memories come first. It is not comparable with `/search` scores.\n\n**Limits** \u2014 by default at most 5 LLM rounds and 45 seconds per request. Reaching a limit is not an error: the memories found so far are returned.\n\n**Latency** \u2014 several LLM calls per request, so noticeably slower than `/search`.", "operationId": "retrieveContext", "requestBody": { "content": { @@ -769,7 +769,7 @@ "Memory" ], "summary": "Request a memory-space purge (step 1 of 2) [Cloud-only]", - "description": "**Permanent \u2014 there is no undo.** Step 1 of 2: asks for a purge and returns a `nonce`. Nothing is deleted yet.\n\n- `scope: \"space\"` purges the whole memory space; `\"app\"` one app (`app_id`); `\"project\"` one project of one app (`app_id` + `project_id`).\n- Confirm with `POST /purge/confirm` before `expires_at` (5 minutes). The nonce is single use and only valid for the same memory space and API key.\n\nWhat is deleted: memories, sessions, messages, memory cells, feedback, events and (space scope only) senders and engine knowledge bases, from every index. Not deleted: files uploaded through `/object/sign`, and data of the separate knowledge-base service.", + "description": "**Permanent \u2014 there is no undo.** Step 1 of 2: asks for a purge and returns a `nonce`. Nothing is deleted yet.\n\n- `scope: \"space\"` purges the whole memory space; `\"app\"` one app (`app_id`); `\"project\"` one project of one app (`app_id` + `project_id`).\n- Confirm with `POST /purge/confirm` before `expires_at` (5 minutes). The nonce is single use and only valid for the same memory space and API key.\n\nWhat is deleted: memories, sessions, messages, memory cells, feedback, events and (space scope only) senders and knowledge bases (`/api/v2/knowledge_bases`: categories, documents, topics), from every index. Left in object storage, no longer reachable through the API: files uploaded through `/object/sign`, and (space scope) the stored text of knowledge base topics.", "operationId": "requestPurge", "requestBody": { "content": { @@ -4398,32 +4398,11 @@ "description": "Second half of the scope, defaulting to \"default\"." }, "user_id": { - "anyOf": [ - { - "type": "string", - "maxLength": 256, - "minLength": 1 - }, - { - "type": "null" - } - ], + "type": "string", + "maxLength": 256, + "minLength": 1, "title": "User Id", - "description": "Search one user's memories \u2014 matched against the messages' `sender_id`. Exactly one of `user_id` / `agent_id` is required, and only a user owner gets episodes back." - }, - "agent_id": { - "anyOf": [ - { - "type": "string", - "maxLength": 256, - "minLength": 1 - }, - { - "type": "null" - } - ], - "title": "Agent Id", - "description": "Accepted for symmetry with /search, but the loop retrieves user episodes only: with an agent owner every result collection is empty." + "description": "Required. The user whose memories are searched \u2014 matched against the messages' `sender_id`. `agent_id` is not accepted here (422); use /search for agent memories." }, "query": { "type": "string", @@ -4479,10 +4458,11 @@ "additionalProperties": false, "type": "object", "required": [ + "user_id", "query" ], "title": "ContextInput", - "description": "Request body of `POST /api/v2/memory/context`.\n\nThe same fields as the `/search` request, except that `method` is fixed to\n`\"context\"`, `min_score` is not supported, and `radius`, `enable_llm_rerank` and\n`with_readable_episode` are not accepted." + "description": "Request body of `POST /api/v2/memory/context`.\n\nThe same fields as the `/search` request, except that `user_id` is required and\n`agent_id` is not accepted (user memories only), `method` is fixed to `\"context\"`,\n`min_score` is not supported, and `radius`, `enable_llm_rerank` and\n`with_readable_episode` are not accepted." }, "DeleteByIdsData": { "properties": { diff --git a/pyproject.toml b/pyproject.toml index cece329..3797a46 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "everos_cloud" -version = "1.3.0-rc2" +version = "1.3.0-rc3" description = "EverOS Cloud Memory API" authors = ["EverMind AI "] license = "Apache-2.0" diff --git a/setup.py b/setup.py index 2661eed..56d5df0 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ # prerequisite: setuptools # http://pypi.python.org/pypi/setuptools NAME = "everos-cloud" -VERSION = "1.3.0-rc2" +VERSION = "1.3.0-rc3" # Floor = the oldest interpreter CI actually runs (see .github/workflows/ci.yml in # the public repo). Nothing in the generated code needs it this high — the tree # parses as 3.8 — so this is a support policy, not a technical bound, and it is set diff --git a/test/test_context_input.py b/test/test_context_input.py index 008b7d2..5ca60b3 100644 --- a/test/test_context_input.py +++ b/test/test_context_input.py @@ -39,7 +39,6 @@ def make_instance(self, include_optional) -> ContextInput: app_id = 'default', project_id = 'default', user_id = '0', - agent_id = '0', query = '0', method = 'context', top_k = 56, @@ -49,6 +48,7 @@ def make_instance(self, include_optional) -> ContextInput: ) else: return ContextInput( + user_id = '0', query = '0', ) """