From b3cec23fc58a05d7e645974f6183dda9a3ee0f26 Mon Sep 17 00:00:00 2001 From: everos-sdk-factory Date: Fri, 4 Sep 2026 19:22:36 +0000 Subject: [PATCH] chore(sdk): generate 1.1.0 from contract 2.0.0 Sources: memory-engine@release-20260901_v5 multimodal-storage@release-20260729_v1 gateway-tasks@evermemos-gateway_release-20260901_v1 --- .openapi-generator/FILES | 42 + docs/AddData.md | 2 +- docs/AddInput.md | 8 +- docs/AddOperation.md | 4 +- docs/AgentCaseItem.md | 18 +- docs/AgentSkillItem.md | 22 +- docs/AtomicFactItem.md | 4 +- docs/CategoryData.md | 6 +- docs/CategoryListData.md | 2 +- docs/Content.md | 1 + docs/Content1.md | 29 + docs/ContentItem.md | 2 +- docs/Data.md | 7 +- docs/Data1.md | 1 + docs/DeleteInput.md | 4 +- docs/DeleteOperation.md | 6 +- docs/DocData.md | 7 +- docs/DocIngestBody.md | 2 +- docs/DocListData.md | 4 +- docs/DocPatchData.md | 4 +- docs/DocumentContext.md | 4 +- docs/EditData.md | 10 +- docs/EditInput.md | 10 +- docs/EditInputOperationsInner.md | 6 +- docs/EditResultItem.md | 8 +- docs/Envelope.md | 2 +- docs/EnvelopeResult.md | 1 + docs/EpisodeItem.md | 22 +- docs/ErrorBody.md | 31 + docs/ErrorEnvelope.md | 31 + docs/ExplicitInfoData.md | 4 +- docs/FlushData.md | 2 +- docs/FlushInput.md | 6 +- docs/GetData.md | 12 +- docs/GetInput.md | 16 +- docs/HTTPValidationError.md | 2 +- docs/ImplicitTraitData.md | 4 +- docs/KbData.md | 6 +- docs/KbListData.md | 4 +- docs/KbSearchData.md | 6 +- docs/KnowledgeApi.md | 308 +++ docs/MemoryApi.md | 18 + docs/MessageItem.md | 6 +- docs/ProfileItem.md | 12 +- docs/RelatedTagUsageBody.md | 30 + docs/RelatedTagUsageItem.md | 31 + docs/RelatedTagUsageListData.md | 31 + docs/SearchAgentCaseItem.md | 20 +- docs/SearchAgentSkillItem.md | 24 +- docs/SearchAtomicFactItem.md | 6 +- docs/SearchBody.md | 12 +- docs/SearchData.md | 10 +- docs/SearchEpisodeItem.md | 24 +- docs/SearchFilters.md | 1 + docs/SearchHit.md | 24 +- docs/SearchInput.md | 16 +- docs/SearchProfileItem.md | 12 +- docs/SignEnvelope.md | 2 +- docs/SignObjectItem.md | 4 +- docs/SignResponse.md | 2 +- docs/SignResponseItem.md | 10 +- docs/SignedInfo.md | 4 +- docs/StorageApi.md | 2 + .../SuccessEnvelopeRelatedTagUsageListData.md | 30 + docs/SuccessEnvelopeTopicFilterListData.md | 30 + docs/SuccessEnvelopeTopicTagWriteData.md | 30 + docs/TagBindData.md | 4 +- docs/TagBindInput.md | 6 +- docs/TagRef.md | 31 + docs/TagReplaceData.md | 4 +- docs/TagReplaceInput.md | 6 +- docs/TagUnbindData.md | 4 +- docs/TagUnbindInput.md | 6 +- docs/TaskErrorResponseError.md | 1 + docs/TaskItem.md | 8 +- docs/TaskListResponse.md | 2 +- docs/TaskListResponseData.md | 1 + docs/TaskStatsResponse.md | 2 +- docs/TaskStatsResponseData.md | 1 + docs/TaskStatusResponse.md | 4 +- docs/TasksApi.md | 2 +- docs/ToolCall.md | 6 +- docs/ToolCallFunction.md | 4 +- docs/TopicDetailData.md | 25 +- docs/TopicFilterItem.md | 40 + docs/TopicFilterListData.md | 30 + docs/TopicListData.md | 2 +- docs/TopicListItem.md | 4 + docs/TopicTagReplaceBody.md | 30 + docs/TopicTagWriteData.md | 35 + docs/UnprocessedMessageDTO.md | 16 +- docs/UpdateOperation.md | 6 +- docs/ValidationError.md | 6 +- everos_cloud/__init__.py | 16 +- everos_cloud/api/knowledge_api.py | 1181 ++++++++- everos_cloud/api/memory_api.py | 27 + everos_cloud/api/storage_api.py | 3 + everos_cloud/api/tasks_api.py | 6 +- everos_cloud/api_client.py | 2 +- everos_cloud/configuration.py | 2 +- everos_cloud/models/__init__.py | 14 + everos_cloud/models/add_data.py | 2 +- everos_cloud/models/add_input.py | 8 +- everos_cloud/models/add_operation.py | 4 +- everos_cloud/models/agent_case_item.py | 20 +- everos_cloud/models/agent_skill_item.py | 41 +- everos_cloud/models/atomic_fact_item.py | 6 +- everos_cloud/models/category_data.py | 6 +- everos_cloud/models/category_list_data.py | 4 +- everos_cloud/models/content.py | 2 +- everos_cloud/models/content1.py | 140 + everos_cloud/models/content_item.py | 2 +- everos_cloud/models/data.py | 2 +- everos_cloud/models/data1.py | 2 +- everos_cloud/models/delete_input.py | 4 +- everos_cloud/models/delete_operation.py | 6 +- everos_cloud/models/doc_data.py | 18 +- everos_cloud/models/doc_ingest_body.py | 2 +- everos_cloud/models/doc_list_data.py | 6 +- everos_cloud/models/doc_patch_data.py | 6 +- everos_cloud/models/document_context.py | 6 +- everos_cloud/models/edit_data.py | 12 +- everos_cloud/models/edit_input.py | 10 +- everos_cloud/models/edit_result_item.py | 10 +- everos_cloud/models/envelope.py | 2 +- everos_cloud/models/envelope_result.py | 2 +- everos_cloud/models/episode_item.py | 24 +- everos_cloud/models/error_body.py | 103 + everos_cloud/models/error_envelope.py | 107 + everos_cloud/models/explicit_info_data.py | 4 +- everos_cloud/models/flush_data.py | 4 +- everos_cloud/models/flush_input.py | 6 +- everos_cloud/models/get_data.py | 14 +- everos_cloud/models/get_input.py | 16 +- everos_cloud/models/http_validation_error.py | 4 +- everos_cloud/models/implicit_trait_data.py | 4 +- everos_cloud/models/kb_data.py | 6 +- everos_cloud/models/kb_list_data.py | 6 +- everos_cloud/models/kb_search_data.py | 14 +- everos_cloud/models/message_item.py | 8 +- everos_cloud/models/profile_item.py | 31 +- everos_cloud/models/related_tag_usage_body.py | 102 + everos_cloud/models/related_tag_usage_item.py | 104 + .../models/related_tag_usage_list_data.py | 112 + everos_cloud/models/search_agent_case_item.py | 22 +- .../models/search_agent_skill_item.py | 41 +- .../models/search_atomic_fact_item.py | 8 +- everos_cloud/models/search_body.py | 19 +- everos_cloud/models/search_data.py | 12 +- everos_cloud/models/search_episode_item.py | 26 +- everos_cloud/models/search_filters.py | 9 +- everos_cloud/models/search_hit.py | 75 +- everos_cloud/models/search_input.py | 16 +- everos_cloud/models/search_profile_item.py | 29 +- everos_cloud/models/sign_envelope.py | 2 +- everos_cloud/models/sign_object_item.py | 4 +- everos_cloud/models/sign_response.py | 2 +- everos_cloud/models/sign_response_item.py | 10 +- everos_cloud/models/signed_info.py | 4 +- ...ss_envelope_related_tag_usage_list_data.py | 107 + ...success_envelope_topic_filter_list_data.py | 107 + .../success_envelope_topic_tag_write_data.py | 107 + everos_cloud/models/tag_bind_data.py | 6 +- everos_cloud/models/tag_bind_input.py | 6 +- everos_cloud/models/tag_ref.py | 108 + everos_cloud/models/tag_replace_data.py | 6 +- everos_cloud/models/tag_replace_input.py | 6 +- everos_cloud/models/tag_unbind_data.py | 6 +- everos_cloud/models/tag_unbind_input.py | 6 +- .../models/task_error_response_error.py | 2 +- everos_cloud/models/task_item.py | 8 +- everos_cloud/models/task_list_response.py | 4 +- .../models/task_list_response_data.py | 2 +- everos_cloud/models/task_stats_response.py | 4 +- .../models/task_stats_response_data.py | 2 +- everos_cloud/models/task_status_response.py | 6 +- everos_cloud/models/tool_call.py | 8 +- everos_cloud/models/tool_call_function.py | 6 +- everos_cloud/models/topic_detail_data.py | 40 +- everos_cloud/models/topic_filter_item.py | 137 + everos_cloud/models/topic_filter_list_data.py | 112 + everos_cloud/models/topic_list_data.py | 4 +- everos_cloud/models/topic_list_item.py | 11 +- everos_cloud/models/topic_tag_replace_body.py | 104 + everos_cloud/models/topic_tag_write_data.py | 121 + .../models/unprocessed_message_dto.py | 22 +- everos_cloud/models/update_operation.py | 6 +- everos_cloud/models/validation_error.py | 8 +- openapi.json | 2361 +++++++++++++---- pyproject.toml | 2 +- setup.py | 14 +- test/test_agent_skill_item.py | 4 +- test/test_content1.py | 51 + test/test_doc_data.py | 6 + test/test_doc_list_data.py | 3 + test/test_error_body.py | 55 + test/test_error_envelope.py | 59 + test/test_get_data.py | 8 +- test/test_kb_search_data.py | 34 +- test/test_knowledge_api.py | 21 + test/test_profile_item.py | 4 +- test/test_related_tag_usage_body.py | 57 + test/test_related_tag_usage_item.py | 55 + test/test_related_tag_usage_list_data.py | 59 + test/test_search_agent_skill_item.py | 2 + test/test_search_body.py | 7 +- test/test_search_data.py | 4 + test/test_search_filters.py | 5 +- test/test_search_hit.py | 15 +- test/test_search_profile_item.py | 2 + test/test_success_envelope_doc_data.py | 6 + test/test_success_envelope_doc_list_data.py | 6 + test/test_success_envelope_get_data.py | 16 +- test/test_success_envelope_kb_search_data.py | 16 +- ...ss_envelope_related_tag_usage_list_data.py | 55 + test/test_success_envelope_search_data.py | 8 + ...test_success_envelope_topic_detail_data.py | 10 + ...success_envelope_topic_filter_list_data.py | 55 + test/test_success_envelope_topic_list_data.py | 12 + ...t_success_envelope_topic_tag_write_data.py | 55 + test/test_tag_ref.py | 54 + test/test_topic_detail_data.py | 10 + test/test_topic_filter_item.py | 70 + test/test_topic_filter_list_data.py | 59 + test/test_topic_list_data.py | 6 + test/test_topic_list_item.py | 6 + test/test_topic_tag_replace_body.py | 59 + test/test_topic_tag_write_data.py | 69 + 228 files changed, 7182 insertions(+), 1159 deletions(-) create mode 100644 docs/Content1.md create mode 100644 docs/ErrorBody.md create mode 100644 docs/ErrorEnvelope.md create mode 100644 docs/RelatedTagUsageBody.md create mode 100644 docs/RelatedTagUsageItem.md create mode 100644 docs/RelatedTagUsageListData.md create mode 100644 docs/SuccessEnvelopeRelatedTagUsageListData.md create mode 100644 docs/SuccessEnvelopeTopicFilterListData.md create mode 100644 docs/SuccessEnvelopeTopicTagWriteData.md create mode 100644 docs/TagRef.md create mode 100644 docs/TopicFilterItem.md create mode 100644 docs/TopicFilterListData.md create mode 100644 docs/TopicTagReplaceBody.md create mode 100644 docs/TopicTagWriteData.md create mode 100644 everos_cloud/models/content1.py create mode 100644 everos_cloud/models/error_body.py create mode 100644 everos_cloud/models/error_envelope.py create mode 100644 everos_cloud/models/related_tag_usage_body.py create mode 100644 everos_cloud/models/related_tag_usage_item.py create mode 100644 everos_cloud/models/related_tag_usage_list_data.py create mode 100644 everos_cloud/models/success_envelope_related_tag_usage_list_data.py create mode 100644 everos_cloud/models/success_envelope_topic_filter_list_data.py create mode 100644 everos_cloud/models/success_envelope_topic_tag_write_data.py create mode 100644 everos_cloud/models/tag_ref.py create mode 100644 everos_cloud/models/topic_filter_item.py create mode 100644 everos_cloud/models/topic_filter_list_data.py create mode 100644 everos_cloud/models/topic_tag_replace_body.py create mode 100644 everos_cloud/models/topic_tag_write_data.py create mode 100644 test/test_content1.py create mode 100644 test/test_error_body.py create mode 100644 test/test_error_envelope.py create mode 100644 test/test_related_tag_usage_body.py create mode 100644 test/test_related_tag_usage_item.py create mode 100644 test/test_related_tag_usage_list_data.py create mode 100644 test/test_success_envelope_related_tag_usage_list_data.py create mode 100644 test/test_success_envelope_topic_filter_list_data.py create mode 100644 test/test_success_envelope_topic_tag_write_data.py create mode 100644 test/test_tag_ref.py create mode 100644 test/test_topic_filter_item.py create mode 100644 test/test_topic_filter_list_data.py create mode 100644 test/test_topic_tag_replace_body.py create mode 100644 test/test_topic_tag_write_data.py diff --git a/.openapi-generator/FILES b/.openapi-generator/FILES index e6f3744..b4f97ce 100644 --- a/.openapi-generator/FILES +++ b/.openapi-generator/FILES @@ -12,6 +12,7 @@ docs/CategoryDeleteData.md docs/CategoryListData.md docs/CategoryPatchBody.md docs/Content.md +docs/Content1.md docs/ContentItem.md docs/Data.md docs/Data1.md @@ -33,6 +34,8 @@ docs/EditResultItem.md docs/Envelope.md docs/EnvelopeResult.md docs/EpisodeItem.md +docs/ErrorBody.md +docs/ErrorEnvelope.md docs/ExplicitInfoData.md docs/ExplicitInfoPatch.md docs/FilterNode.md @@ -53,6 +56,9 @@ docs/KnowledgeApi.md docs/MemoryApi.md docs/MessageItem.md docs/ProfileItem.md +docs/RelatedTagUsageBody.md +docs/RelatedTagUsageItem.md +docs/RelatedTagUsageListData.md docs/SearchAgentCaseItem.md docs/SearchAgentSkillItem.md docs/SearchAtomicFactItem.md @@ -88,14 +94,18 @@ docs/SuccessEnvelopeKbData.md docs/SuccessEnvelopeKbDeleteData.md docs/SuccessEnvelopeKbListData.md docs/SuccessEnvelopeKbSearchData.md +docs/SuccessEnvelopeRelatedTagUsageListData.md docs/SuccessEnvelopeSearchData.md docs/SuccessEnvelopeTagBindData.md docs/SuccessEnvelopeTagReplaceData.md docs/SuccessEnvelopeTagUnbindData.md docs/SuccessEnvelopeTopicDetailData.md +docs/SuccessEnvelopeTopicFilterListData.md docs/SuccessEnvelopeTopicListData.md +docs/SuccessEnvelopeTopicTagWriteData.md docs/TagBindData.md docs/TagBindInput.md +docs/TagRef.md docs/TagReplaceData.md docs/TagReplaceInput.md docs/TagUnbindData.md @@ -113,8 +123,12 @@ docs/TasksApi.md docs/ToolCall.md docs/ToolCallFunction.md docs/TopicDetailData.md +docs/TopicFilterItem.md +docs/TopicFilterListData.md docs/TopicListData.md docs/TopicListItem.md +docs/TopicTagReplaceBody.md +docs/TopicTagWriteData.md docs/UnprocessedMessageDTO.md docs/UpdateOperation.md docs/ValidationError.md @@ -142,6 +156,7 @@ everos_cloud/models/category_delete_data.py everos_cloud/models/category_list_data.py everos_cloud/models/category_patch_body.py everos_cloud/models/content.py +everos_cloud/models/content1.py everos_cloud/models/content_item.py everos_cloud/models/data.py everos_cloud/models/data1.py @@ -163,6 +178,8 @@ everos_cloud/models/edit_result_item.py everos_cloud/models/envelope.py everos_cloud/models/envelope_result.py everos_cloud/models/episode_item.py +everos_cloud/models/error_body.py +everos_cloud/models/error_envelope.py everos_cloud/models/explicit_info_data.py everos_cloud/models/explicit_info_patch.py everos_cloud/models/filter_node.py @@ -181,6 +198,9 @@ everos_cloud/models/kb_patch_body.py everos_cloud/models/kb_search_data.py everos_cloud/models/message_item.py everos_cloud/models/profile_item.py +everos_cloud/models/related_tag_usage_body.py +everos_cloud/models/related_tag_usage_item.py +everos_cloud/models/related_tag_usage_list_data.py everos_cloud/models/search_agent_case_item.py everos_cloud/models/search_agent_skill_item.py everos_cloud/models/search_atomic_fact_item.py @@ -215,14 +235,18 @@ everos_cloud/models/success_envelope_kb_data.py everos_cloud/models/success_envelope_kb_delete_data.py everos_cloud/models/success_envelope_kb_list_data.py everos_cloud/models/success_envelope_kb_search_data.py +everos_cloud/models/success_envelope_related_tag_usage_list_data.py everos_cloud/models/success_envelope_search_data.py everos_cloud/models/success_envelope_tag_bind_data.py everos_cloud/models/success_envelope_tag_replace_data.py everos_cloud/models/success_envelope_tag_unbind_data.py everos_cloud/models/success_envelope_topic_detail_data.py +everos_cloud/models/success_envelope_topic_filter_list_data.py everos_cloud/models/success_envelope_topic_list_data.py +everos_cloud/models/success_envelope_topic_tag_write_data.py everos_cloud/models/tag_bind_data.py everos_cloud/models/tag_bind_input.py +everos_cloud/models/tag_ref.py everos_cloud/models/tag_replace_data.py everos_cloud/models/tag_replace_input.py everos_cloud/models/tag_unbind_data.py @@ -239,8 +263,12 @@ everos_cloud/models/task_status_response.py everos_cloud/models/tool_call.py everos_cloud/models/tool_call_function.py everos_cloud/models/topic_detail_data.py +everos_cloud/models/topic_filter_item.py +everos_cloud/models/topic_filter_list_data.py everos_cloud/models/topic_list_data.py everos_cloud/models/topic_list_item.py +everos_cloud/models/topic_tag_replace_body.py +everos_cloud/models/topic_tag_write_data.py everos_cloud/models/unprocessed_message_dto.py everos_cloud/models/update_operation.py everos_cloud/models/validation_error.py @@ -265,6 +293,7 @@ test/test_category_delete_data.py test/test_category_list_data.py test/test_category_patch_body.py test/test_content.py +test/test_content1.py test/test_content_item.py test/test_data.py test/test_data1.py @@ -286,6 +315,8 @@ test/test_edit_result_item.py test/test_envelope.py test/test_envelope_result.py test/test_episode_item.py +test/test_error_body.py +test/test_error_envelope.py test/test_explicit_info_data.py test/test_explicit_info_patch.py test/test_filter_node.py @@ -306,6 +337,9 @@ test/test_knowledge_api.py test/test_memory_api.py test/test_message_item.py test/test_profile_item.py +test/test_related_tag_usage_body.py +test/test_related_tag_usage_item.py +test/test_related_tag_usage_list_data.py test/test_search_agent_case_item.py test/test_search_agent_skill_item.py test/test_search_atomic_fact_item.py @@ -341,14 +375,18 @@ test/test_success_envelope_kb_data.py test/test_success_envelope_kb_delete_data.py test/test_success_envelope_kb_list_data.py test/test_success_envelope_kb_search_data.py +test/test_success_envelope_related_tag_usage_list_data.py test/test_success_envelope_search_data.py test/test_success_envelope_tag_bind_data.py test/test_success_envelope_tag_replace_data.py test/test_success_envelope_tag_unbind_data.py test/test_success_envelope_topic_detail_data.py +test/test_success_envelope_topic_filter_list_data.py test/test_success_envelope_topic_list_data.py +test/test_success_envelope_topic_tag_write_data.py test/test_tag_bind_data.py test/test_tag_bind_input.py +test/test_tag_ref.py test/test_tag_replace_data.py test/test_tag_replace_input.py test/test_tag_unbind_data.py @@ -366,8 +404,12 @@ test/test_tasks_api.py test/test_tool_call.py test/test_tool_call_function.py test/test_topic_detail_data.py +test/test_topic_filter_item.py +test/test_topic_filter_list_data.py test/test_topic_list_data.py test/test_topic_list_item.py +test/test_topic_tag_replace_body.py +test/test_topic_tag_write_data.py test/test_unprocessed_message_dto.py test/test_update_operation.py test/test_validation_error.py diff --git a/docs/AddData.md b/docs/AddData.md index f25311b..294daf9 100644 --- a/docs/AddData.md +++ b/docs/AddData.md @@ -5,7 +5,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**message_count** | **int** | | +**message_count** | **int** | How many messages this call accepted. | **status** | **str** | \"queued\" — async enqueue accepted (HTTP 202). \"accumulated\"/\"extracted\" — synchronous write outcome (HTTP 200, async_mode=false). | ## Example diff --git a/docs/AddInput.md b/docs/AddInput.md index 0d4fac9..0d2c2a7 100644 --- a/docs/AddInput.md +++ b/docs/AddInput.md @@ -5,10 +5,10 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**app_id** | **str** | | [optional] [default to 'default'] -**project_id** | **str** | | [optional] [default to 'default'] -**session_id** | **str** | | -**messages** | [**List[MessageItem]**](MessageItem.md) | | +**app_id** | **str** | Business-semantic scope for this write, defaulting to \"default\". Reads must use the same app_id / project_id pair to see what was written under it. Note this is a partition, not the security boundary — that is the tenant resolved from your API key. | [optional] [default to 'default'] +**project_id** | **str** | Second half of the business-semantic scope, defaulting to \"default\". See `app_id`. | [optional] [default to 'default'] +**session_id** | **str** | The conversation these messages belong to (1–128 characters). It is the unit extraction works on: /api/v2/memory/flush takes this id, and a session boundary is what triggers extraction on its own. | +**messages** | [**List[MessageItem]**](MessageItem.md) | The turns to append, in order — 1 to 500 per call. Each carries its own sender and timestamp, so one call can hold a whole exchange. | **async_mode** | **bool** | Selects the write path. true (default): validated and enqueued asynchronously → HTTP 202 with status \"queued\". false: forwarded synchronously to the engine, returning its 200 result and surfacing write errors directly. Extraction is always asynchronous (flush-triggered). | [optional] [default to True] ## Example diff --git a/docs/AddOperation.md b/docs/AddOperation.md index d64580d..677b038 100644 --- a/docs/AddOperation.md +++ b/docs/AddOperation.md @@ -7,8 +7,8 @@ Add a new profile item (``item_id`` forbidden — the server mints it). Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **reason** | **str** | | [optional] -**action** | **str** | | -**type** | **str** | | +**action** | **str** | Always \"add\" for this variant. | +**type** | **str** | Which profile item this edit targets — \"explicit_info\" (a stated fact, needing `category` + `description`) or \"implicit_traits\" (an inferred trait, needing `trait` + `description`). | **data** | [**Data**](Data.md) | | ## Example diff --git a/docs/AgentCaseItem.md b/docs/AgentCaseItem.md index c247803..75d918f 100644 --- a/docs/AgentCaseItem.md +++ b/docs/AgentCaseItem.md @@ -5,16 +5,16 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**id** | **str** | | -**app_id** | **str** | | -**project_id** | **str** | | -**agent_id** | **str** | | -**session_id** | **str** | | -**task_intent** | **str** | | -**approach** | **str** | | -**quality_score** | **float** | | +**id** | **str** | Agent-case id. | +**app_id** | **str** | The business-semantic scope this case was written under. | +**project_id** | **str** | Second half of that scope. | +**agent_id** | **str** | The agent that owns this case. | +**session_id** | **str** | The session whose trajectory the case was distilled from. | +**task_intent** | **str** | What the agent was trying to do in that trajectory. | +**approach** | **str** | How it went about it — the reusable part of the case. | +**quality_score** | **float** | How good this case is judged to be. Nominally 0.0–1.0 with 0.5 as the no-opinion default, but the value is the extractor's own and nothing on the write path enforces the range — treat an out-of-range number as possible. One threshold is real: a case scoring below 0.2 is never distilled into a skill. | **key_insight** | **str** | | [optional] -**timestamp** | **datetime** | | +**timestamp** | **datetime** | When the trajectory happened (ISO 8601). | ## Example diff --git a/docs/AgentSkillItem.md b/docs/AgentSkillItem.md index ffa1287..d46fe28 100644 --- a/docs/AgentSkillItem.md +++ b/docs/AgentSkillItem.md @@ -5,16 +5,18 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**id** | **str** | | -**app_id** | **str** | | -**project_id** | **str** | | -**agent_id** | **str** | | -**name** | **str** | | -**description** | **str** | | -**content** | **str** | | -**confidence** | **float** | | -**maturity_score** | **float** | | -**source_case_ids** | **List[str]** | | [optional] +**id** | **str** | Agent-skill id. | +**app_id** | **str** | The business-semantic scope this skill was written under. | +**project_id** | **str** | Second half of that scope. | +**agent_id** | **str** | The agent that owns this skill. | +**name** | **str** | The skill's name. | +**description** | **str** | What the skill is for, in a sentence. | +**content** | **str** | The skill itself — the reusable procedure, ready to put in a prompt. | +**confidence** | **float** | How much the distillation trusts this skill. Nominally 0.0–1.0, defaulting to 0.0 before anything scores it; the range is not enforced on the write path. Nothing in retrieval filters on it today, and how it divides labour with `maturity_score` is still open — so do not build a threshold on it yet. | +**maturity_score** | **float** | How well-established the skill is. Nominally 0.0–1.0 and unenforced, and — unlike the other two scores — its default is 0.6 rather than 0.0, chosen so an unscored skill starts mid-optimistic. The cost is that an unscored 0.6 is indistinguishable from a scored 0.6: there is no \"not evaluated\" sentinel, and maturity scoring is skipped by default. Filtering near 0.6 is therefore unreliable. | +**source_case_ids** | **List[str]** | The agent cases this skill was distilled from. Fetch them for the underlying evidence. | [optional] +**created_at** | **datetime** | | [optional] +**updated_at** | **datetime** | | [optional] ## Example diff --git a/docs/AtomicFactItem.md b/docs/AtomicFactItem.md index 2b44349..f04d7cf 100644 --- a/docs/AtomicFactItem.md +++ b/docs/AtomicFactItem.md @@ -6,8 +6,8 @@ Atomic fact nested in an episode. Spec appendix E references it but does not enu Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**id** | **str** | | -**content** | **str** | | +**id** | **str** | Atomic-fact id. | +**content** | **str** | The fact itself, as a single statement. | ## Example diff --git a/docs/CategoryData.md b/docs/CategoryData.md index 496e6de..e9e3432 100644 --- a/docs/CategoryData.md +++ b/docs/CategoryData.md @@ -7,9 +7,9 @@ A category as returned to clients. ``id`` is the system-generated stable key. Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **id** | **str** | Category id (system-generated, stable) | -**name** | **str** | | -**description** | **str** | | [optional] [default to ''] -**document_count** | **int** | | [optional] [default to 0] +**name** | **str** | The category's display name. | +**description** | **str** | What belongs in this category. The classifier matches documents against this text, so it is functional, not decorative. | [optional] [default to ''] +**document_count** | **int** | How many documents are filed under it. | [optional] [default to 0] **scope** | **str** | 'kb' = user-created in this kb; 'tenant' = global preset (read-only) | [optional] [default to 'kb'] **editable** | **bool** | False for tenant-global preset categories (read-only) | [optional] [default to True] diff --git a/docs/CategoryListData.md b/docs/CategoryListData.md index 445de96..e964841 100644 --- a/docs/CategoryListData.md +++ b/docs/CategoryListData.md @@ -5,7 +5,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**categories** | [**List[CategoryData]**](CategoryData.md) | | [optional] +**categories** | [**List[CategoryData]**](CategoryData.md) | Every category available in this knowledge base — the ones created here plus the tenant-global presets. | [optional] ## Example diff --git a/docs/Content.md b/docs/Content.md index 59869ce..972f747 100644 --- a/docs/Content.md +++ b/docs/Content.md @@ -1,5 +1,6 @@ # Content +The message body: a plain string (shorthand for a single text item), or a list of content items for multimodal input. ## Properties diff --git a/docs/Content1.md b/docs/Content1.md new file mode 100644 index 0000000..ec79a0c --- /dev/null +++ b/docs/Content1.md @@ -0,0 +1,29 @@ +# Content1 + +The message body as submitted. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +## Example + +```python +from everos_cloud.models.content1 import Content1 + +# TODO update the JSON string below +json = "{}" +# create an instance of Content1 from a JSON string +content1_instance = Content1.from_json(json) +# print the JSON string representation of the object +print(Content1.to_json()) + +# convert the object into a dict +content1_dict = content1_instance.to_dict() +# create an instance of Content1 from a dict +content1_from_dict = Content1.from_dict(content1_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/docs/ContentItem.md b/docs/ContentItem.md index a555c1f..2245e14 100644 --- a/docs/ContentItem.md +++ b/docs/ContentItem.md @@ -6,7 +6,7 @@ A single content element (appendix A). Current phase: only ``type=\"text\"``. Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**type** | **str** | | +**type** | **str** | What this item is: \"text\", \"image\", \"audio\", \"doc\", \"pdf\", \"html\" or \"email\". It selects how the content is parsed, so it must match the payload. | **text** | **str** | | [optional] **source** | **str** | | [optional] **var_base64** | **str** | | [optional] diff --git a/docs/Data.md b/docs/Data.md index 668d517..2029a09 100644 --- a/docs/Data.md +++ b/docs/Data.md @@ -1,13 +1,14 @@ # Data +The item to add. Its required keys depend on `type`; other keys (evidence, sources, basis, …) ride through untouched. ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**category** | **str** | | -**description** | **str** | | -**trait** | **str** | | +**category** | **str** | What kind of fact this is, e.g. \"hobby\". Required, non-empty. | +**description** | **str** | What the trait means and how it shows up, up to 4000 characters. | +**trait** | **str** | The inferred trait's name. Required, non-empty. | ## Example diff --git a/docs/Data1.md b/docs/Data1.md index d8e6736..130f91d 100644 --- a/docs/Data1.md +++ b/docs/Data1.md @@ -1,5 +1,6 @@ # Data1 +Partial patch, shallow-merged into the stored item. At least one of the type's own keys must be present. ## Properties diff --git a/docs/DeleteInput.md b/docs/DeleteInput.md index f32d714..56abf4a 100644 --- a/docs/DeleteInput.md +++ b/docs/DeleteInput.md @@ -5,8 +5,8 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**app_id** | **str** | | [optional] [default to 'default'] -**project_id** | **str** | | [optional] [default to 'default'] +**app_id** | **str** | Scope to delete within, defaulting to \"default\". | [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] **session_id** | **str** | | [optional] diff --git a/docs/DeleteOperation.md b/docs/DeleteOperation.md index 0194a16..e986e76 100644 --- a/docs/DeleteOperation.md +++ b/docs/DeleteOperation.md @@ -7,9 +7,9 @@ Delete an existing profile item by ``item_id`` (carries no ``data``). Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **reason** | **str** | | [optional] -**action** | **str** | | -**type** | **str** | | -**item_id** | **str** | | +**action** | **str** | Always \"delete\" for this variant. | +**type** | **str** | Which profile item this edit targets — \"explicit_info\" or \"implicit_traits\". It must match the `item_id` prefix. | +**item_id** | **str** | The item to delete. Its prefix must match the item type (\"ei_\" / \"it_\") followed by 24 hex characters. | ## Example diff --git a/docs/DocData.md b/docs/DocData.md index 1385b61..117784b 100644 --- a/docs/DocData.md +++ b/docs/DocData.md @@ -7,13 +7,14 @@ A document as returned to clients. ``topic_count`` = the node_count (>0 = ingest Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **id** | **str** | Document id (bare primary key) | -**kb_id** | **str** | | -**category_id** | **str** | | [optional] [default to ''] +**kb_id** | **str** | The knowledge base this document belongs to. | +**category_id** | **str** | The category it is filed under; empty when it is uncategorized. | [optional] [default to ''] **category_name** | **str** | | [optional] -**title** | **str** | | +**title** | **str** | The document's title. | **summary** | **str** | | [optional] **source_name** | **str** | | [optional] **source_type** | **str** | | [optional] +**tags** | [**List[TagRef]**](TagRef.md) | Distinct opaque ids from the document's read-only topic-tag union. Cloud leaves name unset; KHS may validate and expand display names. This document aggregate is read-only and carries no topic ownership field. | **topic_count** | **int** | Number of real topics extracted (0 = not ingested yet / ingest failed). EXCLUDES the synthetic document-root node, so `GET .../topics` — which includes it — returns exactly one more item than this | [optional] [default to 0] **created_at** | **datetime** | | [optional] **updated_at** | **datetime** | | [optional] diff --git a/docs/DocIngestBody.md b/docs/DocIngestBody.md index 1096f45..551977a 100644 --- a/docs/DocIngestBody.md +++ b/docs/DocIngestBody.md @@ -6,7 +6,7 @@ Public POST/PUT documents request body (design §3.2 / §3.3). ``content`` is th Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**title** | **str** | | +**title** | **str** | Human-readable name for the document. Until the async ingest finishes this is the only handle the caller has — the document id is minted downstream, so GET .../documents is resolved by title. | **content** | [**ContentItem**](ContentItem.md) | The object to ingest (its uri = the SMM object_key) | **category_id** | **str** | Category id in this kb; omit for LLM auto-classify | [optional] [default to ''] diff --git a/docs/DocListData.md b/docs/DocListData.md index 8a6dccc..6403f50 100644 --- a/docs/DocListData.md +++ b/docs/DocListData.md @@ -5,8 +5,8 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**documents** | [**List[DocData]**](DocData.md) | | [optional] -**total** | **int** | | [optional] [default to 0] +**documents** | [**List[DocData]**](DocData.md) | This page of documents. | [optional] +**total** | **int** | How many documents match, across all pages. | [optional] [default to 0] ## Example diff --git a/docs/DocPatchData.md b/docs/DocPatchData.md index c32209f..f83bbb5 100644 --- a/docs/DocPatchData.md +++ b/docs/DocPatchData.md @@ -5,8 +5,8 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**id** | **str** | | -**updated_fields** | **List[str]** | | [optional] +**id** | **str** | The document that was patched. | +**updated_fields** | **List[str]** | Which fields actually changed — omitted fields are not listed. | [optional] **updated_at** | **datetime** | | [optional] ## Example diff --git a/docs/DocumentContext.md b/docs/DocumentContext.md index dcb6937..e7b58a4 100644 --- a/docs/DocumentContext.md +++ b/docs/DocumentContext.md @@ -6,8 +6,8 @@ The parent document a hit belongs to (rolled up for display). Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**doc_id** | **str** | | -**title** | **str** | | [optional] [default to ''] +**doc_id** | **str** | The parent document's id. | +**title** | **str** | Its title. | [optional] [default to ''] **summary** | **str** | | [optional] ## Example diff --git a/docs/EditData.md b/docs/EditData.md index 17d43e4..7d83fc7 100644 --- a/docs/EditData.md +++ b/docs/EditData.md @@ -6,11 +6,11 @@ Response payload for a successful profile edit request. Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**user_id** | **str** | | -**version** | **int** | | -**applied** | **int** | | -**results** | [**List[EditResultItem]**](EditResultItem.md) | | [optional] -**profile** | **Dict[str, object]** | | [optional] +**user_id** | **str** | The user whose profile was edited. | +**version** | **int** | The profile's version after this edit. It advances every time the profile changes. | +**applied** | **int** | How many of the submitted operations took effect. | +**results** | [**List[EditResultItem]**](EditResultItem.md) | Per-operation outcome, in submission order — check this rather than assuming all applied. | [optional] +**profile** | **Dict[str, object]** | The profile as it stands after the edit, so no follow-up read is needed. | [optional] ## Example diff --git a/docs/EditInput.md b/docs/EditInput.md index 43493ab..2d9feb7 100644 --- a/docs/EditInput.md +++ b/docs/EditInput.md @@ -6,11 +6,11 @@ Bulk profile edit request [Cloud-only]. Carries 1–50 ``EditOperation`` items Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**app_id** | **str** | | [optional] [default to 'default'] -**project_id** | **str** | | [optional] [default to 'default'] -**user_id** | **str** | | -**memory_type** | **str** | | [optional] [default to 'profile'] -**operations** | [**List[EditInputOperationsInner]**](EditInputOperationsInner.md) | | +**app_id** | **str** | Scope the profile lives in, defaulting to \"default\". | [optional] [default to 'default'] +**project_id** | **str** | Second half of the scope, defaulting to \"default\". | [optional] [default to 'default'] +**user_id** | **str** | The user whose profile is being edited. | +**memory_type** | **str** | Pinned to \"profile\" — this endpoint edits nothing else. | [optional] [default to 'profile'] +**operations** | [**List[EditInputOperationsInner]**](EditInputOperationsInner.md) | 1 to 50 edits applied in one call. \"add\" mints the item id and must not carry one; \"update\" and \"delete\" require an `item_id` whose prefix matches the item type (\"ei_\" for explicit_info, \"it_\" for implicit_traits). Each operation's outcome is reported separately, so one can be rejected while the rest apply. | ## Example diff --git a/docs/EditInputOperationsInner.md b/docs/EditInputOperationsInner.md index a64596a..9751d6a 100644 --- a/docs/EditInputOperationsInner.md +++ b/docs/EditInputOperationsInner.md @@ -6,10 +6,10 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **reason** | **str** | | [optional] -**action** | **str** | | -**type** | **str** | | +**action** | **str** | Always \"delete\" for this variant. | +**type** | **str** | Which profile item this edit targets — \"explicit_info\" (a stated fact, needing `category` + `description`) or \"implicit_traits\" (an inferred trait, needing `trait` + `description`). | **data** | [**Data1**](Data1.md) | | -**item_id** | **str** | | +**item_id** | **str** | The item to delete. Its prefix must match the item type (\"ei_\" / \"it_\") followed by 24 hex characters. | ## Example diff --git a/docs/EditResultItem.md b/docs/EditResultItem.md index cff6f1e..6f6e315 100644 --- a/docs/EditResultItem.md +++ b/docs/EditResultItem.md @@ -6,10 +6,10 @@ Per-operation outcome returned in ``EditData.results``. Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**op_index** | **int** | | -**action** | **str** | | -**type** | **str** | | -**status** | **str** | | +**op_index** | **int** | Which submitted operation this is, by 0-based position in the request. | +**action** | **str** | The action that was attempted — \"add\", \"update\" or \"delete\". | +**type** | **str** | The profile item type it targeted. | +**status** | **str** | \"applied\" or \"rejected\". A rejected operation does not fail the request. | **item_id** | **str** | | [optional] **new_item_id** | **str** | | [optional] **error** | **str** | | [optional] diff --git a/docs/Envelope.md b/docs/Envelope.md index 3942b7c..01d451f 100644 --- a/docs/Envelope.md +++ b/docs/Envelope.md @@ -7,7 +7,7 @@ Common response envelope Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **error** | **str** | `\"OK\"` on success, otherwise a human-readable error message decoded from the business error. | [optional] -**request_id** | **str** | | [optional] +**request_id** | **str** | Id of this request — quote it when reporting a problem. | [optional] **status** | **int** | Business status code; 0 means success | [optional] **result** | [**EnvelopeResult**](EnvelopeResult.md) | | [optional] diff --git a/docs/EnvelopeResult.md b/docs/EnvelopeResult.md index 0e54369..e186f5c 100644 --- a/docs/EnvelopeResult.md +++ b/docs/EnvelopeResult.md @@ -1,5 +1,6 @@ # EnvelopeResult +The response payload. ## Properties diff --git a/docs/EpisodeItem.md b/docs/EpisodeItem.md index fa1e03c..bfce241 100644 --- a/docs/EpisodeItem.md +++ b/docs/EpisodeItem.md @@ -5,20 +5,20 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**id** | **str** | | -**app_id** | **str** | | -**project_id** | **str** | | +**id** | **str** | Episode id. Use it to bind tags or to fetch this episode again. | +**app_id** | **str** | The business-semantic scope this memory was written under. | +**project_id** | **str** | Second half of that scope. | **user_id** | **str** | | [optional] **session_id** | **str** | | [optional] -**timestamp** | **datetime** | | -**sender_ids** | **List[str]** | | [optional] -**summary** | **str** | | -**subject** | **str** | | -**episode** | **str** | | +**timestamp** | **datetime** | When the remembered exchange happened (ISO 8601), not when it was extracted. | +**sender_ids** | **List[str]** | The senders that appear in the source exchange. | [optional] +**summary** | **str** | Short summary of the episode — what a result list should show. | +**subject** | **str** | What the episode is about, in a few words. | +**episode** | **str** | The episode's stored narrative body. This is the indexed, searchable text. | **readable_episode** | **str** | | [optional] -**type** | **str** | | -**atomic_facts** | [**List[AtomicFactItem]**](AtomicFactItem.md) | | [optional] -**tags** | **List[str]** | | [optional] +**type** | **str** | How the episode was produced — \"Conversation\" or \"AgentConversation\". | +**atomic_facts** | [**List[AtomicFactItem]**](AtomicFactItem.md) | The individual facts extracted from this episode, nested rather than returned separately. | [optional] +**tags** | **List[str]** | Tags attached through /api/v2/memory/tag/*. | [optional] ## Example diff --git a/docs/ErrorBody.md b/docs/ErrorBody.md new file mode 100644 index 0000000..3bce63d --- /dev/null +++ b/docs/ErrorBody.md @@ -0,0 +1,31 @@ +# ErrorBody + +Nested error object inside the error envelope. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**code** | **str** | Domain error code | +**message** | **str** | Human-readable error message | + +## Example + +```python +from everos_cloud.models.error_body import ErrorBody + +# TODO update the JSON string below +json = "{}" +# create an instance of ErrorBody from a JSON string +error_body_instance = ErrorBody.from_json(json) +# print the JSON string representation of the object +print(ErrorBody.to_json()) + +# convert the object into a dict +error_body_dict = error_body_instance.to_dict() +# create an instance of ErrorBody from a dict +error_body_from_dict = ErrorBody.from_dict(error_body_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/docs/ErrorEnvelope.md b/docs/ErrorEnvelope.md new file mode 100644 index 0000000..d98be33 --- /dev/null +++ b/docs/ErrorEnvelope.md @@ -0,0 +1,31 @@ +# ErrorEnvelope + +v1 error envelope (spec §1): ``{request_id, error:{code,message}}``. Used by ``global_exception_handler`` for both HTTPException (carrying the domain code via ``InvocationHttpError``) and unhandled exceptions. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**request_id** | **str** | Request trace id | +**error** | [**ErrorBody**](ErrorBody.md) | Error detail (code + message) | + +## Example + +```python +from everos_cloud.models.error_envelope import ErrorEnvelope + +# TODO update the JSON string below +json = "{}" +# create an instance of ErrorEnvelope from a JSON string +error_envelope_instance = ErrorEnvelope.from_json(json) +# print the JSON string representation of the object +print(ErrorEnvelope.to_json()) + +# convert the object into a dict +error_envelope_dict = error_envelope_instance.to_dict() +# create an instance of ErrorEnvelope from a dict +error_envelope_from_dict = ErrorEnvelope.from_dict(error_envelope_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/docs/ExplicitInfoData.md b/docs/ExplicitInfoData.md index 6032d29..5a96b2b 100644 --- a/docs/ExplicitInfoData.md +++ b/docs/ExplicitInfoData.md @@ -6,8 +6,8 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**category** | **str** | | -**description** | **str** | | +**category** | **str** | What kind of fact this is, e.g. \"hobby\". Required, non-empty. | +**description** | **str** | The fact itself, up to 4000 characters. Required, non-empty. | ## Example diff --git a/docs/FlushData.md b/docs/FlushData.md index 2e0ea6a..0097405 100644 --- a/docs/FlushData.md +++ b/docs/FlushData.md @@ -5,7 +5,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**status** | **str** | | +**status** | **str** | \"extracted\" when the flush distilled new memories, \"no_extraction\" when there was nothing to extract — including the case of an async add still queued. | ## Example diff --git a/docs/FlushInput.md b/docs/FlushInput.md index 7e3ab0b..052d60d 100644 --- a/docs/FlushInput.md +++ b/docs/FlushInput.md @@ -5,9 +5,9 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**app_id** | **str** | | [optional] [default to 'default'] -**project_id** | **str** | | [optional] [default to 'default'] -**session_id** | **str** | | +**app_id** | **str** | Scope the session lives in, defaulting to \"default\". | [optional] [default to 'default'] +**project_id** | **str** | Second half of the scope, defaulting to \"default\". | [optional] [default to 'default'] +**session_id** | **str** | The session to extract from. Only messages already accumulated for this session are considered, so a still-queued async add yields \"no_extraction\". | ## Example diff --git a/docs/GetData.md b/docs/GetData.md index e561319..c5a2893 100644 --- a/docs/GetData.md +++ b/docs/GetData.md @@ -5,12 +5,12 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**episodes** | [**List[EpisodeItem]**](EpisodeItem.md) | | [optional] -**profiles** | [**List[ProfileItem]**](ProfileItem.md) | | [optional] -**agent_cases** | [**List[AgentCaseItem]**](AgentCaseItem.md) | | [optional] -**agent_skills** | [**List[AgentSkillItem]**](AgentSkillItem.md) | | [optional] -**total_count** | **int** | | [optional] [default to 0] -**count** | **int** | | [optional] [default to 0] +**episodes** | [**List[EpisodeItem]**](EpisodeItem.md) | Episodes, when `memory_type` was \"episode\". Empty otherwise. | [optional] +**profiles** | [**List[ProfileItem]**](ProfileItem.md) | Profiles, when `memory_type` was \"profile\". Empty otherwise. | [optional] +**agent_cases** | [**List[AgentCaseItem]**](AgentCaseItem.md) | Agent cases, when `memory_type` was \"agent_case\". Empty otherwise. | [optional] +**agent_skills** | [**List[AgentSkillItem]**](AgentSkillItem.md) | Agent skills, when `memory_type` was \"agent_skill\". Empty otherwise. | [optional] +**total_count** | **int** | How many memories match the request in total, across all pages. | [optional] [default to 0] +**count** | **int** | How many are in this page. | [optional] [default to 0] ## Example diff --git a/docs/GetInput.md b/docs/GetInput.md index 813d11e..877bae4 100644 --- a/docs/GetInput.md +++ b/docs/GetInput.md @@ -5,16 +5,16 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**app_id** | **str** | | [optional] [default to 'default'] -**project_id** | **str** | | [optional] [default to 'default'] +**app_id** | **str** | Scope to read from, 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] -**memory_type** | **str** | | -**page** | **int** | | [optional] [default to 1] -**page_size** | **int** | | [optional] [default to 20] -**sort_by** | **str** | | [optional] [default to 'timestamp'] -**sort_order** | **str** | | [optional] [default to 'desc'] -**with_readable_episode** | **bool** | | [optional] [default to False] +**memory_type** | **str** | Which kind of memory to list: \"episode\" (narrative summaries of past sessions), \"profile\" (stable identity and preferences), \"agent_case\" (a distilled past trajectory) or \"agent_skill\" (a reusable skill). It must match the owner — the mismatched pairings are rejected with 422. | +**page** | **int** | 1-based page number. | [optional] [default to 1] +**page_size** | **int** | Items per page, 1 to 100 (default 20). | [optional] [default to 20] +**sort_by** | **str** | Order by \"timestamp\" (when the memory happened, default) or \"updated_at\" (when it was last written). Profiles and agent skills have no temporal column and always sort by \"updated_at\". | [optional] [default to 'timestamp'] +**sort_order** | **str** | \"desc\" (default, newest first) or \"asc\". | [optional] [default to 'desc'] +**with_readable_episode** | **bool** | Attach a human-readable rendering to each returned episode, for display only. Ignored for every non-episode `memory_type` rather than rejected. | [optional] [default to False] **filters** | [**FilterNode**](FilterNode.md) | | [optional] ## Example diff --git a/docs/HTTPValidationError.md b/docs/HTTPValidationError.md index c34ef27..0397933 100644 --- a/docs/HTTPValidationError.md +++ b/docs/HTTPValidationError.md @@ -5,7 +5,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**detail** | [**List[ValidationError]**](ValidationError.md) | | [optional] +**detail** | [**List[ValidationError]**](ValidationError.md) | One entry per field that failed validation. | [optional] ## Example diff --git a/docs/ImplicitTraitData.md b/docs/ImplicitTraitData.md index b8e320d..520ef97 100644 --- a/docs/ImplicitTraitData.md +++ b/docs/ImplicitTraitData.md @@ -6,8 +6,8 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**trait** | **str** | | -**description** | **str** | | +**trait** | **str** | The inferred trait's name. Required, non-empty. | +**description** | **str** | What the trait means and how it shows up, up to 4000 characters. | ## Example diff --git a/docs/KbData.md b/docs/KbData.md index 3785282..a82ac9b 100644 --- a/docs/KbData.md +++ b/docs/KbData.md @@ -7,10 +7,10 @@ A knowledge base as returned to clients (create / get / list item / patch). Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **id** | **str** | Knowledge base id (bare primary key) | -**name** | **str** | | -**description** | **str** | | [optional] [default to ''] +**name** | **str** | The knowledge base's display name. | +**description** | **str** | Its description. | [optional] [default to ''] **owner_id** | **str** | | [optional] -**document_count** | **int** | | [optional] [default to 0] +**document_count** | **int** | How many documents it holds. | [optional] [default to 0] **created_at** | **datetime** | | [optional] **updated_at** | **datetime** | | [optional] diff --git a/docs/KbListData.md b/docs/KbListData.md index 47c73fc..a62a07f 100644 --- a/docs/KbListData.md +++ b/docs/KbListData.md @@ -5,8 +5,8 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**knowledge_bases** | [**List[KbData]**](KbData.md) | | [optional] -**total** | **int** | | [optional] [default to 0] +**knowledge_bases** | [**List[KbData]**](KbData.md) | This page of knowledge bases. | [optional] +**total** | **int** | How many exist in total, across all pages. | [optional] [default to 0] ## Example diff --git a/docs/KbSearchData.md b/docs/KbSearchData.md index 5fb733a..e8319b1 100644 --- a/docs/KbSearchData.md +++ b/docs/KbSearchData.md @@ -6,9 +6,9 @@ Knowledge search response payload. Prefixed ``Kb`` to stay distinct from ``memor Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**hits** | [**List[SearchHit]**](SearchHit.md) | | [optional] -**total** | **int** | | [optional] [default to 0] -**took_ms** | **float** | | [optional] [default to 0.0] +**hits** | [**List[SearchHit]**](SearchHit.md) | Matching topics, most relevant first. | +**total** | **int** | How many topics matched. | +**took_ms** | **float** | How long the search took, in milliseconds. | ## Example diff --git a/docs/KnowledgeApi.md b/docs/KnowledgeApi.md index 51ea61d..3485201 100644 --- a/docs/KnowledgeApi.md +++ b/docs/KnowledgeApi.md @@ -17,7 +17,10 @@ Method | HTTP request | Description [**list_documents**](KnowledgeApi.md#list_documents) | **GET** /api/v2/knowledge_bases/{kb_id}/documents | List documents in a knowledge base [**list_knowledge_bases**](KnowledgeApi.md#list_knowledge_bases) | **GET** /api/v2/knowledge_bases | List knowledge bases [**list_topics**](KnowledgeApi.md#list_topics) | **GET** /api/v2/knowledge_bases/{kb_id}/documents/{doc_id}/topics | List a document's topic tree (optionally with each topic's content) +[**list_topics_by_tags**](KnowledgeApi.md#list_topics_by_tags) | **GET** /api/v2/knowledge_bases/{kb_id}/topics | List tag-matched topics in a knowledge base +[**query_related_tags**](KnowledgeApi.md#query_related_tags) | **POST** /api/v2/knowledge_bases/{kb_id}/tags | Count candidate tags used by live documents in a knowledge base [**replace_document**](KnowledgeApi.md#replace_document) | **PUT** /api/v2/knowledge_bases/{kb_id}/documents/{doc_id} | Replace a document (async, atomic swap) +[**replace_topic_tags**](KnowledgeApi.md#replace_topic_tags) | **POST** /api/v2/knowledge_bases/{kb_id}/documents/{doc_id}/topics/{topic_id}/tag/replace | Replace the complete materialized semantic tag snapshot of a topic [**search_knowledge**](KnowledgeApi.md#search_knowledge) | **POST** /api/v2/knowledge_bases/{kb_id}/search | Search within a knowledge base (keyword / vector / hybrid) [**update_category**](KnowledgeApi.md#update_category) | **PATCH** /api/v2/knowledge_bases/{kb_id}/categories/{category_id} | Update a category [**update_document**](KnowledgeApi.md#update_document) | **PATCH** /api/v2/knowledge_bases/{kb_id}/documents/{doc_id} | Update document metadata (title / category) @@ -29,6 +32,8 @@ Method | HTTP request | Description Create a category +Add a category to this knowledge base's taxonomy. Categories are what a document is filed under: on ingest each document is classified into one of them, unless the caller pins `category_id` on the upload. The category's description is not decoration — it is what the classifier matches against. + ### Example * Bearer Authentication (BearerAuth): @@ -113,6 +118,8 @@ Name | Type | Description | Notes Upload a document (async ingest) +Upload a document for ingest. Ingest is asynchronous at the gateway: it answers 202 with status \"queued\" and a `task_id`, and the document id is minted downstream — poll GET /api/v2/tasks/{task_id}, then resolve the id from GET .../documents. Ingest is only truly complete once that document reports `topic_count` greater than 0. `content` is one content object: inline text, or a file already uploaded through POST /api/v2/object/sign, referenced by its object key as the content's `uri`. Omit `category_id` to let the server classify the document into this base's taxonomy. + ### Example * Bearer Authentication (BearerAuth): @@ -197,6 +204,8 @@ Name | Type | Description | Notes Create a knowledge base +Create a knowledge base — a searchable document library with its own category taxonomy. The returned id is the `kb_id` every other knowledge operation takes. + ### Example * Bearer Authentication (BearerAuth): @@ -279,6 +288,8 @@ Name | Type | Description | Notes Delete a category +Delete a category from this knowledge base's taxonomy. Its documents are NOT deleted: they (and their topics) are reassigned to uncategorized first, then the category is soft-deleted. Idempotent — deleting one that is already gone returns `deleted: false` rather than 404. + ### Example * Bearer Authentication (BearerAuth): @@ -362,6 +373,8 @@ Name | Type | Description | Notes Delete a document (+ cascade nodes, P5) +Soft-delete a document. Its topics and their search-index entries are removed with it, so nothing of the document stays searchable. Idempotent — deleting one that is already gone returns `deleted: false` rather than 404. + ### Example * Bearer Authentication (BearerAuth): @@ -445,6 +458,8 @@ Name | Type | Description | Notes Delete a knowledge base +Delete a knowledge base and everything under it: every document (with its topics, search-index entries and stored objects) and every category are soft-deleted first, then the base itself. Idempotent — deleting a base that is already gone returns `deleted: false` rather than 404. + ### Example * Bearer Authentication (BearerAuth): @@ -526,6 +541,8 @@ Name | Type | Description | Notes Get a document (with topic_count) +Read one document's metadata, including how many topics were extracted from it — `topic_count` greater than 0 is also the authoritative signal that an async ingest finished. The text itself lives in those topics; list them with GET .../documents/{doc_id}/topics. + ### Example * Bearer Authentication (BearerAuth): @@ -609,6 +626,8 @@ Name | Type | Description | Notes Get a knowledge base +Read one knowledge base's metadata, including its document count. + ### Example * Bearer Authentication (BearerAuth): @@ -690,6 +709,8 @@ Name | Type | Description | Notes Get a topic's full content (inline / S3 transparent) +Read one topic's full content. Storage is transparent to the caller: content held inline and content held in object storage are returned the same way. + ### Example * Bearer Authentication (BearerAuth): @@ -762,6 +783,7 @@ Name | Type | Description | Notes | Status code | Description | Response headers | |-------------|-------------|------------------| **200** | Successful Response | - | +**404** | Topic absent or not owned by the path kb/document | - | **422** | Validation Error | - | **401** | Missing or invalid bearer token. | - | **403** | Authenticated but not permitted — either rejected by the auth service, or the account's memory API version does not match the interface version implied by the path (a v1 account calling an /api/v2 route). | - | @@ -775,6 +797,8 @@ Name | Type | Description | Notes List categories in a knowledge base +List this knowledge base's categories — both the ones created here and the tenant-global presets — each with the number of documents filed under it. + ### Example * Bearer Authentication (BearerAuth): @@ -856,6 +880,8 @@ Name | Type | Description | Notes List documents in a knowledge base +Paginated list of the documents in a knowledge base, each with its category and topic count. Filterable by category. + ### Example * Bearer Authentication (BearerAuth): @@ -943,6 +969,8 @@ Name | Type | Description | Notes List knowledge bases +Paginated list of the account's knowledge bases, each with its document count. + ### Example * Bearer Authentication (BearerAuth): @@ -1028,6 +1056,8 @@ Name | Type | Description | Notes List a document's topic tree (optionally with each topic's content) +List a document's topic tree — the sections an LLM extracted from it — flat and already in depth-first order; build the tree from each item's `parent_id`. The list includes one synthetic document-root item (`type` \"root\"), so it returns exactly one more item than the document's `topic_count`, which counts real topics only. Bodies are omitted by default; ask for `content` in `include` to hydrate every item, which can enlarge the response by orders of magnitude. + ### Example * Bearer Authentication (BearerAuth): @@ -1108,11 +1138,188 @@ Name | Type | Description | Notes [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) +# **list_topics_by_tags** +> SuccessEnvelopeTopicFilterListData list_topics_by_tags(kb_id, tag_ids, page=page, page_size=page_size) + +List tag-matched topics in a knowledge base + +Filter live topics by their own materialized tag set. Every requested id must occur on the same topic (ALL semantics); total is counted before paging. + +### Example + +* Bearer Authentication (BearerAuth): + +```python +import everos_cloud +from everos_cloud.models.success_envelope_topic_filter_list_data import SuccessEnvelopeTopicFilterListData +from everos_cloud.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to https://api.evermind.ai +# See configuration.py for a list of all supported configuration parameters. +configuration = everos_cloud.Configuration( + host = "https://api.evermind.ai" +) + +# The client must configure the authentication and authorization parameters +# in accordance with the API server security policy. +# Examples for each auth method are provided below, use the example that +# satisfies your auth use case. + +# Configure Bearer authorization: BearerAuth +configuration = everos_cloud.Configuration( + access_token = os.environ["BEARER_TOKEN"] +) + +# Enter a context with an instance of the API client +with everos_cloud.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = everos_cloud.KnowledgeApi(api_client) + kb_id = 'kb_id_example' # str | The knowledge base to search within. + tag_ids = ['tag_ids_example'] # List[str] | Hard filter: a topic is returned only if it carries EVERY one of these tag ids. Use `boost_tag_ids` on the search endpoint instead to reweight without excluding anything. + page = 1 # int | 1-based page number. (optional) (default to 1) + page_size = 20 # int | Items per page, 1 to 100 (default 20). (optional) (default to 20) + + try: + # List tag-matched topics in a knowledge base + api_response = api_instance.list_topics_by_tags(kb_id, tag_ids, page=page, page_size=page_size) + print("The response of KnowledgeApi->list_topics_by_tags:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling KnowledgeApi->list_topics_by_tags: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **kb_id** | **str**| The knowledge base to search within. | + **tag_ids** | [**List[str]**](str.md)| Hard filter: a topic is returned only if it carries EVERY one of these tag ids. Use `boost_tag_ids` on the search endpoint instead to reweight without excluding anything. | + **page** | **int**| 1-based page number. | [optional] [default to 1] + **page_size** | **int**| Items per page, 1 to 100 (default 20). | [optional] [default to 20] + +### Return type + +[**SuccessEnvelopeTopicFilterListData**](SuccessEnvelopeTopicFilterListData.md) + +### Authorization + +[BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | +**401** | Missing or invalid bearer token. | - | +**403** | Authenticated but not permitted — either rejected by the auth service, or the account's memory API version does not match the interface version implied by the path (a v1 account calling an /api/v2 route). | - | +**429** | Rate limit or quota exceeded. | - | +**503** | The gateway could not reach the authentication service. Transient — retry with backoff. | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **query_related_tags** +> SuccessEnvelopeRelatedTagUsageListData query_related_tags(kb_id, related_tag_usage_body) + +Count candidate tags used by live documents in a knowledge base + +Returns requested opaque tag ids used by live topics of live documents. Counts are distinct by document and items are sorted by id. The bounded multi-command Mongo read is not a point-in-time snapshot across concurrent lifecycle writes. + +### Example + +* Bearer Authentication (BearerAuth): + +```python +import everos_cloud +from everos_cloud.models.related_tag_usage_body import RelatedTagUsageBody +from everos_cloud.models.success_envelope_related_tag_usage_list_data import SuccessEnvelopeRelatedTagUsageListData +from everos_cloud.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to https://api.evermind.ai +# See configuration.py for a list of all supported configuration parameters. +configuration = everos_cloud.Configuration( + host = "https://api.evermind.ai" +) + +# The client must configure the authentication and authorization parameters +# in accordance with the API server security policy. +# Examples for each auth method are provided below, use the example that +# satisfies your auth use case. + +# Configure Bearer authorization: BearerAuth +configuration = everos_cloud.Configuration( + access_token = os.environ["BEARER_TOKEN"] +) + +# Enter a context with an instance of the API client +with everos_cloud.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = everos_cloud.KnowledgeApi(api_client) + kb_id = 'kb_id_example' # str | + related_tag_usage_body = everos_cloud.RelatedTagUsageBody() # RelatedTagUsageBody | + + try: + # Count candidate tags used by live documents in a knowledge base + api_response = api_instance.query_related_tags(kb_id, related_tag_usage_body) + print("The response of KnowledgeApi->query_related_tags:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling KnowledgeApi->query_related_tags: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **kb_id** | **str**| | + **related_tag_usage_body** | [**RelatedTagUsageBody**](RelatedTagUsageBody.md)| | + +### Return type + +[**SuccessEnvelopeRelatedTagUsageListData**](SuccessEnvelopeRelatedTagUsageListData.md) + +### Authorization + +[BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | +**401** | Missing or invalid bearer token. | - | +**403** | Authenticated but not permitted — either rejected by the auth service, or the account's memory API version does not match the interface version implied by the path (a v1 account calling an /api/v2 route). | - | +**429** | Rate limit or quota exceeded. | - | +**503** | The gateway could not reach the authentication service. Transient — retry with backoff. | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + # **replace_document** > SuccessEnvelopeDocIngestData replace_document(kb_id, doc_id, doc_ingest_body) Replace a document (async, atomic swap) +Re-ingest content under an existing document id. Same asynchronous contract as upload (202 with `status` and `task_id`), and idempotent per document id — the same replace applied twice leaves the same state. As with upload, completion is authoritative from GET .../documents/{doc_id} reporting `topic_count` greater than 0. + ### Example * Bearer Authentication (BearerAuth): @@ -1194,11 +1401,106 @@ Name | Type | Description | Notes [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) +# **replace_topic_tags** +> SuccessEnvelopeTopicTagWriteData replace_topic_tags(kb_id, doc_id, topic_id, topic_tag_replace_body) + +Replace the complete materialized semantic tag snapshot of a topic + +version is the expected current tag_version. Cloud stable-deduplicates the request and stores the first 50 ids; requests with 51-100 distinct ids succeed with structured truncation metadata. Identical snapshots are no-ops and do not advance the version. + +### Example + +* Bearer Authentication (BearerAuth): + +```python +import everos_cloud +from everos_cloud.models.success_envelope_topic_tag_write_data import SuccessEnvelopeTopicTagWriteData +from everos_cloud.models.topic_tag_replace_body import TopicTagReplaceBody +from everos_cloud.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to https://api.evermind.ai +# See configuration.py for a list of all supported configuration parameters. +configuration = everos_cloud.Configuration( + host = "https://api.evermind.ai" +) + +# The client must configure the authentication and authorization parameters +# in accordance with the API server security policy. +# Examples for each auth method are provided below, use the example that +# satisfies your auth use case. + +# Configure Bearer authorization: BearerAuth +configuration = everos_cloud.Configuration( + access_token = os.environ["BEARER_TOKEN"] +) + +# Enter a context with an instance of the API client +with everos_cloud.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = everos_cloud.KnowledgeApi(api_client) + kb_id = 'kb_id_example' # str | + doc_id = 'doc_id_example' # str | + topic_id = 'topic_id_example' # str | + topic_tag_replace_body = everos_cloud.TopicTagReplaceBody() # TopicTagReplaceBody | + + try: + # Replace the complete materialized semantic tag snapshot of a topic + api_response = api_instance.replace_topic_tags(kb_id, doc_id, topic_id, topic_tag_replace_body) + print("The response of KnowledgeApi->replace_topic_tags:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling KnowledgeApi->replace_topic_tags: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **kb_id** | **str**| | + **doc_id** | **str**| | + **topic_id** | **str**| | + **topic_tag_replace_body** | [**TopicTagReplaceBody**](TopicTagReplaceBody.md)| | + +### Return type + +[**SuccessEnvelopeTopicTagWriteData**](SuccessEnvelopeTopicTagWriteData.md) + +### Authorization + +[BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**404** | Topic absent or not owned by the path kb/document | - | +**409** | Stale topic tag version (atomic zero-write conflict) | - | +**500** | Storage or search projection failure. Mongo may already contain the snapshot; replay the same snapshot to converge. | - | +**422** | Validation Error | - | +**401** | Missing or invalid bearer token. | - | +**403** | Authenticated but not permitted — either rejected by the auth service, or the account's memory API version does not match the interface version implied by the path (a v1 account calling an /api/v2 route). | - | +**429** | Rate limit or quota exceeded. | - | +**503** | The gateway could not reach the authentication service. Transient — retry with backoff. | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + # **search_knowledge** > SuccessEnvelopeKbSearchData search_knowledge(kb_id, search_body) Search within a knowledge base (keyword / vector / hybrid) +Search within one knowledge base (keyword, vector or hybrid). The unit of retrieval is the topic, not the document: each hit carries its parent document's title and summary, so rendering a result needs no second call. Topic bodies are omitted by default; ask for `content` in `include` to inline them, or drill down with GET .../documents/{doc_id}/topics/{topic_id}. + ### Example * Bearer Authentication (BearerAuth): @@ -1283,6 +1585,8 @@ Name | Type | Description | Notes Update a category +Rename a category or edit its description. Documents filed under it are not re-classified; they keep pointing at the same category id. Tenant-global preset categories are read-only. + ### Example * Bearer Authentication (BearerAuth): @@ -1369,6 +1673,8 @@ Name | Type | Description | Notes Update document metadata (title / category) +Patch a document's metadata — its title, or the category it is filed under. Content is not editable here: re-ingest with PUT .../documents/{doc_id} to change it. The response lists which fields actually changed. + ### Example * Bearer Authentication (BearerAuth): @@ -1455,6 +1761,8 @@ Name | Type | Description | Notes Update a knowledge base +Patch a knowledge base's name or description. Metadata only — it does not touch the documents inside it. + ### Example * Bearer Authentication (BearerAuth): diff --git a/docs/MemoryApi.md b/docs/MemoryApi.md index 5b018c5..5832a00 100644 --- a/docs/MemoryApi.md +++ b/docs/MemoryApi.md @@ -20,6 +20,8 @@ Method | HTTP request | Description Add messages [OSS + Cloud] +Append conversation messages to a session's working memory. Asynchronous by default (`async_mode` true): the gateway validates and enqueues the write, answering 202 with status \"queued\". Pass `async_mode: false` to forward synchronously and receive the engine's 200 result instead. Distillation into long-term memory is always asynchronous — it runs on a session boundary, or when you call /api/v2/memory/flush. One call carries 1–500 messages. + ### Example * Bearer Authentication (BearerAuth): @@ -103,6 +105,8 @@ Name | Type | Description | Notes Bind tags to memory items [Cloud] +Add tags to existing memories, keeping the tags they already carry. Tags are scoped by the memory ids themselves — pass `memory_type` plus the ids, not an app or project scope. Tags are created by use: binding a name that does not exist yet is how it comes into existence. Idempotent, and batched over memory_ids x tags. + ### Example * Bearer Authentication (BearerAuth): @@ -185,6 +189,8 @@ Name | Type | Description | Notes Delete memories [Cloud-only] +Soft-delete memories within a scope. At least one of `user_id`, `agent_id` or `session_id` is required (an empty body is rejected with 422), and `user_id` / `agent_id` are mutually exclusive. The response echoes which scope filters were applied and how many records were removed across all memory types. + ### Example * Bearer Authentication (BearerAuth): @@ -267,6 +273,8 @@ Name | Type | Description | Notes Edit profile items [Cloud-only] +Apply 1–50 edits to one user's profile in a single call. Each operation carries an `action` (add, update or delete), a `type` (explicit_info or implicit_traits), the item `data`, and an optional `reason`. Profile is the only memory type this endpoint edits — `memory_type` is pinned to \"profile\"; every other type is produced by extraction. Operations are reported individually in the response, so some can be rejected while others apply. + ### Example * Bearer Authentication (BearerAuth): @@ -349,6 +357,8 @@ Name | Type | Description | Notes Force memory extraction [OSS + Cloud] +Force extraction for a session instead of waiting for a boundary. Returns status \"extracted\" when memories were distilled and \"no_extraction\" when there was nothing to extract — note that a default (async) add that is still queued yields \"no_extraction\", so either write with `async_mode: false` or poll the add's task before flushing. + ### Example * Bearer Authentication (BearerAuth): @@ -431,6 +441,8 @@ Name | Type | Description | Notes Get memories (paginated) [OSS + Cloud] +List stored memories of one type, paginated. Exactly one of `user_id` / `agent_id` is required, and `memory_type` must match that owner: a user owns \"episode\" and \"profile\", an agent owns \"agent_case\" and \"agent_skill\" — the other pairings are rejected with 422. This is a structured read, not a query: it does not embed the request, so a memory is readable as soon as it is extracted, whereas the vector index /api/v2/memory/search relies on lags behind extraction by seconds. + ### Example * Bearer Authentication (BearerAuth): @@ -513,6 +525,8 @@ Name | Type | Description | Notes Replace (overwrite) tags on memory items [Cloud] +Overwrite the tag set on the given memories: tags absent from the request are dropped, and an empty `tags` list clears them all. Use /api/v2/memory/tag/bind to add without removing. + ### Example * Bearer Authentication (BearerAuth): @@ -595,6 +609,8 @@ Name | Type | Description | Notes Search memories [OSS + Cloud] +Retrieve the memories relevant to a query. Exactly one of `user_id` / `agent_id` is required and decides what comes back: a user owner returns episodes (plus profiles with `include_profile`), an agent owner returns agent cases and skills. All result collections are always present in the response, empty when they do not apply. The vector-backed methods read an index that lags extraction by seconds — to read back something just extracted, use /api/v2/memory/get. + ### Example * Bearer Authentication (BearerAuth): @@ -677,6 +693,8 @@ Name | Type | Description | Notes Unbind tags from memory items [Cloud] +Remove the given tags from the given memories, leaving their other tags in place. Idempotent: unbinding a tag an item does not carry still counts as matched. + ### Example * Bearer Authentication (BearerAuth): diff --git a/docs/MessageItem.md b/docs/MessageItem.md index 7047e22..00fcf6f 100644 --- a/docs/MessageItem.md +++ b/docs/MessageItem.md @@ -6,10 +6,10 @@ One message in an /add batch (spec §2). ``content`` accepts a plain string (sho Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**sender_id** | **str** | | +**sender_id** | **str** | Who produced this message — the user id for a user turn, the agent id for an assistant turn. This is the identifier /api/v2/memory/get and /api/v2/memory/search later scope by (`user_id` / `agent_id`). | **sender_name** | **str** | | [optional] -**role** | **str** | | -**timestamp** | **int** | | +**role** | **str** | Turn type: \"user\", \"assistant\", or \"tool\" for a tool result. An agent trajectory uses the OpenAI shape — an \"assistant\" message carrying `tool_calls`, followed by a \"tool\" message carrying `tool_call_id`. | +**timestamp** | **int** | When the message was produced, as a UNIX timestamp in MILLISECONDS. A seconds-scale value is rejected with 422 rather than silently rescaled, because a window mixing the two would mis-order and mis-split. | **content** | [**Content**](Content.md) | | **tool_calls** | [**List[ToolCall]**](ToolCall.md) | | [optional] **tool_call_id** | **str** | | [optional] diff --git a/docs/ProfileItem.md b/docs/ProfileItem.md index 10bb570..8f2aaa2 100644 --- a/docs/ProfileItem.md +++ b/docs/ProfileItem.md @@ -5,11 +5,13 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**id** | **str** | | -**app_id** | **str** | | -**project_id** | **str** | | -**user_id** | **str** | | -**profile_data** | **Dict[str, object]** | | [optional] +**id** | **str** | Profile id. | +**app_id** | **str** | The business-semantic scope this profile was written under. | +**project_id** | **str** | Second half of that scope. | +**user_id** | **str** | The user this profile describes. | +**profile_data** | **Dict[str, object]** | The profile itself — the explicit_info and implicit_traits items maintained by extraction and by /api/v2/memory/edit. Each item's id is what an edit operation targets. | [optional] +**created_at** | **datetime** | | [optional] +**updated_at** | **datetime** | | [optional] ## Example diff --git a/docs/RelatedTagUsageBody.md b/docs/RelatedTagUsageBody.md new file mode 100644 index 0000000..787fe5e --- /dev/null +++ b/docs/RelatedTagUsageBody.md @@ -0,0 +1,30 @@ +# RelatedTagUsageBody + +Candidate tag ids for ``POST /knowledge_bases/{kb_id}/tags``. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**tag_ids** | **List[str]** | Candidate opaque tag ids to check against the current live tree | + +## Example + +```python +from everos_cloud.models.related_tag_usage_body import RelatedTagUsageBody + +# TODO update the JSON string below +json = "{}" +# create an instance of RelatedTagUsageBody from a JSON string +related_tag_usage_body_instance = RelatedTagUsageBody.from_json(json) +# print the JSON string representation of the object +print(RelatedTagUsageBody.to_json()) + +# convert the object into a dict +related_tag_usage_body_dict = related_tag_usage_body_instance.to_dict() +# create an instance of RelatedTagUsageBody from a dict +related_tag_usage_body_from_dict = RelatedTagUsageBody.from_dict(related_tag_usage_body_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/docs/RelatedTagUsageItem.md b/docs/RelatedTagUsageItem.md new file mode 100644 index 0000000..319bfc1 --- /dev/null +++ b/docs/RelatedTagUsageItem.md @@ -0,0 +1,31 @@ +# RelatedTagUsageItem + +One opaque tag id and its distinct live-document usage in the current KB. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**id** | **str** | Opaque semantic tag id | +**document_count** | **int** | Distinct live documents using this tag | + +## Example + +```python +from everos_cloud.models.related_tag_usage_item import RelatedTagUsageItem + +# TODO update the JSON string below +json = "{}" +# create an instance of RelatedTagUsageItem from a JSON string +related_tag_usage_item_instance = RelatedTagUsageItem.from_json(json) +# print the JSON string representation of the object +print(RelatedTagUsageItem.to_json()) + +# convert the object into a dict +related_tag_usage_item_dict = related_tag_usage_item_instance.to_dict() +# create an instance of RelatedTagUsageItem from a dict +related_tag_usage_item_from_dict = RelatedTagUsageItem.from_dict(related_tag_usage_item_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/docs/RelatedTagUsageListData.md b/docs/RelatedTagUsageListData.md new file mode 100644 index 0000000..500229e --- /dev/null +++ b/docs/RelatedTagUsageListData.md @@ -0,0 +1,31 @@ +# RelatedTagUsageListData + +Complete non-zero usage result for the requested candidate tag ids. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**items** | [**List[RelatedTagUsageItem]**](RelatedTagUsageItem.md) | One entry per requested tag id that is actually in use, sorted by id. | +**total** | **int** | Number of returned distinct tag ids | + +## Example + +```python +from everos_cloud.models.related_tag_usage_list_data import RelatedTagUsageListData + +# TODO update the JSON string below +json = "{}" +# create an instance of RelatedTagUsageListData from a JSON string +related_tag_usage_list_data_instance = RelatedTagUsageListData.from_json(json) +# print the JSON string representation of the object +print(RelatedTagUsageListData.to_json()) + +# convert the object into a dict +related_tag_usage_list_data_dict = related_tag_usage_list_data_instance.to_dict() +# create an instance of RelatedTagUsageListData from a dict +related_tag_usage_list_data_from_dict = RelatedTagUsageListData.from_dict(related_tag_usage_list_data_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/docs/SearchAgentCaseItem.md b/docs/SearchAgentCaseItem.md index 02701b3..6c21f57 100644 --- a/docs/SearchAgentCaseItem.md +++ b/docs/SearchAgentCaseItem.md @@ -5,17 +5,17 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**id** | **str** | | -**app_id** | **str** | | -**project_id** | **str** | | -**agent_id** | **str** | | -**session_id** | **str** | | -**task_intent** | **str** | | -**approach** | **str** | | -**quality_score** | **float** | | +**id** | **str** | Agent-case id. | +**app_id** | **str** | The business-semantic scope this case was written under. | +**project_id** | **str** | Second half of that scope. | +**agent_id** | **str** | The agent that owns this case. | +**session_id** | **str** | The session whose trajectory the case was distilled from. | +**task_intent** | **str** | What the agent was trying to do in that trajectory. | +**approach** | **str** | How it went about it — the reusable part of the case. | +**quality_score** | **float** | How good this case is judged to be. Nominally 0.0–1.0 with 0.5 as the no-opinion default, but the value is the extractor's own and nothing on the write path enforces the range — treat an out-of-range number as possible. One threshold is real: a case scoring below 0.2 is never distilled into a skill. | **key_insight** | **str** | | [optional] -**timestamp** | **datetime** | | -**score** | **float** | | +**timestamp** | **datetime** | When the trajectory happened (ISO 8601). | +**score** | **float** | Relevance of this case to the query. | ## Example diff --git a/docs/SearchAgentSkillItem.md b/docs/SearchAgentSkillItem.md index e921a2a..e7a7761 100644 --- a/docs/SearchAgentSkillItem.md +++ b/docs/SearchAgentSkillItem.md @@ -5,17 +5,19 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**id** | **str** | | -**app_id** | **str** | | -**project_id** | **str** | | -**agent_id** | **str** | | -**name** | **str** | | -**description** | **str** | | -**content** | **str** | | -**confidence** | **float** | | -**maturity_score** | **float** | | -**source_case_ids** | **List[str]** | | [optional] -**score** | **float** | | +**id** | **str** | Agent-skill id. | +**app_id** | **str** | The business-semantic scope this skill was written under. | +**project_id** | **str** | Second half of that scope. | +**agent_id** | **str** | The agent that owns this skill. | +**name** | **str** | The skill's name. | +**description** | **str** | What the skill is for, in a sentence. | +**content** | **str** | The skill itself — the reusable procedure, ready to put in a prompt. | +**confidence** | **float** | How much the distillation trusts this skill. Nominally 0.0–1.0, defaulting to 0.0 before anything scores it; the range is not enforced on the write path. Nothing in retrieval filters on it today, and how it divides labour with `maturity_score` is still open — so do not build a threshold on it yet. | +**maturity_score** | **float** | How well-established the skill is. Nominally 0.0–1.0 and unenforced, and — unlike the other two scores — its default is 0.6 rather than 0.0, chosen so an unscored skill starts mid-optimistic. The cost is that an unscored 0.6 is indistinguishable from a scored 0.6: there is no \"not evaluated\" sentinel, and maturity scoring is skipped by default. Filtering near 0.6 is therefore unreliable. | +**source_case_ids** | **List[str]** | The agent cases this skill was distilled from. Fetch them for the underlying evidence. | [optional] +**created_at** | **datetime** | | [optional] +**updated_at** | **datetime** | | [optional] +**score** | **float** | Relevance of this skill to the query. | ## Example diff --git a/docs/SearchAtomicFactItem.md b/docs/SearchAtomicFactItem.md index 33276f1..cd2a934 100644 --- a/docs/SearchAtomicFactItem.md +++ b/docs/SearchAtomicFactItem.md @@ -5,9 +5,9 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**id** | **str** | | -**content** | **str** | | -**score** | **float** | | +**id** | **str** | Atomic-fact id. | +**content** | **str** | The fact itself, as a single statement. | +**score** | **float** | Relevance of this fact to the query. | ## Example diff --git a/docs/SearchBody.md b/docs/SearchBody.md index 00bb154..24a2061 100644 --- a/docs/SearchBody.md +++ b/docs/SearchBody.md @@ -6,12 +6,14 @@ POST body (kb_id rides the path, not the body). Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**query** | **str** | | -**method** | **str** | | [optional] [default to 'hybrid'] -**top_k** | **int** | | [optional] [default to 10] +**query** | **str** | | [optional] +**method** | **str** | Retrieval strategy: \"keyword\" (lexical), \"vector\" (embedding similarity) or \"hybrid\" (default, both). | [optional] [default to 'hybrid'] +**page** | **int** | Filter-only page number; query search supports page 1 only | [optional] [default to 1] +**top_k** | **int** | Maximum number of topics to return, 1 to 100 (default 10). On a query search the server also bounds the result by its rerank pool — 50 candidates by default — so asking for more than that returns what the pool held. On a filter-only request (tags without a query) it is the page size instead, and `page` walks the rest. | [optional] [default to 10] **score_threshold** | **float** | | [optional] -**include** | **List[str]** | e.g. ['content'] | [optional] -**filters** | [**SearchFilters**](SearchFilters.md) | | [optional] +**include** | **List[str]** | e.g. ['content'] | [optional] [default to []] +**boost_tag_ids** | **List[str]** | Reweight, do not filter: topics carrying these tags are pushed up, and topics without them still come back. Use `filters.tag_ids` when the intent is to exclude everything else. | [optional] [default to []] +**filters** | [**SearchFilters**](SearchFilters.md) | Optional filters narrowing what is searched. | [optional] ## Example diff --git a/docs/SearchData.md b/docs/SearchData.md index 4e78041..78afa52 100644 --- a/docs/SearchData.md +++ b/docs/SearchData.md @@ -5,11 +5,11 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**episodes** | [**List[SearchEpisodeItem]**](SearchEpisodeItem.md) | | [optional] -**profiles** | [**List[SearchProfileItem]**](SearchProfileItem.md) | | [optional] -**agent_cases** | [**List[SearchAgentCaseItem]**](SearchAgentCaseItem.md) | | [optional] -**agent_skills** | [**List[SearchAgentSkillItem]**](SearchAgentSkillItem.md) | | [optional] -**unprocessed_messages** | [**List[UnprocessedMessageDTO]**](UnprocessedMessageDTO.md) | | [optional] +**episodes** | [**List[SearchEpisodeItem]**](SearchEpisodeItem.md) | Matching episodes, for a user owner. Always present, empty when not applicable. | [optional] +**profiles** | [**List[SearchProfileItem]**](SearchProfileItem.md) | The user's profile, when `include_profile` asked for it. | [optional] +**agent_cases** | [**List[SearchAgentCaseItem]**](SearchAgentCaseItem.md) | Matching agent cases, for an agent owner. | [optional] +**agent_skills** | [**List[SearchAgentSkillItem]**](SearchAgentSkillItem.md) | Matching agent skills, for an agent owner. | [optional] +**unprocessed_messages** | [**List[UnprocessedMessageDTO]**](UnprocessedMessageDTO.md) | Raw buffered messages not yet extracted. Returned only when the request filtered on a single `session_id`, so a caller can see what is still in flight. | [optional] ## Example diff --git a/docs/SearchEpisodeItem.md b/docs/SearchEpisodeItem.md index 700df38..d9bee8e 100644 --- a/docs/SearchEpisodeItem.md +++ b/docs/SearchEpisodeItem.md @@ -5,21 +5,21 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**id** | **str** | | -**app_id** | **str** | | -**project_id** | **str** | | +**id** | **str** | Episode id. Use it to bind tags or to fetch this episode again. | +**app_id** | **str** | The business-semantic scope this memory was written under. | +**project_id** | **str** | Second half of that scope. | **user_id** | **str** | | [optional] **session_id** | **str** | | [optional] -**timestamp** | **datetime** | | -**sender_ids** | **List[str]** | | [optional] -**summary** | **str** | | -**subject** | **str** | | -**episode** | **str** | | +**timestamp** | **datetime** | When the remembered exchange happened (ISO 8601), not when it was extracted. | +**sender_ids** | **List[str]** | The senders that appear in the source exchange. | [optional] +**summary** | **str** | Short summary of the episode — what a result list should show. | +**subject** | **str** | What the episode is about, in a few words. | +**episode** | **str** | The episode's stored narrative body. This is the indexed, searchable text. | **readable_episode** | **str** | | [optional] -**type** | **str** | | -**atomic_facts** | [**List[SearchAtomicFactItem]**](SearchAtomicFactItem.md) | | [optional] -**tags** | **List[str]** | | [optional] -**score** | **float** | | +**type** | **str** | How the episode was produced — \"Conversation\" or \"AgentConversation\". | +**atomic_facts** | [**List[SearchAtomicFactItem]**](SearchAtomicFactItem.md) | The facts extracted from this episode, each with its own relevance score. | [optional] +**tags** | **List[str]** | Tags attached through /api/v2/memory/tag/*. | [optional] +**score** | **float** | Relevance of this episode to the query. What the number means depends on `method`: the hybrid path fuses its two routes into a probability in 0.0–1.0 (which is what `min_score` filters on), while keyword and vector pass the underlying engine's own score through — BM25 has no upper bound and vector similarity depends on the metric. So compare scores within one method, not across methods. | ## Example diff --git a/docs/SearchFilters.md b/docs/SearchFilters.md index ef51009..70e4ff6 100644 --- a/docs/SearchFilters.md +++ b/docs/SearchFilters.md @@ -7,6 +7,7 @@ Optional hard filters. ``category_id`` is a soft filter on recall (design 01 §3 Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **category_id** | **str** | | [optional] +**tag_ids** | **List[str]** | Hard filter that does not affect scoring: only topics carrying EVERY one of these tag ids are eligible. Use `boost_tag_ids` when the intent is to reweight rather than exclude. | [optional] [default to []] ## Example diff --git a/docs/SearchHit.md b/docs/SearchHit.md index 38c1d76..8287473 100644 --- a/docs/SearchHit.md +++ b/docs/SearchHit.md @@ -1,25 +1,27 @@ # SearchHit -A single search hit. ``object`` self-describes the unit (currently always topic). +A topic hit from recall or a document hit from filter-only search. ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**object** | **str** | | [optional] [default to 'topic'] -**id** | **str** | | -**doc_id** | **str** | | -**kb_id** | **str** | | -**category_id** | **str** | | [optional] [default to ''] +**object** | **str** | What this hit is. Always \"topic\" today — the unit of knowledge retrieval. | +**id** | **str** | The topic's id; fetch its full body with GET .../topics/{topic_id}. | +**doc_id** | **str** | The document the topic belongs to. | +**kb_id** | **str** | The knowledge base searched. | +**category_id** | **str** | The category that document is filed under; empty when uncategorized. | [optional] [default to ''] **category_name** | **str** | | [optional] -**name** | **str** | | [optional] [default to ''] -**depth** | **int** | | [optional] [default to 0] -**summary** | **str** | | [optional] [default to ''] +**name** | **str** | The topic's title. | +**depth** | **int** | The topic's depth in the document tree. | [optional] [default to 0] +**summary** | **str** | | [optional] **content** | **str** | | [optional] -**score** | **float** | | [optional] [default to 0.0] -**retrieval_method** | **str** | | [optional] [default to 'hybrid'] +**score** | **float** | Relevance of this topic to the query, and NOT a raw keyword or vector score: candidates from every method are reranked by a cross-encoder, min-max normalized WITHIN THIS RESPONSE, then given a category boost (up to 0.1) and, when `boost_tag_ids` was passed, a tag-coverage boost (up to 0.3). So it lands in roughly 0.0–1.4, the best hit of any response sits near the top of that range by construction, and scores compare inside one response but not across responses or queries. Three edge values to expect: every hit comes back at 0.5 when the reranker cannot separate the pool, every hit is 0.0 on a filter-only request (tags without a query, which never runs relevance at all), and a hit carries a synthetic -100.0 when its rerank batch failed — that is a fail-soft marker, not a relevance judgement. | +**retrieval_method** | **str** | The retrieval strategy this search ran with, so every hit in one response carries the same value and a stored or traced response is self-describing. It echoes the request's `method`, except on a filter-only request (tags without a query), which reports \"filter\" because no retrieval ran. It is deliberately NOT per-hit provenance: in a hybrid search the two lanes are fused, and hits recalled by only one of them still report \"hybrid\". | **source** | **str** | | [optional] **document** | [**DocumentContext**](DocumentContext.md) | | [optional] +**tags** | [**List[TagRef]**](TagRef.md) | The semantic tags materialized on this topic. | +**updated_at** | **datetime** | | [optional] ## Example diff --git a/docs/SearchInput.md b/docs/SearchInput.md index c383e70..6fc0860 100644 --- a/docs/SearchInput.md +++ b/docs/SearchInput.md @@ -5,18 +5,18 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**app_id** | **str** | | [optional] [default to 'default'] -**project_id** | **str** | | [optional] [default to 'default'] +**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] -**query** | **str** | | -**method** | **str** | | [optional] [default to 'hybrid'] -**top_k** | **int** | | [optional] [default to -1] +**query** | **str** | The natural-language query to retrieve against. | +**method** | **str** | Retrieval strategy. \"keyword\" is lexical, \"vector\" is embedding similarity, \"hybrid\" (default) combines both, and \"agentic\" lets the engine run a multi-round LLM-guided retrieval — more thorough, slower. | [optional] [default to 'hybrid'] +**top_k** | **int** | Maximum number of hits. 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] **radius** | **float** | | [optional] **min_score** | **float** | | [optional] -**include_profile** | **bool** | | [optional] [default to False] -**with_readable_episode** | **bool** | | [optional] [default to False] -**enable_llm_rerank** | **bool** | | [optional] [default to False] +**include_profile** | **bool** | Also return the user's profile alongside the hits, saving a second call. Ignored for an agent owner, whose results carry no profiles. | [optional] [default to False] +**with_readable_episode** | **bool** | Attach a human-readable rendering of each episode to the returned items, for display only — it is not indexed, filterable or scored, and callers fall back to `episode` when it is null. Ignored for an agent owner. | [optional] [default to False] +**enable_llm_rerank** | **bool** | Opt-in LLM rerank, and only for hybrid agent_case / agent_skill retrieval. The episode hybrid path has its own fact eviction and ignores this, as do keyword, vector and agentic. | [optional] [default to False] **filters** | [**FilterNode**](FilterNode.md) | | [optional] ## Example diff --git a/docs/SearchProfileItem.md b/docs/SearchProfileItem.md index 2228d2d..82c26c1 100644 --- a/docs/SearchProfileItem.md +++ b/docs/SearchProfileItem.md @@ -5,11 +5,13 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**id** | **str** | | -**app_id** | **str** | | -**project_id** | **str** | | -**user_id** | **str** | | -**profile_data** | **Dict[str, object]** | | [optional] +**id** | **str** | Profile id. | +**app_id** | **str** | The business-semantic scope this profile was written under. | +**project_id** | **str** | Second half of that scope. | +**user_id** | **str** | The user this profile describes. | +**profile_data** | **Dict[str, object]** | The profile itself — the explicit_info and implicit_traits items maintained by extraction and by /api/v2/memory/edit. Each item's id is what an edit operation targets. | [optional] +**created_at** | **datetime** | | [optional] +**updated_at** | **datetime** | | [optional] **score** | **float** | | [optional] ## Example diff --git a/docs/SignEnvelope.md b/docs/SignEnvelope.md index 7461bdf..825aab7 100644 --- a/docs/SignEnvelope.md +++ b/docs/SignEnvelope.md @@ -7,7 +7,7 @@ Response envelope for the sign endpoint. The `result.data` shape depends on `sta Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **error** | **str** | `\"OK\"` on success, otherwise a human-readable error message decoded from the business error. | [optional] -**request_id** | **str** | | [optional] +**request_id** | **str** | Id of this request — quote it when reporting a problem. | [optional] **status** | **int** | Business status code; 0 means success | [optional] **result** | [**SignEnvelopeAllOfResult**](SignEnvelopeAllOfResult.md) | | [optional] diff --git a/docs/SignObjectItem.md b/docs/SignObjectItem.md index acf5262..0757516 100644 --- a/docs/SignObjectItem.md +++ b/docs/SignObjectItem.md @@ -5,8 +5,8 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**file_id** | **str** | | -**file_name** | **str** | | +**file_id** | **str** | Your own id for this file. It comes back on the matching response item. | +**file_name** | **str** | The file's name, used to derive its type and preserved for display. | **file_type** | **str** | Media class. Default size limits per type: image=10MB, file=100MB, video=500MB. These are defaults and may be overridden per token (via the token's `file_limits`); the effective limit is enforced by S3 through the presigned POST `content-length-range` condition, and surfaced as `objectSignedInfo.maxSize`. | ## Example diff --git a/docs/SignResponse.md b/docs/SignResponse.md index 3896b89..78f3902 100644 --- a/docs/SignResponse.md +++ b/docs/SignResponse.md @@ -5,7 +5,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**object_list** | [**List[SignResponseItem]**](SignResponseItem.md) | | [optional] +**object_list** | [**List[SignResponseItem]**](SignResponseItem.md) | One signed entry per requested file, in the same order. | [optional] ## Example diff --git a/docs/SignResponseItem.md b/docs/SignResponseItem.md index b2441e2..559f9cd 100644 --- a/docs/SignResponseItem.md +++ b/docs/SignResponseItem.md @@ -5,12 +5,12 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**file_id** | **str** | | [optional] -**file_name** | **str** | | [optional] -**file_type** | **str** | | [optional] -**object_key** | **str** | | [optional] +**file_id** | **str** | The id you supplied for this file. | [optional] +**file_name** | **str** | The file's name, echoed back. | [optional] +**file_type** | **str** | The type the service resolved for it. | [optional] +**object_key** | **str** | The stored object's key — this is the value to pass later as a content `uri` on /api/v2/memory/add or a document ingest. | [optional] **object_url** | **str** | Present in the response struct for parity with the find endpoint, but not populated on the sign path (omitted from the JSON). | [optional] -**object_signed_info** | [**SignedInfo**](SignedInfo.md) | | [optional] +**object_signed_info** | [**SignedInfo**](SignedInfo.md) | Where and how to upload the bytes. | [optional] ## Example diff --git a/docs/SignedInfo.md b/docs/SignedInfo.md index 9aeb0d4..2abde3e 100644 --- a/docs/SignedInfo.md +++ b/docs/SignedInfo.md @@ -6,8 +6,8 @@ Presigned POST form data for direct-to-S3 upload Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**url** | **str** | | [optional] -**fields** | **Dict[str, str]** | | [optional] +**url** | **str** | The URL to POST the file to. | [optional] +**fields** | **Dict[str, str]** | Form fields that must accompany the upload, exactly as given, with the file itself last. | [optional] **max_size** | **int** | Maximum file size in bytes | [optional] ## Example diff --git a/docs/StorageApi.md b/docs/StorageApi.md index e74b2b7..788c4ba 100644 --- a/docs/StorageApi.md +++ b/docs/StorageApi.md @@ -12,6 +12,8 @@ Method | HTTP request | Description Get multimodal upload URLs +Presign a direct-to-storage upload for multimodal data. POST the file to the returned URL yourself, then reference the returned object key as a message's content `uri` (/api/v2/memory/add) or as a document's content `uri` (.../documents). Uploading first and passing the key is the only path that gets a non-text item parsed — see `base64` on the content object. The Python SDK's `upload()` does both steps in one call. + ### Example * Bearer Authentication (BearerAuth): diff --git a/docs/SuccessEnvelopeRelatedTagUsageListData.md b/docs/SuccessEnvelopeRelatedTagUsageListData.md new file mode 100644 index 0000000..57259bb --- /dev/null +++ b/docs/SuccessEnvelopeRelatedTagUsageListData.md @@ -0,0 +1,30 @@ +# SuccessEnvelopeRelatedTagUsageListData + + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**request_id** | **str** | Request trace id (peer to data) | +**data** | [**RelatedTagUsageListData**](RelatedTagUsageListData.md) | Endpoint-defined business result | + +## Example + +```python +from everos_cloud.models.success_envelope_related_tag_usage_list_data import SuccessEnvelopeRelatedTagUsageListData + +# TODO update the JSON string below +json = "{}" +# create an instance of SuccessEnvelopeRelatedTagUsageListData from a JSON string +success_envelope_related_tag_usage_list_data_instance = SuccessEnvelopeRelatedTagUsageListData.from_json(json) +# print the JSON string representation of the object +print(SuccessEnvelopeRelatedTagUsageListData.to_json()) + +# convert the object into a dict +success_envelope_related_tag_usage_list_data_dict = success_envelope_related_tag_usage_list_data_instance.to_dict() +# create an instance of SuccessEnvelopeRelatedTagUsageListData from a dict +success_envelope_related_tag_usage_list_data_from_dict = SuccessEnvelopeRelatedTagUsageListData.from_dict(success_envelope_related_tag_usage_list_data_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/docs/SuccessEnvelopeTopicFilterListData.md b/docs/SuccessEnvelopeTopicFilterListData.md new file mode 100644 index 0000000..64ab2fd --- /dev/null +++ b/docs/SuccessEnvelopeTopicFilterListData.md @@ -0,0 +1,30 @@ +# SuccessEnvelopeTopicFilterListData + + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**request_id** | **str** | Request trace id (peer to data) | +**data** | [**TopicFilterListData**](TopicFilterListData.md) | Endpoint-defined business result | + +## Example + +```python +from everos_cloud.models.success_envelope_topic_filter_list_data import SuccessEnvelopeTopicFilterListData + +# TODO update the JSON string below +json = "{}" +# create an instance of SuccessEnvelopeTopicFilterListData from a JSON string +success_envelope_topic_filter_list_data_instance = SuccessEnvelopeTopicFilterListData.from_json(json) +# print the JSON string representation of the object +print(SuccessEnvelopeTopicFilterListData.to_json()) + +# convert the object into a dict +success_envelope_topic_filter_list_data_dict = success_envelope_topic_filter_list_data_instance.to_dict() +# create an instance of SuccessEnvelopeTopicFilterListData from a dict +success_envelope_topic_filter_list_data_from_dict = SuccessEnvelopeTopicFilterListData.from_dict(success_envelope_topic_filter_list_data_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/docs/SuccessEnvelopeTopicTagWriteData.md b/docs/SuccessEnvelopeTopicTagWriteData.md new file mode 100644 index 0000000..3065224 --- /dev/null +++ b/docs/SuccessEnvelopeTopicTagWriteData.md @@ -0,0 +1,30 @@ +# SuccessEnvelopeTopicTagWriteData + + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**request_id** | **str** | Request trace id (peer to data) | +**data** | [**TopicTagWriteData**](TopicTagWriteData.md) | Endpoint-defined business result | + +## Example + +```python +from everos_cloud.models.success_envelope_topic_tag_write_data import SuccessEnvelopeTopicTagWriteData + +# TODO update the JSON string below +json = "{}" +# create an instance of SuccessEnvelopeTopicTagWriteData from a JSON string +success_envelope_topic_tag_write_data_instance = SuccessEnvelopeTopicTagWriteData.from_json(json) +# print the JSON string representation of the object +print(SuccessEnvelopeTopicTagWriteData.to_json()) + +# convert the object into a dict +success_envelope_topic_tag_write_data_dict = success_envelope_topic_tag_write_data_instance.to_dict() +# create an instance of SuccessEnvelopeTopicTagWriteData from a dict +success_envelope_topic_tag_write_data_from_dict = SuccessEnvelopeTopicTagWriteData.from_dict(success_envelope_topic_tag_write_data_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/docs/TagBindData.md b/docs/TagBindData.md index a1db2f8..fc9d675 100644 --- a/docs/TagBindData.md +++ b/docs/TagBindData.md @@ -5,8 +5,8 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**matched** | **int** | | [optional] [default to 0] -**requested** | **int** | | [optional] [default to 0] +**matched** | **int** | How many of the submitted memories the operation matched. Matching is not the same as changing: re-binding a tag an item already carries matches without modifying it. | [optional] [default to 0] +**requested** | **int** | How many ids were submitted. `matched` below `requested` means some ids were not found — deleted, another tenant's, or (for bind) already at the per-memory tag limit. | [optional] [default to 0] ## Example diff --git a/docs/TagBindInput.md b/docs/TagBindInput.md index 33c6234..268b859 100644 --- a/docs/TagBindInput.md +++ b/docs/TagBindInput.md @@ -5,9 +5,9 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**memory_type** | **str** | | -**memory_ids** | **List[str]** | | -**tags** | **List[str]** | | +**memory_type** | **str** | The type of the memories being tagged. \"episode\" is what this phase supports; agent cases and skills onboard later without an API change. | +**memory_ids** | **List[str]** | The memories to tag, by id (1–200 per request). Ids come from /api/v2/memory/get or /api/v2/memory/search. | +**tags** | **List[str]** | Tags to add (1–100 per request, each 1–32 characters). Tags the memories already carry are left in place. | ## Example diff --git a/docs/TagRef.md b/docs/TagRef.md new file mode 100644 index 0000000..73c75c6 --- /dev/null +++ b/docs/TagRef.md @@ -0,0 +1,31 @@ +# TagRef + +Opaque semantic tag reference; its containing topic conveys ownership. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**id** | **str** | Opaque semantic tag id. | +**name** | **str** | | [optional] + +## Example + +```python +from everos_cloud.models.tag_ref import TagRef + +# TODO update the JSON string below +json = "{}" +# create an instance of TagRef from a JSON string +tag_ref_instance = TagRef.from_json(json) +# print the JSON string representation of the object +print(TagRef.to_json()) + +# convert the object into a dict +tag_ref_dict = tag_ref_instance.to_dict() +# create an instance of TagRef from a dict +tag_ref_from_dict = TagRef.from_dict(tag_ref_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/docs/TagReplaceData.md b/docs/TagReplaceData.md index 4dc6ad5..d7a9406 100644 --- a/docs/TagReplaceData.md +++ b/docs/TagReplaceData.md @@ -5,8 +5,8 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**matched** | **int** | | [optional] [default to 0] -**requested** | **int** | | [optional] [default to 0] +**matched** | **int** | How many of the submitted memories the operation matched. Matching is not the same as changing: re-binding a tag an item already carries matches without modifying it. | [optional] [default to 0] +**requested** | **int** | How many ids were submitted. `matched` below `requested` means some ids were not found — deleted, another tenant's, or (for bind) already at the per-memory tag limit. | [optional] [default to 0] ## Example diff --git a/docs/TagReplaceInput.md b/docs/TagReplaceInput.md index 387a243..1edeb5d 100644 --- a/docs/TagReplaceInput.md +++ b/docs/TagReplaceInput.md @@ -6,9 +6,9 @@ Full replacement (PUT semantics): overwrite each item's tag set with ``tags``. Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**memory_type** | **str** | | -**memory_ids** | **List[str]** | | -**tags** | **List[str]** | | +**memory_type** | **str** | The type of the memories being retagged, e.g. \"episode\". | +**memory_ids** | **List[str]** | The memories to retag, by id (1–200 per request). | +**tags** | **List[str]** | The complete tag set to store (up to 100, each 1–32 characters). Tags absent from this list are dropped, and an empty list clears them all. Duplicates collapse. | ## Example diff --git a/docs/TagUnbindData.md b/docs/TagUnbindData.md index c9bee90..49ce4f9 100644 --- a/docs/TagUnbindData.md +++ b/docs/TagUnbindData.md @@ -5,8 +5,8 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**matched** | **int** | | [optional] [default to 0] -**requested** | **int** | | [optional] [default to 0] +**matched** | **int** | How many of the submitted memories the operation matched. Matching is not the same as changing: re-binding a tag an item already carries matches without modifying it. | [optional] [default to 0] +**requested** | **int** | How many ids were submitted. `matched` below `requested` means some ids were not found — deleted, another tenant's, or (for bind) already at the per-memory tag limit. | [optional] [default to 0] ## Example diff --git a/docs/TagUnbindInput.md b/docs/TagUnbindInput.md index f9b382c..4bcf7e2 100644 --- a/docs/TagUnbindInput.md +++ b/docs/TagUnbindInput.md @@ -5,9 +5,9 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**memory_type** | **str** | | -**memory_ids** | **List[str]** | | -**tags** | **List[str]** | | +**memory_type** | **str** | The type of the memories being untagged, e.g. \"episode\". | +**memory_ids** | **List[str]** | The memories to untag, by id (1–200 per request). | +**tags** | **List[str]** | Tags to remove (1–100 per request). Tags not listed here are left in place. | ## Example diff --git a/docs/TaskErrorResponseError.md b/docs/TaskErrorResponseError.md index 8ff1ad6..14337a1 100644 --- a/docs/TaskErrorResponseError.md +++ b/docs/TaskErrorResponseError.md @@ -1,5 +1,6 @@ # TaskErrorResponseError +What went wrong, with a machine-readable code and a message. ## Properties diff --git a/docs/TaskItem.md b/docs/TaskItem.md index a00117a..091b90d 100644 --- a/docs/TaskItem.md +++ b/docs/TaskItem.md @@ -5,14 +5,14 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**created_at** | **datetime** | | [optional] +**created_at** | **datetime** | When the task was accepted. | [optional] **error** | **str** | Failure reason; present only when status is failed | [optional] -**error_code** | **str** | | [optional] +**error_code** | **str** | Machine-readable failure code, alongside the human-readable `error`. | [optional] **finished_at** | **datetime** | Completion time; absent while the task is not in a terminal state | [optional] **id** | **str** | Task id (the request's X-Request-Id), not a database primary key | **object** | **str** | Resource type produced by the task (frozen field, cannot express a batch) | [optional] -**object_id** | **str** | | [optional] -**status** | **str** | | +**object_id** | **str** | Id of the resource the task produced, once there is one. | [optional] +**status** | **str** | Where the task is: \"queued\", \"processing\", \"pending\", \"success\" or \"failed\". Treat it as an open set — a value you do not recognise is terminal only when `finished_at` is set. | **task_type** | **str** | Async interface that produced the task, e.g. memory_add / knowledge_document / batch_import | [optional] ## Example diff --git a/docs/TaskListResponse.md b/docs/TaskListResponse.md index 19503a4..41189ab 100644 --- a/docs/TaskListResponse.md +++ b/docs/TaskListResponse.md @@ -6,7 +6,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **data** | [**TaskListResponseData**](TaskListResponseData.md) | | -**request_id** | **str** | | [optional] +**request_id** | **str** | Id of this request — quote it when reporting a problem. | [optional] ## Example diff --git a/docs/TaskListResponseData.md b/docs/TaskListResponseData.md index 4bab1fe..c41de83 100644 --- a/docs/TaskListResponseData.md +++ b/docs/TaskListResponseData.md @@ -1,5 +1,6 @@ # TaskListResponseData +The page of tasks, with its paging counters. ## Properties diff --git a/docs/TaskStatsResponse.md b/docs/TaskStatsResponse.md index 66c5299..ee8c29c 100644 --- a/docs/TaskStatsResponse.md +++ b/docs/TaskStatsResponse.md @@ -6,7 +6,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **data** | [**TaskStatsResponseData**](TaskStatsResponseData.md) | | -**request_id** | **str** | | [optional] +**request_id** | **str** | Id of this request — quote it when reporting a problem. | [optional] ## Example diff --git a/docs/TaskStatsResponseData.md b/docs/TaskStatsResponseData.md index 1a89daa..af0978c 100644 --- a/docs/TaskStatsResponseData.md +++ b/docs/TaskStatsResponseData.md @@ -1,5 +1,6 @@ # TaskStatsResponseData +The per-status counts and the window they cover. ## Properties diff --git a/docs/TaskStatusResponse.md b/docs/TaskStatusResponse.md index 68dc2dd..ff131d9 100644 --- a/docs/TaskStatusResponse.md +++ b/docs/TaskStatusResponse.md @@ -5,8 +5,8 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**data** | [**TaskItem**](TaskItem.md) | | -**request_id** | **str** | | [optional] +**data** | [**TaskItem**](TaskItem.md) | The task. | +**request_id** | **str** | Id of this request — quote it when reporting a problem. | [optional] ## Example diff --git a/docs/TasksApi.md b/docs/TasksApi.md index ada414f..54db5a8 100644 --- a/docs/TasksApi.md +++ b/docs/TasksApi.md @@ -14,7 +14,7 @@ Method | HTTP request | Description Aggregate task counts by status -Counts tasks per status over a time window. All four statuses are always present (0 when absent) so dashboards get a stable shape, and the response echoes the window actually used after server-side clamping. Results are scoped to the caller's tenant, resolved from the request context; a caller can only ever see its own tasks. +Counts tasks per status over a time window. All five statuses (queued, processing, pending, success, failed) are always present (0 when absent) so dashboards get a stable shape, and the response echoes the window actually used after server-side clamping. Results are scoped to the caller's tenant, resolved from the request context. ### Example diff --git a/docs/ToolCall.md b/docs/ToolCall.md index d187ff8..584ad07 100644 --- a/docs/ToolCall.md +++ b/docs/ToolCall.md @@ -5,9 +5,9 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**id** | **str** | | -**type** | **str** | | [optional] [default to 'function'] -**function** | [**ToolCallFunction**](ToolCallFunction.md) | | +**id** | **str** | Tool-call id; the matching \"tool\" message echoes it as `tool_call_id`. | +**type** | **str** | Tool-call kind. Always \"function\" today. | [optional] [default to 'function'] +**function** | [**ToolCallFunction**](ToolCallFunction.md) | The function invoked, with its arguments. | ## Example diff --git a/docs/ToolCallFunction.md b/docs/ToolCallFunction.md index 7b52d86..b927059 100644 --- a/docs/ToolCallFunction.md +++ b/docs/ToolCallFunction.md @@ -5,8 +5,8 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**name** | **str** | | -**arguments** | **str** | | +**name** | **str** | Name of the function the assistant called. | +**arguments** | **str** | The call's arguments as a JSON-encoded string (OpenAI shape), not an object. | ## Example diff --git a/docs/TopicDetailData.md b/docs/TopicDetailData.md index 271536f..f3d19bf 100644 --- a/docs/TopicDetailData.md +++ b/docs/TopicDetailData.md @@ -6,20 +6,23 @@ Full topic (node), with content transparently restored (inline or from S3). Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**id** | **str** | | -**doc_id** | **str** | | -**kb_id** | **str** | | -**category_id** | **str** | | [optional] [default to ''] +**id** | **str** | Topic id. | +**doc_id** | **str** | The document this topic was extracted from. | +**kb_id** | **str** | The knowledge base that document belongs to. | +**type** | **str** | Structural role of this topic node | +**category_id** | **str** | The category the document is filed under; empty when uncategorized. | [optional] [default to ''] **category_name** | **str** | | [optional] -**name** | **str** | | -**depth** | **int** | | [optional] [default to 0] -**seq** | **int** | | [optional] [default to 0] -**summary** | **str** | | [optional] [default to ''] +**name** | **str** | The topic's title. | +**depth** | **int** | Depth in the document tree — 0 is the document root, 1 a top-level topic. | [optional] [default to 0] +**seq** | **int** | Depth-first position within the document. Use it as an ordering, not as an index to compute with. | [optional] [default to 0] +**summary** | **str** | Retrieval-oriented summary covering this topic and everything under it. | [optional] [default to ''] **content** | **str** | | [optional] -**labels** | **List[str]** | | [optional] +**labels** | **List[str]** | Labels attached to the topic during extraction. | [optional] **parent_id** | **str** | | [optional] -**children_ids** | **List[str]** | | [optional] -**metadata** | **Dict[str, object]** | | [optional] +**children_ids** | **List[str]** | The topics directly beneath this one. | [optional] +**metadata** | **Dict[str, object]** | Extraction metadata carried alongside the topic. | [optional] +**tag_ids** | **List[str]** | Opaque final materialized semantic tag ids (maximum 50) | +**version** | **int** | Current topic tag CAS version | **created_at** | **datetime** | | [optional] **updated_at** | **datetime** | | [optional] diff --git a/docs/TopicFilterItem.md b/docs/TopicFilterItem.md new file mode 100644 index 0000000..5cde899 --- /dev/null +++ b/docs/TopicFilterItem.md @@ -0,0 +1,40 @@ +# TopicFilterItem + +Slim item for the KB-wide tag-filter endpoint. This is deliberately separate from :class:`TopicListItem`: the document-tree API may hydrate content and exposes timestamps, while the cross-service tag-filter wire is frozen without those fields. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**id** | **str** | Topic (node) id | +**doc_id** | **str** | Owning document id | [optional] [default to ''] +**kb_id** | **str** | Owning knowledge base id | [optional] [default to ''] +**name** | **str** | Topic title | +**type** | **str** | Structural role of the topic — \"root\" for the synthetic document-root node, \"section\" for a real topic. | [optional] [default to 'section'] +**depth** | **int** | Depth in the document tree — 0 is the document root, 1 a top-level topic. | [optional] [default to 0] +**seq** | **int** | Depth-first position within the document. Use it as an ordering, not as an index to compute with. | [optional] [default to 0] +**parent_id** | **str** | | [optional] +**summary** | **str** | Retrieval-oriented summary covering this topic and everything under it. | [optional] [default to ''] +**tag_ids** | **List[str]** | Opaque final materialized semantic tag ids (maximum 50) | +**version** | **int** | Current topic tag CAS version | + +## Example + +```python +from everos_cloud.models.topic_filter_item import TopicFilterItem + +# TODO update the JSON string below +json = "{}" +# create an instance of TopicFilterItem from a JSON string +topic_filter_item_instance = TopicFilterItem.from_json(json) +# print the JSON string representation of the object +print(TopicFilterItem.to_json()) + +# convert the object into a dict +topic_filter_item_dict = topic_filter_item_instance.to_dict() +# create an instance of TopicFilterItem from a dict +topic_filter_item_from_dict = TopicFilterItem.from_dict(topic_filter_item_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/docs/TopicFilterListData.md b/docs/TopicFilterListData.md new file mode 100644 index 0000000..edc46a1 --- /dev/null +++ b/docs/TopicFilterListData.md @@ -0,0 +1,30 @@ +# TopicFilterListData + + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**topics** | [**List[TopicFilterItem]**](TopicFilterItem.md) | The matching topics, one page of them. | +**total** | **int** | How many topics satisfy the all-tags-on-one-topic condition in total, counted before paging. | + +## Example + +```python +from everos_cloud.models.topic_filter_list_data import TopicFilterListData + +# TODO update the JSON string below +json = "{}" +# create an instance of TopicFilterListData from a JSON string +topic_filter_list_data_instance = TopicFilterListData.from_json(json) +# print the JSON string representation of the object +print(TopicFilterListData.to_json()) + +# convert the object into a dict +topic_filter_list_data_dict = topic_filter_list_data_instance.to_dict() +# create an instance of TopicFilterListData from a dict +topic_filter_list_data_from_dict = TopicFilterListData.from_dict(topic_filter_list_data_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/docs/TopicListData.md b/docs/TopicListData.md index 3a1bdba..04353f0 100644 --- a/docs/TopicListData.md +++ b/docs/TopicListData.md @@ -6,7 +6,7 @@ A document's topic tree, DFS-ordered (flat list; build the tree from `parent_id` Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**topics** | [**List[TopicListItem]**](TopicListItem.md) | | [optional] +**topics** | [**List[TopicListItem]**](TopicListItem.md) | The document's topics, flat and depth-first ordered — build the tree from `parent_id`. Includes the synthetic document-root item, so this list holds exactly one more entry than the document's `topic_count`. | [optional] ## Example diff --git a/docs/TopicListItem.md b/docs/TopicListItem.md index ba4b770..1e60714 100644 --- a/docs/TopicListItem.md +++ b/docs/TopicListItem.md @@ -7,6 +7,8 @@ Node-tree overview item. ``content`` only when the caller asks for it. Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **id** | **str** | Topic (node) id | +**doc_id** | **str** | Owning document id | [optional] [default to ''] +**kb_id** | **str** | Owning knowledge base id | [optional] [default to ''] **name** | **str** | Node title. For the document-root item (`type=root`) this is the document title, i.e. the same value as the document's `title` | **type** | **str** | Structural role: `root` = the document-root container (exactly one per document, `depth=0`, `parent_id=null`, empty body), `section` = a real topic, `element` = rich media (reserved, not produced yet). Filter on this rather than on `depth==0` to tell the root apart from real topics | [optional] [default to 'section'] **depth** | **int** | Tree depth: 0 = document root, 1 = a top-level topic | [optional] [default to 0] @@ -14,6 +16,8 @@ Name | Type | Description | Notes **parent_id** | **str** | | [optional] **summary** | **str** | Retrieval-oriented summary covering this node AND its subtree. On the root item it is the document-level summary | [optional] [default to ''] **content** | **str** | | [optional] +**tag_ids** | **List[str]** | Opaque final materialized semantic tag ids (maximum 50) | [optional] +**version** | **int** | Current topic tag CAS version | [optional] [default to 0] **created_at** | **datetime** | | [optional] **updated_at** | **datetime** | | [optional] diff --git a/docs/TopicTagReplaceBody.md b/docs/TopicTagReplaceBody.md new file mode 100644 index 0000000..120a99a --- /dev/null +++ b/docs/TopicTagReplaceBody.md @@ -0,0 +1,30 @@ +# TopicTagReplaceBody + + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**tag_ids** | **List[str]** | Complete materialized snapshot. Cloud stable-deduplicates the request, stores the first 50 ids, and reports any truncation. | +**version** | **int** | Expected current topic tag_version (CAS) | + +## Example + +```python +from everos_cloud.models.topic_tag_replace_body import TopicTagReplaceBody + +# TODO update the JSON string below +json = "{}" +# create an instance of TopicTagReplaceBody from a JSON string +topic_tag_replace_body_instance = TopicTagReplaceBody.from_json(json) +# print the JSON string representation of the object +print(TopicTagReplaceBody.to_json()) + +# convert the object into a dict +topic_tag_replace_body_dict = topic_tag_replace_body_instance.to_dict() +# create an instance of TopicTagReplaceBody from a dict +topic_tag_replace_body_from_dict = TopicTagReplaceBody.from_dict(topic_tag_replace_body_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/docs/TopicTagWriteData.md b/docs/TopicTagWriteData.md new file mode 100644 index 0000000..c303371 --- /dev/null +++ b/docs/TopicTagWriteData.md @@ -0,0 +1,35 @@ +# TopicTagWriteData + + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**topic_id** | **str** | The topic whose tag snapshot was written. | +**requested** | **int** | Stable-distinct request id count; not vocabulary-validity count | +**tag_ids** | **List[str]** | Complete materialized topic tag snapshot after the accepted write | +**version** | **int** | Current topic tag version | +**truncated** | **bool** | Whether distinct input exceeded the store limit | +**limit** | **int** | Materialized topic tag limit | +**dropped_count** | **int** | Distinct requested ids omitted by stable truncation | + +## Example + +```python +from everos_cloud.models.topic_tag_write_data import TopicTagWriteData + +# TODO update the JSON string below +json = "{}" +# create an instance of TopicTagWriteData from a JSON string +topic_tag_write_data_instance = TopicTagWriteData.from_json(json) +# print the JSON string representation of the object +print(TopicTagWriteData.to_json()) + +# convert the object into a dict +topic_tag_write_data_dict = topic_tag_write_data_instance.to_dict() +# create an instance of TopicTagWriteData from a dict +topic_tag_write_data_from_dict = TopicTagWriteData.from_dict(topic_tag_write_data_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/docs/UnprocessedMessageDTO.md b/docs/UnprocessedMessageDTO.md index 85509cb..b68029a 100644 --- a/docs/UnprocessedMessageDTO.md +++ b/docs/UnprocessedMessageDTO.md @@ -6,15 +6,15 @@ Buffered raw message not yet extracted (no owner — inference happens after bou Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**id** | **str** | | -**app_id** | **str** | | -**project_id** | **str** | | -**session_id** | **str** | | -**sender_id** | **str** | | +**id** | **str** | Buffered-message id. | +**app_id** | **str** | The business-semantic scope the message was written under. | +**project_id** | **str** | Second half of that scope. | +**session_id** | **str** | The session the message is buffered under. | +**sender_id** | **str** | Who sent it. | **sender_name** | **str** | | [optional] -**role** | **str** | | -**content** | [**Content**](Content.md) | | -**timestamp** | **datetime** | | +**role** | **str** | \"user\", \"assistant\" or \"tool\", as submitted. | +**content** | [**Content1**](Content1.md) | | +**timestamp** | **datetime** | When the message was produced (ISO 8601). | **tool_calls** | [**List[ToolCall]**](ToolCall.md) | | [optional] **tool_call_id** | **str** | | [optional] diff --git a/docs/UpdateOperation.md b/docs/UpdateOperation.md index 5a166b1..9b9007d 100644 --- a/docs/UpdateOperation.md +++ b/docs/UpdateOperation.md @@ -7,9 +7,9 @@ Update an existing profile item (partial ``data`` shallow-merge). Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **reason** | **str** | | [optional] -**action** | **str** | | -**type** | **str** | | -**item_id** | **str** | | +**action** | **str** | Always \"update\" for this variant. | +**type** | **str** | Which profile item this edit targets — \"explicit_info\" or \"implicit_traits\". It must match the `item_id` prefix. | +**item_id** | **str** | The item to update. Its prefix must match the item type — \"ei_\" for explicit_info, \"it_\" for implicit_traits — followed by 24 hex characters. | **data** | [**Data1**](Data1.md) | | ## Example diff --git a/docs/ValidationError.md b/docs/ValidationError.md index cd5716c..7974b18 100644 --- a/docs/ValidationError.md +++ b/docs/ValidationError.md @@ -5,9 +5,9 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**loc** | [**List[ValidationErrorLocInner]**](ValidationErrorLocInner.md) | | -**msg** | **str** | | -**type** | **str** | | +**loc** | [**List[ValidationErrorLocInner]**](ValidationErrorLocInner.md) | Path to the offending field, from the body root. | +**msg** | **str** | What is wrong with it. | +**type** | **str** | Machine-readable validation-error kind. | ## Example diff --git a/everos_cloud/__init__.py b/everos_cloud/__init__.py index 747ea1a..ceed538 100644 --- a/everos_cloud/__init__.py +++ b/everos_cloud/__init__.py @@ -15,7 +15,7 @@ """ # noqa: E501 -__version__ = "1.1.0-rc2" +__version__ = "1.1.0" # import apis into sdk package from everos_cloud.api.knowledge_api import KnowledgeApi @@ -47,6 +47,7 @@ from everos_cloud.models.category_list_data import CategoryListData from everos_cloud.models.category_patch_body import CategoryPatchBody from everos_cloud.models.content import Content +from everos_cloud.models.content1 import Content1 from everos_cloud.models.content_item import ContentItem from everos_cloud.models.data import Data from everos_cloud.models.data1 import Data1 @@ -68,6 +69,8 @@ from everos_cloud.models.envelope import Envelope from everos_cloud.models.envelope_result import EnvelopeResult from everos_cloud.models.episode_item import EpisodeItem +from everos_cloud.models.error_body import ErrorBody +from everos_cloud.models.error_envelope import ErrorEnvelope from everos_cloud.models.explicit_info_data import ExplicitInfoData from everos_cloud.models.explicit_info_patch import ExplicitInfoPatch from everos_cloud.models.filter_node import FilterNode @@ -86,6 +89,9 @@ from everos_cloud.models.kb_search_data import KbSearchData from everos_cloud.models.message_item import MessageItem from everos_cloud.models.profile_item import ProfileItem +from everos_cloud.models.related_tag_usage_body import RelatedTagUsageBody +from everos_cloud.models.related_tag_usage_item import RelatedTagUsageItem +from everos_cloud.models.related_tag_usage_list_data import RelatedTagUsageListData from everos_cloud.models.search_agent_case_item import SearchAgentCaseItem from everos_cloud.models.search_agent_skill_item import SearchAgentSkillItem from everos_cloud.models.search_atomic_fact_item import SearchAtomicFactItem @@ -120,14 +126,18 @@ from everos_cloud.models.success_envelope_kb_delete_data import SuccessEnvelopeKbDeleteData from everos_cloud.models.success_envelope_kb_list_data import SuccessEnvelopeKbListData from everos_cloud.models.success_envelope_kb_search_data import SuccessEnvelopeKbSearchData +from everos_cloud.models.success_envelope_related_tag_usage_list_data import SuccessEnvelopeRelatedTagUsageListData from everos_cloud.models.success_envelope_search_data import SuccessEnvelopeSearchData from everos_cloud.models.success_envelope_tag_bind_data import SuccessEnvelopeTagBindData from everos_cloud.models.success_envelope_tag_replace_data import SuccessEnvelopeTagReplaceData from everos_cloud.models.success_envelope_tag_unbind_data import SuccessEnvelopeTagUnbindData from everos_cloud.models.success_envelope_topic_detail_data import SuccessEnvelopeTopicDetailData +from everos_cloud.models.success_envelope_topic_filter_list_data import SuccessEnvelopeTopicFilterListData from everos_cloud.models.success_envelope_topic_list_data import SuccessEnvelopeTopicListData +from everos_cloud.models.success_envelope_topic_tag_write_data import SuccessEnvelopeTopicTagWriteData from everos_cloud.models.tag_bind_data import TagBindData from everos_cloud.models.tag_bind_input import TagBindInput +from everos_cloud.models.tag_ref import TagRef from everos_cloud.models.tag_replace_data import TagReplaceData from everos_cloud.models.tag_replace_input import TagReplaceInput from everos_cloud.models.tag_unbind_data import TagUnbindData @@ -144,8 +154,12 @@ from everos_cloud.models.tool_call import ToolCall from everos_cloud.models.tool_call_function import ToolCallFunction from everos_cloud.models.topic_detail_data import TopicDetailData +from everos_cloud.models.topic_filter_item import TopicFilterItem +from everos_cloud.models.topic_filter_list_data import TopicFilterListData from everos_cloud.models.topic_list_data import TopicListData from everos_cloud.models.topic_list_item import TopicListItem +from everos_cloud.models.topic_tag_replace_body import TopicTagReplaceBody +from everos_cloud.models.topic_tag_write_data import TopicTagWriteData from everos_cloud.models.unprocessed_message_dto import UnprocessedMessageDTO from everos_cloud.models.update_operation import UpdateOperation from everos_cloud.models.validation_error import ValidationError diff --git a/everos_cloud/api/knowledge_api.py b/everos_cloud/api/knowledge_api.py index b6a166d..c2c5269 100644 --- a/everos_cloud/api/knowledge_api.py +++ b/everos_cloud/api/knowledge_api.py @@ -26,6 +26,7 @@ from everos_cloud.models.doc_patch_body import DocPatchBody from everos_cloud.models.kb_create_input import KbCreateInput from everos_cloud.models.kb_patch_body import KbPatchBody +from everos_cloud.models.related_tag_usage_body import RelatedTagUsageBody from everos_cloud.models.search_body import SearchBody from everos_cloud.models.success_envelope_category_data import SuccessEnvelopeCategoryData from everos_cloud.models.success_envelope_category_delete_data import SuccessEnvelopeCategoryDeleteData @@ -39,8 +40,12 @@ from everos_cloud.models.success_envelope_kb_delete_data import SuccessEnvelopeKbDeleteData from everos_cloud.models.success_envelope_kb_list_data import SuccessEnvelopeKbListData from everos_cloud.models.success_envelope_kb_search_data import SuccessEnvelopeKbSearchData +from everos_cloud.models.success_envelope_related_tag_usage_list_data import SuccessEnvelopeRelatedTagUsageListData from everos_cloud.models.success_envelope_topic_detail_data import SuccessEnvelopeTopicDetailData +from everos_cloud.models.success_envelope_topic_filter_list_data import SuccessEnvelopeTopicFilterListData from everos_cloud.models.success_envelope_topic_list_data import SuccessEnvelopeTopicListData +from everos_cloud.models.success_envelope_topic_tag_write_data import SuccessEnvelopeTopicTagWriteData +from everos_cloud.models.topic_tag_replace_body import TopicTagReplaceBody from everos_cloud.api_client import ApiClient, RequestSerialized from everos_cloud.api_response import ApiResponse @@ -80,6 +85,7 @@ def create_category( ) -> SuccessEnvelopeCategoryData: """Create a category + Add a category to this knowledge base's taxonomy. Categories are what a document is filed under: on ingest each document is classified into one of them, unless the caller pins `category_id` on the upload. The category's description is not decoration — it is what the classifier matches against. :param kb_id: (required) :type kb_id: str @@ -155,6 +161,7 @@ def create_category_with_http_info( ) -> ApiResponse[SuccessEnvelopeCategoryData]: """Create a category + Add a category to this knowledge base's taxonomy. Categories are what a document is filed under: on ingest each document is classified into one of them, unless the caller pins `category_id` on the upload. The category's description is not decoration — it is what the classifier matches against. :param kb_id: (required) :type kb_id: str @@ -230,6 +237,7 @@ def create_category_without_preload_content( ) -> RESTResponseType: """Create a category + Add a category to this knowledge base's taxonomy. Categories are what a document is filed under: on ingest each document is classified into one of them, unless the caller pins `category_id` on the upload. The category's description is not decoration — it is what the classifier matches against. :param kb_id: (required) :type kb_id: str @@ -381,6 +389,7 @@ def create_document( ) -> SuccessEnvelopeDocIngestData: """Upload a document (async ingest) + Upload a document for ingest. Ingest is asynchronous at the gateway: it answers 202 with status \"queued\" and a `task_id`, and the document id is minted downstream — poll GET /api/v2/tasks/{task_id}, then resolve the id from GET .../documents. Ingest is only truly complete once that document reports `topic_count` greater than 0. `content` is one content object: inline text, or a file already uploaded through POST /api/v2/object/sign, referenced by its object key as the content's `uri`. Omit `category_id` to let the server classify the document into this base's taxonomy. :param kb_id: (required) :type kb_id: str @@ -456,6 +465,7 @@ def create_document_with_http_info( ) -> ApiResponse[SuccessEnvelopeDocIngestData]: """Upload a document (async ingest) + Upload a document for ingest. Ingest is asynchronous at the gateway: it answers 202 with status \"queued\" and a `task_id`, and the document id is minted downstream — poll GET /api/v2/tasks/{task_id}, then resolve the id from GET .../documents. Ingest is only truly complete once that document reports `topic_count` greater than 0. `content` is one content object: inline text, or a file already uploaded through POST /api/v2/object/sign, referenced by its object key as the content's `uri`. Omit `category_id` to let the server classify the document into this base's taxonomy. :param kb_id: (required) :type kb_id: str @@ -531,6 +541,7 @@ def create_document_without_preload_content( ) -> RESTResponseType: """Upload a document (async ingest) + Upload a document for ingest. Ingest is asynchronous at the gateway: it answers 202 with status \"queued\" and a `task_id`, and the document id is minted downstream — poll GET /api/v2/tasks/{task_id}, then resolve the id from GET .../documents. Ingest is only truly complete once that document reports `topic_count` greater than 0. `content` is one content object: inline text, or a file already uploaded through POST /api/v2/object/sign, referenced by its object key as the content's `uri`. Omit `category_id` to let the server classify the document into this base's taxonomy. :param kb_id: (required) :type kb_id: str @@ -681,6 +692,7 @@ def create_knowledge_base( ) -> SuccessEnvelopeKbData: """Create a knowledge base + Create a knowledge base — a searchable document library with its own category taxonomy. The returned id is the `kb_id` every other knowledge operation takes. :param kb_create_input: (required) :type kb_create_input: KbCreateInput @@ -752,6 +764,7 @@ def create_knowledge_base_with_http_info( ) -> ApiResponse[SuccessEnvelopeKbData]: """Create a knowledge base + Create a knowledge base — a searchable document library with its own category taxonomy. The returned id is the `kb_id` every other knowledge operation takes. :param kb_create_input: (required) :type kb_create_input: KbCreateInput @@ -823,6 +836,7 @@ def create_knowledge_base_without_preload_content( ) -> RESTResponseType: """Create a knowledge base + Create a knowledge base — a searchable document library with its own category taxonomy. The returned id is the `kb_id` every other knowledge operation takes. :param kb_create_input: (required) :type kb_create_input: KbCreateInput @@ -968,6 +982,7 @@ def delete_category( ) -> SuccessEnvelopeCategoryDeleteData: """Delete a category + Delete a category from this knowledge base's taxonomy. Its documents are NOT deleted: they (and their topics) are reassigned to uncategorized first, then the category is soft-deleted. Idempotent — deleting one that is already gone returns `deleted: false` rather than 404. :param kb_id: (required) :type kb_id: str @@ -1043,6 +1058,7 @@ def delete_category_with_http_info( ) -> ApiResponse[SuccessEnvelopeCategoryDeleteData]: """Delete a category + Delete a category from this knowledge base's taxonomy. Its documents are NOT deleted: they (and their topics) are reassigned to uncategorized first, then the category is soft-deleted. Idempotent — deleting one that is already gone returns `deleted: false` rather than 404. :param kb_id: (required) :type kb_id: str @@ -1118,6 +1134,7 @@ def delete_category_without_preload_content( ) -> RESTResponseType: """Delete a category + Delete a category from this knowledge base's taxonomy. Its documents are NOT deleted: they (and their topics) are reassigned to uncategorized first, then the category is soft-deleted. Idempotent — deleting one that is already gone returns `deleted: false` rather than 404. :param kb_id: (required) :type kb_id: str @@ -1256,6 +1273,7 @@ def delete_document( ) -> SuccessEnvelopeDocDeleteData: """Delete a document (+ cascade nodes, P5) + Soft-delete a document. Its topics and their search-index entries are removed with it, so nothing of the document stays searchable. Idempotent — deleting one that is already gone returns `deleted: false` rather than 404. :param kb_id: (required) :type kb_id: str @@ -1331,6 +1349,7 @@ def delete_document_with_http_info( ) -> ApiResponse[SuccessEnvelopeDocDeleteData]: """Delete a document (+ cascade nodes, P5) + Soft-delete a document. Its topics and their search-index entries are removed with it, so nothing of the document stays searchable. Idempotent — deleting one that is already gone returns `deleted: false` rather than 404. :param kb_id: (required) :type kb_id: str @@ -1406,6 +1425,7 @@ def delete_document_without_preload_content( ) -> RESTResponseType: """Delete a document (+ cascade nodes, P5) + Soft-delete a document. Its topics and their search-index entries are removed with it, so nothing of the document stays searchable. Idempotent — deleting one that is already gone returns `deleted: false` rather than 404. :param kb_id: (required) :type kb_id: str @@ -1543,6 +1563,7 @@ def delete_knowledge_base( ) -> SuccessEnvelopeKbDeleteData: """Delete a knowledge base + Delete a knowledge base and everything under it: every document (with its topics, search-index entries and stored objects) and every category are soft-deleted first, then the base itself. Idempotent — deleting a base that is already gone returns `deleted: false` rather than 404. :param kb_id: (required) :type kb_id: str @@ -1614,6 +1635,7 @@ def delete_knowledge_base_with_http_info( ) -> ApiResponse[SuccessEnvelopeKbDeleteData]: """Delete a knowledge base + Delete a knowledge base and everything under it: every document (with its topics, search-index entries and stored objects) and every category are soft-deleted first, then the base itself. Idempotent — deleting a base that is already gone returns `deleted: false` rather than 404. :param kb_id: (required) :type kb_id: str @@ -1685,6 +1707,7 @@ def delete_knowledge_base_without_preload_content( ) -> RESTResponseType: """Delete a knowledge base + Delete a knowledge base and everything under it: every document (with its topics, search-index entries and stored objects) and every category are soft-deleted first, then the base itself. Idempotent — deleting a base that is already gone returns `deleted: false` rather than 404. :param kb_id: (required) :type kb_id: str @@ -1817,6 +1840,7 @@ def get_document( ) -> SuccessEnvelopeDocData: """Get a document (with topic_count) + Read one document's metadata, including how many topics were extracted from it — `topic_count` greater than 0 is also the authoritative signal that an async ingest finished. The text itself lives in those topics; list them with GET .../documents/{doc_id}/topics. :param kb_id: (required) :type kb_id: str @@ -1892,6 +1916,7 @@ def get_document_with_http_info( ) -> ApiResponse[SuccessEnvelopeDocData]: """Get a document (with topic_count) + Read one document's metadata, including how many topics were extracted from it — `topic_count` greater than 0 is also the authoritative signal that an async ingest finished. The text itself lives in those topics; list them with GET .../documents/{doc_id}/topics. :param kb_id: (required) :type kb_id: str @@ -1967,6 +1992,7 @@ def get_document_without_preload_content( ) -> RESTResponseType: """Get a document (with topic_count) + Read one document's metadata, including how many topics were extracted from it — `topic_count` greater than 0 is also the authoritative signal that an async ingest finished. The text itself lives in those topics; list them with GET .../documents/{doc_id}/topics. :param kb_id: (required) :type kb_id: str @@ -2104,6 +2130,7 @@ def get_knowledge_base( ) -> SuccessEnvelopeKbData: """Get a knowledge base + Read one knowledge base's metadata, including its document count. :param kb_id: (required) :type kb_id: str @@ -2175,6 +2202,7 @@ def get_knowledge_base_with_http_info( ) -> ApiResponse[SuccessEnvelopeKbData]: """Get a knowledge base + Read one knowledge base's metadata, including its document count. :param kb_id: (required) :type kb_id: str @@ -2246,6 +2274,7 @@ def get_knowledge_base_without_preload_content( ) -> RESTResponseType: """Get a knowledge base + Read one knowledge base's metadata, including its document count. :param kb_id: (required) :type kb_id: str @@ -2379,6 +2408,7 @@ def get_topic( ) -> SuccessEnvelopeTopicDetailData: """Get a topic's full content (inline / S3 transparent) + Read one topic's full content. Storage is transparent to the caller: content held inline and content held in object storage are returned the same way. :param kb_id: (required) :type kb_id: str @@ -2420,6 +2450,7 @@ def get_topic( _response_types_map: Dict[str, Optional[str]] = { '200': "SuccessEnvelopeTopicDetailData", + '404': None, '422': "HTTPValidationError", '401': "Dict[str, object]", '403': "Dict[str, object]", @@ -2458,6 +2489,7 @@ def get_topic_with_http_info( ) -> ApiResponse[SuccessEnvelopeTopicDetailData]: """Get a topic's full content (inline / S3 transparent) + Read one topic's full content. Storage is transparent to the caller: content held inline and content held in object storage are returned the same way. :param kb_id: (required) :type kb_id: str @@ -2499,6 +2531,7 @@ def get_topic_with_http_info( _response_types_map: Dict[str, Optional[str]] = { '200': "SuccessEnvelopeTopicDetailData", + '404': None, '422': "HTTPValidationError", '401': "Dict[str, object]", '403': "Dict[str, object]", @@ -2537,6 +2570,7 @@ def get_topic_without_preload_content( ) -> RESTResponseType: """Get a topic's full content (inline / S3 transparent) + Read one topic's full content. Storage is transparent to the caller: content held inline and content held in object storage are returned the same way. :param kb_id: (required) :type kb_id: str @@ -2578,6 +2612,7 @@ def get_topic_without_preload_content( _response_types_map: Dict[str, Optional[str]] = { '200': "SuccessEnvelopeTopicDetailData", + '404': None, '422': "HTTPValidationError", '401': "Dict[str, object]", '403': "Dict[str, object]", @@ -2680,6 +2715,7 @@ def list_categories( ) -> SuccessEnvelopeCategoryListData: """List categories in a knowledge base + List this knowledge base's categories — both the ones created here and the tenant-global presets — each with the number of documents filed under it. :param kb_id: (required) :type kb_id: str @@ -2751,6 +2787,7 @@ def list_categories_with_http_info( ) -> ApiResponse[SuccessEnvelopeCategoryListData]: """List categories in a knowledge base + List this knowledge base's categories — both the ones created here and the tenant-global presets — each with the number of documents filed under it. :param kb_id: (required) :type kb_id: str @@ -2822,6 +2859,7 @@ def list_categories_without_preload_content( ) -> RESTResponseType: """List categories in a knowledge base + List this knowledge base's categories — both the ones created here and the tenant-global presets — each with the number of documents filed under it. :param kb_id: (required) :type kb_id: str @@ -2956,6 +2994,7 @@ def list_documents( ) -> SuccessEnvelopeDocListData: """List documents in a knowledge base + Paginated list of the documents in a knowledge base, each with its category and topic count. Filterable by category. :param kb_id: (required) :type kb_id: str @@ -3039,6 +3078,7 @@ def list_documents_with_http_info( ) -> ApiResponse[SuccessEnvelopeDocListData]: """List documents in a knowledge base + Paginated list of the documents in a knowledge base, each with its category and topic count. Filterable by category. :param kb_id: (required) :type kb_id: str @@ -3122,6 +3162,7 @@ def list_documents_without_preload_content( ) -> RESTResponseType: """List documents in a knowledge base + Paginated list of the documents in a knowledge base, each with its category and topic count. Filterable by category. :param kb_id: (required) :type kb_id: str @@ -3261,8 +3302,8 @@ def _list_documents_serialize( @validate_call def list_knowledge_bases( self, - page: Optional[StrictInt] = None, - page_size: Optional[StrictInt] = None, + page: Optional[Annotated[int, Field(strict=True, ge=1)]] = None, + page_size: Optional[Annotated[int, Field(le=100, strict=True, ge=1)]] = None, owner_id: Optional[StrictStr] = None, _request_timeout: Union[ None, @@ -3279,6 +3320,7 @@ def list_knowledge_bases( ) -> SuccessEnvelopeKbListData: """List knowledge bases + Paginated list of the account's knowledge bases, each with its document count. :param page: :type page: int @@ -3340,8 +3382,8 @@ def list_knowledge_bases( @validate_call def list_knowledge_bases_with_http_info( self, - page: Optional[StrictInt] = None, - page_size: Optional[StrictInt] = None, + page: Optional[Annotated[int, Field(strict=True, ge=1)]] = None, + page_size: Optional[Annotated[int, Field(le=100, strict=True, ge=1)]] = None, owner_id: Optional[StrictStr] = None, _request_timeout: Union[ None, @@ -3358,6 +3400,7 @@ def list_knowledge_bases_with_http_info( ) -> ApiResponse[SuccessEnvelopeKbListData]: """List knowledge bases + Paginated list of the account's knowledge bases, each with its document count. :param page: :type page: int @@ -3419,8 +3462,8 @@ def list_knowledge_bases_with_http_info( @validate_call def list_knowledge_bases_without_preload_content( self, - page: Optional[StrictInt] = None, - page_size: Optional[StrictInt] = None, + page: Optional[Annotated[int, Field(strict=True, ge=1)]] = None, + page_size: Optional[Annotated[int, Field(le=100, strict=True, ge=1)]] = None, owner_id: Optional[StrictStr] = None, _request_timeout: Union[ None, @@ -3437,6 +3480,7 @@ def list_knowledge_bases_without_preload_content( ) -> RESTResponseType: """List knowledge bases + Paginated list of the account's knowledge bases, each with its document count. :param page: :type page: int @@ -3588,6 +3632,7 @@ def list_topics( ) -> SuccessEnvelopeTopicListData: """List a document's topic tree (optionally with each topic's content) + List a document's topic tree — the sections an LLM extracted from it — flat and already in depth-first order; build the tree from each item's `parent_id`. The list includes one synthetic document-root item (`type` \"root\"), so it returns exactly one more item than the document's `topic_count`, which counts real topics only. Bodies are omitted by default; ask for `content` in `include` to hydrate every item, which can enlarge the response by orders of magnitude. :param kb_id: (required) :type kb_id: str @@ -3667,6 +3712,7 @@ def list_topics_with_http_info( ) -> ApiResponse[SuccessEnvelopeTopicListData]: """List a document's topic tree (optionally with each topic's content) + List a document's topic tree — the sections an LLM extracted from it — flat and already in depth-first order; build the tree from each item's `parent_id`. The list includes one synthetic document-root item (`type` \"root\"), so it returns exactly one more item than the document's `topic_count`, which counts real topics only. Bodies are omitted by default; ask for `content` in `include` to hydrate every item, which can enlarge the response by orders of magnitude. :param kb_id: (required) :type kb_id: str @@ -3746,6 +3792,7 @@ def list_topics_without_preload_content( ) -> RESTResponseType: """List a document's topic tree (optionally with each topic's content) + List a document's topic tree — the sections an LLM extracted from it — flat and already in depth-first order; build the tree from each item's `parent_id`. The list includes one synthetic document-root item (`type` \"root\"), so it returns exactly one more item than the document's `topic_count`, which counts real topics only. Bodies are omitted by default; ask for `content` in `include` to hydrate every item, which can enlarge the response by orders of magnitude. :param kb_id: (required) :type kb_id: str @@ -3874,11 +3921,12 @@ def _list_topics_serialize( @validate_call - def replace_document( + def list_topics_by_tags( self, - kb_id: StrictStr, - doc_id: StrictStr, - doc_ingest_body: DocIngestBody, + kb_id: Annotated[StrictStr, Field(description="The knowledge base to search within.")], + tag_ids: Annotated[List[Annotated[str, Field(min_length=1, strict=True, max_length=128)]], Field(min_length=1, max_length=100, description="Hard filter: a topic is returned only if it carries EVERY one of these tag ids. Use `boost_tag_ids` on the search endpoint instead to reweight without excluding anything.")], + page: Annotated[Optional[Annotated[int, Field(strict=True, ge=1)]], Field(description="1-based page number.")] = None, + page_size: Annotated[Optional[Annotated[int, Field(le=100, strict=True, ge=1)]], Field(description="Items per page, 1 to 100 (default 20).")] = None, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], @@ -3891,16 +3939,19 @@ def replace_document( _content_type: Optional[StrictStr] = None, _headers: Optional[Dict[StrictStr, Any]] = None, _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, - ) -> SuccessEnvelopeDocIngestData: - """Replace a document (async, atomic swap) + ) -> SuccessEnvelopeTopicFilterListData: + """List tag-matched topics in a knowledge base + Filter live topics by their own materialized tag set. Every requested id must occur on the same topic (ALL semantics); total is counted before paging. - :param kb_id: (required) + :param kb_id: The knowledge base to search within. (required) :type kb_id: str - :param doc_id: (required) - :type doc_id: str - :param doc_ingest_body: (required) - :type doc_ingest_body: DocIngestBody + :param tag_ids: Hard filter: a topic is returned only if it carries EVERY one of these tag ids. Use `boost_tag_ids` on the search endpoint instead to reweight without excluding anything. (required) + :type tag_ids: List[str] + :param page: 1-based page number. + :type page: int + :param page_size: Items per page, 1 to 100 (default 20). + :type page_size: int :param _request_timeout: timeout setting for this request. If one number provided, it will be total request timeout. It can also be a pair (tuple) of @@ -3923,10 +3974,11 @@ def replace_document( :return: Returns the result object. """ # noqa: E501 - _param = self._replace_document_serialize( + _param = self._list_topics_by_tags_serialize( kb_id=kb_id, - doc_id=doc_id, - doc_ingest_body=doc_ingest_body, + tag_ids=tag_ids, + page=page, + page_size=page_size, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, @@ -3934,7 +3986,7 @@ def replace_document( ) _response_types_map: Dict[str, Optional[str]] = { - '202': "SuccessEnvelopeDocIngestData", + '200': "SuccessEnvelopeTopicFilterListData", '422': "HTTPValidationError", '401': "Dict[str, object]", '403': "Dict[str, object]", @@ -3953,11 +4005,12 @@ def replace_document( @validate_call - def replace_document_with_http_info( + def list_topics_by_tags_with_http_info( self, - kb_id: StrictStr, - doc_id: StrictStr, - doc_ingest_body: DocIngestBody, + kb_id: Annotated[StrictStr, Field(description="The knowledge base to search within.")], + tag_ids: Annotated[List[Annotated[str, Field(min_length=1, strict=True, max_length=128)]], Field(min_length=1, max_length=100, description="Hard filter: a topic is returned only if it carries EVERY one of these tag ids. Use `boost_tag_ids` on the search endpoint instead to reweight without excluding anything.")], + page: Annotated[Optional[Annotated[int, Field(strict=True, ge=1)]], Field(description="1-based page number.")] = None, + page_size: Annotated[Optional[Annotated[int, Field(le=100, strict=True, ge=1)]], Field(description="Items per page, 1 to 100 (default 20).")] = None, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], @@ -3970,16 +4023,19 @@ def replace_document_with_http_info( _content_type: Optional[StrictStr] = None, _headers: Optional[Dict[StrictStr, Any]] = None, _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, - ) -> ApiResponse[SuccessEnvelopeDocIngestData]: - """Replace a document (async, atomic swap) + ) -> ApiResponse[SuccessEnvelopeTopicFilterListData]: + """List tag-matched topics in a knowledge base + Filter live topics by their own materialized tag set. Every requested id must occur on the same topic (ALL semantics); total is counted before paging. - :param kb_id: (required) + :param kb_id: The knowledge base to search within. (required) :type kb_id: str - :param doc_id: (required) - :type doc_id: str - :param doc_ingest_body: (required) - :type doc_ingest_body: DocIngestBody + :param tag_ids: Hard filter: a topic is returned only if it carries EVERY one of these tag ids. Use `boost_tag_ids` on the search endpoint instead to reweight without excluding anything. (required) + :type tag_ids: List[str] + :param page: 1-based page number. + :type page: int + :param page_size: Items per page, 1 to 100 (default 20). + :type page_size: int :param _request_timeout: timeout setting for this request. If one number provided, it will be total request timeout. It can also be a pair (tuple) of @@ -4002,10 +4058,11 @@ def replace_document_with_http_info( :return: Returns the result object. """ # noqa: E501 - _param = self._replace_document_serialize( + _param = self._list_topics_by_tags_serialize( kb_id=kb_id, - doc_id=doc_id, - doc_ingest_body=doc_ingest_body, + tag_ids=tag_ids, + page=page, + page_size=page_size, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, @@ -4013,7 +4070,7 @@ def replace_document_with_http_info( ) _response_types_map: Dict[str, Optional[str]] = { - '202': "SuccessEnvelopeDocIngestData", + '200': "SuccessEnvelopeTopicFilterListData", '422': "HTTPValidationError", '401': "Dict[str, object]", '403': "Dict[str, object]", @@ -4032,11 +4089,12 @@ def replace_document_with_http_info( @validate_call - def replace_document_without_preload_content( + def list_topics_by_tags_without_preload_content( self, - kb_id: StrictStr, - doc_id: StrictStr, - doc_ingest_body: DocIngestBody, + kb_id: Annotated[StrictStr, Field(description="The knowledge base to search within.")], + tag_ids: Annotated[List[Annotated[str, Field(min_length=1, strict=True, max_length=128)]], Field(min_length=1, max_length=100, description="Hard filter: a topic is returned only if it carries EVERY one of these tag ids. Use `boost_tag_ids` on the search endpoint instead to reweight without excluding anything.")], + page: Annotated[Optional[Annotated[int, Field(strict=True, ge=1)]], Field(description="1-based page number.")] = None, + page_size: Annotated[Optional[Annotated[int, Field(le=100, strict=True, ge=1)]], Field(description="Items per page, 1 to 100 (default 20).")] = None, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], @@ -4050,15 +4108,18 @@ def replace_document_without_preload_content( _headers: Optional[Dict[StrictStr, Any]] = None, _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, ) -> RESTResponseType: - """Replace a document (async, atomic swap) + """List tag-matched topics in a knowledge base + Filter live topics by their own materialized tag set. Every requested id must occur on the same topic (ALL semantics); total is counted before paging. - :param kb_id: (required) + :param kb_id: The knowledge base to search within. (required) :type kb_id: str - :param doc_id: (required) - :type doc_id: str - :param doc_ingest_body: (required) - :type doc_ingest_body: DocIngestBody + :param tag_ids: Hard filter: a topic is returned only if it carries EVERY one of these tag ids. Use `boost_tag_ids` on the search endpoint instead to reweight without excluding anything. (required) + :type tag_ids: List[str] + :param page: 1-based page number. + :type page: int + :param page_size: Items per page, 1 to 100 (default 20). + :type page_size: int :param _request_timeout: timeout setting for this request. If one number provided, it will be total request timeout. It can also be a pair (tuple) of @@ -4081,10 +4142,11 @@ def replace_document_without_preload_content( :return: Returns the result object. """ # noqa: E501 - _param = self._replace_document_serialize( + _param = self._list_topics_by_tags_serialize( kb_id=kb_id, - doc_id=doc_id, - doc_ingest_body=doc_ingest_body, + tag_ids=tag_ids, + page=page, + page_size=page_size, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, @@ -4092,7 +4154,7 @@ def replace_document_without_preload_content( ) _response_types_map: Dict[str, Optional[str]] = { - '202': "SuccessEnvelopeDocIngestData", + '200': "SuccessEnvelopeTopicFilterListData", '422': "HTTPValidationError", '401': "Dict[str, object]", '403': "Dict[str, object]", @@ -4106,11 +4168,12 @@ def replace_document_without_preload_content( return response_data.response - def _replace_document_serialize( + def _list_topics_by_tags_serialize( self, kb_id, - doc_id, - doc_ingest_body, + tag_ids, + page, + page_size, _request_auth, _content_type, _headers, @@ -4120,6 +4183,7 @@ def _replace_document_serialize( _host = None _collection_formats: Dict[str, str] = { + 'tag_ids': 'multi', } _path_params: Dict[str, str] = {} @@ -4134,14 +4198,22 @@ def _replace_document_serialize( # process the path parameters if kb_id is not None: _path_params['kb_id'] = kb_id - if doc_id is not None: - _path_params['doc_id'] = doc_id # process the query parameters + if tag_ids is not None: + + _query_params.append(('tag_ids', tag_ids)) + + if page is not None: + + _query_params.append(('page', page)) + + if page_size is not None: + + _query_params.append(('page_size', page_size)) + # process the header parameters # process the form parameters # process the body parameter - if doc_ingest_body is not None: - _body_params = doc_ingest_body # set the HTTP header `Accept` @@ -4152,19 +4224,6 @@ def _replace_document_serialize( ] ) - # set the HTTP header `Content-Type` - if _content_type: - _header_params['Content-Type'] = _content_type - else: - _default_content_type = ( - self.api_client.select_header_content_type( - [ - 'application/json' - ] - ) - ) - if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type # authentication setting _auth_settings: List[str] = [ @@ -4172,8 +4231,974 @@ def _replace_document_serialize( ] return self.api_client.param_serialize( - method='PUT', - resource_path='/api/v2/knowledge_bases/{kb_id}/documents/{doc_id}', + method='GET', + resource_path='/api/v2/knowledge_bases/{kb_id}/topics', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def query_related_tags( + self, + kb_id: StrictStr, + related_tag_usage_body: RelatedTagUsageBody, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> SuccessEnvelopeRelatedTagUsageListData: + """Count candidate tags used by live documents in a knowledge base + + Returns requested opaque tag ids used by live topics of live documents. Counts are distinct by document and items are sorted by id. The bounded multi-command Mongo read is not a point-in-time snapshot across concurrent lifecycle writes. + + :param kb_id: (required) + :type kb_id: str + :param related_tag_usage_body: (required) + :type related_tag_usage_body: RelatedTagUsageBody + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._query_related_tags_serialize( + kb_id=kb_id, + related_tag_usage_body=related_tag_usage_body, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "SuccessEnvelopeRelatedTagUsageListData", + '422': "HTTPValidationError", + '401': "Dict[str, object]", + '403': "Dict[str, object]", + '429': "Dict[str, object]", + '503': "Dict[str, object]", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def query_related_tags_with_http_info( + self, + kb_id: StrictStr, + related_tag_usage_body: RelatedTagUsageBody, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[SuccessEnvelopeRelatedTagUsageListData]: + """Count candidate tags used by live documents in a knowledge base + + Returns requested opaque tag ids used by live topics of live documents. Counts are distinct by document and items are sorted by id. The bounded multi-command Mongo read is not a point-in-time snapshot across concurrent lifecycle writes. + + :param kb_id: (required) + :type kb_id: str + :param related_tag_usage_body: (required) + :type related_tag_usage_body: RelatedTagUsageBody + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._query_related_tags_serialize( + kb_id=kb_id, + related_tag_usage_body=related_tag_usage_body, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "SuccessEnvelopeRelatedTagUsageListData", + '422': "HTTPValidationError", + '401': "Dict[str, object]", + '403': "Dict[str, object]", + '429': "Dict[str, object]", + '503': "Dict[str, object]", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def query_related_tags_without_preload_content( + self, + kb_id: StrictStr, + related_tag_usage_body: RelatedTagUsageBody, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Count candidate tags used by live documents in a knowledge base + + Returns requested opaque tag ids used by live topics of live documents. Counts are distinct by document and items are sorted by id. The bounded multi-command Mongo read is not a point-in-time snapshot across concurrent lifecycle writes. + + :param kb_id: (required) + :type kb_id: str + :param related_tag_usage_body: (required) + :type related_tag_usage_body: RelatedTagUsageBody + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._query_related_tags_serialize( + kb_id=kb_id, + related_tag_usage_body=related_tag_usage_body, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "SuccessEnvelopeRelatedTagUsageListData", + '422': "HTTPValidationError", + '401': "Dict[str, object]", + '403': "Dict[str, object]", + '429': "Dict[str, object]", + '503': "Dict[str, object]", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _query_related_tags_serialize( + self, + kb_id, + related_tag_usage_body, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if kb_id is not None: + _path_params['kb_id'] = kb_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if related_tag_usage_body is not None: + _body_params = related_tag_usage_body + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + 'BearerAuth' + ] + + return self.api_client.param_serialize( + method='POST', + resource_path='/api/v2/knowledge_bases/{kb_id}/tags', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def replace_document( + self, + kb_id: StrictStr, + doc_id: StrictStr, + doc_ingest_body: DocIngestBody, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> SuccessEnvelopeDocIngestData: + """Replace a document (async, atomic swap) + + Re-ingest content under an existing document id. Same asynchronous contract as upload (202 with `status` and `task_id`), and idempotent per document id — the same replace applied twice leaves the same state. As with upload, completion is authoritative from GET .../documents/{doc_id} reporting `topic_count` greater than 0. + + :param kb_id: (required) + :type kb_id: str + :param doc_id: (required) + :type doc_id: str + :param doc_ingest_body: (required) + :type doc_ingest_body: DocIngestBody + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._replace_document_serialize( + kb_id=kb_id, + doc_id=doc_id, + doc_ingest_body=doc_ingest_body, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '202': "SuccessEnvelopeDocIngestData", + '422': "HTTPValidationError", + '401': "Dict[str, object]", + '403': "Dict[str, object]", + '429': "Dict[str, object]", + '503': "Dict[str, object]", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def replace_document_with_http_info( + self, + kb_id: StrictStr, + doc_id: StrictStr, + doc_ingest_body: DocIngestBody, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[SuccessEnvelopeDocIngestData]: + """Replace a document (async, atomic swap) + + Re-ingest content under an existing document id. Same asynchronous contract as upload (202 with `status` and `task_id`), and idempotent per document id — the same replace applied twice leaves the same state. As with upload, completion is authoritative from GET .../documents/{doc_id} reporting `topic_count` greater than 0. + + :param kb_id: (required) + :type kb_id: str + :param doc_id: (required) + :type doc_id: str + :param doc_ingest_body: (required) + :type doc_ingest_body: DocIngestBody + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._replace_document_serialize( + kb_id=kb_id, + doc_id=doc_id, + doc_ingest_body=doc_ingest_body, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '202': "SuccessEnvelopeDocIngestData", + '422': "HTTPValidationError", + '401': "Dict[str, object]", + '403': "Dict[str, object]", + '429': "Dict[str, object]", + '503': "Dict[str, object]", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def replace_document_without_preload_content( + self, + kb_id: StrictStr, + doc_id: StrictStr, + doc_ingest_body: DocIngestBody, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Replace a document (async, atomic swap) + + Re-ingest content under an existing document id. Same asynchronous contract as upload (202 with `status` and `task_id`), and idempotent per document id — the same replace applied twice leaves the same state. As with upload, completion is authoritative from GET .../documents/{doc_id} reporting `topic_count` greater than 0. + + :param kb_id: (required) + :type kb_id: str + :param doc_id: (required) + :type doc_id: str + :param doc_ingest_body: (required) + :type doc_ingest_body: DocIngestBody + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._replace_document_serialize( + kb_id=kb_id, + doc_id=doc_id, + doc_ingest_body=doc_ingest_body, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '202': "SuccessEnvelopeDocIngestData", + '422': "HTTPValidationError", + '401': "Dict[str, object]", + '403': "Dict[str, object]", + '429': "Dict[str, object]", + '503': "Dict[str, object]", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _replace_document_serialize( + self, + kb_id, + doc_id, + doc_ingest_body, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if kb_id is not None: + _path_params['kb_id'] = kb_id + if doc_id is not None: + _path_params['doc_id'] = doc_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if doc_ingest_body is not None: + _body_params = doc_ingest_body + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + 'BearerAuth' + ] + + return self.api_client.param_serialize( + method='PUT', + resource_path='/api/v2/knowledge_bases/{kb_id}/documents/{doc_id}', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def replace_topic_tags( + self, + kb_id: StrictStr, + doc_id: StrictStr, + topic_id: StrictStr, + topic_tag_replace_body: TopicTagReplaceBody, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> SuccessEnvelopeTopicTagWriteData: + """Replace the complete materialized semantic tag snapshot of a topic + + version is the expected current tag_version. Cloud stable-deduplicates the request and stores the first 50 ids; requests with 51-100 distinct ids succeed with structured truncation metadata. Identical snapshots are no-ops and do not advance the version. + + :param kb_id: (required) + :type kb_id: str + :param doc_id: (required) + :type doc_id: str + :param topic_id: (required) + :type topic_id: str + :param topic_tag_replace_body: (required) + :type topic_tag_replace_body: TopicTagReplaceBody + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._replace_topic_tags_serialize( + kb_id=kb_id, + doc_id=doc_id, + topic_id=topic_id, + topic_tag_replace_body=topic_tag_replace_body, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "SuccessEnvelopeTopicTagWriteData", + '404': None, + '409': "ErrorEnvelope", + '500': "ErrorEnvelope", + '422': "HTTPValidationError", + '401': "Dict[str, object]", + '403': "Dict[str, object]", + '429': "Dict[str, object]", + '503': "Dict[str, object]", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def replace_topic_tags_with_http_info( + self, + kb_id: StrictStr, + doc_id: StrictStr, + topic_id: StrictStr, + topic_tag_replace_body: TopicTagReplaceBody, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[SuccessEnvelopeTopicTagWriteData]: + """Replace the complete materialized semantic tag snapshot of a topic + + version is the expected current tag_version. Cloud stable-deduplicates the request and stores the first 50 ids; requests with 51-100 distinct ids succeed with structured truncation metadata. Identical snapshots are no-ops and do not advance the version. + + :param kb_id: (required) + :type kb_id: str + :param doc_id: (required) + :type doc_id: str + :param topic_id: (required) + :type topic_id: str + :param topic_tag_replace_body: (required) + :type topic_tag_replace_body: TopicTagReplaceBody + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._replace_topic_tags_serialize( + kb_id=kb_id, + doc_id=doc_id, + topic_id=topic_id, + topic_tag_replace_body=topic_tag_replace_body, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "SuccessEnvelopeTopicTagWriteData", + '404': None, + '409': "ErrorEnvelope", + '500': "ErrorEnvelope", + '422': "HTTPValidationError", + '401': "Dict[str, object]", + '403': "Dict[str, object]", + '429': "Dict[str, object]", + '503': "Dict[str, object]", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def replace_topic_tags_without_preload_content( + self, + kb_id: StrictStr, + doc_id: StrictStr, + topic_id: StrictStr, + topic_tag_replace_body: TopicTagReplaceBody, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Replace the complete materialized semantic tag snapshot of a topic + + version is the expected current tag_version. Cloud stable-deduplicates the request and stores the first 50 ids; requests with 51-100 distinct ids succeed with structured truncation metadata. Identical snapshots are no-ops and do not advance the version. + + :param kb_id: (required) + :type kb_id: str + :param doc_id: (required) + :type doc_id: str + :param topic_id: (required) + :type topic_id: str + :param topic_tag_replace_body: (required) + :type topic_tag_replace_body: TopicTagReplaceBody + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._replace_topic_tags_serialize( + kb_id=kb_id, + doc_id=doc_id, + topic_id=topic_id, + topic_tag_replace_body=topic_tag_replace_body, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "SuccessEnvelopeTopicTagWriteData", + '404': None, + '409': "ErrorEnvelope", + '500': "ErrorEnvelope", + '422': "HTTPValidationError", + '401': "Dict[str, object]", + '403': "Dict[str, object]", + '429': "Dict[str, object]", + '503': "Dict[str, object]", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _replace_topic_tags_serialize( + self, + kb_id, + doc_id, + topic_id, + topic_tag_replace_body, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if kb_id is not None: + _path_params['kb_id'] = kb_id + if doc_id is not None: + _path_params['doc_id'] = doc_id + if topic_id is not None: + _path_params['topic_id'] = topic_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if topic_tag_replace_body is not None: + _body_params = topic_tag_replace_body + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + 'BearerAuth' + ] + + return self.api_client.param_serialize( + method='POST', + resource_path='/api/v2/knowledge_bases/{kb_id}/documents/{doc_id}/topics/{topic_id}/tag/replace', path_params=_path_params, query_params=_query_params, header_params=_header_params, @@ -4209,6 +5234,7 @@ def search_knowledge( ) -> SuccessEnvelopeKbSearchData: """Search within a knowledge base (keyword / vector / hybrid) + Search within one knowledge base (keyword, vector or hybrid). The unit of retrieval is the topic, not the document: each hit carries its parent document's title and summary, so rendering a result needs no second call. Topic bodies are omitted by default; ask for `content` in `include` to inline them, or drill down with GET .../documents/{doc_id}/topics/{topic_id}. :param kb_id: (required) :type kb_id: str @@ -4284,6 +5310,7 @@ def search_knowledge_with_http_info( ) -> ApiResponse[SuccessEnvelopeKbSearchData]: """Search within a knowledge base (keyword / vector / hybrid) + Search within one knowledge base (keyword, vector or hybrid). The unit of retrieval is the topic, not the document: each hit carries its parent document's title and summary, so rendering a result needs no second call. Topic bodies are omitted by default; ask for `content` in `include` to inline them, or drill down with GET .../documents/{doc_id}/topics/{topic_id}. :param kb_id: (required) :type kb_id: str @@ -4359,6 +5386,7 @@ def search_knowledge_without_preload_content( ) -> RESTResponseType: """Search within a knowledge base (keyword / vector / hybrid) + Search within one knowledge base (keyword, vector or hybrid). The unit of retrieval is the topic, not the document: each hit carries its parent document's title and summary, so rendering a result needs no second call. Topic bodies are omitted by default; ask for `content` in `include` to inline them, or drill down with GET .../documents/{doc_id}/topics/{topic_id}. :param kb_id: (required) :type kb_id: str @@ -4511,6 +5539,7 @@ def update_category( ) -> SuccessEnvelopeCategoryData: """Update a category + Rename a category or edit its description. Documents filed under it are not re-classified; they keep pointing at the same category id. Tenant-global preset categories are read-only. :param kb_id: (required) :type kb_id: str @@ -4590,6 +5619,7 @@ def update_category_with_http_info( ) -> ApiResponse[SuccessEnvelopeCategoryData]: """Update a category + Rename a category or edit its description. Documents filed under it are not re-classified; they keep pointing at the same category id. Tenant-global preset categories are read-only. :param kb_id: (required) :type kb_id: str @@ -4669,6 +5699,7 @@ def update_category_without_preload_content( ) -> RESTResponseType: """Update a category + Rename a category or edit its description. Documents filed under it are not re-classified; they keep pointing at the same category id. Tenant-global preset categories are read-only. :param kb_id: (required) :type kb_id: str @@ -4827,6 +5858,7 @@ def update_document( ) -> SuccessEnvelopeDocPatchData: """Update document metadata (title / category) + Patch a document's metadata — its title, or the category it is filed under. Content is not editable here: re-ingest with PUT .../documents/{doc_id} to change it. The response lists which fields actually changed. :param kb_id: (required) :type kb_id: str @@ -4906,6 +5938,7 @@ def update_document_with_http_info( ) -> ApiResponse[SuccessEnvelopeDocPatchData]: """Update document metadata (title / category) + Patch a document's metadata — its title, or the category it is filed under. Content is not editable here: re-ingest with PUT .../documents/{doc_id} to change it. The response lists which fields actually changed. :param kb_id: (required) :type kb_id: str @@ -4985,6 +6018,7 @@ def update_document_without_preload_content( ) -> RESTResponseType: """Update document metadata (title / category) + Patch a document's metadata — its title, or the category it is filed under. Content is not editable here: re-ingest with PUT .../documents/{doc_id} to change it. The response lists which fields actually changed. :param kb_id: (required) :type kb_id: str @@ -5142,6 +6176,7 @@ def update_knowledge_base( ) -> SuccessEnvelopeKbData: """Update a knowledge base + Patch a knowledge base's name or description. Metadata only — it does not touch the documents inside it. :param kb_id: (required) :type kb_id: str @@ -5217,6 +6252,7 @@ def update_knowledge_base_with_http_info( ) -> ApiResponse[SuccessEnvelopeKbData]: """Update a knowledge base + Patch a knowledge base's name or description. Metadata only — it does not touch the documents inside it. :param kb_id: (required) :type kb_id: str @@ -5292,6 +6328,7 @@ def update_knowledge_base_without_preload_content( ) -> RESTResponseType: """Update a knowledge base + Patch a knowledge base's name or description. Metadata only — it does not touch the documents inside it. :param kb_id: (required) :type kb_id: str diff --git a/everos_cloud/api/memory_api.py b/everos_cloud/api/memory_api.py index e84875e..65dd644 100644 --- a/everos_cloud/api/memory_api.py +++ b/everos_cloud/api/memory_api.py @@ -73,6 +73,7 @@ def add_memory( ) -> SuccessEnvelopeAddData: """Add messages [OSS + Cloud] + Append conversation messages to a session's working memory. Asynchronous by default (`async_mode` true): the gateway validates and enqueues the write, answering 202 with status \"queued\". Pass `async_mode: false` to forward synchronously and receive the engine's 200 result instead. Distillation into long-term memory is always asynchronous — it runs on a session boundary, or when you call /api/v2/memory/flush. One call carries 1–500 messages. :param add_input: (required) :type add_input: AddInput @@ -145,6 +146,7 @@ def add_memory_with_http_info( ) -> ApiResponse[SuccessEnvelopeAddData]: """Add messages [OSS + Cloud] + Append conversation messages to a session's working memory. Asynchronous by default (`async_mode` true): the gateway validates and enqueues the write, answering 202 with status \"queued\". Pass `async_mode: false` to forward synchronously and receive the engine's 200 result instead. Distillation into long-term memory is always asynchronous — it runs on a session boundary, or when you call /api/v2/memory/flush. One call carries 1–500 messages. :param add_input: (required) :type add_input: AddInput @@ -217,6 +219,7 @@ def add_memory_without_preload_content( ) -> RESTResponseType: """Add messages [OSS + Cloud] + Append conversation messages to a session's working memory. Asynchronous by default (`async_mode` true): the gateway validates and enqueues the write, answering 202 with status \"queued\". Pass `async_mode: false` to forward synchronously and receive the engine's 200 result instead. Distillation into long-term memory is always asynchronous — it runs on a session boundary, or when you call /api/v2/memory/flush. One call carries 1–500 messages. :param add_input: (required) :type add_input: AddInput @@ -362,6 +365,7 @@ def bind_tags( ) -> SuccessEnvelopeTagBindData: """Bind tags to memory items [Cloud] + Add tags to existing memories, keeping the tags they already carry. Tags are scoped by the memory ids themselves — pass `memory_type` plus the ids, not an app or project scope. Tags are created by use: binding a name that does not exist yet is how it comes into existence. Idempotent, and batched over memory_ids x tags. :param tag_bind_input: (required) :type tag_bind_input: TagBindInput @@ -433,6 +437,7 @@ def bind_tags_with_http_info( ) -> ApiResponse[SuccessEnvelopeTagBindData]: """Bind tags to memory items [Cloud] + Add tags to existing memories, keeping the tags they already carry. Tags are scoped by the memory ids themselves — pass `memory_type` plus the ids, not an app or project scope. Tags are created by use: binding a name that does not exist yet is how it comes into existence. Idempotent, and batched over memory_ids x tags. :param tag_bind_input: (required) :type tag_bind_input: TagBindInput @@ -504,6 +509,7 @@ def bind_tags_without_preload_content( ) -> RESTResponseType: """Bind tags to memory items [Cloud] + Add tags to existing memories, keeping the tags they already carry. Tags are scoped by the memory ids themselves — pass `memory_type` plus the ids, not an app or project scope. Tags are created by use: binding a name that does not exist yet is how it comes into existence. Idempotent, and batched over memory_ids x tags. :param tag_bind_input: (required) :type tag_bind_input: TagBindInput @@ -648,6 +654,7 @@ def delete_memory( ) -> SuccessEnvelopeDeleteData: """Delete memories [Cloud-only] + Soft-delete memories within a scope. At least one of `user_id`, `agent_id` or `session_id` is required (an empty body is rejected with 422), and `user_id` / `agent_id` are mutually exclusive. The response echoes which scope filters were applied and how many records were removed across all memory types. :param delete_input: (required) :type delete_input: DeleteInput @@ -719,6 +726,7 @@ def delete_memory_with_http_info( ) -> ApiResponse[SuccessEnvelopeDeleteData]: """Delete memories [Cloud-only] + Soft-delete memories within a scope. At least one of `user_id`, `agent_id` or `session_id` is required (an empty body is rejected with 422), and `user_id` / `agent_id` are mutually exclusive. The response echoes which scope filters were applied and how many records were removed across all memory types. :param delete_input: (required) :type delete_input: DeleteInput @@ -790,6 +798,7 @@ def delete_memory_without_preload_content( ) -> RESTResponseType: """Delete memories [Cloud-only] + Soft-delete memories within a scope. At least one of `user_id`, `agent_id` or `session_id` is required (an empty body is rejected with 422), and `user_id` / `agent_id` are mutually exclusive. The response echoes which scope filters were applied and how many records were removed across all memory types. :param delete_input: (required) :type delete_input: DeleteInput @@ -934,6 +943,7 @@ def edit_profile( ) -> SuccessEnvelopeEditData: """Edit profile items [Cloud-only] + Apply 1–50 edits to one user's profile in a single call. Each operation carries an `action` (add, update or delete), a `type` (explicit_info or implicit_traits), the item `data`, and an optional `reason`. Profile is the only memory type this endpoint edits — `memory_type` is pinned to \"profile\"; every other type is produced by extraction. Operations are reported individually in the response, so some can be rejected while others apply. :param edit_input: (required) :type edit_input: EditInput @@ -1005,6 +1015,7 @@ def edit_profile_with_http_info( ) -> ApiResponse[SuccessEnvelopeEditData]: """Edit profile items [Cloud-only] + Apply 1–50 edits to one user's profile in a single call. Each operation carries an `action` (add, update or delete), a `type` (explicit_info or implicit_traits), the item `data`, and an optional `reason`. Profile is the only memory type this endpoint edits — `memory_type` is pinned to \"profile\"; every other type is produced by extraction. Operations are reported individually in the response, so some can be rejected while others apply. :param edit_input: (required) :type edit_input: EditInput @@ -1076,6 +1087,7 @@ def edit_profile_without_preload_content( ) -> RESTResponseType: """Edit profile items [Cloud-only] + Apply 1–50 edits to one user's profile in a single call. Each operation carries an `action` (add, update or delete), a `type` (explicit_info or implicit_traits), the item `data`, and an optional `reason`. Profile is the only memory type this endpoint edits — `memory_type` is pinned to \"profile\"; every other type is produced by extraction. Operations are reported individually in the response, so some can be rejected while others apply. :param edit_input: (required) :type edit_input: EditInput @@ -1220,6 +1232,7 @@ def flush_memory( ) -> SuccessEnvelopeFlushData: """Force memory extraction [OSS + Cloud] + Force extraction for a session instead of waiting for a boundary. Returns status \"extracted\" when memories were distilled and \"no_extraction\" when there was nothing to extract — note that a default (async) add that is still queued yields \"no_extraction\", so either write with `async_mode: false` or poll the add's task before flushing. :param flush_input: (required) :type flush_input: FlushInput @@ -1291,6 +1304,7 @@ def flush_memory_with_http_info( ) -> ApiResponse[SuccessEnvelopeFlushData]: """Force memory extraction [OSS + Cloud] + Force extraction for a session instead of waiting for a boundary. Returns status \"extracted\" when memories were distilled and \"no_extraction\" when there was nothing to extract — note that a default (async) add that is still queued yields \"no_extraction\", so either write with `async_mode: false` or poll the add's task before flushing. :param flush_input: (required) :type flush_input: FlushInput @@ -1362,6 +1376,7 @@ def flush_memory_without_preload_content( ) -> RESTResponseType: """Force memory extraction [OSS + Cloud] + Force extraction for a session instead of waiting for a boundary. Returns status \"extracted\" when memories were distilled and \"no_extraction\" when there was nothing to extract — note that a default (async) add that is still queued yields \"no_extraction\", so either write with `async_mode: false` or poll the add's task before flushing. :param flush_input: (required) :type flush_input: FlushInput @@ -1506,6 +1521,7 @@ def get_memory( ) -> SuccessEnvelopeGetData: """Get memories (paginated) [OSS + Cloud] + List stored memories of one type, paginated. Exactly one of `user_id` / `agent_id` is required, and `memory_type` must match that owner: a user owns \"episode\" and \"profile\", an agent owns \"agent_case\" and \"agent_skill\" — the other pairings are rejected with 422. This is a structured read, not a query: it does not embed the request, so a memory is readable as soon as it is extracted, whereas the vector index /api/v2/memory/search relies on lags behind extraction by seconds. :param get_input: (required) :type get_input: GetInput @@ -1577,6 +1593,7 @@ def get_memory_with_http_info( ) -> ApiResponse[SuccessEnvelopeGetData]: """Get memories (paginated) [OSS + Cloud] + List stored memories of one type, paginated. Exactly one of `user_id` / `agent_id` is required, and `memory_type` must match that owner: a user owns \"episode\" and \"profile\", an agent owns \"agent_case\" and \"agent_skill\" — the other pairings are rejected with 422. This is a structured read, not a query: it does not embed the request, so a memory is readable as soon as it is extracted, whereas the vector index /api/v2/memory/search relies on lags behind extraction by seconds. :param get_input: (required) :type get_input: GetInput @@ -1648,6 +1665,7 @@ def get_memory_without_preload_content( ) -> RESTResponseType: """Get memories (paginated) [OSS + Cloud] + List stored memories of one type, paginated. Exactly one of `user_id` / `agent_id` is required, and `memory_type` must match that owner: a user owns \"episode\" and \"profile\", an agent owns \"agent_case\" and \"agent_skill\" — the other pairings are rejected with 422. This is a structured read, not a query: it does not embed the request, so a memory is readable as soon as it is extracted, whereas the vector index /api/v2/memory/search relies on lags behind extraction by seconds. :param get_input: (required) :type get_input: GetInput @@ -1792,6 +1810,7 @@ def replace_tags( ) -> SuccessEnvelopeTagReplaceData: """Replace (overwrite) tags on memory items [Cloud] + Overwrite the tag set on the given memories: tags absent from the request are dropped, and an empty `tags` list clears them all. Use /api/v2/memory/tag/bind to add without removing. :param tag_replace_input: (required) :type tag_replace_input: TagReplaceInput @@ -1863,6 +1882,7 @@ def replace_tags_with_http_info( ) -> ApiResponse[SuccessEnvelopeTagReplaceData]: """Replace (overwrite) tags on memory items [Cloud] + Overwrite the tag set on the given memories: tags absent from the request are dropped, and an empty `tags` list clears them all. Use /api/v2/memory/tag/bind to add without removing. :param tag_replace_input: (required) :type tag_replace_input: TagReplaceInput @@ -1934,6 +1954,7 @@ def replace_tags_without_preload_content( ) -> RESTResponseType: """Replace (overwrite) tags on memory items [Cloud] + Overwrite the tag set on the given memories: tags absent from the request are dropped, and an empty `tags` list clears them all. Use /api/v2/memory/tag/bind to add without removing. :param tag_replace_input: (required) :type tag_replace_input: TagReplaceInput @@ -2078,6 +2099,7 @@ def search_memory( ) -> SuccessEnvelopeSearchData: """Search memories [OSS + Cloud] + Retrieve the memories relevant to a query. Exactly one of `user_id` / `agent_id` is required and decides what comes back: a user owner returns episodes (plus profiles with `include_profile`), an agent owner returns agent cases and skills. All result collections are always present in the response, empty when they do not apply. The vector-backed methods read an index that lags extraction by seconds — to read back something just extracted, use /api/v2/memory/get. :param search_input: (required) :type search_input: SearchInput @@ -2149,6 +2171,7 @@ def search_memory_with_http_info( ) -> ApiResponse[SuccessEnvelopeSearchData]: """Search memories [OSS + Cloud] + Retrieve the memories relevant to a query. Exactly one of `user_id` / `agent_id` is required and decides what comes back: a user owner returns episodes (plus profiles with `include_profile`), an agent owner returns agent cases and skills. All result collections are always present in the response, empty when they do not apply. The vector-backed methods read an index that lags extraction by seconds — to read back something just extracted, use /api/v2/memory/get. :param search_input: (required) :type search_input: SearchInput @@ -2220,6 +2243,7 @@ def search_memory_without_preload_content( ) -> RESTResponseType: """Search memories [OSS + Cloud] + Retrieve the memories relevant to a query. Exactly one of `user_id` / `agent_id` is required and decides what comes back: a user owner returns episodes (plus profiles with `include_profile`), an agent owner returns agent cases and skills. All result collections are always present in the response, empty when they do not apply. The vector-backed methods read an index that lags extraction by seconds — to read back something just extracted, use /api/v2/memory/get. :param search_input: (required) :type search_input: SearchInput @@ -2364,6 +2388,7 @@ def unbind_tags( ) -> SuccessEnvelopeTagUnbindData: """Unbind tags from memory items [Cloud] + Remove the given tags from the given memories, leaving their other tags in place. Idempotent: unbinding a tag an item does not carry still counts as matched. :param tag_unbind_input: (required) :type tag_unbind_input: TagUnbindInput @@ -2435,6 +2460,7 @@ def unbind_tags_with_http_info( ) -> ApiResponse[SuccessEnvelopeTagUnbindData]: """Unbind tags from memory items [Cloud] + Remove the given tags from the given memories, leaving their other tags in place. Idempotent: unbinding a tag an item does not carry still counts as matched. :param tag_unbind_input: (required) :type tag_unbind_input: TagUnbindInput @@ -2506,6 +2532,7 @@ def unbind_tags_without_preload_content( ) -> RESTResponseType: """Unbind tags from memory items [Cloud] + Remove the given tags from the given memories, leaving their other tags in place. Idempotent: unbinding a tag an item does not carry still counts as matched. :param tag_unbind_input: (required) :type tag_unbind_input: TagUnbindInput diff --git a/everos_cloud/api/storage_api.py b/everos_cloud/api/storage_api.py index fed2935..009a819 100644 --- a/everos_cloud/api/storage_api.py +++ b/everos_cloud/api/storage_api.py @@ -57,6 +57,7 @@ def sign_objects( ) -> SignEnvelope: """Get multimodal upload URLs + Presign a direct-to-storage upload for multimodal data. POST the file to the returned URL yourself, then reference the returned object key as a message's content `uri` (/api/v2/memory/add) or as a document's content `uri` (.../documents). Uploading first and passing the key is the only path that gets a non-text item parsed — see `base64` on the content object. The Python SDK's `upload()` does both steps in one call. :param sign_request: (required) :type sign_request: SignRequest @@ -127,6 +128,7 @@ def sign_objects_with_http_info( ) -> ApiResponse[SignEnvelope]: """Get multimodal upload URLs + Presign a direct-to-storage upload for multimodal data. POST the file to the returned URL yourself, then reference the returned object key as a message's content `uri` (/api/v2/memory/add) or as a document's content `uri` (.../documents). Uploading first and passing the key is the only path that gets a non-text item parsed — see `base64` on the content object. The Python SDK's `upload()` does both steps in one call. :param sign_request: (required) :type sign_request: SignRequest @@ -197,6 +199,7 @@ def sign_objects_without_preload_content( ) -> RESTResponseType: """Get multimodal upload URLs + Presign a direct-to-storage upload for multimodal data. POST the file to the returned URL yourself, then reference the returned object key as a message's content `uri` (/api/v2/memory/add) or as a document's content `uri` (.../documents). Uploading first and passing the key is the only path that gets a non-text item parsed — see `base64` on the content object. The Python SDK's `upload()` does both steps in one call. :param sign_request: (required) :type sign_request: SignRequest diff --git a/everos_cloud/api/tasks_api.py b/everos_cloud/api/tasks_api.py index cc2fdf7..ce7cabc 100644 --- a/everos_cloud/api/tasks_api.py +++ b/everos_cloud/api/tasks_api.py @@ -62,7 +62,7 @@ def get_task_stats( ) -> TaskStatsResponse: """Aggregate task counts by status - Counts tasks per status over a time window. All four statuses are always present (0 when absent) so dashboards get a stable shape, and the response echoes the window actually used after server-side clamping. Results are scoped to the caller's tenant, resolved from the request context; a caller can only ever see its own tasks. + Counts tasks per status over a time window. All five statuses (queued, processing, pending, success, failed) are always present (0 when absent) so dashboards get a stable shape, and the response echoes the window actually used after server-side clamping. Results are scoped to the caller's tenant, resolved from the request context. :param start: :type start: str @@ -138,7 +138,7 @@ def get_task_stats_with_http_info( ) -> ApiResponse[TaskStatsResponse]: """Aggregate task counts by status - Counts tasks per status over a time window. All four statuses are always present (0 when absent) so dashboards get a stable shape, and the response echoes the window actually used after server-side clamping. Results are scoped to the caller's tenant, resolved from the request context; a caller can only ever see its own tasks. + Counts tasks per status over a time window. All five statuses (queued, processing, pending, success, failed) are always present (0 when absent) so dashboards get a stable shape, and the response echoes the window actually used after server-side clamping. Results are scoped to the caller's tenant, resolved from the request context. :param start: :type start: str @@ -214,7 +214,7 @@ def get_task_stats_without_preload_content( ) -> RESTResponseType: """Aggregate task counts by status - Counts tasks per status over a time window. All four statuses are always present (0 when absent) so dashboards get a stable shape, and the response echoes the window actually used after server-side clamping. Results are scoped to the caller's tenant, resolved from the request context; a caller can only ever see its own tasks. + Counts tasks per status over a time window. All five statuses (queued, processing, pending, success, failed) are always present (0 when absent) so dashboards get a stable shape, and the response echoes the window actually used after server-side clamping. Results are scoped to the caller's tenant, resolved from the request context. :param start: :type start: str diff --git a/everos_cloud/api_client.py b/everos_cloud/api_client.py index a2861b2..2a8d201 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.1.0-rc2/python' + self.user_agent = 'OpenAPI-Generator/1.1.0/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 8854b62..c3fac40 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.1.0-rc2".\ + "SDK Package Version: 1.1.0".\ format(env=sys.platform, pyversion=sys.version) def get_host_settings(self) -> List[HostSetting]: diff --git a/everos_cloud/models/__init__.py b/everos_cloud/models/__init__.py index 5425e5a..50d8353 100644 --- a/everos_cloud/models/__init__.py +++ b/everos_cloud/models/__init__.py @@ -27,6 +27,7 @@ from everos_cloud.models.category_list_data import CategoryListData from everos_cloud.models.category_patch_body import CategoryPatchBody from everos_cloud.models.content import Content +from everos_cloud.models.content1 import Content1 from everos_cloud.models.content_item import ContentItem from everos_cloud.models.data import Data from everos_cloud.models.data1 import Data1 @@ -48,6 +49,8 @@ from everos_cloud.models.envelope import Envelope from everos_cloud.models.envelope_result import EnvelopeResult from everos_cloud.models.episode_item import EpisodeItem +from everos_cloud.models.error_body import ErrorBody +from everos_cloud.models.error_envelope import ErrorEnvelope from everos_cloud.models.explicit_info_data import ExplicitInfoData from everos_cloud.models.explicit_info_patch import ExplicitInfoPatch from everos_cloud.models.filter_node import FilterNode @@ -66,6 +69,9 @@ from everos_cloud.models.kb_search_data import KbSearchData from everos_cloud.models.message_item import MessageItem from everos_cloud.models.profile_item import ProfileItem +from everos_cloud.models.related_tag_usage_body import RelatedTagUsageBody +from everos_cloud.models.related_tag_usage_item import RelatedTagUsageItem +from everos_cloud.models.related_tag_usage_list_data import RelatedTagUsageListData from everos_cloud.models.search_agent_case_item import SearchAgentCaseItem from everos_cloud.models.search_agent_skill_item import SearchAgentSkillItem from everos_cloud.models.search_atomic_fact_item import SearchAtomicFactItem @@ -100,14 +106,18 @@ from everos_cloud.models.success_envelope_kb_delete_data import SuccessEnvelopeKbDeleteData from everos_cloud.models.success_envelope_kb_list_data import SuccessEnvelopeKbListData from everos_cloud.models.success_envelope_kb_search_data import SuccessEnvelopeKbSearchData +from everos_cloud.models.success_envelope_related_tag_usage_list_data import SuccessEnvelopeRelatedTagUsageListData from everos_cloud.models.success_envelope_search_data import SuccessEnvelopeSearchData from everos_cloud.models.success_envelope_tag_bind_data import SuccessEnvelopeTagBindData from everos_cloud.models.success_envelope_tag_replace_data import SuccessEnvelopeTagReplaceData from everos_cloud.models.success_envelope_tag_unbind_data import SuccessEnvelopeTagUnbindData from everos_cloud.models.success_envelope_topic_detail_data import SuccessEnvelopeTopicDetailData +from everos_cloud.models.success_envelope_topic_filter_list_data import SuccessEnvelopeTopicFilterListData from everos_cloud.models.success_envelope_topic_list_data import SuccessEnvelopeTopicListData +from everos_cloud.models.success_envelope_topic_tag_write_data import SuccessEnvelopeTopicTagWriteData from everos_cloud.models.tag_bind_data import TagBindData from everos_cloud.models.tag_bind_input import TagBindInput +from everos_cloud.models.tag_ref import TagRef from everos_cloud.models.tag_replace_data import TagReplaceData from everos_cloud.models.tag_replace_input import TagReplaceInput from everos_cloud.models.tag_unbind_data import TagUnbindData @@ -124,8 +134,12 @@ from everos_cloud.models.tool_call import ToolCall from everos_cloud.models.tool_call_function import ToolCallFunction from everos_cloud.models.topic_detail_data import TopicDetailData +from everos_cloud.models.topic_filter_item import TopicFilterItem +from everos_cloud.models.topic_filter_list_data import TopicFilterListData from everos_cloud.models.topic_list_data import TopicListData from everos_cloud.models.topic_list_item import TopicListItem +from everos_cloud.models.topic_tag_replace_body import TopicTagReplaceBody +from everos_cloud.models.topic_tag_write_data import TopicTagWriteData from everos_cloud.models.unprocessed_message_dto import UnprocessedMessageDTO from everos_cloud.models.update_operation import UpdateOperation from everos_cloud.models.validation_error import ValidationError diff --git a/everos_cloud/models/add_data.py b/everos_cloud/models/add_data.py index d70abd2..e1dd8cb 100644 --- a/everos_cloud/models/add_data.py +++ b/everos_cloud/models/add_data.py @@ -27,7 +27,7 @@ class AddData(BaseModel): """ AddData """ # noqa: E501 - message_count: StrictInt + message_count: StrictInt = Field(description="How many messages this call accepted.") status: StrictStr = Field(description="\"queued\" — async enqueue accepted (HTTP 202). \"accumulated\"/\"extracted\" — synchronous write outcome (HTTP 200, async_mode=false).") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["message_count", "status"] diff --git a/everos_cloud/models/add_input.py b/everos_cloud/models/add_input.py index 533b71b..32aed6f 100644 --- a/everos_cloud/models/add_input.py +++ b/everos_cloud/models/add_input.py @@ -29,10 +29,10 @@ class AddInput(BaseModel): """ AddInput """ # noqa: E501 - app_id: Optional[StrictStr] = 'default' - project_id: Optional[StrictStr] = 'default' - session_id: Annotated[str, Field(min_length=1, strict=True, max_length=128)] - messages: Annotated[List[MessageItem], Field(min_length=1, max_length=500)] + app_id: Optional[StrictStr] = Field(default='default', description="Business-semantic scope for this write, defaulting to \"default\". Reads must use the same app_id / project_id pair to see what was written under it. Note this is a partition, not the security boundary — that is the tenant resolved from your API key.") + project_id: Optional[StrictStr] = Field(default='default', description="Second half of the business-semantic scope, defaulting to \"default\". See `app_id`.") + session_id: Annotated[str, Field(min_length=1, strict=True, max_length=128)] = Field(description="The conversation these messages belong to (1–128 characters). It is the unit extraction works on: /api/v2/memory/flush takes this id, and a session boundary is what triggers extraction on its own.") + messages: Annotated[List[MessageItem], Field(min_length=1, max_length=500)] = Field(description="The turns to append, in order — 1 to 500 per call. Each carries its own sender and timestamp, so one call can hold a whole exchange.") async_mode: Optional[StrictBool] = Field(default=True, description="Selects the write path. true (default): validated and enqueued asynchronously → HTTP 202 with status \"queued\". false: forwarded synchronously to the engine, returning its 200 result and surfacing write errors directly. Extraction is always asynchronous (flush-triggered).") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["app_id", "project_id", "session_id", "messages", "async_mode"] diff --git a/everos_cloud/models/add_operation.py b/everos_cloud/models/add_operation.py index 34b121b..08f93de 100644 --- a/everos_cloud/models/add_operation.py +++ b/everos_cloud/models/add_operation.py @@ -30,8 +30,8 @@ class AddOperation(BaseModel): Add a new profile item (``item_id`` forbidden — the server mints it). """ # noqa: E501 reason: Optional[Annotated[str, Field(strict=True, max_length=256)]] = None - action: StrictStr - type: StrictStr + action: StrictStr = Field(description="Always \"add\" for this variant.") + type: StrictStr = Field(description="Which profile item this edit targets — \"explicit_info\" (a stated fact, needing `category` + `description`) or \"implicit_traits\" (an inferred trait, needing `trait` + `description`).") data: Data additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["reason", "action", "type", "data"] diff --git a/everos_cloud/models/agent_case_item.py b/everos_cloud/models/agent_case_item.py index ce809df..ce60bb3 100644 --- a/everos_cloud/models/agent_case_item.py +++ b/everos_cloud/models/agent_case_item.py @@ -19,7 +19,7 @@ import json from datetime import datetime -from pydantic import BaseModel, ConfigDict, StrictFloat, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt, StrictStr from typing import Any, ClassVar, Dict, List, Optional, Union from typing import Optional, Set from typing_extensions import Self @@ -28,16 +28,16 @@ class AgentCaseItem(BaseModel): """ AgentCaseItem """ # noqa: E501 - id: StrictStr - app_id: StrictStr - project_id: StrictStr - agent_id: StrictStr - session_id: StrictStr - task_intent: StrictStr - approach: StrictStr - quality_score: Union[StrictFloat, StrictInt] + id: StrictStr = Field(description="Agent-case id.") + app_id: StrictStr = Field(description="The business-semantic scope this case was written under.") + project_id: StrictStr = Field(description="Second half of that scope.") + agent_id: StrictStr = Field(description="The agent that owns this case.") + session_id: StrictStr = Field(description="The session whose trajectory the case was distilled from.") + task_intent: StrictStr = Field(description="What the agent was trying to do in that trajectory.") + approach: StrictStr = Field(description="How it went about it — the reusable part of the case.") + quality_score: Union[StrictFloat, StrictInt] = Field(description="How good this case is judged to be. Nominally 0.0–1.0 with 0.5 as the no-opinion default, but the value is the extractor's own and nothing on the write path enforces the range — treat an out-of-range number as possible. One threshold is real: a case scoring below 0.2 is never distilled into a skill.") key_insight: Optional[StrictStr] = None - timestamp: datetime + timestamp: datetime = Field(description="When the trajectory happened (ISO 8601).") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["id", "app_id", "project_id", "agent_id", "session_id", "task_intent", "approach", "quality_score", "key_insight", "timestamp"] diff --git a/everos_cloud/models/agent_skill_item.py b/everos_cloud/models/agent_skill_item.py index 40496cb..c1627f8 100644 --- a/everos_cloud/models/agent_skill_item.py +++ b/everos_cloud/models/agent_skill_item.py @@ -18,7 +18,8 @@ import re # noqa: F401 import json -from pydantic import BaseModel, ConfigDict, StrictFloat, StrictInt, StrictStr +from datetime import datetime +from pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt, StrictStr from typing import Any, ClassVar, Dict, List, Optional, Union from typing import Optional, Set from typing_extensions import Self @@ -27,18 +28,20 @@ class AgentSkillItem(BaseModel): """ AgentSkillItem """ # noqa: E501 - id: StrictStr - app_id: StrictStr - project_id: StrictStr - agent_id: StrictStr - name: StrictStr - description: StrictStr - content: StrictStr - confidence: Union[StrictFloat, StrictInt] - maturity_score: Union[StrictFloat, StrictInt] - source_case_ids: Optional[List[StrictStr]] = None + id: StrictStr = Field(description="Agent-skill id.") + app_id: StrictStr = Field(description="The business-semantic scope this skill was written under.") + project_id: StrictStr = Field(description="Second half of that scope.") + agent_id: StrictStr = Field(description="The agent that owns this skill.") + name: StrictStr = Field(description="The skill's name.") + description: StrictStr = Field(description="What the skill is for, in a sentence.") + content: StrictStr = Field(description="The skill itself — the reusable procedure, ready to put in a prompt.") + confidence: Union[StrictFloat, StrictInt] = Field(description="How much the distillation trusts this skill. Nominally 0.0–1.0, defaulting to 0.0 before anything scores it; the range is not enforced on the write path. Nothing in retrieval filters on it today, and how it divides labour with `maturity_score` is still open — so do not build a threshold on it yet.") + maturity_score: Union[StrictFloat, StrictInt] = Field(description="How well-established the skill is. Nominally 0.0–1.0 and unenforced, and — unlike the other two scores — its default is 0.6 rather than 0.0, chosen so an unscored skill starts mid-optimistic. The cost is that an unscored 0.6 is indistinguishable from a scored 0.6: there is no \"not evaluated\" sentinel, and maturity scoring is skipped by default. Filtering near 0.6 is therefore unreliable.") + source_case_ids: Optional[List[StrictStr]] = Field(default=None, description="The agent cases this skill was distilled from. Fetch them for the underlying evidence.") + created_at: Optional[datetime] = None + updated_at: Optional[datetime] = None additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["id", "app_id", "project_id", "agent_id", "name", "description", "content", "confidence", "maturity_score", "source_case_ids"] + __properties: ClassVar[List[str]] = ["id", "app_id", "project_id", "agent_id", "name", "description", "content", "confidence", "maturity_score", "source_case_ids", "created_at", "updated_at"] model_config = ConfigDict( populate_by_name=True, @@ -86,6 +89,16 @@ def to_dict(self) -> Dict[str, Any]: for _key, _value in self.additional_properties.items(): _dict[_key] = _value + # set to None if created_at (nullable) is None + # and model_fields_set contains the field + if self.created_at is None and "created_at" in self.model_fields_set: + _dict['created_at'] = None + + # set to None if updated_at (nullable) is None + # and model_fields_set contains the field + if self.updated_at is None and "updated_at" in self.model_fields_set: + _dict['updated_at'] = None + return _dict @classmethod @@ -107,7 +120,9 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: "content": obj.get("content"), "confidence": obj.get("confidence"), "maturity_score": obj.get("maturity_score"), - "source_case_ids": obj.get("source_case_ids") + "source_case_ids": obj.get("source_case_ids"), + "created_at": obj.get("created_at"), + "updated_at": obj.get("updated_at") }) # store additional fields in additional_properties for _key in obj.keys(): diff --git a/everos_cloud/models/atomic_fact_item.py b/everos_cloud/models/atomic_fact_item.py index 86f4196..b1c4ab4 100644 --- a/everos_cloud/models/atomic_fact_item.py +++ b/everos_cloud/models/atomic_fact_item.py @@ -18,7 +18,7 @@ import re # noqa: F401 import json -from pydantic import BaseModel, ConfigDict, StrictStr +from pydantic import BaseModel, ConfigDict, Field, StrictStr from typing import Any, ClassVar, Dict, List from typing import Optional, Set from typing_extensions import Self @@ -27,8 +27,8 @@ class AtomicFactItem(BaseModel): """ Atomic fact nested in an episode. Spec appendix E references it but does not enumerate its fields — minimal shape until the contract is detailed. """ # noqa: E501 - id: StrictStr - content: StrictStr + id: StrictStr = Field(description="Atomic-fact id.") + content: StrictStr = Field(description="The fact itself, as a single statement.") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["id", "content"] diff --git a/everos_cloud/models/category_data.py b/everos_cloud/models/category_data.py index 77e33c2..51bcf4e 100644 --- a/everos_cloud/models/category_data.py +++ b/everos_cloud/models/category_data.py @@ -28,9 +28,9 @@ class CategoryData(BaseModel): A category as returned to clients. ``id`` is the system-generated stable key. """ # noqa: E501 id: StrictStr = Field(description="Category id (system-generated, stable)") - name: StrictStr - description: Optional[StrictStr] = '' - document_count: Optional[StrictInt] = 0 + name: StrictStr = Field(description="The category's display name.") + description: Optional[StrictStr] = Field(default='', description="What belongs in this category. The classifier matches documents against this text, so it is functional, not decorative.") + document_count: Optional[StrictInt] = Field(default=0, description="How many documents are filed under it.") scope: Optional[StrictStr] = Field(default='kb', description="'kb' = user-created in this kb; 'tenant' = global preset (read-only)") editable: Optional[StrictBool] = Field(default=True, description="False for tenant-global preset categories (read-only)") additional_properties: Dict[str, Any] = {} diff --git a/everos_cloud/models/category_list_data.py b/everos_cloud/models/category_list_data.py index cfa8c60..39dd64f 100644 --- a/everos_cloud/models/category_list_data.py +++ b/everos_cloud/models/category_list_data.py @@ -18,7 +18,7 @@ import re # noqa: F401 import json -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field from typing import Any, ClassVar, Dict, List, Optional from everos_cloud.models.category_data import CategoryData from typing import Optional, Set @@ -28,7 +28,7 @@ class CategoryListData(BaseModel): """ CategoryListData """ # noqa: E501 - categories: Optional[List[CategoryData]] = None + categories: Optional[List[CategoryData]] = Field(default=None, description="Every category available in this knowledge base — the ones created here plus the tenant-global presets.") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["categories"] diff --git a/everos_cloud/models/content.py b/everos_cloud/models/content.py index 4ae8f64..9c54953 100644 --- a/everos_cloud/models/content.py +++ b/everos_cloud/models/content.py @@ -29,7 +29,7 @@ class Content(BaseModel): """ - Content + The message body: a plain string (shorthand for a single text item), or a list of content items for multimodal input. """ # data type: str diff --git a/everos_cloud/models/content1.py b/everos_cloud/models/content1.py new file mode 100644 index 0000000..4c2f88f --- /dev/null +++ b/everos_cloud/models/content1.py @@ -0,0 +1,140 @@ +# coding: utf-8 + +""" + EverOS Cloud Memory API + + Official Python client for the EverOS Cloud Memory API. Add, search, retrieve, and manage long-term memory for your AI applications over a typed interface (pydantic v2, with full type hints). Install and usage guides: https://github.com/EverMind-AI/everos-cloud-sdk-python + + The version of the OpenAPI document: 2.0.0 + Contact: service@evermind.ai + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +from inspect import getfullargspec +import json +import pprint +import re # noqa: F401 +from pydantic import BaseModel, ConfigDict, Field, StrictStr, ValidationError, field_validator +from typing import List, Optional +from everos_cloud.models.content_item import ContentItem +from typing import Union, Any, List, Set, TYPE_CHECKING, Optional, Dict +from typing_extensions import Literal, Self +from pydantic import Field + +CONTENT1_ANY_OF_SCHEMAS = ["List[ContentItem]", "str"] + +class Content1(BaseModel): + """ + The message body as submitted. + """ + + # data type: str + anyof_schema_1_validator: Optional[StrictStr] = None + # data type: List[ContentItem] + anyof_schema_2_validator: Optional[List[ContentItem]] = None + if TYPE_CHECKING: + actual_instance: Optional[Union[List[ContentItem], str]] = None + else: + actual_instance: Any = None + any_of_schemas: Set[str] = { "List[ContentItem]", "str" } + + model_config = { + "validate_assignment": True, + "protected_namespaces": (), + } + + def __init__(self, *args, **kwargs) -> None: + if args: + if len(args) > 1: + raise ValueError("If a position argument is used, only 1 is allowed to set `actual_instance`") + if kwargs: + raise ValueError("If a position argument is used, keyword arguments cannot be used.") + super().__init__(actual_instance=args[0]) + else: + super().__init__(**kwargs) + + @field_validator('actual_instance') + def actual_instance_must_validate_anyof(cls, v): + instance = Content1.model_construct() + error_messages = [] + # validate data type: str + try: + instance.anyof_schema_1_validator = v + return v + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # validate data type: List[ContentItem] + try: + instance.anyof_schema_2_validator = v + return v + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + if error_messages: + # no match + raise ValueError("No match found when setting the actual_instance in Content1 with anyOf schemas: List[ContentItem], str. Details: " + ", ".join(error_messages)) + else: + return v + + @classmethod + def from_dict(cls, obj: Dict[str, Any]) -> Self: + return cls.from_json(json.dumps(obj)) + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Returns the object represented by the json string""" + instance = cls.model_construct() + error_messages = [] + # deserialize data into str + try: + # validation + instance.anyof_schema_1_validator = json.loads(json_str) + # assign value to actual_instance + instance.actual_instance = instance.anyof_schema_1_validator + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # deserialize data into List[ContentItem] + try: + # validation + instance.anyof_schema_2_validator = json.loads(json_str) + # assign value to actual_instance + instance.actual_instance = instance.anyof_schema_2_validator + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + + if error_messages: + # no match + raise ValueError("No match found when deserializing the JSON string into Content1 with anyOf schemas: List[ContentItem], str. Details: " + ", ".join(error_messages)) + else: + return instance + + def to_json(self) -> str: + """Returns the JSON representation of the actual instance""" + if self.actual_instance is None: + return "null" + + if hasattr(self.actual_instance, "to_json") and callable(self.actual_instance.to_json): + return self.actual_instance.to_json() + else: + return json.dumps(self.actual_instance) + + def to_dict(self) -> Optional[Union[Dict[str, Any], List[ContentItem], str]]: + """Returns the dict representation of the actual instance""" + if self.actual_instance is None: + return None + + if hasattr(self.actual_instance, "to_dict") and callable(self.actual_instance.to_dict): + return self.actual_instance.to_dict() + else: + return self.actual_instance + + def to_str(self) -> str: + """Returns the string representation of the actual instance""" + return pprint.pformat(self.model_dump()) + + diff --git a/everos_cloud/models/content_item.py b/everos_cloud/models/content_item.py index f1fa244..6d244ca 100644 --- a/everos_cloud/models/content_item.py +++ b/everos_cloud/models/content_item.py @@ -27,7 +27,7 @@ class ContentItem(BaseModel): """ A single content element (appendix A). Current phase: only ``type=\"text\"``. """ # noqa: E501 - type: StrictStr + type: StrictStr = Field(description="What this item is: \"text\", \"image\", \"audio\", \"doc\", \"pdf\", \"html\" or \"email\". It selects how the content is parsed, so it must match the payload.") text: Optional[StrictStr] = None source: Optional[StrictStr] = None var_base64: Optional[StrictStr] = Field(default=None, alias="base64") diff --git a/everos_cloud/models/data.py b/everos_cloud/models/data.py index 5c81f0c..be9a94a 100644 --- a/everos_cloud/models/data.py +++ b/everos_cloud/models/data.py @@ -30,7 +30,7 @@ class Data(BaseModel): """ - Data + The item to add. Its required keys depend on `type`; other keys (evidence, sources, basis, …) ride through untouched. """ # data type: ExplicitInfoData diff --git a/everos_cloud/models/data1.py b/everos_cloud/models/data1.py index c78317a..830753a 100644 --- a/everos_cloud/models/data1.py +++ b/everos_cloud/models/data1.py @@ -30,7 +30,7 @@ class Data1(BaseModel): """ - Data1 + Partial patch, shallow-merged into the stored item. At least one of the type's own keys must be present. """ # data type: ExplicitInfoPatch diff --git a/everos_cloud/models/delete_input.py b/everos_cloud/models/delete_input.py index 6a95a96..d43abec 100644 --- a/everos_cloud/models/delete_input.py +++ b/everos_cloud/models/delete_input.py @@ -28,8 +28,8 @@ class DeleteInput(BaseModel): """ DeleteInput """ # noqa: E501 - app_id: Optional[StrictStr] = 'default' - project_id: Optional[StrictStr] = 'default' + app_id: Optional[StrictStr] = Field(default='default', description="Scope to delete within, defaulting to \"default\".") + project_id: Optional[StrictStr] = Field(default='default', description="Second half of the scope, defaulting to \"default\".") user_id: Optional[Annotated[str, Field(min_length=1, strict=True)]] = None agent_id: Optional[Annotated[str, Field(min_length=1, strict=True)]] = None session_id: Optional[StrictStr] = None diff --git a/everos_cloud/models/delete_operation.py b/everos_cloud/models/delete_operation.py index 41156c3..87fbdb7 100644 --- a/everos_cloud/models/delete_operation.py +++ b/everos_cloud/models/delete_operation.py @@ -29,9 +29,9 @@ class DeleteOperation(BaseModel): Delete an existing profile item by ``item_id`` (carries no ``data``). """ # noqa: E501 reason: Optional[Annotated[str, Field(strict=True, max_length=256)]] = None - action: StrictStr - type: StrictStr - item_id: StrictStr + action: StrictStr = Field(description="Always \"delete\" for this variant.") + type: StrictStr = Field(description="Which profile item this edit targets — \"explicit_info\" or \"implicit_traits\". It must match the `item_id` prefix.") + item_id: StrictStr = Field(description="The item to delete. Its prefix must match the item type (\"ei_\" / \"it_\") followed by 24 hex characters.") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["reason", "action", "type", "item_id"] diff --git a/everos_cloud/models/doc_data.py b/everos_cloud/models/doc_data.py index 2fcf53c..60bb939 100644 --- a/everos_cloud/models/doc_data.py +++ b/everos_cloud/models/doc_data.py @@ -21,6 +21,7 @@ from datetime import datetime from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr from typing import Any, ClassVar, Dict, List, Optional +from everos_cloud.models.tag_ref import TagRef from typing import Optional, Set from typing_extensions import Self @@ -29,18 +30,19 @@ class DocData(BaseModel): A document as returned to clients. ``topic_count`` = the node_count (>0 = ingested). Contract note — ``topic_count`` vs ``GET .../topics``: the count is of REAL topics and excludes the synthetic document-root node, while the topics list INCLUDES it. So ``len(topics) == topic_count + 1`` for an ingested document. See ``TopicListData``. """ # noqa: E501 id: StrictStr = Field(description="Document id (bare primary key)") - kb_id: StrictStr - category_id: Optional[StrictStr] = '' + kb_id: StrictStr = Field(description="The knowledge base this document belongs to.") + category_id: Optional[StrictStr] = Field(default='', description="The category it is filed under; empty when it is uncategorized.") category_name: Optional[StrictStr] = None - title: StrictStr + title: StrictStr = Field(description="The document's title.") summary: Optional[StrictStr] = None source_name: Optional[StrictStr] = None source_type: Optional[StrictStr] = None + tags: List[TagRef] = Field(description="Distinct opaque ids from the document's read-only topic-tag union. Cloud leaves name unset; KHS may validate and expand display names. This document aggregate is read-only and carries no topic ownership field.") topic_count: Optional[StrictInt] = Field(default=0, description="Number of real topics extracted (0 = not ingested yet / ingest failed). EXCLUDES the synthetic document-root node, so `GET .../topics` — which includes it — returns exactly one more item than this") created_at: Optional[datetime] = None updated_at: Optional[datetime] = None additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["id", "kb_id", "category_id", "category_name", "title", "summary", "source_name", "source_type", "topic_count", "created_at", "updated_at"] + __properties: ClassVar[List[str]] = ["id", "kb_id", "category_id", "category_name", "title", "summary", "source_name", "source_type", "tags", "topic_count", "created_at", "updated_at"] model_config = ConfigDict( populate_by_name=True, @@ -83,6 +85,13 @@ def to_dict(self) -> Dict[str, Any]: exclude=excluded_fields, exclude_none=True, ) + # override the default output from pydantic by calling `to_dict()` of each item in tags (list) + _items = [] + if self.tags: + for _item_tags in self.tags: + if _item_tags: + _items.append(_item_tags.to_dict()) + _dict['tags'] = _items # puts key-value pairs in additional_properties in the top level if self.additional_properties is not None: for _key, _value in self.additional_properties.items(): @@ -138,6 +147,7 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: "summary": obj.get("summary"), "source_name": obj.get("source_name"), "source_type": obj.get("source_type"), + "tags": [TagRef.from_dict(_item) for _item in obj["tags"]] if obj.get("tags") is not None else None, "topic_count": obj.get("topic_count") if obj.get("topic_count") is not None else 0, "created_at": obj.get("created_at"), "updated_at": obj.get("updated_at") diff --git a/everos_cloud/models/doc_ingest_body.py b/everos_cloud/models/doc_ingest_body.py index ecc3e88..3ab5422 100644 --- a/everos_cloud/models/doc_ingest_body.py +++ b/everos_cloud/models/doc_ingest_body.py @@ -29,7 +29,7 @@ class DocIngestBody(BaseModel): """ Public POST/PUT documents request body (design §3.2 / §3.3). ``content`` is the object to ingest (its ``uri`` = the SMM object_key). On PUT the ``doc_id`` rides the path, not the body; on POST no id is supplied — the engine mints it. """ # noqa: E501 - title: Annotated[str, Field(min_length=1, strict=True)] + title: Annotated[str, Field(min_length=1, strict=True)] = Field(description="Human-readable name for the document. Until the async ingest finishes this is the only handle the caller has — the document id is minted downstream, so GET .../documents is resolved by title.") content: ContentItem = Field(description="The object to ingest (its uri = the SMM object_key)") category_id: Optional[StrictStr] = Field(default='', description="Category id in this kb; omit for LLM auto-classify") additional_properties: Dict[str, Any] = {} diff --git a/everos_cloud/models/doc_list_data.py b/everos_cloud/models/doc_list_data.py index de255f7..630c463 100644 --- a/everos_cloud/models/doc_list_data.py +++ b/everos_cloud/models/doc_list_data.py @@ -18,7 +18,7 @@ import re # noqa: F401 import json -from pydantic import BaseModel, ConfigDict, StrictInt +from pydantic import BaseModel, ConfigDict, Field, StrictInt from typing import Any, ClassVar, Dict, List, Optional from everos_cloud.models.doc_data import DocData from typing import Optional, Set @@ -28,8 +28,8 @@ class DocListData(BaseModel): """ DocListData """ # noqa: E501 - documents: Optional[List[DocData]] = None - total: Optional[StrictInt] = 0 + documents: Optional[List[DocData]] = Field(default=None, description="This page of documents.") + total: Optional[StrictInt] = Field(default=0, description="How many documents match, across all pages.") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["documents", "total"] diff --git a/everos_cloud/models/doc_patch_data.py b/everos_cloud/models/doc_patch_data.py index 234408d..da2b879 100644 --- a/everos_cloud/models/doc_patch_data.py +++ b/everos_cloud/models/doc_patch_data.py @@ -19,7 +19,7 @@ import json from datetime import datetime -from pydantic import BaseModel, ConfigDict, StrictStr +from pydantic import BaseModel, ConfigDict, Field, StrictStr from typing import Any, ClassVar, Dict, List, Optional from typing import Optional, Set from typing_extensions import Self @@ -28,8 +28,8 @@ class DocPatchData(BaseModel): """ DocPatchData """ # noqa: E501 - id: StrictStr - updated_fields: Optional[List[StrictStr]] = None + id: StrictStr = Field(description="The document that was patched.") + updated_fields: Optional[List[StrictStr]] = Field(default=None, description="Which fields actually changed — omitted fields are not listed.") updated_at: Optional[datetime] = None additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["id", "updated_fields", "updated_at"] diff --git a/everos_cloud/models/document_context.py b/everos_cloud/models/document_context.py index 94f359c..0099ee1 100644 --- a/everos_cloud/models/document_context.py +++ b/everos_cloud/models/document_context.py @@ -18,7 +18,7 @@ import re # noqa: F401 import json -from pydantic import BaseModel, ConfigDict, StrictStr +from pydantic import BaseModel, ConfigDict, Field, StrictStr from typing import Any, ClassVar, Dict, List, Optional from typing import Optional, Set from typing_extensions import Self @@ -27,8 +27,8 @@ class DocumentContext(BaseModel): """ The parent document a hit belongs to (rolled up for display). """ # noqa: E501 - doc_id: StrictStr - title: Optional[StrictStr] = '' + doc_id: StrictStr = Field(description="The parent document's id.") + title: Optional[StrictStr] = Field(default='', description="Its title.") summary: Optional[StrictStr] = None additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["doc_id", "title", "summary"] diff --git a/everos_cloud/models/edit_data.py b/everos_cloud/models/edit_data.py index 9ce794c..5c82cea 100644 --- a/everos_cloud/models/edit_data.py +++ b/everos_cloud/models/edit_data.py @@ -18,7 +18,7 @@ import re # noqa: F401 import json -from pydantic import BaseModel, ConfigDict, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr from typing import Any, ClassVar, Dict, List, Optional from everos_cloud.models.edit_result_item import EditResultItem from typing import Optional, Set @@ -28,11 +28,11 @@ class EditData(BaseModel): """ Response payload for a successful profile edit request. """ # noqa: E501 - user_id: StrictStr - version: StrictInt - applied: StrictInt - results: Optional[List[EditResultItem]] = None - profile: Optional[Dict[str, Any]] = None + user_id: StrictStr = Field(description="The user whose profile was edited.") + version: StrictInt = Field(description="The profile's version after this edit. It advances every time the profile changes.") + applied: StrictInt = Field(description="How many of the submitted operations took effect.") + results: Optional[List[EditResultItem]] = Field(default=None, description="Per-operation outcome, in submission order — check this rather than assuming all applied.") + profile: Optional[Dict[str, Any]] = Field(default=None, description="The profile as it stands after the edit, so no follow-up read is needed.") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["user_id", "version", "applied", "results", "profile"] diff --git a/everos_cloud/models/edit_input.py b/everos_cloud/models/edit_input.py index 863fb0d..046b182 100644 --- a/everos_cloud/models/edit_input.py +++ b/everos_cloud/models/edit_input.py @@ -29,11 +29,11 @@ class EditInput(BaseModel): """ Bulk profile edit request [Cloud-only]. Carries 1–50 ``EditOperation`` items targeting a single user's profile. ``memory_type`` is pinned to ``\"profile\"``; ``source`` is server-set and not accepted from the client. """ # noqa: E501 - app_id: Optional[StrictStr] = 'default' - project_id: Optional[StrictStr] = 'default' - user_id: Annotated[str, Field(min_length=1, strict=True)] - memory_type: Optional[StrictStr] = 'profile' - operations: Annotated[List[EditInputOperationsInner], Field(min_length=1, max_length=50)] + app_id: Optional[StrictStr] = Field(default='default', description="Scope the profile lives in, defaulting to \"default\".") + project_id: Optional[StrictStr] = Field(default='default', description="Second half of the scope, defaulting to \"default\".") + user_id: Annotated[str, Field(min_length=1, strict=True)] = Field(description="The user whose profile is being edited.") + memory_type: Optional[StrictStr] = Field(default='profile', description="Pinned to \"profile\" — this endpoint edits nothing else.") + operations: Annotated[List[EditInputOperationsInner], Field(min_length=1, max_length=50)] = Field(description="1 to 50 edits applied in one call. \"add\" mints the item id and must not carry one; \"update\" and \"delete\" require an `item_id` whose prefix matches the item type (\"ei_\" for explicit_info, \"it_\" for implicit_traits). Each operation's outcome is reported separately, so one can be rejected while the rest apply.") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["app_id", "project_id", "user_id", "memory_type", "operations"] diff --git a/everos_cloud/models/edit_result_item.py b/everos_cloud/models/edit_result_item.py index 91bfb58..f99b7eb 100644 --- a/everos_cloud/models/edit_result_item.py +++ b/everos_cloud/models/edit_result_item.py @@ -18,7 +18,7 @@ import re # noqa: F401 import json -from pydantic import BaseModel, ConfigDict, StrictInt, StrictStr, field_validator +from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr, field_validator from typing import Any, ClassVar, Dict, List, Optional from typing import Optional, Set from typing_extensions import Self @@ -27,10 +27,10 @@ class EditResultItem(BaseModel): """ Per-operation outcome returned in ``EditData.results``. """ # noqa: E501 - op_index: StrictInt - action: StrictStr - type: StrictStr - status: StrictStr + op_index: StrictInt = Field(description="Which submitted operation this is, by 0-based position in the request.") + action: StrictStr = Field(description="The action that was attempted — \"add\", \"update\" or \"delete\".") + type: StrictStr = Field(description="The profile item type it targeted.") + status: StrictStr = Field(description="\"applied\" or \"rejected\". A rejected operation does not fail the request.") item_id: Optional[StrictStr] = None new_item_id: Optional[StrictStr] = None error: Optional[StrictStr] = None diff --git a/everos_cloud/models/envelope.py b/everos_cloud/models/envelope.py index 9ddaa95..d3bf98e 100644 --- a/everos_cloud/models/envelope.py +++ b/everos_cloud/models/envelope.py @@ -29,7 +29,7 @@ class Envelope(BaseModel): Common response envelope """ # noqa: E501 error: Optional[StrictStr] = Field(default=None, description="`\"OK\"` on success, otherwise a human-readable error message decoded from the business error. ") - request_id: Optional[StrictStr] = None + request_id: Optional[StrictStr] = Field(default=None, description="Id of this request — quote it when reporting a problem.") status: Optional[StrictInt] = Field(default=None, description="Business status code; 0 means success") result: Optional[EnvelopeResult] = None additional_properties: Dict[str, Any] = {} diff --git a/everos_cloud/models/envelope_result.py b/everos_cloud/models/envelope_result.py index 052c6b6..7e67cf4 100644 --- a/everos_cloud/models/envelope_result.py +++ b/everos_cloud/models/envelope_result.py @@ -25,7 +25,7 @@ class EnvelopeResult(BaseModel): """ - EnvelopeResult + The response payload. """ # noqa: E501 data: Optional[Any] = None additional_properties: Dict[str, Any] = {} diff --git a/everos_cloud/models/episode_item.py b/everos_cloud/models/episode_item.py index 22dd584..94b17ee 100644 --- a/everos_cloud/models/episode_item.py +++ b/everos_cloud/models/episode_item.py @@ -19,7 +19,7 @@ import json from datetime import datetime -from pydantic import BaseModel, ConfigDict, StrictStr +from pydantic import BaseModel, ConfigDict, Field, StrictStr from typing import Any, ClassVar, Dict, List, Optional from everos_cloud.models.atomic_fact_item import AtomicFactItem from typing import Optional, Set @@ -29,20 +29,20 @@ class EpisodeItem(BaseModel): """ EpisodeItem """ # noqa: E501 - id: StrictStr - app_id: StrictStr - project_id: StrictStr + id: StrictStr = Field(description="Episode id. Use it to bind tags or to fetch this episode again.") + app_id: StrictStr = Field(description="The business-semantic scope this memory was written under.") + project_id: StrictStr = Field(description="Second half of that scope.") user_id: Optional[StrictStr] = None session_id: Optional[StrictStr] = None - timestamp: datetime - sender_ids: Optional[List[StrictStr]] = None - summary: StrictStr - subject: StrictStr - episode: StrictStr + timestamp: datetime = Field(description="When the remembered exchange happened (ISO 8601), not when it was extracted.") + sender_ids: Optional[List[StrictStr]] = Field(default=None, description="The senders that appear in the source exchange.") + summary: StrictStr = Field(description="Short summary of the episode — what a result list should show.") + subject: StrictStr = Field(description="What the episode is about, in a few words.") + episode: StrictStr = Field(description="The episode's stored narrative body. This is the indexed, searchable text.") readable_episode: Optional[StrictStr] = None - type: StrictStr - atomic_facts: Optional[List[AtomicFactItem]] = None - tags: Optional[List[StrictStr]] = None + type: StrictStr = Field(description="How the episode was produced — \"Conversation\" or \"AgentConversation\".") + atomic_facts: Optional[List[AtomicFactItem]] = Field(default=None, description="The individual facts extracted from this episode, nested rather than returned separately.") + tags: Optional[List[StrictStr]] = Field(default=None, description="Tags attached through /api/v2/memory/tag/*.") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["id", "app_id", "project_id", "user_id", "session_id", "timestamp", "sender_ids", "summary", "subject", "episode", "readable_episode", "type", "atomic_facts", "tags"] diff --git a/everos_cloud/models/error_body.py b/everos_cloud/models/error_body.py new file mode 100644 index 0000000..6b7ad6d --- /dev/null +++ b/everos_cloud/models/error_body.py @@ -0,0 +1,103 @@ +# coding: utf-8 + +""" + EverOS Cloud Memory API + + Official Python client for the EverOS Cloud Memory API. Add, search, retrieve, and manage long-term memory for your AI applications over a typed interface (pydantic v2, with full type hints). Install and usage guides: https://github.com/EverMind-AI/everos-cloud-sdk-python + + The version of the OpenAPI document: 2.0.0 + Contact: service@evermind.ai + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictStr +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self + +class ErrorBody(BaseModel): + """ + Nested error object inside the error envelope. + """ # noqa: E501 + code: StrictStr = Field(description="Domain error code") + message: StrictStr = Field(description="Human-readable error message") + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["code", "message"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of ErrorBody from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of ErrorBody from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "code": obj.get("code"), + "message": obj.get("message") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/everos_cloud/models/error_envelope.py b/everos_cloud/models/error_envelope.py new file mode 100644 index 0000000..28d66bb --- /dev/null +++ b/everos_cloud/models/error_envelope.py @@ -0,0 +1,107 @@ +# coding: utf-8 + +""" + EverOS Cloud Memory API + + Official Python client for the EverOS Cloud Memory API. Add, search, retrieve, and manage long-term memory for your AI applications over a typed interface (pydantic v2, with full type hints). Install and usage guides: https://github.com/EverMind-AI/everos-cloud-sdk-python + + The version of the OpenAPI document: 2.0.0 + Contact: service@evermind.ai + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictStr +from typing import Any, ClassVar, Dict, List +from everos_cloud.models.error_body import ErrorBody +from typing import Optional, Set +from typing_extensions import Self + +class ErrorEnvelope(BaseModel): + """ + v1 error envelope (spec §1): ``{request_id, error:{code,message}}``. Used by ``global_exception_handler`` for both HTTPException (carrying the domain code via ``InvocationHttpError``) and unhandled exceptions. + """ # noqa: E501 + request_id: StrictStr = Field(description="Request trace id") + error: ErrorBody = Field(description="Error detail (code + message)") + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["request_id", "error"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of ErrorEnvelope from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of error + if self.error: + _dict['error'] = self.error.to_dict() + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of ErrorEnvelope from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "request_id": obj.get("request_id"), + "error": ErrorBody.from_dict(obj["error"]) if obj.get("error") is not None else None + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/everos_cloud/models/explicit_info_data.py b/everos_cloud/models/explicit_info_data.py index 189ca4a..049951b 100644 --- a/everos_cloud/models/explicit_info_data.py +++ b/everos_cloud/models/explicit_info_data.py @@ -28,8 +28,8 @@ class ExplicitInfoData(BaseModel): """ ``data`` payload for ``add explicit_info`` — ``category`` + ``description`` required (non-empty); other fields (``evidence``, ``sources``, …) pass through. """ # noqa: E501 - category: Annotated[str, Field(min_length=1, strict=True)] - description: Annotated[str, Field(min_length=1, strict=True, max_length=4000)] + category: Annotated[str, Field(min_length=1, strict=True)] = Field(description="What kind of fact this is, e.g. \"hobby\". Required, non-empty.") + description: Annotated[str, Field(min_length=1, strict=True, max_length=4000)] = Field(description="The fact itself, up to 4000 characters. Required, non-empty.") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["category", "description"] diff --git a/everos_cloud/models/flush_data.py b/everos_cloud/models/flush_data.py index e4f7aa1..0c64df2 100644 --- a/everos_cloud/models/flush_data.py +++ b/everos_cloud/models/flush_data.py @@ -18,7 +18,7 @@ import re # noqa: F401 import json -from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator from typing import Any, ClassVar, Dict, List from typing import Optional, Set from typing_extensions import Self @@ -27,7 +27,7 @@ class FlushData(BaseModel): """ FlushData """ # noqa: E501 - status: StrictStr + status: StrictStr = Field(description="\"extracted\" when the flush distilled new memories, \"no_extraction\" when there was nothing to extract — including the case of an async add still queued.") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["status"] diff --git a/everos_cloud/models/flush_input.py b/everos_cloud/models/flush_input.py index 701e6eb..19442eb 100644 --- a/everos_cloud/models/flush_input.py +++ b/everos_cloud/models/flush_input.py @@ -28,9 +28,9 @@ class FlushInput(BaseModel): """ FlushInput """ # noqa: E501 - app_id: Optional[StrictStr] = 'default' - project_id: Optional[StrictStr] = 'default' - session_id: Annotated[str, Field(min_length=1, strict=True)] + app_id: Optional[StrictStr] = Field(default='default', description="Scope the session lives in, defaulting to \"default\".") + project_id: Optional[StrictStr] = Field(default='default', description="Second half of the scope, defaulting to \"default\".") + session_id: Annotated[str, Field(min_length=1, strict=True)] = Field(description="The session to extract from. Only messages already accumulated for this session are considered, so a still-queued async add yields \"no_extraction\".") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["app_id", "project_id", "session_id"] diff --git a/everos_cloud/models/get_data.py b/everos_cloud/models/get_data.py index 110c59b..780d7d6 100644 --- a/everos_cloud/models/get_data.py +++ b/everos_cloud/models/get_data.py @@ -18,7 +18,7 @@ import re # noqa: F401 import json -from pydantic import BaseModel, ConfigDict, StrictInt +from pydantic import BaseModel, ConfigDict, Field, StrictInt from typing import Any, ClassVar, Dict, List, Optional from everos_cloud.models.agent_case_item import AgentCaseItem from everos_cloud.models.agent_skill_item import AgentSkillItem @@ -31,12 +31,12 @@ class GetData(BaseModel): """ GetData """ # noqa: E501 - episodes: Optional[List[EpisodeItem]] = None - profiles: Optional[List[ProfileItem]] = None - agent_cases: Optional[List[AgentCaseItem]] = None - agent_skills: Optional[List[AgentSkillItem]] = None - total_count: Optional[StrictInt] = 0 - count: Optional[StrictInt] = 0 + episodes: Optional[List[EpisodeItem]] = Field(default=None, description="Episodes, when `memory_type` was \"episode\". Empty otherwise.") + profiles: Optional[List[ProfileItem]] = Field(default=None, description="Profiles, when `memory_type` was \"profile\". Empty otherwise.") + agent_cases: Optional[List[AgentCaseItem]] = Field(default=None, description="Agent cases, when `memory_type` was \"agent_case\". Empty otherwise.") + agent_skills: Optional[List[AgentSkillItem]] = Field(default=None, description="Agent skills, when `memory_type` was \"agent_skill\". Empty otherwise.") + total_count: Optional[StrictInt] = Field(default=0, description="How many memories match the request in total, across all pages.") + count: Optional[StrictInt] = Field(default=0, description="How many are in this page.") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["episodes", "profiles", "agent_cases", "agent_skills", "total_count", "count"] diff --git a/everos_cloud/models/get_input.py b/everos_cloud/models/get_input.py index 69c5528..ac82a57 100644 --- a/everos_cloud/models/get_input.py +++ b/everos_cloud/models/get_input.py @@ -29,16 +29,16 @@ class GetInput(BaseModel): """ GetInput """ # noqa: E501 - app_id: Optional[StrictStr] = 'default' - project_id: Optional[StrictStr] = 'default' + app_id: Optional[StrictStr] = Field(default='default', description="Scope to read from, defaulting to \"default\". Must match the pair used on write.") + project_id: Optional[StrictStr] = Field(default='default', description="Second half of the scope, defaulting to \"default\".") user_id: Optional[Annotated[str, Field(min_length=1, strict=True)]] = None agent_id: Optional[Annotated[str, Field(min_length=1, strict=True)]] = None - memory_type: StrictStr - page: Optional[Annotated[int, Field(strict=True, ge=1)]] = 1 - page_size: Optional[Annotated[int, Field(le=100, strict=True, ge=1)]] = 20 - sort_by: Optional[StrictStr] = 'timestamp' - sort_order: Optional[StrictStr] = 'desc' - with_readable_episode: Optional[StrictBool] = False + memory_type: StrictStr = Field(description="Which kind of memory to list: \"episode\" (narrative summaries of past sessions), \"profile\" (stable identity and preferences), \"agent_case\" (a distilled past trajectory) or \"agent_skill\" (a reusable skill). It must match the owner — the mismatched pairings are rejected with 422.") + page: Optional[Annotated[int, Field(strict=True, ge=1)]] = Field(default=1, description="1-based page number.") + page_size: Optional[Annotated[int, Field(le=100, strict=True, ge=1)]] = Field(default=20, description="Items per page, 1 to 100 (default 20).") + sort_by: Optional[StrictStr] = Field(default='timestamp', description="Order by \"timestamp\" (when the memory happened, default) or \"updated_at\" (when it was last written). Profiles and agent skills have no temporal column and always sort by \"updated_at\".") + sort_order: Optional[StrictStr] = Field(default='desc', description="\"desc\" (default, newest first) or \"asc\".") + with_readable_episode: Optional[StrictBool] = Field(default=False, description="Attach a human-readable rendering to each returned episode, for display only. Ignored for every non-episode `memory_type` rather than rejected.") filters: Optional[FilterNode] = None additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["app_id", "project_id", "user_id", "agent_id", "memory_type", "page", "page_size", "sort_by", "sort_order", "with_readable_episode", "filters"] diff --git a/everos_cloud/models/http_validation_error.py b/everos_cloud/models/http_validation_error.py index 1104446..1b62c6d 100644 --- a/everos_cloud/models/http_validation_error.py +++ b/everos_cloud/models/http_validation_error.py @@ -18,7 +18,7 @@ import re # noqa: F401 import json -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field from typing import Any, ClassVar, Dict, List, Optional from everos_cloud.models.validation_error import ValidationError from typing import Optional, Set @@ -28,7 +28,7 @@ class HTTPValidationError(BaseModel): """ HTTPValidationError """ # noqa: E501 - detail: Optional[List[ValidationError]] = None + detail: Optional[List[ValidationError]] = Field(default=None, description="One entry per field that failed validation.") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["detail"] diff --git a/everos_cloud/models/implicit_trait_data.py b/everos_cloud/models/implicit_trait_data.py index 414440a..dd46223 100644 --- a/everos_cloud/models/implicit_trait_data.py +++ b/everos_cloud/models/implicit_trait_data.py @@ -28,8 +28,8 @@ class ImplicitTraitData(BaseModel): """ ``data`` payload for ``add implicit_traits`` — ``trait`` + ``description`` required (non-empty); other fields (``basis``, ``evidence``, ``sources``, …) pass through. """ # noqa: E501 - trait: Annotated[str, Field(min_length=1, strict=True)] - description: Annotated[str, Field(min_length=1, strict=True, max_length=4000)] + trait: Annotated[str, Field(min_length=1, strict=True)] = Field(description="The inferred trait's name. Required, non-empty.") + description: Annotated[str, Field(min_length=1, strict=True, max_length=4000)] = Field(description="What the trait means and how it shows up, up to 4000 characters.") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["trait", "description"] diff --git a/everos_cloud/models/kb_data.py b/everos_cloud/models/kb_data.py index 135a441..dfc5a0d 100644 --- a/everos_cloud/models/kb_data.py +++ b/everos_cloud/models/kb_data.py @@ -29,10 +29,10 @@ class KbData(BaseModel): A knowledge base as returned to clients (create / get / list item / patch). """ # noqa: E501 id: StrictStr = Field(description="Knowledge base id (bare primary key)") - name: StrictStr - description: Optional[StrictStr] = '' + name: StrictStr = Field(description="The knowledge base's display name.") + description: Optional[StrictStr] = Field(default='', description="Its description.") owner_id: Optional[StrictStr] = None - document_count: Optional[StrictInt] = 0 + document_count: Optional[StrictInt] = Field(default=0, description="How many documents it holds.") created_at: Optional[datetime] = None updated_at: Optional[datetime] = None additional_properties: Dict[str, Any] = {} diff --git a/everos_cloud/models/kb_list_data.py b/everos_cloud/models/kb_list_data.py index cab4199..cc438d7 100644 --- a/everos_cloud/models/kb_list_data.py +++ b/everos_cloud/models/kb_list_data.py @@ -18,7 +18,7 @@ import re # noqa: F401 import json -from pydantic import BaseModel, ConfigDict, StrictInt +from pydantic import BaseModel, ConfigDict, Field, StrictInt from typing import Any, ClassVar, Dict, List, Optional from everos_cloud.models.kb_data import KbData from typing import Optional, Set @@ -28,8 +28,8 @@ class KbListData(BaseModel): """ KbListData """ # noqa: E501 - knowledge_bases: Optional[List[KbData]] = None - total: Optional[StrictInt] = 0 + knowledge_bases: Optional[List[KbData]] = Field(default=None, description="This page of knowledge bases.") + total: Optional[StrictInt] = Field(default=0, description="How many exist in total, across all pages.") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["knowledge_bases", "total"] diff --git a/everos_cloud/models/kb_search_data.py b/everos_cloud/models/kb_search_data.py index dc845f1..1195ddf 100644 --- a/everos_cloud/models/kb_search_data.py +++ b/everos_cloud/models/kb_search_data.py @@ -18,8 +18,8 @@ import re # noqa: F401 import json -from pydantic import BaseModel, ConfigDict, StrictFloat, StrictInt -from typing import Any, ClassVar, Dict, List, Optional, Union +from pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt +from typing import Any, ClassVar, Dict, List, Union from everos_cloud.models.search_hit import SearchHit from typing import Optional, Set from typing_extensions import Self @@ -28,9 +28,9 @@ class KbSearchData(BaseModel): """ Knowledge search response payload. Prefixed ``Kb`` to stay distinct from ``memory_api.SearchData`` — two same-named models under ``SuccessEnvelope[...]`` collide to a non-deterministic OpenAPI component name (see openapi-sync / check-openapi). """ # noqa: E501 - hits: Optional[List[SearchHit]] = None - total: Optional[StrictInt] = 0 - took_ms: Optional[Union[StrictFloat, StrictInt]] = 0.0 + hits: List[SearchHit] = Field(description="Matching topics, most relevant first.") + total: StrictInt = Field(description="How many topics matched.") + took_ms: Union[StrictFloat, StrictInt] = Field(description="How long the search took, in milliseconds.") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["hits", "total", "took_ms"] @@ -100,8 +100,8 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: _obj = cls.model_validate({ "hits": [SearchHit.from_dict(_item) for _item in obj["hits"]] if obj.get("hits") is not None else None, - "total": obj.get("total") if obj.get("total") is not None else 0, - "took_ms": obj.get("took_ms") if obj.get("took_ms") is not None else 0.0 + "total": obj.get("total"), + "took_ms": obj.get("took_ms") }) # store additional fields in additional_properties for _key in obj.keys(): diff --git a/everos_cloud/models/message_item.py b/everos_cloud/models/message_item.py index 220f9e4..05f8406 100644 --- a/everos_cloud/models/message_item.py +++ b/everos_cloud/models/message_item.py @@ -18,7 +18,7 @@ import re # noqa: F401 import json -from pydantic import BaseModel, ConfigDict, StrictInt, StrictStr, field_validator +from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr, field_validator from typing import Any, ClassVar, Dict, List, Optional from everos_cloud.models.content import Content from everos_cloud.models.tool_call import ToolCall @@ -29,10 +29,10 @@ class MessageItem(BaseModel): """ One message in an /add batch (spec §2). ``content`` accepts a plain string (shorthand for a single text ContentItem) or an explicit ContentItem list. """ # noqa: E501 - sender_id: StrictStr + sender_id: StrictStr = Field(description="Who produced this message — the user id for a user turn, the agent id for an assistant turn. This is the identifier /api/v2/memory/get and /api/v2/memory/search later scope by (`user_id` / `agent_id`).") sender_name: Optional[StrictStr] = None - role: StrictStr - timestamp: StrictInt + role: StrictStr = Field(description="Turn type: \"user\", \"assistant\", or \"tool\" for a tool result. An agent trajectory uses the OpenAI shape — an \"assistant\" message carrying `tool_calls`, followed by a \"tool\" message carrying `tool_call_id`.") + timestamp: StrictInt = Field(description="When the message was produced, as a UNIX timestamp in MILLISECONDS. A seconds-scale value is rejected with 422 rather than silently rescaled, because a window mixing the two would mis-order and mis-split.") content: Content tool_calls: Optional[List[ToolCall]] = None tool_call_id: Optional[StrictStr] = None diff --git a/everos_cloud/models/profile_item.py b/everos_cloud/models/profile_item.py index 858072a..19c4a7d 100644 --- a/everos_cloud/models/profile_item.py +++ b/everos_cloud/models/profile_item.py @@ -18,7 +18,8 @@ import re # noqa: F401 import json -from pydantic import BaseModel, ConfigDict, StrictStr +from datetime import datetime +from pydantic import BaseModel, ConfigDict, Field, StrictStr from typing import Any, ClassVar, Dict, List, Optional from typing import Optional, Set from typing_extensions import Self @@ -27,13 +28,15 @@ class ProfileItem(BaseModel): """ ProfileItem """ # noqa: E501 - id: StrictStr - app_id: StrictStr - project_id: StrictStr - user_id: StrictStr - profile_data: Optional[Dict[str, Any]] = None + id: StrictStr = Field(description="Profile id.") + app_id: StrictStr = Field(description="The business-semantic scope this profile was written under.") + project_id: StrictStr = Field(description="Second half of that scope.") + user_id: StrictStr = Field(description="The user this profile describes.") + profile_data: Optional[Dict[str, Any]] = Field(default=None, description="The profile itself — the explicit_info and implicit_traits items maintained by extraction and by /api/v2/memory/edit. Each item's id is what an edit operation targets.") + created_at: Optional[datetime] = None + updated_at: Optional[datetime] = None additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["id", "app_id", "project_id", "user_id", "profile_data"] + __properties: ClassVar[List[str]] = ["id", "app_id", "project_id", "user_id", "profile_data", "created_at", "updated_at"] model_config = ConfigDict( populate_by_name=True, @@ -81,6 +84,16 @@ def to_dict(self) -> Dict[str, Any]: for _key, _value in self.additional_properties.items(): _dict[_key] = _value + # set to None if created_at (nullable) is None + # and model_fields_set contains the field + if self.created_at is None and "created_at" in self.model_fields_set: + _dict['created_at'] = None + + # set to None if updated_at (nullable) is None + # and model_fields_set contains the field + if self.updated_at is None and "updated_at" in self.model_fields_set: + _dict['updated_at'] = None + return _dict @classmethod @@ -97,7 +110,9 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: "app_id": obj.get("app_id"), "project_id": obj.get("project_id"), "user_id": obj.get("user_id"), - "profile_data": obj.get("profile_data") + "profile_data": obj.get("profile_data"), + "created_at": obj.get("created_at"), + "updated_at": obj.get("updated_at") }) # store additional fields in additional_properties for _key in obj.keys(): diff --git a/everos_cloud/models/related_tag_usage_body.py b/everos_cloud/models/related_tag_usage_body.py new file mode 100644 index 0000000..c2c4701 --- /dev/null +++ b/everos_cloud/models/related_tag_usage_body.py @@ -0,0 +1,102 @@ +# coding: utf-8 + +""" + EverOS Cloud Memory API + + Official Python client for the EverOS Cloud Memory API. Add, search, retrieve, and manage long-term memory for your AI applications over a typed interface (pydantic v2, with full type hints). Install and usage guides: https://github.com/EverMind-AI/everos-cloud-sdk-python + + The version of the OpenAPI document: 2.0.0 + Contact: service@evermind.ai + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field +from typing import Any, ClassVar, Dict, List +from typing_extensions import Annotated +from typing import Optional, Set +from typing_extensions import Self + +class RelatedTagUsageBody(BaseModel): + """ + Candidate tag ids for ``POST /knowledge_bases/{kb_id}/tags``. + """ # noqa: E501 + tag_ids: Annotated[List[Annotated[str, Field(min_length=1, strict=True, max_length=128)]], Field(min_length=1, max_length=10000)] = Field(description="Candidate opaque tag ids to check against the current live tree") + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["tag_ids"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of RelatedTagUsageBody from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of RelatedTagUsageBody from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "tag_ids": obj.get("tag_ids") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/everos_cloud/models/related_tag_usage_item.py b/everos_cloud/models/related_tag_usage_item.py new file mode 100644 index 0000000..8abb0bb --- /dev/null +++ b/everos_cloud/models/related_tag_usage_item.py @@ -0,0 +1,104 @@ +# coding: utf-8 + +""" + EverOS Cloud Memory API + + Official Python client for the EverOS Cloud Memory API. Add, search, retrieve, and manage long-term memory for your AI applications over a typed interface (pydantic v2, with full type hints). Install and usage guides: https://github.com/EverMind-AI/everos-cloud-sdk-python + + The version of the OpenAPI document: 2.0.0 + Contact: service@evermind.ai + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictInt +from typing import Any, ClassVar, Dict, List +from typing_extensions import Annotated +from typing import Optional, Set +from typing_extensions import Self + +class RelatedTagUsageItem(BaseModel): + """ + One opaque tag id and its distinct live-document usage in the current KB. + """ # noqa: E501 + id: Annotated[str, Field(min_length=1, strict=True, max_length=128)] = Field(description="Opaque semantic tag id") + document_count: StrictInt = Field(description="Distinct live documents using this tag") + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["id", "document_count"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of RelatedTagUsageItem from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of RelatedTagUsageItem from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "id": obj.get("id"), + "document_count": obj.get("document_count") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/everos_cloud/models/related_tag_usage_list_data.py b/everos_cloud/models/related_tag_usage_list_data.py new file mode 100644 index 0000000..0560256 --- /dev/null +++ b/everos_cloud/models/related_tag_usage_list_data.py @@ -0,0 +1,112 @@ +# coding: utf-8 + +""" + EverOS Cloud Memory API + + Official Python client for the EverOS Cloud Memory API. Add, search, retrieve, and manage long-term memory for your AI applications over a typed interface (pydantic v2, with full type hints). Install and usage guides: https://github.com/EverMind-AI/everos-cloud-sdk-python + + The version of the OpenAPI document: 2.0.0 + Contact: service@evermind.ai + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field +from typing import Any, ClassVar, Dict, List +from typing_extensions import Annotated +from everos_cloud.models.related_tag_usage_item import RelatedTagUsageItem +from typing import Optional, Set +from typing_extensions import Self + +class RelatedTagUsageListData(BaseModel): + """ + Complete non-zero usage result for the requested candidate tag ids. + """ # noqa: E501 + items: List[RelatedTagUsageItem] = Field(description="One entry per requested tag id that is actually in use, sorted by id.") + total: Annotated[int, Field(strict=True, ge=0)] = Field(description="Number of returned distinct tag ids") + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["items", "total"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of RelatedTagUsageListData from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in items (list) + _items = [] + if self.items: + for _item_items in self.items: + if _item_items: + _items.append(_item_items.to_dict()) + _dict['items'] = _items + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of RelatedTagUsageListData from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "items": [RelatedTagUsageItem.from_dict(_item) for _item in obj["items"]] if obj.get("items") is not None else None, + "total": obj.get("total") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/everos_cloud/models/search_agent_case_item.py b/everos_cloud/models/search_agent_case_item.py index 53cf184..1e72b4c 100644 --- a/everos_cloud/models/search_agent_case_item.py +++ b/everos_cloud/models/search_agent_case_item.py @@ -19,7 +19,7 @@ import json from datetime import datetime -from pydantic import BaseModel, ConfigDict, StrictFloat, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt, StrictStr from typing import Any, ClassVar, Dict, List, Optional, Union from typing import Optional, Set from typing_extensions import Self @@ -28,17 +28,17 @@ class SearchAgentCaseItem(BaseModel): """ SearchAgentCaseItem """ # noqa: E501 - id: StrictStr - app_id: StrictStr - project_id: StrictStr - agent_id: StrictStr - session_id: StrictStr - task_intent: StrictStr - approach: StrictStr - quality_score: Union[StrictFloat, StrictInt] + id: StrictStr = Field(description="Agent-case id.") + app_id: StrictStr = Field(description="The business-semantic scope this case was written under.") + project_id: StrictStr = Field(description="Second half of that scope.") + agent_id: StrictStr = Field(description="The agent that owns this case.") + session_id: StrictStr = Field(description="The session whose trajectory the case was distilled from.") + task_intent: StrictStr = Field(description="What the agent was trying to do in that trajectory.") + approach: StrictStr = Field(description="How it went about it — the reusable part of the case.") + quality_score: Union[StrictFloat, StrictInt] = Field(description="How good this case is judged to be. Nominally 0.0–1.0 with 0.5 as the no-opinion default, but the value is the extractor's own and nothing on the write path enforces the range — treat an out-of-range number as possible. One threshold is real: a case scoring below 0.2 is never distilled into a skill.") key_insight: Optional[StrictStr] = None - timestamp: datetime - score: Union[StrictFloat, StrictInt] + timestamp: datetime = Field(description="When the trajectory happened (ISO 8601).") + score: Union[StrictFloat, StrictInt] = Field(description="Relevance of this case to the query.") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["id", "app_id", "project_id", "agent_id", "session_id", "task_intent", "approach", "quality_score", "key_insight", "timestamp", "score"] diff --git a/everos_cloud/models/search_agent_skill_item.py b/everos_cloud/models/search_agent_skill_item.py index 0473463..d288539 100644 --- a/everos_cloud/models/search_agent_skill_item.py +++ b/everos_cloud/models/search_agent_skill_item.py @@ -18,7 +18,8 @@ import re # noqa: F401 import json -from pydantic import BaseModel, ConfigDict, StrictFloat, StrictInt, StrictStr +from datetime import datetime +from pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt, StrictStr from typing import Any, ClassVar, Dict, List, Optional, Union from typing import Optional, Set from typing_extensions import Self @@ -27,19 +28,21 @@ class SearchAgentSkillItem(BaseModel): """ SearchAgentSkillItem """ # noqa: E501 - id: StrictStr - app_id: StrictStr - project_id: StrictStr - agent_id: StrictStr - name: StrictStr - description: StrictStr - content: StrictStr - confidence: Union[StrictFloat, StrictInt] - maturity_score: Union[StrictFloat, StrictInt] - source_case_ids: Optional[List[StrictStr]] = None - score: Union[StrictFloat, StrictInt] + id: StrictStr = Field(description="Agent-skill id.") + app_id: StrictStr = Field(description="The business-semantic scope this skill was written under.") + project_id: StrictStr = Field(description="Second half of that scope.") + agent_id: StrictStr = Field(description="The agent that owns this skill.") + name: StrictStr = Field(description="The skill's name.") + description: StrictStr = Field(description="What the skill is for, in a sentence.") + content: StrictStr = Field(description="The skill itself — the reusable procedure, ready to put in a prompt.") + confidence: Union[StrictFloat, StrictInt] = Field(description="How much the distillation trusts this skill. Nominally 0.0–1.0, defaulting to 0.0 before anything scores it; the range is not enforced on the write path. Nothing in retrieval filters on it today, and how it divides labour with `maturity_score` is still open — so do not build a threshold on it yet.") + maturity_score: Union[StrictFloat, StrictInt] = Field(description="How well-established the skill is. Nominally 0.0–1.0 and unenforced, and — unlike the other two scores — its default is 0.6 rather than 0.0, chosen so an unscored skill starts mid-optimistic. The cost is that an unscored 0.6 is indistinguishable from a scored 0.6: there is no \"not evaluated\" sentinel, and maturity scoring is skipped by default. Filtering near 0.6 is therefore unreliable.") + source_case_ids: Optional[List[StrictStr]] = Field(default=None, description="The agent cases this skill was distilled from. Fetch them for the underlying evidence.") + created_at: Optional[datetime] = None + updated_at: Optional[datetime] = None + score: Union[StrictFloat, StrictInt] = Field(description="Relevance of this skill to the query.") additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["id", "app_id", "project_id", "agent_id", "name", "description", "content", "confidence", "maturity_score", "source_case_ids", "score"] + __properties: ClassVar[List[str]] = ["id", "app_id", "project_id", "agent_id", "name", "description", "content", "confidence", "maturity_score", "source_case_ids", "created_at", "updated_at", "score"] model_config = ConfigDict( populate_by_name=True, @@ -87,6 +90,16 @@ def to_dict(self) -> Dict[str, Any]: for _key, _value in self.additional_properties.items(): _dict[_key] = _value + # set to None if created_at (nullable) is None + # and model_fields_set contains the field + if self.created_at is None and "created_at" in self.model_fields_set: + _dict['created_at'] = None + + # set to None if updated_at (nullable) is None + # and model_fields_set contains the field + if self.updated_at is None and "updated_at" in self.model_fields_set: + _dict['updated_at'] = None + return _dict @classmethod @@ -109,6 +122,8 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: "confidence": obj.get("confidence"), "maturity_score": obj.get("maturity_score"), "source_case_ids": obj.get("source_case_ids"), + "created_at": obj.get("created_at"), + "updated_at": obj.get("updated_at"), "score": obj.get("score") }) # store additional fields in additional_properties diff --git a/everos_cloud/models/search_atomic_fact_item.py b/everos_cloud/models/search_atomic_fact_item.py index 230de5b..fbd1d74 100644 --- a/everos_cloud/models/search_atomic_fact_item.py +++ b/everos_cloud/models/search_atomic_fact_item.py @@ -18,7 +18,7 @@ import re # noqa: F401 import json -from pydantic import BaseModel, ConfigDict, StrictFloat, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt, StrictStr from typing import Any, ClassVar, Dict, List, Union from typing import Optional, Set from typing_extensions import Self @@ -27,9 +27,9 @@ class SearchAtomicFactItem(BaseModel): """ SearchAtomicFactItem """ # noqa: E501 - id: StrictStr - content: StrictStr - score: Union[StrictFloat, StrictInt] + id: StrictStr = Field(description="Atomic-fact id.") + content: StrictStr = Field(description="The fact itself, as a single statement.") + score: Union[StrictFloat, StrictInt] = Field(description="Relevance of this fact to the query.") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["id", "content", "score"] diff --git a/everos_cloud/models/search_body.py b/everos_cloud/models/search_body.py index bdd4927..36bcee0 100644 --- a/everos_cloud/models/search_body.py +++ b/everos_cloud/models/search_body.py @@ -29,14 +29,16 @@ class SearchBody(BaseModel): """ POST body (kb_id rides the path, not the body). """ # noqa: E501 - query: Annotated[str, Field(min_length=1, strict=True, max_length=2000)] - method: Optional[StrictStr] = 'hybrid' - top_k: Optional[Annotated[int, Field(le=100, strict=True, ge=1)]] = 10 + query: Optional[Annotated[str, Field(strict=True, max_length=2000)]] = None + method: Optional[StrictStr] = Field(default='hybrid', description="Retrieval strategy: \"keyword\" (lexical), \"vector\" (embedding similarity) or \"hybrid\" (default, both).") + page: Optional[Annotated[int, Field(strict=True, ge=1)]] = Field(default=1, description="Filter-only page number; query search supports page 1 only") + top_k: Optional[Annotated[int, Field(le=100, strict=True, ge=1)]] = Field(default=10, description="Maximum number of topics to return, 1 to 100 (default 10). On a query search the server also bounds the result by its rerank pool — 50 candidates by default — so asking for more than that returns what the pool held. On a filter-only request (tags without a query) it is the page size instead, and `page` walks the rest.") score_threshold: Optional[Union[StrictFloat, StrictInt]] = None include: Optional[List[StrictStr]] = Field(default=None, description="e.g. ['content']") - filters: Optional[SearchFilters] = None + boost_tag_ids: Optional[Annotated[List[Annotated[str, Field(min_length=1, strict=True, max_length=128)]], Field(max_length=100)]] = Field(default=None, description="Reweight, do not filter: topics carrying these tags are pushed up, and topics without them still come back. Use `filters.tag_ids` when the intent is to exclude everything else.") + filters: Optional[SearchFilters] = Field(default=None, description="Optional filters narrowing what is searched.") additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["query", "method", "top_k", "score_threshold", "include", "filters"] + __properties: ClassVar[List[str]] = ["query", "method", "page", "top_k", "score_threshold", "include", "boost_tag_ids", "filters"] @field_validator('method') def method_validate_enum(cls, value): @@ -97,6 +99,11 @@ def to_dict(self) -> Dict[str, Any]: for _key, _value in self.additional_properties.items(): _dict[_key] = _value + # set to None if query (nullable) is None + # and model_fields_set contains the field + if self.query is None and "query" in self.model_fields_set: + _dict['query'] = None + # set to None if score_threshold (nullable) is None # and model_fields_set contains the field if self.score_threshold is None and "score_threshold" in self.model_fields_set: @@ -116,9 +123,11 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: _obj = cls.model_validate({ "query": obj.get("query"), "method": obj.get("method") if obj.get("method") is not None else 'hybrid', + "page": obj.get("page") if obj.get("page") is not None else 1, "top_k": obj.get("top_k") if obj.get("top_k") is not None else 10, "score_threshold": obj.get("score_threshold"), "include": obj.get("include"), + "boost_tag_ids": obj.get("boost_tag_ids"), "filters": SearchFilters.from_dict(obj["filters"]) if obj.get("filters") is not None else None }) # store additional fields in additional_properties diff --git a/everos_cloud/models/search_data.py b/everos_cloud/models/search_data.py index 3bbe99d..ffb145b 100644 --- a/everos_cloud/models/search_data.py +++ b/everos_cloud/models/search_data.py @@ -18,7 +18,7 @@ import re # noqa: F401 import json -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field from typing import Any, ClassVar, Dict, List, Optional from everos_cloud.models.search_agent_case_item import SearchAgentCaseItem from everos_cloud.models.search_agent_skill_item import SearchAgentSkillItem @@ -32,11 +32,11 @@ class SearchData(BaseModel): """ SearchData """ # noqa: E501 - episodes: Optional[List[SearchEpisodeItem]] = None - profiles: Optional[List[SearchProfileItem]] = None - agent_cases: Optional[List[SearchAgentCaseItem]] = None - agent_skills: Optional[List[SearchAgentSkillItem]] = None - unprocessed_messages: Optional[List[UnprocessedMessageDTO]] = None + episodes: Optional[List[SearchEpisodeItem]] = Field(default=None, description="Matching episodes, for a user owner. Always present, empty when not applicable.") + profiles: Optional[List[SearchProfileItem]] = Field(default=None, description="The user's profile, when `include_profile` asked for it.") + agent_cases: Optional[List[SearchAgentCaseItem]] = Field(default=None, description="Matching agent cases, for an agent owner.") + agent_skills: Optional[List[SearchAgentSkillItem]] = Field(default=None, description="Matching agent skills, for an agent owner.") + unprocessed_messages: Optional[List[UnprocessedMessageDTO]] = Field(default=None, description="Raw buffered messages not yet extracted. Returned only when the request filtered on a single `session_id`, so a caller can see what is still in flight.") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["episodes", "profiles", "agent_cases", "agent_skills", "unprocessed_messages"] diff --git a/everos_cloud/models/search_episode_item.py b/everos_cloud/models/search_episode_item.py index 21ba588..76515ec 100644 --- a/everos_cloud/models/search_episode_item.py +++ b/everos_cloud/models/search_episode_item.py @@ -19,7 +19,7 @@ import json from datetime import datetime -from pydantic import BaseModel, ConfigDict, StrictFloat, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt, StrictStr from typing import Any, ClassVar, Dict, List, Optional, Union from everos_cloud.models.search_atomic_fact_item import SearchAtomicFactItem from typing import Optional, Set @@ -29,21 +29,21 @@ class SearchEpisodeItem(BaseModel): """ SearchEpisodeItem """ # noqa: E501 - id: StrictStr - app_id: StrictStr - project_id: StrictStr + id: StrictStr = Field(description="Episode id. Use it to bind tags or to fetch this episode again.") + app_id: StrictStr = Field(description="The business-semantic scope this memory was written under.") + project_id: StrictStr = Field(description="Second half of that scope.") user_id: Optional[StrictStr] = None session_id: Optional[StrictStr] = None - timestamp: datetime - sender_ids: Optional[List[StrictStr]] = None - summary: StrictStr - subject: StrictStr - episode: StrictStr + timestamp: datetime = Field(description="When the remembered exchange happened (ISO 8601), not when it was extracted.") + sender_ids: Optional[List[StrictStr]] = Field(default=None, description="The senders that appear in the source exchange.") + summary: StrictStr = Field(description="Short summary of the episode — what a result list should show.") + subject: StrictStr = Field(description="What the episode is about, in a few words.") + episode: StrictStr = Field(description="The episode's stored narrative body. This is the indexed, searchable text.") readable_episode: Optional[StrictStr] = None - type: StrictStr - atomic_facts: Optional[List[SearchAtomicFactItem]] = None - tags: Optional[List[StrictStr]] = None - score: Union[StrictFloat, StrictInt] + type: StrictStr = Field(description="How the episode was produced — \"Conversation\" or \"AgentConversation\".") + atomic_facts: Optional[List[SearchAtomicFactItem]] = Field(default=None, description="The facts extracted from this episode, each with its own relevance score.") + tags: Optional[List[StrictStr]] = Field(default=None, description="Tags attached through /api/v2/memory/tag/*.") + score: Union[StrictFloat, StrictInt] = Field(description="Relevance of this episode to the query. What the number means depends on `method`: the hybrid path fuses its two routes into a probability in 0.0–1.0 (which is what `min_score` filters on), while keyword and vector pass the underlying engine's own score through — BM25 has no upper bound and vector similarity depends on the metric. So compare scores within one method, not across methods.") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["id", "app_id", "project_id", "user_id", "session_id", "timestamp", "sender_ids", "summary", "subject", "episode", "readable_episode", "type", "atomic_facts", "tags", "score"] diff --git a/everos_cloud/models/search_filters.py b/everos_cloud/models/search_filters.py index 9571551..5731b95 100644 --- a/everos_cloud/models/search_filters.py +++ b/everos_cloud/models/search_filters.py @@ -18,8 +18,9 @@ import re # noqa: F401 import json -from pydantic import BaseModel, ConfigDict, StrictStr +from pydantic import BaseModel, ConfigDict, Field, StrictStr from typing import Any, ClassVar, Dict, List, Optional +from typing_extensions import Annotated from typing import Optional, Set from typing_extensions import Self @@ -28,8 +29,9 @@ class SearchFilters(BaseModel): Optional hard filters. ``category_id`` is a soft filter on recall (design 01 §3.9). """ # noqa: E501 category_id: Optional[StrictStr] = None + tag_ids: Optional[Annotated[List[Annotated[str, Field(min_length=1, strict=True, max_length=128)]], Field(max_length=100)]] = Field(default=None, description="Hard filter that does not affect scoring: only topics carrying EVERY one of these tag ids are eligible. Use `boost_tag_ids` when the intent is to reweight rather than exclude.") additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["category_id"] + __properties: ClassVar[List[str]] = ["category_id", "tag_ids"] model_config = ConfigDict( populate_by_name=True, @@ -94,7 +96,8 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: return cls.model_validate(obj) _obj = cls.model_validate({ - "category_id": obj.get("category_id") + "category_id": obj.get("category_id"), + "tag_ids": obj.get("tag_ids") }) # store additional fields in additional_properties for _key in obj.keys(): diff --git a/everos_cloud/models/search_hit.py b/everos_cloud/models/search_hit.py index 28fb56b..c3a6aa3 100644 --- a/everos_cloud/models/search_hit.py +++ b/everos_cloud/models/search_hit.py @@ -18,32 +18,50 @@ import re # noqa: F401 import json -from pydantic import BaseModel, ConfigDict, StrictFloat, StrictInt, StrictStr +from datetime import datetime +from pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt, StrictStr, field_validator from typing import Any, ClassVar, Dict, List, Optional, Union from everos_cloud.models.document_context import DocumentContext +from everos_cloud.models.tag_ref import TagRef from typing import Optional, Set from typing_extensions import Self class SearchHit(BaseModel): """ - A single search hit. ``object`` self-describes the unit (currently always topic). + A topic hit from recall or a document hit from filter-only search. """ # noqa: E501 - object: Optional[StrictStr] = 'topic' - id: StrictStr - doc_id: StrictStr - kb_id: StrictStr - category_id: Optional[StrictStr] = '' + object: StrictStr = Field(description="What this hit is. Always \"topic\" today — the unit of knowledge retrieval.") + id: StrictStr = Field(description="The topic's id; fetch its full body with GET .../topics/{topic_id}.") + doc_id: StrictStr = Field(description="The document the topic belongs to.") + kb_id: StrictStr = Field(description="The knowledge base searched.") + category_id: Optional[StrictStr] = Field(default='', description="The category that document is filed under; empty when uncategorized.") category_name: Optional[StrictStr] = None - name: Optional[StrictStr] = '' - depth: Optional[StrictInt] = 0 - summary: Optional[StrictStr] = '' + name: StrictStr = Field(description="The topic's title.") + depth: Optional[StrictInt] = Field(default=0, description="The topic's depth in the document tree.") + summary: Optional[StrictStr] = None content: Optional[StrictStr] = None - score: Optional[Union[StrictFloat, StrictInt]] = 0.0 - retrieval_method: Optional[StrictStr] = 'hybrid' + score: Union[StrictFloat, StrictInt] = Field(description="Relevance of this topic to the query, and NOT a raw keyword or vector score: candidates from every method are reranked by a cross-encoder, min-max normalized WITHIN THIS RESPONSE, then given a category boost (up to 0.1) and, when `boost_tag_ids` was passed, a tag-coverage boost (up to 0.3). So it lands in roughly 0.0–1.4, the best hit of any response sits near the top of that range by construction, and scores compare inside one response but not across responses or queries. Three edge values to expect: every hit comes back at 0.5 when the reranker cannot separate the pool, every hit is 0.0 on a filter-only request (tags without a query, which never runs relevance at all), and a hit carries a synthetic -100.0 when its rerank batch failed — that is a fail-soft marker, not a relevance judgement.") + retrieval_method: StrictStr = Field(description="The retrieval strategy this search ran with, so every hit in one response carries the same value and a stored or traced response is self-describing. It echoes the request's `method`, except on a filter-only request (tags without a query), which reports \"filter\" because no retrieval ran. It is deliberately NOT per-hit provenance: in a hybrid search the two lanes are fused, and hits recalled by only one of them still report \"hybrid\".") source: Optional[StrictStr] = None document: Optional[DocumentContext] = None + tags: List[TagRef] = Field(description="The semantic tags materialized on this topic.") + updated_at: Optional[datetime] = None additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["object", "id", "doc_id", "kb_id", "category_id", "category_name", "name", "depth", "summary", "content", "score", "retrieval_method", "source", "document"] + __properties: ClassVar[List[str]] = ["object", "id", "doc_id", "kb_id", "category_id", "category_name", "name", "depth", "summary", "content", "score", "retrieval_method", "source", "document", "tags", "updated_at"] + + @field_validator('object') + def object_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['topic', 'document']): + raise ValueError("must be one of enum values ('topic', 'document')") + return value + + @field_validator('retrieval_method') + def retrieval_method_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['keyword', 'vector', 'hybrid', 'filter']): + raise ValueError("must be one of enum values ('keyword', 'vector', 'hybrid', 'filter')") + return value model_config = ConfigDict( populate_by_name=True, @@ -89,6 +107,13 @@ def to_dict(self) -> Dict[str, Any]: # override the default output from pydantic by calling `to_dict()` of document if self.document: _dict['document'] = self.document.to_dict() + # override the default output from pydantic by calling `to_dict()` of each item in tags (list) + _items = [] + if self.tags: + for _item_tags in self.tags: + if _item_tags: + _items.append(_item_tags.to_dict()) + _dict['tags'] = _items # puts key-value pairs in additional_properties in the top level if self.additional_properties is not None: for _key, _value in self.additional_properties.items(): @@ -99,6 +124,11 @@ def to_dict(self) -> Dict[str, Any]: if self.category_name is None and "category_name" in self.model_fields_set: _dict['category_name'] = None + # set to None if summary (nullable) is None + # and model_fields_set contains the field + if self.summary is None and "summary" in self.model_fields_set: + _dict['summary'] = None + # set to None if content (nullable) is None # and model_fields_set contains the field if self.content is None and "content" in self.model_fields_set: @@ -114,6 +144,11 @@ def to_dict(self) -> Dict[str, Any]: if self.document is None and "document" in self.model_fields_set: _dict['document'] = None + # set to None if updated_at (nullable) is None + # and model_fields_set contains the field + if self.updated_at is None and "updated_at" in self.model_fields_set: + _dict['updated_at'] = None + return _dict @classmethod @@ -126,20 +161,22 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: return cls.model_validate(obj) _obj = cls.model_validate({ - "object": obj.get("object") if obj.get("object") is not None else 'topic', + "object": obj.get("object"), "id": obj.get("id"), "doc_id": obj.get("doc_id"), "kb_id": obj.get("kb_id"), "category_id": obj.get("category_id") if obj.get("category_id") is not None else '', "category_name": obj.get("category_name"), - "name": obj.get("name") if obj.get("name") is not None else '', + "name": obj.get("name"), "depth": obj.get("depth") if obj.get("depth") is not None else 0, - "summary": obj.get("summary") if obj.get("summary") is not None else '', + "summary": obj.get("summary"), "content": obj.get("content"), - "score": obj.get("score") if obj.get("score") is not None else 0.0, - "retrieval_method": obj.get("retrieval_method") if obj.get("retrieval_method") is not None else 'hybrid', + "score": obj.get("score"), + "retrieval_method": obj.get("retrieval_method"), "source": obj.get("source"), - "document": DocumentContext.from_dict(obj["document"]) if obj.get("document") is not None else None + "document": DocumentContext.from_dict(obj["document"]) if obj.get("document") is not None else None, + "tags": [TagRef.from_dict(_item) for _item in obj["tags"]] if obj.get("tags") is not None else None, + "updated_at": obj.get("updated_at") }) # store additional fields in additional_properties for _key in obj.keys(): diff --git a/everos_cloud/models/search_input.py b/everos_cloud/models/search_input.py index 406f707..5152893 100644 --- a/everos_cloud/models/search_input.py +++ b/everos_cloud/models/search_input.py @@ -29,18 +29,18 @@ class SearchInput(BaseModel): """ SearchInput """ # noqa: E501 - app_id: Optional[StrictStr] = 'default' - project_id: Optional[StrictStr] = 'default' + app_id: Optional[StrictStr] = Field(default='default', description="Scope to search in, defaulting to \"default\". Must match the pair used on write.") + project_id: Optional[StrictStr] = Field(default='default', description="Second half of the scope, defaulting to \"default\".") user_id: Optional[Annotated[str, Field(min_length=1, strict=True)]] = None agent_id: Optional[Annotated[str, Field(min_length=1, strict=True)]] = None - query: Annotated[str, Field(min_length=1, strict=True)] - method: Optional[StrictStr] = 'hybrid' - top_k: Optional[StrictInt] = -1 + query: Annotated[str, Field(min_length=1, strict=True)] = Field(description="The natural-language query to retrieve against.") + method: Optional[StrictStr] = Field(default='hybrid', description="Retrieval strategy. \"keyword\" is lexical, \"vector\" is embedding similarity, \"hybrid\" (default) combines both, and \"agentic\" lets the engine run a multi-round LLM-guided retrieval — more thorough, slower.") + top_k: Optional[StrictInt] = Field(default=-1, description="Maximum number of hits. Either -1 (the default, letting the engine decide) or a value from 1 to 100; anything else is rejected with 422.") radius: Optional[Union[Annotated[float, Field(le=1.0, strict=True, ge=0.0)], Annotated[int, Field(le=1, strict=True, ge=0)]]] = None min_score: Optional[Union[Annotated[float, Field(le=1.0, strict=True, ge=0.0)], Annotated[int, Field(le=1, strict=True, ge=0)]]] = None - include_profile: Optional[StrictBool] = False - with_readable_episode: Optional[StrictBool] = False - enable_llm_rerank: Optional[StrictBool] = False + include_profile: Optional[StrictBool] = Field(default=False, description="Also return the user's profile alongside the hits, saving a second call. Ignored for an agent owner, whose results carry no profiles.") + with_readable_episode: Optional[StrictBool] = Field(default=False, description="Attach a human-readable rendering of each episode to the returned items, for display only — it is not indexed, filterable or scored, and callers fall back to `episode` when it is null. Ignored for an agent owner.") + enable_llm_rerank: Optional[StrictBool] = Field(default=False, description="Opt-in LLM rerank, and only for hybrid agent_case / agent_skill retrieval. The episode hybrid path has its own fact eviction and ignores this, as do keyword, vector and agentic.") 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", "radius", "min_score", "include_profile", "with_readable_episode", "enable_llm_rerank", "filters"] diff --git a/everos_cloud/models/search_profile_item.py b/everos_cloud/models/search_profile_item.py index 4f976f1..85528cb 100644 --- a/everos_cloud/models/search_profile_item.py +++ b/everos_cloud/models/search_profile_item.py @@ -18,7 +18,8 @@ import re # noqa: F401 import json -from pydantic import BaseModel, ConfigDict, StrictFloat, StrictInt, StrictStr +from datetime import datetime +from pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt, StrictStr from typing import Any, ClassVar, Dict, List, Optional, Union from typing import Optional, Set from typing_extensions import Self @@ -27,14 +28,16 @@ class SearchProfileItem(BaseModel): """ SearchProfileItem """ # noqa: E501 - id: StrictStr - app_id: StrictStr - project_id: StrictStr - user_id: StrictStr - profile_data: Optional[Dict[str, Any]] = None + id: StrictStr = Field(description="Profile id.") + app_id: StrictStr = Field(description="The business-semantic scope this profile was written under.") + project_id: StrictStr = Field(description="Second half of that scope.") + user_id: StrictStr = Field(description="The user this profile describes.") + profile_data: Optional[Dict[str, Any]] = Field(default=None, description="The profile itself — the explicit_info and implicit_traits items maintained by extraction and by /api/v2/memory/edit. Each item's id is what an edit operation targets.") + created_at: Optional[datetime] = None + updated_at: Optional[datetime] = None score: Optional[Union[StrictFloat, StrictInt]] = None additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["id", "app_id", "project_id", "user_id", "profile_data", "score"] + __properties: ClassVar[List[str]] = ["id", "app_id", "project_id", "user_id", "profile_data", "created_at", "updated_at", "score"] model_config = ConfigDict( populate_by_name=True, @@ -82,6 +85,16 @@ def to_dict(self) -> Dict[str, Any]: for _key, _value in self.additional_properties.items(): _dict[_key] = _value + # set to None if created_at (nullable) is None + # and model_fields_set contains the field + if self.created_at is None and "created_at" in self.model_fields_set: + _dict['created_at'] = None + + # set to None if updated_at (nullable) is None + # and model_fields_set contains the field + if self.updated_at is None and "updated_at" in self.model_fields_set: + _dict['updated_at'] = None + # set to None if score (nullable) is None # and model_fields_set contains the field if self.score is None and "score" in self.model_fields_set: @@ -104,6 +117,8 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: "project_id": obj.get("project_id"), "user_id": obj.get("user_id"), "profile_data": obj.get("profile_data"), + "created_at": obj.get("created_at"), + "updated_at": obj.get("updated_at"), "score": obj.get("score") }) # store additional fields in additional_properties diff --git a/everos_cloud/models/sign_envelope.py b/everos_cloud/models/sign_envelope.py index bb7f39f..c963987 100644 --- a/everos_cloud/models/sign_envelope.py +++ b/everos_cloud/models/sign_envelope.py @@ -29,7 +29,7 @@ class SignEnvelope(BaseModel): Response envelope for the sign endpoint. The `result.data` shape depends on `status`: - `status: 0` (success) — `result.data` is a `SignResponse`, as modelled below. - `status: 2018` (validation failed) — `result.data` is a plain string carrying the validator error message, not a `SignResponse`. - all other non-zero statuses — `result.data` is `null`. Generated clients should treat `result.data` as populated only when `status` is 0. """ # noqa: E501 error: Optional[StrictStr] = Field(default=None, description="`\"OK\"` on success, otherwise a human-readable error message decoded from the business error. ") - request_id: Optional[StrictStr] = None + request_id: Optional[StrictStr] = Field(default=None, description="Id of this request — quote it when reporting a problem.") status: Optional[StrictInt] = Field(default=None, description="Business status code; 0 means success") result: Optional[SignEnvelopeAllOfResult] = None additional_properties: Dict[str, Any] = {} diff --git a/everos_cloud/models/sign_object_item.py b/everos_cloud/models/sign_object_item.py index 26a50b7..1175e42 100644 --- a/everos_cloud/models/sign_object_item.py +++ b/everos_cloud/models/sign_object_item.py @@ -27,8 +27,8 @@ class SignObjectItem(BaseModel): """ SignObjectItem """ # noqa: E501 - file_id: StrictStr = Field(alias="fileId") - file_name: StrictStr = Field(alias="fileName") + file_id: StrictStr = Field(description="Your own id for this file. It comes back on the matching response item.", alias="fileId") + file_name: StrictStr = Field(description="The file's name, used to derive its type and preserved for display.", alias="fileName") file_type: StrictStr = Field(description="Media class. Default size limits per type: image=10MB, file=100MB, video=500MB. These are defaults and may be overridden per token (via the token's `file_limits`); the effective limit is enforced by S3 through the presigned POST `content-length-range` condition, and surfaced as `objectSignedInfo.maxSize`. ", alias="fileType") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["fileId", "fileName", "fileType"] diff --git a/everos_cloud/models/sign_response.py b/everos_cloud/models/sign_response.py index 28b8497..4c94caf 100644 --- a/everos_cloud/models/sign_response.py +++ b/everos_cloud/models/sign_response.py @@ -28,7 +28,7 @@ class SignResponse(BaseModel): """ SignResponse """ # noqa: E501 - object_list: Optional[List[SignResponseItem]] = Field(default=None, alias="objectList") + object_list: Optional[List[SignResponseItem]] = Field(default=None, description="One signed entry per requested file, in the same order.", alias="objectList") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["objectList"] diff --git a/everos_cloud/models/sign_response_item.py b/everos_cloud/models/sign_response_item.py index cc416d6..6f097d2 100644 --- a/everos_cloud/models/sign_response_item.py +++ b/everos_cloud/models/sign_response_item.py @@ -28,12 +28,12 @@ class SignResponseItem(BaseModel): """ SignResponseItem """ # noqa: E501 - file_id: Optional[StrictStr] = Field(default=None, alias="fileId") - file_name: Optional[StrictStr] = Field(default=None, alias="fileName") - file_type: Optional[StrictStr] = Field(default=None, alias="fileType") - object_key: Optional[StrictStr] = Field(default=None, alias="objectKey") + file_id: Optional[StrictStr] = Field(default=None, description="The id you supplied for this file.", alias="fileId") + file_name: Optional[StrictStr] = Field(default=None, description="The file's name, echoed back.", alias="fileName") + file_type: Optional[StrictStr] = Field(default=None, description="The type the service resolved for it.", alias="fileType") + object_key: Optional[StrictStr] = Field(default=None, description="The stored object's key — this is the value to pass later as a content `uri` on /api/v2/memory/add or a document ingest.", alias="objectKey") object_url: Optional[StrictStr] = Field(default=None, description="Present in the response struct for parity with the find endpoint, but not populated on the sign path (omitted from the JSON). ", alias="objectUrl") - object_signed_info: Optional[SignedInfo] = Field(default=None, alias="objectSignedInfo") + object_signed_info: Optional[SignedInfo] = Field(default=None, description="Where and how to upload the bytes.", alias="objectSignedInfo") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["fileId", "fileName", "fileType", "objectKey", "objectUrl", "objectSignedInfo"] diff --git a/everos_cloud/models/signed_info.py b/everos_cloud/models/signed_info.py index 304f953..363d05b 100644 --- a/everos_cloud/models/signed_info.py +++ b/everos_cloud/models/signed_info.py @@ -27,8 +27,8 @@ class SignedInfo(BaseModel): """ Presigned POST form data for direct-to-S3 upload """ # noqa: E501 - url: Optional[StrictStr] = None - fields: Optional[Dict[str, StrictStr]] = None + url: Optional[StrictStr] = Field(default=None, description="The URL to POST the file to.") + fields: Optional[Dict[str, StrictStr]] = Field(default=None, description="Form fields that must accompany the upload, exactly as given, with the file itself last.") max_size: Optional[StrictInt] = Field(default=None, description="Maximum file size in bytes", alias="maxSize") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["url", "fields", "maxSize"] diff --git a/everos_cloud/models/success_envelope_related_tag_usage_list_data.py b/everos_cloud/models/success_envelope_related_tag_usage_list_data.py new file mode 100644 index 0000000..a248fbe --- /dev/null +++ b/everos_cloud/models/success_envelope_related_tag_usage_list_data.py @@ -0,0 +1,107 @@ +# coding: utf-8 + +""" + EverOS Cloud Memory API + + Official Python client for the EverOS Cloud Memory API. Add, search, retrieve, and manage long-term memory for your AI applications over a typed interface (pydantic v2, with full type hints). Install and usage guides: https://github.com/EverMind-AI/everos-cloud-sdk-python + + The version of the OpenAPI document: 2.0.0 + Contact: service@evermind.ai + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictStr +from typing import Any, ClassVar, Dict, List +from everos_cloud.models.related_tag_usage_list_data import RelatedTagUsageListData +from typing import Optional, Set +from typing_extensions import Self + +class SuccessEnvelopeRelatedTagUsageListData(BaseModel): + """ + SuccessEnvelopeRelatedTagUsageListData + """ # noqa: E501 + request_id: StrictStr = Field(description="Request trace id (peer to data)") + data: RelatedTagUsageListData = Field(description="Endpoint-defined business result") + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["request_id", "data"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of SuccessEnvelopeRelatedTagUsageListData from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of data + if self.data: + _dict['data'] = self.data.to_dict() + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of SuccessEnvelopeRelatedTagUsageListData from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "request_id": obj.get("request_id"), + "data": RelatedTagUsageListData.from_dict(obj["data"]) if obj.get("data") is not None else None + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/everos_cloud/models/success_envelope_topic_filter_list_data.py b/everos_cloud/models/success_envelope_topic_filter_list_data.py new file mode 100644 index 0000000..07d0939 --- /dev/null +++ b/everos_cloud/models/success_envelope_topic_filter_list_data.py @@ -0,0 +1,107 @@ +# coding: utf-8 + +""" + EverOS Cloud Memory API + + Official Python client for the EverOS Cloud Memory API. Add, search, retrieve, and manage long-term memory for your AI applications over a typed interface (pydantic v2, with full type hints). Install and usage guides: https://github.com/EverMind-AI/everos-cloud-sdk-python + + The version of the OpenAPI document: 2.0.0 + Contact: service@evermind.ai + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictStr +from typing import Any, ClassVar, Dict, List +from everos_cloud.models.topic_filter_list_data import TopicFilterListData +from typing import Optional, Set +from typing_extensions import Self + +class SuccessEnvelopeTopicFilterListData(BaseModel): + """ + SuccessEnvelopeTopicFilterListData + """ # noqa: E501 + request_id: StrictStr = Field(description="Request trace id (peer to data)") + data: TopicFilterListData = Field(description="Endpoint-defined business result") + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["request_id", "data"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of SuccessEnvelopeTopicFilterListData from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of data + if self.data: + _dict['data'] = self.data.to_dict() + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of SuccessEnvelopeTopicFilterListData from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "request_id": obj.get("request_id"), + "data": TopicFilterListData.from_dict(obj["data"]) if obj.get("data") is not None else None + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/everos_cloud/models/success_envelope_topic_tag_write_data.py b/everos_cloud/models/success_envelope_topic_tag_write_data.py new file mode 100644 index 0000000..2c2cdc7 --- /dev/null +++ b/everos_cloud/models/success_envelope_topic_tag_write_data.py @@ -0,0 +1,107 @@ +# coding: utf-8 + +""" + EverOS Cloud Memory API + + Official Python client for the EverOS Cloud Memory API. Add, search, retrieve, and manage long-term memory for your AI applications over a typed interface (pydantic v2, with full type hints). Install and usage guides: https://github.com/EverMind-AI/everos-cloud-sdk-python + + The version of the OpenAPI document: 2.0.0 + Contact: service@evermind.ai + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictStr +from typing import Any, ClassVar, Dict, List +from everos_cloud.models.topic_tag_write_data import TopicTagWriteData +from typing import Optional, Set +from typing_extensions import Self + +class SuccessEnvelopeTopicTagWriteData(BaseModel): + """ + SuccessEnvelopeTopicTagWriteData + """ # noqa: E501 + request_id: StrictStr = Field(description="Request trace id (peer to data)") + data: TopicTagWriteData = Field(description="Endpoint-defined business result") + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["request_id", "data"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of SuccessEnvelopeTopicTagWriteData from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of data + if self.data: + _dict['data'] = self.data.to_dict() + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of SuccessEnvelopeTopicTagWriteData from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "request_id": obj.get("request_id"), + "data": TopicTagWriteData.from_dict(obj["data"]) if obj.get("data") is not None else None + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/everos_cloud/models/tag_bind_data.py b/everos_cloud/models/tag_bind_data.py index 8d8e810..aa62494 100644 --- a/everos_cloud/models/tag_bind_data.py +++ b/everos_cloud/models/tag_bind_data.py @@ -18,7 +18,7 @@ import re # noqa: F401 import json -from pydantic import BaseModel, ConfigDict, StrictInt +from pydantic import BaseModel, ConfigDict, Field, StrictInt from typing import Any, ClassVar, Dict, List, Optional from typing import Optional, Set from typing_extensions import Self @@ -27,8 +27,8 @@ class TagBindData(BaseModel): """ TagBindData """ # noqa: E501 - matched: Optional[StrictInt] = 0 - requested: Optional[StrictInt] = 0 + matched: Optional[StrictInt] = Field(default=0, description="How many of the submitted memories the operation matched. Matching is not the same as changing: re-binding a tag an item already carries matches without modifying it.") + requested: Optional[StrictInt] = Field(default=0, description="How many ids were submitted. `matched` below `requested` means some ids were not found — deleted, another tenant's, or (for bind) already at the per-memory tag limit.") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["matched", "requested"] diff --git a/everos_cloud/models/tag_bind_input.py b/everos_cloud/models/tag_bind_input.py index 8b39efe..7a349e0 100644 --- a/everos_cloud/models/tag_bind_input.py +++ b/everos_cloud/models/tag_bind_input.py @@ -28,9 +28,9 @@ class TagBindInput(BaseModel): """ TagBindInput """ # noqa: E501 - memory_type: Annotated[str, Field(min_length=1, strict=True)] - memory_ids: Annotated[List[StrictStr], Field(min_length=1, max_length=200)] - tags: Annotated[List[Annotated[str, Field(min_length=1, strict=True, max_length=32)]], Field(min_length=1, max_length=100)] + memory_type: Annotated[str, Field(min_length=1, strict=True)] = Field(description="The type of the memories being tagged. \"episode\" is what this phase supports; agent cases and skills onboard later without an API change.") + memory_ids: Annotated[List[StrictStr], Field(min_length=1, max_length=200)] = Field(description="The memories to tag, by id (1–200 per request). Ids come from /api/v2/memory/get or /api/v2/memory/search.") + tags: Annotated[List[Annotated[str, Field(min_length=1, strict=True, max_length=32)]], Field(min_length=1, max_length=100)] = Field(description="Tags to add (1–100 per request, each 1–32 characters). Tags the memories already carry are left in place.") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["memory_type", "memory_ids", "tags"] diff --git a/everos_cloud/models/tag_ref.py b/everos_cloud/models/tag_ref.py new file mode 100644 index 0000000..3c620df --- /dev/null +++ b/everos_cloud/models/tag_ref.py @@ -0,0 +1,108 @@ +# coding: utf-8 + +""" + EverOS Cloud Memory API + + Official Python client for the EverOS Cloud Memory API. Add, search, retrieve, and manage long-term memory for your AI applications over a typed interface (pydantic v2, with full type hints). Install and usage guides: https://github.com/EverMind-AI/everos-cloud-sdk-python + + The version of the OpenAPI document: 2.0.0 + Contact: service@evermind.ai + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self + +class TagRef(BaseModel): + """ + Opaque semantic tag reference; its containing topic conveys ownership. + """ # noqa: E501 + id: StrictStr = Field(description="Opaque semantic tag id.") + name: Optional[StrictStr] = None + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["id", "name"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of TagRef from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if name (nullable) is None + # and model_fields_set contains the field + if self.name is None and "name" in self.model_fields_set: + _dict['name'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of TagRef from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "id": obj.get("id"), + "name": obj.get("name") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/everos_cloud/models/tag_replace_data.py b/everos_cloud/models/tag_replace_data.py index bed44d4..69b2eaf 100644 --- a/everos_cloud/models/tag_replace_data.py +++ b/everos_cloud/models/tag_replace_data.py @@ -18,7 +18,7 @@ import re # noqa: F401 import json -from pydantic import BaseModel, ConfigDict, StrictInt +from pydantic import BaseModel, ConfigDict, Field, StrictInt from typing import Any, ClassVar, Dict, List, Optional from typing import Optional, Set from typing_extensions import Self @@ -27,8 +27,8 @@ class TagReplaceData(BaseModel): """ TagReplaceData """ # noqa: E501 - matched: Optional[StrictInt] = 0 - requested: Optional[StrictInt] = 0 + matched: Optional[StrictInt] = Field(default=0, description="How many of the submitted memories the operation matched. Matching is not the same as changing: re-binding a tag an item already carries matches without modifying it.") + requested: Optional[StrictInt] = Field(default=0, description="How many ids were submitted. `matched` below `requested` means some ids were not found — deleted, another tenant's, or (for bind) already at the per-memory tag limit.") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["matched", "requested"] diff --git a/everos_cloud/models/tag_replace_input.py b/everos_cloud/models/tag_replace_input.py index 7628419..21b181a 100644 --- a/everos_cloud/models/tag_replace_input.py +++ b/everos_cloud/models/tag_replace_input.py @@ -28,9 +28,9 @@ class TagReplaceInput(BaseModel): """ Full replacement (PUT semantics): overwrite each item's tag set with ``tags``. ``tags`` may be empty — an empty list clears all tags on the targeted items. Duplicates collapse (tags is a set; the service dedups before ``$set``). """ # noqa: E501 - memory_type: Annotated[str, Field(min_length=1, strict=True)] - memory_ids: Annotated[List[StrictStr], Field(min_length=1, max_length=200)] - tags: Annotated[List[Annotated[str, Field(min_length=1, strict=True, max_length=32)]], Field(max_length=100)] + memory_type: Annotated[str, Field(min_length=1, strict=True)] = Field(description="The type of the memories being retagged, e.g. \"episode\".") + memory_ids: Annotated[List[StrictStr], Field(min_length=1, max_length=200)] = Field(description="The memories to retag, by id (1–200 per request).") + tags: Annotated[List[Annotated[str, Field(min_length=1, strict=True, max_length=32)]], Field(max_length=100)] = Field(description="The complete tag set to store (up to 100, each 1–32 characters). Tags absent from this list are dropped, and an empty list clears them all. Duplicates collapse.") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["memory_type", "memory_ids", "tags"] diff --git a/everos_cloud/models/tag_unbind_data.py b/everos_cloud/models/tag_unbind_data.py index a81abc0..bc1ef6e 100644 --- a/everos_cloud/models/tag_unbind_data.py +++ b/everos_cloud/models/tag_unbind_data.py @@ -18,7 +18,7 @@ import re # noqa: F401 import json -from pydantic import BaseModel, ConfigDict, StrictInt +from pydantic import BaseModel, ConfigDict, Field, StrictInt from typing import Any, ClassVar, Dict, List, Optional from typing import Optional, Set from typing_extensions import Self @@ -27,8 +27,8 @@ class TagUnbindData(BaseModel): """ TagUnbindData """ # noqa: E501 - matched: Optional[StrictInt] = 0 - requested: Optional[StrictInt] = 0 + matched: Optional[StrictInt] = Field(default=0, description="How many of the submitted memories the operation matched. Matching is not the same as changing: re-binding a tag an item already carries matches without modifying it.") + requested: Optional[StrictInt] = Field(default=0, description="How many ids were submitted. `matched` below `requested` means some ids were not found — deleted, another tenant's, or (for bind) already at the per-memory tag limit.") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["matched", "requested"] diff --git a/everos_cloud/models/tag_unbind_input.py b/everos_cloud/models/tag_unbind_input.py index 5445acc..3134687 100644 --- a/everos_cloud/models/tag_unbind_input.py +++ b/everos_cloud/models/tag_unbind_input.py @@ -28,9 +28,9 @@ class TagUnbindInput(BaseModel): """ TagUnbindInput """ # noqa: E501 - memory_type: Annotated[str, Field(min_length=1, strict=True)] - memory_ids: Annotated[List[StrictStr], Field(min_length=1, max_length=200)] - tags: Annotated[List[Annotated[str, Field(min_length=1, strict=True, max_length=32)]], Field(min_length=1, max_length=100)] + memory_type: Annotated[str, Field(min_length=1, strict=True)] = Field(description="The type of the memories being untagged, e.g. \"episode\".") + memory_ids: Annotated[List[StrictStr], Field(min_length=1, max_length=200)] = Field(description="The memories to untag, by id (1–200 per request).") + tags: Annotated[List[Annotated[str, Field(min_length=1, strict=True, max_length=32)]], Field(min_length=1, max_length=100)] = Field(description="Tags to remove (1–100 per request). Tags not listed here are left in place.") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["memory_type", "memory_ids", "tags"] diff --git a/everos_cloud/models/task_error_response_error.py b/everos_cloud/models/task_error_response_error.py index 678fd53..091b2f6 100644 --- a/everos_cloud/models/task_error_response_error.py +++ b/everos_cloud/models/task_error_response_error.py @@ -25,7 +25,7 @@ class TaskErrorResponseError(BaseModel): """ - TaskErrorResponseError + What went wrong, with a machine-readable code and a message. """ # noqa: E501 code: StrictStr = Field(description="Error code, e.g. invalid_request, not_found, unavailable") message: StrictStr diff --git a/everos_cloud/models/task_item.py b/everos_cloud/models/task_item.py index bc28561..fae6e37 100644 --- a/everos_cloud/models/task_item.py +++ b/everos_cloud/models/task_item.py @@ -28,14 +28,14 @@ class TaskItem(BaseModel): """ TaskItem """ # noqa: E501 - created_at: Optional[datetime] = None + created_at: Optional[datetime] = Field(default=None, description="When the task was accepted.") error: Optional[StrictStr] = Field(default=None, description="Failure reason; present only when status is failed") - error_code: Optional[StrictStr] = None + error_code: Optional[StrictStr] = Field(default=None, description="Machine-readable failure code, alongside the human-readable `error`.") finished_at: Optional[datetime] = Field(default=None, description="Completion time; absent while the task is not in a terminal state") id: StrictStr = Field(description="Task id (the request's X-Request-Id), not a database primary key") object: Optional[StrictStr] = Field(default=None, description="Resource type produced by the task (frozen field, cannot express a batch)") - object_id: Optional[StrictStr] = None - status: StrictStr + object_id: Optional[StrictStr] = Field(default=None, description="Id of the resource the task produced, once there is one.") + status: StrictStr = Field(description="Where the task is: \"queued\", \"processing\", \"pending\", \"success\" or \"failed\". Treat it as an open set — a value you do not recognise is terminal only when `finished_at` is set.") task_type: Optional[StrictStr] = Field(default=None, description="Async interface that produced the task, e.g. memory_add / knowledge_document / batch_import") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["created_at", "error", "error_code", "finished_at", "id", "object", "object_id", "status", "task_type"] diff --git a/everos_cloud/models/task_list_response.py b/everos_cloud/models/task_list_response.py index 81f47ee..00ad9b5 100644 --- a/everos_cloud/models/task_list_response.py +++ b/everos_cloud/models/task_list_response.py @@ -18,7 +18,7 @@ import re # noqa: F401 import json -from pydantic import BaseModel, ConfigDict, StrictStr +from pydantic import BaseModel, ConfigDict, Field, StrictStr from typing import Any, ClassVar, Dict, List, Optional from everos_cloud.models.task_list_response_data import TaskListResponseData from typing import Optional, Set @@ -29,7 +29,7 @@ class TaskListResponse(BaseModel): TaskListResponse """ # noqa: E501 data: TaskListResponseData - request_id: Optional[StrictStr] = None + request_id: Optional[StrictStr] = Field(default=None, description="Id of this request — quote it when reporting a problem.") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["data", "request_id"] diff --git a/everos_cloud/models/task_list_response_data.py b/everos_cloud/models/task_list_response_data.py index dd98100..78ee74d 100644 --- a/everos_cloud/models/task_list_response_data.py +++ b/everos_cloud/models/task_list_response_data.py @@ -26,7 +26,7 @@ class TaskListResponseData(BaseModel): """ - TaskListResponseData + The page of tasks, with its paging counters. """ # noqa: E501 items: List[TaskItem] page: StrictInt diff --git a/everos_cloud/models/task_stats_response.py b/everos_cloud/models/task_stats_response.py index 9ca2d64..170aeb1 100644 --- a/everos_cloud/models/task_stats_response.py +++ b/everos_cloud/models/task_stats_response.py @@ -18,7 +18,7 @@ import re # noqa: F401 import json -from pydantic import BaseModel, ConfigDict, StrictStr +from pydantic import BaseModel, ConfigDict, Field, StrictStr from typing import Any, ClassVar, Dict, List, Optional from everos_cloud.models.task_stats_response_data import TaskStatsResponseData from typing import Optional, Set @@ -29,7 +29,7 @@ class TaskStatsResponse(BaseModel): TaskStatsResponse """ # noqa: E501 data: TaskStatsResponseData - request_id: Optional[StrictStr] = None + request_id: Optional[StrictStr] = Field(default=None, description="Id of this request — quote it when reporting a problem.") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["data", "request_id"] diff --git a/everos_cloud/models/task_stats_response_data.py b/everos_cloud/models/task_stats_response_data.py index 3d59a8a..6b74868 100644 --- a/everos_cloud/models/task_stats_response_data.py +++ b/everos_cloud/models/task_stats_response_data.py @@ -27,7 +27,7 @@ class TaskStatsResponseData(BaseModel): """ - TaskStatsResponseData + The per-status counts and the window they cover. """ # noqa: E501 by_status: TaskStatsResponseDataByStatus end: datetime = Field(description="End of the window actually aggregated") diff --git a/everos_cloud/models/task_status_response.py b/everos_cloud/models/task_status_response.py index 8d10a35..a772afe 100644 --- a/everos_cloud/models/task_status_response.py +++ b/everos_cloud/models/task_status_response.py @@ -18,7 +18,7 @@ import re # noqa: F401 import json -from pydantic import BaseModel, ConfigDict, StrictStr +from pydantic import BaseModel, ConfigDict, Field, StrictStr from typing import Any, ClassVar, Dict, List, Optional from everos_cloud.models.task_item import TaskItem from typing import Optional, Set @@ -28,8 +28,8 @@ class TaskStatusResponse(BaseModel): """ TaskStatusResponse """ # noqa: E501 - data: TaskItem - request_id: Optional[StrictStr] = None + data: TaskItem = Field(description="The task.") + request_id: Optional[StrictStr] = Field(default=None, description="Id of this request — quote it when reporting a problem.") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["data", "request_id"] diff --git a/everos_cloud/models/tool_call.py b/everos_cloud/models/tool_call.py index e85a6bf..052c75b 100644 --- a/everos_cloud/models/tool_call.py +++ b/everos_cloud/models/tool_call.py @@ -18,7 +18,7 @@ import re # noqa: F401 import json -from pydantic import BaseModel, ConfigDict, StrictStr +from pydantic import BaseModel, ConfigDict, Field, StrictStr from typing import Any, ClassVar, Dict, List, Optional from everos_cloud.models.tool_call_function import ToolCallFunction from typing import Optional, Set @@ -28,9 +28,9 @@ class ToolCall(BaseModel): """ ToolCall """ # noqa: E501 - id: StrictStr - type: Optional[StrictStr] = 'function' - function: ToolCallFunction + id: StrictStr = Field(description="Tool-call id; the matching \"tool\" message echoes it as `tool_call_id`.") + type: Optional[StrictStr] = Field(default='function', description="Tool-call kind. Always \"function\" today.") + function: ToolCallFunction = Field(description="The function invoked, with its arguments.") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["id", "type", "function"] diff --git a/everos_cloud/models/tool_call_function.py b/everos_cloud/models/tool_call_function.py index 71b4ec2..0458558 100644 --- a/everos_cloud/models/tool_call_function.py +++ b/everos_cloud/models/tool_call_function.py @@ -18,7 +18,7 @@ import re # noqa: F401 import json -from pydantic import BaseModel, ConfigDict, StrictStr +from pydantic import BaseModel, ConfigDict, Field, StrictStr from typing import Any, ClassVar, Dict, List from typing import Optional, Set from typing_extensions import Self @@ -27,8 +27,8 @@ class ToolCallFunction(BaseModel): """ ToolCallFunction """ # noqa: E501 - name: StrictStr - arguments: StrictStr + name: StrictStr = Field(description="Name of the function the assistant called.") + arguments: StrictStr = Field(description="The call's arguments as a JSON-encoded string (OpenAI shape), not an object.") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["name", "arguments"] diff --git a/everos_cloud/models/topic_detail_data.py b/everos_cloud/models/topic_detail_data.py index c350807..2378195 100644 --- a/everos_cloud/models/topic_detail_data.py +++ b/everos_cloud/models/topic_detail_data.py @@ -19,8 +19,9 @@ import json from datetime import datetime -from pydantic import BaseModel, ConfigDict, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr, field_validator from typing import Any, ClassVar, Dict, List, Optional +from typing_extensions import Annotated from typing import Optional, Set from typing_extensions import Self @@ -28,24 +29,34 @@ class TopicDetailData(BaseModel): """ Full topic (node), with content transparently restored (inline or from S3). """ # noqa: E501 - id: StrictStr - doc_id: StrictStr - kb_id: StrictStr - category_id: Optional[StrictStr] = '' + id: StrictStr = Field(description="Topic id.") + doc_id: StrictStr = Field(description="The document this topic was extracted from.") + kb_id: StrictStr = Field(description="The knowledge base that document belongs to.") + type: StrictStr = Field(description="Structural role of this topic node") + category_id: Optional[StrictStr] = Field(default='', description="The category the document is filed under; empty when uncategorized.") category_name: Optional[StrictStr] = None - name: StrictStr - depth: Optional[StrictInt] = 0 - seq: Optional[StrictInt] = 0 - summary: Optional[StrictStr] = '' + name: StrictStr = Field(description="The topic's title.") + depth: Optional[StrictInt] = Field(default=0, description="Depth in the document tree — 0 is the document root, 1 a top-level topic.") + seq: Optional[StrictInt] = Field(default=0, description="Depth-first position within the document. Use it as an ordering, not as an index to compute with.") + summary: Optional[StrictStr] = Field(default='', description="Retrieval-oriented summary covering this topic and everything under it.") content: Optional[StrictStr] = None - labels: Optional[List[StrictStr]] = None + labels: Optional[List[StrictStr]] = Field(default=None, description="Labels attached to the topic during extraction.") parent_id: Optional[StrictStr] = None - children_ids: Optional[List[StrictStr]] = None - metadata: Optional[Dict[str, Any]] = None + children_ids: Optional[List[StrictStr]] = Field(default=None, description="The topics directly beneath this one.") + metadata: Optional[Dict[str, Any]] = Field(default=None, description="Extraction metadata carried alongside the topic.") + tag_ids: Annotated[List[Annotated[str, Field(min_length=1, strict=True, max_length=128)]], Field(max_length=50)] = Field(description="Opaque final materialized semantic tag ids (maximum 50)") + version: Annotated[int, Field(strict=True, ge=0)] = Field(description="Current topic tag CAS version") created_at: Optional[datetime] = None updated_at: Optional[datetime] = None additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["id", "doc_id", "kb_id", "category_id", "category_name", "name", "depth", "seq", "summary", "content", "labels", "parent_id", "children_ids", "metadata", "created_at", "updated_at"] + __properties: ClassVar[List[str]] = ["id", "doc_id", "kb_id", "type", "category_id", "category_name", "name", "depth", "seq", "summary", "content", "labels", "parent_id", "children_ids", "metadata", "tag_ids", "version", "created_at", "updated_at"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['root', 'section', 'element']): + raise ValueError("must be one of enum values ('root', 'section', 'element')") + return value model_config = ConfigDict( populate_by_name=True, @@ -133,6 +144,7 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: "id": obj.get("id"), "doc_id": obj.get("doc_id"), "kb_id": obj.get("kb_id"), + "type": obj.get("type"), "category_id": obj.get("category_id") if obj.get("category_id") is not None else '', "category_name": obj.get("category_name"), "name": obj.get("name"), @@ -144,6 +156,8 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: "parent_id": obj.get("parent_id"), "children_ids": obj.get("children_ids"), "metadata": obj.get("metadata"), + "tag_ids": obj.get("tag_ids"), + "version": obj.get("version"), "created_at": obj.get("created_at"), "updated_at": obj.get("updated_at") }) diff --git a/everos_cloud/models/topic_filter_item.py b/everos_cloud/models/topic_filter_item.py new file mode 100644 index 0000000..a89c0fb --- /dev/null +++ b/everos_cloud/models/topic_filter_item.py @@ -0,0 +1,137 @@ +# coding: utf-8 + +""" + EverOS Cloud Memory API + + Official Python client for the EverOS Cloud Memory API. Add, search, retrieve, and manage long-term memory for your AI applications over a typed interface (pydantic v2, with full type hints). Install and usage guides: https://github.com/EverMind-AI/everos-cloud-sdk-python + + The version of the OpenAPI document: 2.0.0 + Contact: service@evermind.ai + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from typing_extensions import Annotated +from typing import Optional, Set +from typing_extensions import Self + +class TopicFilterItem(BaseModel): + """ + Slim item for the KB-wide tag-filter endpoint. This is deliberately separate from :class:`TopicListItem`: the document-tree API may hydrate content and exposes timestamps, while the cross-service tag-filter wire is frozen without those fields. + """ # noqa: E501 + id: StrictStr = Field(description="Topic (node) id") + doc_id: Optional[StrictStr] = Field(default='', description="Owning document id") + kb_id: Optional[StrictStr] = Field(default='', description="Owning knowledge base id") + name: StrictStr = Field(description="Topic title") + type: Optional[StrictStr] = Field(default='section', description="Structural role of the topic — \"root\" for the synthetic document-root node, \"section\" for a real topic.") + depth: Optional[Annotated[int, Field(strict=True, ge=0)]] = Field(default=0, description="Depth in the document tree — 0 is the document root, 1 a top-level topic.") + seq: Optional[Annotated[int, Field(strict=True, ge=0)]] = Field(default=0, description="Depth-first position within the document. Use it as an ordering, not as an index to compute with.") + parent_id: Optional[StrictStr] = None + summary: Optional[StrictStr] = Field(default='', description="Retrieval-oriented summary covering this topic and everything under it.") + tag_ids: Annotated[List[Annotated[str, Field(min_length=1, strict=True, max_length=128)]], Field(max_length=50)] = Field(description="Opaque final materialized semantic tag ids (maximum 50)") + version: Annotated[int, Field(strict=True, ge=0)] = Field(description="Current topic tag CAS version") + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["id", "doc_id", "kb_id", "name", "type", "depth", "seq", "parent_id", "summary", "tag_ids", "version"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value is None: + return value + + if value not in set(['root', 'section', 'element']): + raise ValueError("must be one of enum values ('root', 'section', 'element')") + return value + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of TopicFilterItem from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if parent_id (nullable) is None + # and model_fields_set contains the field + if self.parent_id is None and "parent_id" in self.model_fields_set: + _dict['parent_id'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of TopicFilterItem from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "id": obj.get("id"), + "doc_id": obj.get("doc_id") if obj.get("doc_id") is not None else '', + "kb_id": obj.get("kb_id") if obj.get("kb_id") is not None else '', + "name": obj.get("name"), + "type": obj.get("type") if obj.get("type") is not None else 'section', + "depth": obj.get("depth") if obj.get("depth") is not None else 0, + "seq": obj.get("seq") if obj.get("seq") is not None else 0, + "parent_id": obj.get("parent_id"), + "summary": obj.get("summary") if obj.get("summary") is not None else '', + "tag_ids": obj.get("tag_ids"), + "version": obj.get("version") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/everos_cloud/models/topic_filter_list_data.py b/everos_cloud/models/topic_filter_list_data.py new file mode 100644 index 0000000..fca7194 --- /dev/null +++ b/everos_cloud/models/topic_filter_list_data.py @@ -0,0 +1,112 @@ +# coding: utf-8 + +""" + EverOS Cloud Memory API + + Official Python client for the EverOS Cloud Memory API. Add, search, retrieve, and manage long-term memory for your AI applications over a typed interface (pydantic v2, with full type hints). Install and usage guides: https://github.com/EverMind-AI/everos-cloud-sdk-python + + The version of the OpenAPI document: 2.0.0 + Contact: service@evermind.ai + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field +from typing import Any, ClassVar, Dict, List +from typing_extensions import Annotated +from everos_cloud.models.topic_filter_item import TopicFilterItem +from typing import Optional, Set +from typing_extensions import Self + +class TopicFilterListData(BaseModel): + """ + TopicFilterListData + """ # noqa: E501 + topics: List[TopicFilterItem] = Field(description="The matching topics, one page of them.") + total: Annotated[int, Field(strict=True, ge=0)] = Field(description="How many topics satisfy the all-tags-on-one-topic condition in total, counted before paging.") + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["topics", "total"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of TopicFilterListData from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in topics (list) + _items = [] + if self.topics: + for _item_topics in self.topics: + if _item_topics: + _items.append(_item_topics.to_dict()) + _dict['topics'] = _items + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of TopicFilterListData from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "topics": [TopicFilterItem.from_dict(_item) for _item in obj["topics"]] if obj.get("topics") is not None else None, + "total": obj.get("total") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/everos_cloud/models/topic_list_data.py b/everos_cloud/models/topic_list_data.py index 7ead1ba..13e1f01 100644 --- a/everos_cloud/models/topic_list_data.py +++ b/everos_cloud/models/topic_list_data.py @@ -18,7 +18,7 @@ import re # noqa: F401 import json -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field from typing import Any, ClassVar, Dict, List, Optional from everos_cloud.models.topic_list_item import TopicListItem from typing import Optional, Set @@ -28,7 +28,7 @@ class TopicListData(BaseModel): """ A document's topic tree, DFS-ordered (flat list; build the tree from `parent_id`). The list INCLUDES the synthetic document-root item (`type=root`), so ``len(topics) == document.topic_count + 1`` — the document's ``topic_count`` counts real topics only. Two consumer recipes: * **Full tree** — root at the item whose ``parent_id`` is null, link the rest by ``parent_id``. Returned order is already DFS, so children keep document order. * **Real topics only** (to match ``topic_count``) — drop the ``type=root`` item AND null out the ``parent_id`` of its direct children, otherwise those now point at an id that is no longer in the set. Robust root test for either recipe: ``parent_id is null OR parent_id not in the returned ids`` — that also survives an orphan row left behind by a partial cascade delete. ``include=content`` hydrates every item's body, which can grow the response by orders of magnitude. Ask for it to render a whole document, not to draw the tree. """ # noqa: E501 - topics: Optional[List[TopicListItem]] = None + topics: Optional[List[TopicListItem]] = Field(default=None, description="The document's topics, flat and depth-first ordered — build the tree from `parent_id`. Includes the synthetic document-root item, so this list holds exactly one more entry than the document's `topic_count`.") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["topics"] diff --git a/everos_cloud/models/topic_list_item.py b/everos_cloud/models/topic_list_item.py index a9b83af..48b27db 100644 --- a/everos_cloud/models/topic_list_item.py +++ b/everos_cloud/models/topic_list_item.py @@ -21,6 +21,7 @@ from datetime import datetime from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr from typing import Any, ClassVar, Dict, List, Optional +from typing_extensions import Annotated from typing import Optional, Set from typing_extensions import Self @@ -29,6 +30,8 @@ class TopicListItem(BaseModel): Node-tree overview item. ``content`` only when the caller asks for it. """ # noqa: E501 id: StrictStr = Field(description="Topic (node) id") + doc_id: Optional[StrictStr] = Field(default='', description="Owning document id") + kb_id: Optional[StrictStr] = Field(default='', description="Owning knowledge base id") name: StrictStr = Field(description="Node title. For the document-root item (`type=root`) this is the document title, i.e. the same value as the document's `title`") type: Optional[StrictStr] = Field(default='section', description="Structural role: `root` = the document-root container (exactly one per document, `depth=0`, `parent_id=null`, empty body), `section` = a real topic, `element` = rich media (reserved, not produced yet). Filter on this rather than on `depth==0` to tell the root apart from real topics") depth: Optional[StrictInt] = Field(default=0, description="Tree depth: 0 = document root, 1 = a top-level topic") @@ -36,10 +39,12 @@ class TopicListItem(BaseModel): parent_id: Optional[StrictStr] = None summary: Optional[StrictStr] = Field(default='', description="Retrieval-oriented summary covering this node AND its subtree. On the root item it is the document-level summary") content: Optional[StrictStr] = None + tag_ids: Optional[Annotated[List[Annotated[str, Field(min_length=1, strict=True, max_length=128)]], Field(max_length=50)]] = Field(default=None, description="Opaque final materialized semantic tag ids (maximum 50)") + version: Optional[Annotated[int, Field(strict=True, ge=0)]] = Field(default=0, description="Current topic tag CAS version") created_at: Optional[datetime] = None updated_at: Optional[datetime] = None additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["id", "name", "type", "depth", "seq", "parent_id", "summary", "content", "created_at", "updated_at"] + __properties: ClassVar[List[str]] = ["id", "doc_id", "kb_id", "name", "type", "depth", "seq", "parent_id", "summary", "content", "tag_ids", "version", "created_at", "updated_at"] model_config = ConfigDict( populate_by_name=True, @@ -120,6 +125,8 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: _obj = cls.model_validate({ "id": obj.get("id"), + "doc_id": obj.get("doc_id") if obj.get("doc_id") is not None else '', + "kb_id": obj.get("kb_id") if obj.get("kb_id") is not None else '', "name": obj.get("name"), "type": obj.get("type") if obj.get("type") is not None else 'section', "depth": obj.get("depth") if obj.get("depth") is not None else 0, @@ -127,6 +134,8 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: "parent_id": obj.get("parent_id"), "summary": obj.get("summary") if obj.get("summary") is not None else '', "content": obj.get("content"), + "tag_ids": obj.get("tag_ids"), + "version": obj.get("version") if obj.get("version") is not None else 0, "created_at": obj.get("created_at"), "updated_at": obj.get("updated_at") }) diff --git a/everos_cloud/models/topic_tag_replace_body.py b/everos_cloud/models/topic_tag_replace_body.py new file mode 100644 index 0000000..3fa74fa --- /dev/null +++ b/everos_cloud/models/topic_tag_replace_body.py @@ -0,0 +1,104 @@ +# coding: utf-8 + +""" + EverOS Cloud Memory API + + Official Python client for the EverOS Cloud Memory API. Add, search, retrieve, and manage long-term memory for your AI applications over a typed interface (pydantic v2, with full type hints). Install and usage guides: https://github.com/EverMind-AI/everos-cloud-sdk-python + + The version of the OpenAPI document: 2.0.0 + Contact: service@evermind.ai + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field +from typing import Any, ClassVar, Dict, List +from typing_extensions import Annotated +from typing import Optional, Set +from typing_extensions import Self + +class TopicTagReplaceBody(BaseModel): + """ + TopicTagReplaceBody + """ # noqa: E501 + tag_ids: Annotated[List[Annotated[str, Field(min_length=1, strict=True, max_length=128)]], Field(max_length=100)] = Field(description="Complete materialized snapshot. Cloud stable-deduplicates the request, stores the first 50 ids, and reports any truncation.") + version: Annotated[int, Field(strict=True, ge=0)] = Field(description="Expected current topic tag_version (CAS)") + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["tag_ids", "version"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of TopicTagReplaceBody from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of TopicTagReplaceBody from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "tag_ids": obj.get("tag_ids"), + "version": obj.get("version") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/everos_cloud/models/topic_tag_write_data.py b/everos_cloud/models/topic_tag_write_data.py new file mode 100644 index 0000000..16baaae --- /dev/null +++ b/everos_cloud/models/topic_tag_write_data.py @@ -0,0 +1,121 @@ +# coding: utf-8 + +""" + EverOS Cloud Memory API + + Official Python client for the EverOS Cloud Memory API. Add, search, retrieve, and manage long-term memory for your AI applications over a typed interface (pydantic v2, with full type hints). Install and usage guides: https://github.com/EverMind-AI/everos-cloud-sdk-python + + The version of the OpenAPI document: 2.0.0 + Contact: service@evermind.ai + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from typing_extensions import Annotated +from typing import Optional, Set +from typing_extensions import Self + +class TopicTagWriteData(BaseModel): + """ + TopicTagWriteData + """ # noqa: E501 + topic_id: StrictStr = Field(description="The topic whose tag snapshot was written.") + requested: Annotated[int, Field(strict=True, ge=0)] = Field(description="Stable-distinct request id count; not vocabulary-validity count") + tag_ids: Annotated[List[Annotated[str, Field(min_length=1, strict=True, max_length=128)]], Field(max_length=50)] = Field(description="Complete materialized topic tag snapshot after the accepted write") + version: Annotated[int, Field(strict=True, ge=0)] = Field(description="Current topic tag version") + truncated: StrictBool = Field(description="Whether distinct input exceeded the store limit") + limit: StrictInt = Field(description="Materialized topic tag limit") + dropped_count: Annotated[int, Field(strict=True, ge=0)] = Field(description="Distinct requested ids omitted by stable truncation") + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["topic_id", "requested", "tag_ids", "version", "truncated", "limit", "dropped_count"] + + @field_validator('limit') + def limit_validate_enum(cls, value): + """Validates the enum""" + if value not in set([50]): + raise ValueError("must be one of enum values (50)") + return value + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of TopicTagWriteData from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of TopicTagWriteData from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "topic_id": obj.get("topic_id"), + "requested": obj.get("requested"), + "tag_ids": obj.get("tag_ids"), + "version": obj.get("version"), + "truncated": obj.get("truncated"), + "limit": obj.get("limit"), + "dropped_count": obj.get("dropped_count") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/everos_cloud/models/unprocessed_message_dto.py b/everos_cloud/models/unprocessed_message_dto.py index 216547b..bc25f3a 100644 --- a/everos_cloud/models/unprocessed_message_dto.py +++ b/everos_cloud/models/unprocessed_message_dto.py @@ -19,9 +19,9 @@ import json from datetime import datetime -from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator from typing import Any, ClassVar, Dict, List, Optional -from everos_cloud.models.content import Content +from everos_cloud.models.content1 import Content1 from everos_cloud.models.tool_call import ToolCall from typing import Optional, Set from typing_extensions import Self @@ -30,15 +30,15 @@ class UnprocessedMessageDTO(BaseModel): """ Buffered raw message not yet extracted (no owner — inference happens after boundary detection). Returned by /search only when ``filters.session_id`` is a top-level eq scalar (spec §4 / appendix E). """ # noqa: E501 - id: StrictStr - app_id: StrictStr - project_id: StrictStr - session_id: StrictStr - sender_id: StrictStr + id: StrictStr = Field(description="Buffered-message id.") + app_id: StrictStr = Field(description="The business-semantic scope the message was written under.") + project_id: StrictStr = Field(description="Second half of that scope.") + session_id: StrictStr = Field(description="The session the message is buffered under.") + sender_id: StrictStr = Field(description="Who sent it.") sender_name: Optional[StrictStr] = None - role: StrictStr - content: Content - timestamp: datetime + role: StrictStr = Field(description="\"user\", \"assistant\" or \"tool\", as submitted.") + content: Content1 + timestamp: datetime = Field(description="When the message was produced (ISO 8601).") tool_calls: Optional[List[ToolCall]] = None tool_call_id: Optional[StrictStr] = None additional_properties: Dict[str, Any] = {} @@ -141,7 +141,7 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: "sender_id": obj.get("sender_id"), "sender_name": obj.get("sender_name"), "role": obj.get("role"), - "content": Content.from_dict(obj["content"]) if obj.get("content") is not None else None, + "content": Content1.from_dict(obj["content"]) if obj.get("content") is not None else None, "timestamp": obj.get("timestamp"), "tool_calls": [ToolCall.from_dict(_item) for _item in obj["tool_calls"]] if obj.get("tool_calls") is not None else None, "tool_call_id": obj.get("tool_call_id") diff --git a/everos_cloud/models/update_operation.py b/everos_cloud/models/update_operation.py index 432dc03..24f4453 100644 --- a/everos_cloud/models/update_operation.py +++ b/everos_cloud/models/update_operation.py @@ -30,9 +30,9 @@ class UpdateOperation(BaseModel): Update an existing profile item (partial ``data`` shallow-merge). """ # noqa: E501 reason: Optional[Annotated[str, Field(strict=True, max_length=256)]] = None - action: StrictStr - type: StrictStr - item_id: StrictStr + action: StrictStr = Field(description="Always \"update\" for this variant.") + type: StrictStr = Field(description="Which profile item this edit targets — \"explicit_info\" or \"implicit_traits\". It must match the `item_id` prefix.") + item_id: StrictStr = Field(description="The item to update. Its prefix must match the item type — \"ei_\" for explicit_info, \"it_\" for implicit_traits — followed by 24 hex characters.") data: Data1 additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["reason", "action", "type", "item_id", "data"] diff --git a/everos_cloud/models/validation_error.py b/everos_cloud/models/validation_error.py index f6495a9..905af1c 100644 --- a/everos_cloud/models/validation_error.py +++ b/everos_cloud/models/validation_error.py @@ -18,7 +18,7 @@ import re # noqa: F401 import json -from pydantic import BaseModel, ConfigDict, StrictStr +from pydantic import BaseModel, ConfigDict, Field, StrictStr from typing import Any, ClassVar, Dict, List from everos_cloud.models.validation_error_loc_inner import ValidationErrorLocInner from typing import Optional, Set @@ -28,9 +28,9 @@ class ValidationError(BaseModel): """ ValidationError """ # noqa: E501 - loc: List[ValidationErrorLocInner] - msg: StrictStr - type: StrictStr + loc: List[ValidationErrorLocInner] = Field(description="Path to the offending field, from the body root.") + msg: StrictStr = Field(description="What is wrong with it.") + type: StrictStr = Field(description="Machine-readable validation-error kind.") additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["loc", "msg", "type"] diff --git a/openapi.json b/openapi.json index 1e23f17..eb15af5 100644 --- a/openapi.json +++ b/openapi.json @@ -103,7 +103,8 @@ } } } - } + }, + "description": "Append conversation messages to a session's working memory. Asynchronous by default (`async_mode` true): the gateway validates and enqueues the write, answering 202 with status \"queued\". Pass `async_mode: false` to forward synchronously and receive the engine's 200 result instead. Distillation into long-term memory is always asynchronous \u2014 it runs on a session boundary, or when you call /api/v2/memory/flush. One call carries 1\u2013500 messages." } }, "/api/v2/memory/delete": { @@ -184,7 +185,8 @@ } } } - } + }, + "description": "Soft-delete memories within a scope. At least one of `user_id`, `agent_id` or `session_id` is required (an empty body is rejected with 422), and `user_id` / `agent_id` are mutually exclusive. The response echoes which scope filters were applied and how many records were removed across all memory types." } }, "/api/v2/memory/edit": { @@ -265,7 +267,8 @@ } } } - } + }, + "description": "Apply 1\u201350 edits to one user's profile in a single call. Each operation carries an `action` (add, update or delete), a `type` (explicit_info or implicit_traits), the item `data`, and an optional `reason`. Profile is the only memory type this endpoint edits \u2014 `memory_type` is pinned to \"profile\"; every other type is produced by extraction. Operations are reported individually in the response, so some can be rejected while others apply." } }, "/api/v2/memory/flush": { @@ -346,7 +349,8 @@ } } } - } + }, + "description": "Force extraction for a session instead of waiting for a boundary. Returns status \"extracted\" when memories were distilled and \"no_extraction\" when there was nothing to extract \u2014 note that a default (async) add that is still queued yields \"no_extraction\", so either write with `async_mode: false` or poll the add's task before flushing." } }, "/api/v2/memory/get": { @@ -427,7 +431,8 @@ } } } - } + }, + "description": "List stored memories of one type, paginated. Exactly one of `user_id` / `agent_id` is required, and `memory_type` must match that owner: a user owns \"episode\" and \"profile\", an agent owns \"agent_case\" and \"agent_skill\" \u2014 the other pairings are rejected with 422. This is a structured read, not a query: it does not embed the request, so a memory is readable as soon as it is extracted, whereas the vector index /api/v2/memory/search relies on lags behind extraction by seconds." } }, "/api/v2/memory/search": { @@ -508,7 +513,8 @@ } } } - } + }, + "description": "Retrieve the memories relevant to a query. Exactly one of `user_id` / `agent_id` is required and decides what comes back: a user owner returns episodes (plus profiles with `include_profile`), an agent owner returns agent cases and skills. All result collections are always present in the response, empty when they do not apply. The vector-backed methods read an index that lags extraction by seconds \u2014 to read back something just extracted, use /api/v2/memory/get." } }, "/api/v2/memory/tag/bind": { @@ -589,7 +595,8 @@ } } } - } + }, + "description": "Add tags to existing memories, keeping the tags they already carry. Tags are scoped by the memory ids themselves \u2014 pass `memory_type` plus the ids, not an app or project scope. Tags are created by use: binding a name that does not exist yet is how it comes into existence. Idempotent, and batched over memory_ids x tags." } }, "/api/v2/memory/tag/replace": { @@ -670,7 +677,8 @@ } } } - } + }, + "description": "Overwrite the tag set on the given memories: tags absent from the request are dropped, and an empty `tags` list clears them all. Use /api/v2/memory/tag/bind to add without removing." } }, "/api/v2/memory/tag/unbind": { @@ -751,7 +759,8 @@ } } } - } + }, + "description": "Remove the given tags from the given memories, leaving their other tags in place. Idempotent: unbinding a tag an item does not carry still counts as matched." } }, "/api/v2/knowledge_bases/{kb_id}/categories": { @@ -843,7 +852,8 @@ } } } - } + }, + "description": "Add a category to this knowledge base's taxonomy. Categories are what a document is filed under: on ingest each document is classified into one of them, unless the caller pins `category_id` on the upload. The category's description is not decoration \u2014 it is what the classifier matches against." }, "get": { "tags": [ @@ -923,7 +933,8 @@ } } } - } + }, + "description": "List this knowledge base's categories \u2014 both the ones created here and the tenant-global presets \u2014 each with the number of documents filed under it." } }, "/api/v2/knowledge_bases/{kb_id}/documents": { @@ -1015,7 +1026,8 @@ } } } - } + }, + "description": "Upload a document for ingest. Ingest is asynchronous at the gateway: it answers 202 with status \"queued\" and a `task_id`, and the document id is minted downstream \u2014 poll GET /api/v2/tasks/{task_id}, then resolve the id from GET .../documents. Ingest is only truly complete once that document reports `topic_count` greater than 0. `content` is one content object: inline text, or a file already uploaded through POST /api/v2/object/sign, referenced by its object key as the content's `uri`. Omit `category_id` to let the server classify the document into this base's taxonomy." }, "get": { "tags": [ @@ -1131,7 +1143,8 @@ } } } - } + }, + "description": "Paginated list of the documents in a knowledge base, each with its category and topic count. Filterable by category." } }, "/api/v2/knowledge_bases": { @@ -1212,7 +1225,8 @@ } } } - } + }, + "description": "Create a knowledge base \u2014 a searchable document library with its own category taxonomy. The returned id is the `kb_id` every other knowledge operation takes." }, "get": { "tags": [ @@ -1227,6 +1241,7 @@ "required": false, "schema": { "type": "integer", + "minimum": 1, "default": 1, "title": "Page" } @@ -1237,6 +1252,8 @@ "required": false, "schema": { "type": "integer", + "maximum": 100, + "minimum": 1, "default": 20, "title": "Page Size" } @@ -1319,7 +1336,8 @@ } } } - } + }, + "description": "Paginated list of the account's knowledge bases, each with its document count." } }, "/api/v2/knowledge_bases/{kb_id}/categories/{category_id}": { @@ -1410,7 +1428,8 @@ } } } - } + }, + "description": "Delete a category from this knowledge base's taxonomy. Its documents are NOT deleted: they (and their topics) are reassigned to uncategorized first, then the category is soft-deleted. Idempotent \u2014 deleting one that is already gone returns `deleted: false` rather than 404." }, "patch": { "tags": [ @@ -1509,7 +1528,8 @@ } } } - } + }, + "description": "Rename a category or edit its description. Documents filed under it are not re-classified; they keep pointing at the same category id. Tenant-global preset categories are read-only." } }, "/api/v2/knowledge_bases/{kb_id}/documents/{doc_id}": { @@ -1600,7 +1620,8 @@ } } } - } + }, + "description": "Soft-delete a document. Its topics and their search-index entries are removed with it, so nothing of the document stays searchable. Idempotent \u2014 deleting one that is already gone returns `deleted: false` rather than 404." }, "get": { "tags": [ @@ -1689,7 +1710,8 @@ } } } - } + }, + "description": "Read one document's metadata, including how many topics were extracted from it \u2014 `topic_count` greater than 0 is also the authoritative signal that an async ingest finished. The text itself lives in those topics; list them with GET .../documents/{doc_id}/topics." }, "patch": { "tags": [ @@ -1788,13 +1810,15 @@ } } } - } + }, + "description": "Patch a document's metadata \u2014 its title, or the category it is filed under. Content is not editable here: re-ingest with PUT .../documents/{doc_id} to change it. The response lists which fields actually changed." }, "put": { "tags": [ "Knowledge" ], "summary": "Replace a document (async, atomic swap)", + "description": "Re-ingest content under an existing document id. Same asynchronous contract as upload (202 with `status` and `task_id`), and idempotent per document id \u2014 the same replace applied twice leaves the same state. As with upload, completion is authoritative from GET .../documents/{doc_id} reporting `topic_count` greater than 0.", "operationId": "replaceDocument", "parameters": [ { @@ -1969,7 +1993,8 @@ } } } - } + }, + "description": "Delete a knowledge base and everything under it: every document (with its topics, search-index entries and stored objects) and every category are soft-deleted first, then the base itself. Idempotent \u2014 deleting a base that is already gone returns `deleted: false` rather than 404." }, "get": { "tags": [ @@ -2049,7 +2074,8 @@ } } } - } + }, + "description": "Read one knowledge base's metadata, including its document count." }, "patch": { "tags": [ @@ -2139,7 +2165,8 @@ } } } - } + }, + "description": "Patch a knowledge base's name or description. Metadata only \u2014 it does not touch the documents inside it." } }, "/api/v2/knowledge_bases/{kb_id}/documents/{doc_id}/topics/{topic_id}": { @@ -2189,6 +2216,9 @@ } } }, + "404": { + "description": "Topic absent or not owned by the path kb/document" + }, "422": { "description": "Validation Error", "content": { @@ -2239,7 +2269,8 @@ } } } - } + }, + "description": "Read one topic's full content. Storage is transparent to the caller: content held inline and content held in object storage are returned the same way." } }, "/api/v2/knowledge_bases/{kb_id}/documents/{doc_id}/topics": { @@ -2344,44 +2375,81 @@ } } } - } + }, + "description": "List a document's topic tree \u2014 the sections an LLM extracted from it \u2014 flat and already in depth-first order; build the tree from each item's `parent_id`. The list includes one synthetic document-root item (`type` \"root\"), so it returns exactly one more item than the document's `topic_count`, which counts real topics only. Bodies are omitted by default; ask for `content` in `include` to hydrate every item, which can enlarge the response by orders of magnitude." } }, - "/api/v2/knowledge_bases/{kb_id}/search": { - "post": { + "/api/v2/knowledge_bases/{kb_id}/topics": { + "get": { "tags": [ "Knowledge" ], - "summary": "Search within a knowledge base (keyword / vector / hybrid)", - "operationId": "searchKnowledge", + "summary": "List tag-matched topics in a knowledge base", + "description": "Filter live topics by their own materialized tag set. Every requested id must occur on the same topic (ALL semantics); total is counted before paging.", + "operationId": "listTopicsByTags", "parameters": [ { "name": "kb_id", "in": "path", "required": true, + "description": "The knowledge base to search within.", "schema": { "type": "string", "title": "Kb Id" } - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/SearchBody" - } + }, + { + "name": "tag_ids", + "in": "query", + "required": true, + "description": "Hard filter: a topic is returned only if it carries EVERY one of these tag ids. Use `boost_tag_ids` on the search endpoint instead to reweight without excluding anything.", + "schema": { + "type": "array", + "items": { + "type": "string", + "minLength": 1, + "maxLength": 128, + "description": "Opaque semantic tag id" + }, + "minItems": 1, + "maxItems": 100, + "description": "Hard filter: a topic is returned only if it carries EVERY one of these tag ids.", + "title": "Tag Ids" + } + }, + { + "name": "page", + "in": "query", + "required": false, + "description": "1-based page number.", + "schema": { + "type": "integer", + "minimum": 1, + "default": 1, + "title": "Page" + } + }, + { + "name": "page_size", + "in": "query", + "required": false, + "description": "Items per page, 1 to 100 (default 20).", + "schema": { + "type": "integer", + "maximum": 100, + "minimum": 1, + "default": 20, + "title": "Page Size" } } - }, + ], "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SuccessEnvelope_KbSearchData_" + "$ref": "#/components/schemas/SuccessEnvelope_TopicFilterListData_" } } } @@ -2439,30 +2507,52 @@ } } }, - "/api/v2/object/sign": { + "/api/v2/knowledge_bases/{kb_id}/tags": { "post": { "tags": [ - "Storage" + "Knowledge" + ], + "summary": "Count candidate tags used by live documents in a knowledge base", + "description": "Returns requested opaque tag ids used by live topics of live documents. Counts are distinct by document and items are sorted by id. The bounded multi-command Mongo read is not a point-in-time snapshot across concurrent lifecycle writes.", + "operationId": "queryRelatedTags", + "parameters": [ + { + "name": "kb_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Kb Id" + } + } ], - "summary": "Get multimodal upload URLs", - "operationId": "signObjects", "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SignRequest" + "$ref": "#/components/schemas/RelatedTagUsageBody" } } } }, "responses": { "200": { - "description": "Envelope response (MMS returns HTTP 200 for every business outcome;\nonly unmatched routes return 404). `status: 0` means success and\n`result.data` is a SignResponse. Non-zero `status` values seen on\nthis endpoint:\n\n- `20003` \u2014 request body bind failure (malformed JSON).\n- `2018` \u2014 parameter validation failed (e.g. missing `objectList`,\n `fileId`, `fileName`, or `fileType`); `result.data` is the\n validator error string.\n- `1012` \u2014 `mms-token` missing, invalid, expired, or revoked\n (emitted by the auth middleware before the handler runs).\n- `1013` \u2014 token lacks the required `object:sign` scope.\n- `1007` \u2014 `objectList` exceeds the per-request limit of 50.\n- `1002` \u2014 `fileType` not one of image/video/file.\n- `1009` \u2014 duplicate `fileId` within the request.\n- `1004` \u2014 S3 operation failed (bucket unavailable).\n- `1005` \u2014 presigned POST generation failed.\n- `2015` \u2014 object metadata persistence failed.\n- `20001` \u2014 unhandled internal server error.\n", + "description": "Successful Response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SignEnvelope" + "$ref": "#/components/schemas/SuccessEnvelope_RelatedTagUsageListData_" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" } } } @@ -2510,101 +2600,96 @@ } } }, - "/api/v2/tasks": { - "get": { - "description": "Paginated task list, filterable by status, session and time window. Results are scoped to the caller's tenant, resolved from the request context; a caller can only ever see its own tasks.", - "operationId": "listTasks", + "/api/v2/knowledge_bases/{kb_id}/documents/{doc_id}/topics/{topic_id}/tag/replace": { + "post": { + "tags": [ + "Knowledge" + ], + "summary": "Replace the complete materialized semantic tag snapshot of a topic", + "description": "version is the expected current tag_version. Cloud stable-deduplicates the request and stores the first 50 ids; requests with 51-100 distinct ids succeed with structured truncation metadata. Identical snapshots are no-ops and do not advance the version.", + "operationId": "replaceTopicTags", "parameters": [ { - "in": "query", - "name": "page", - "required": false, - "schema": { - "description": "Page number, 1-based", - "type": "integer" - } - }, - { - "in": "query", - "name": "page_size", - "required": false, - "schema": { - "description": "Items per page", - "type": "integer" - } - }, - { - "in": "query", - "name": "status", - "required": false, - "schema": { - "enum": [ - "queued", - "processing", - "success", - "failed" - ], - "type": "string" - } - }, - { - "in": "query", - "name": "session_id", - "required": false, + "name": "kb_id", + "in": "path", + "required": true, "schema": { - "description": "Filter by session", - "type": "string" + "type": "string", + "title": "Kb Id" } }, { - "in": "query", - "name": "start", - "required": false, + "name": "doc_id", + "in": "path", + "required": true, "schema": { - "description": "Window start (RFC3339 or epoch milliseconds)", - "type": "string" + "type": "string", + "title": "Doc Id" } }, { - "in": "query", - "name": "end", - "required": false, + "name": "topic_id", + "in": "path", + "required": true, "schema": { - "description": "Window end", - "type": "string" + "type": "string", + "title": "Topic Id" } } ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TopicTagReplaceBody" + } + } + } + }, "responses": { "200": { + "description": "Successful Response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/TaskListResponse" + "$ref": "#/components/schemas/SuccessEnvelope_TopicTagWriteData_" } } - }, - "description": "Task list" + } }, - "400": { + "404": { + "description": "Topic absent or not owned by the path kb/document" + }, + "409": { + "description": "Stale topic tag version (atomic zero-write conflict)", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/TaskErrorResponse" + "$ref": "#/components/schemas/ErrorEnvelope" } } - }, - "description": "Invalid query parameter, or missing tenant scope" + } }, - "503": { + "500": { + "description": "Storage or search projection failure. Mongo may already contain the snapshot; replay the same snapshot to converge.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/TaskErrorResponse" + "$ref": "#/components/schemas/ErrorEnvelope" } } - }, - "description": "Listing requires the database-backed store, which is not configured" + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } }, "401": { "description": "Missing or invalid bearer token.", @@ -2635,21 +2720,325 @@ } } } + }, + "503": { + "description": "The gateway could not reach the authentication service. Transient \u2014 retry with backoff.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GatewayError" + } + } + } } - }, - "summary": "List async tasks", - "tags": [ - "Tasks" - ] + } } }, - "/api/v2/tasks/stats": { - "get": { - "description": "Counts tasks per status over a time window. All four statuses are always present (0 when absent) so dashboards get a stable shape, and the response echoes the window actually used after server-side clamping. Results are scoped to the caller's tenant, resolved from the request context; a caller can only ever see its own tasks.", - "operationId": "getTaskStats", - "parameters": [ - { - "in": "query", + "/api/v2/knowledge_bases/{kb_id}/search": { + "post": { + "tags": [ + "Knowledge" + ], + "summary": "Search within a knowledge base (keyword / vector / hybrid)", + "operationId": "searchKnowledge", + "parameters": [ + { + "name": "kb_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Kb Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SearchBody" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SuccessEnvelope_KbSearchData_" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + }, + "401": { + "description": "Missing or invalid bearer token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GatewayError" + } + } + } + }, + "403": { + "description": "Authenticated but not permitted \u2014 either rejected by the auth service, or the account's memory API version does not match the interface version implied by the path (a v1 account calling an /api/v2 route).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GatewayError" + } + } + } + }, + "429": { + "description": "Rate limit or quota exceeded.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GatewayError" + } + } + } + }, + "503": { + "description": "The gateway could not reach the authentication service. Transient \u2014 retry with backoff.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GatewayError" + } + } + } + } + }, + "description": "Search within one knowledge base (keyword, vector or hybrid). The unit of retrieval is the topic, not the document: each hit carries its parent document's title and summary, so rendering a result needs no second call. Topic bodies are omitted by default; ask for `content` in `include` to inline them, or drill down with GET .../documents/{doc_id}/topics/{topic_id}." + } + }, + "/api/v2/object/sign": { + "post": { + "tags": [ + "Storage" + ], + "summary": "Get multimodal upload URLs", + "operationId": "signObjects", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SignRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Envelope response (MMS returns HTTP 200 for every business outcome;\nonly unmatched routes return 404). `status: 0` means success and\n`result.data` is a SignResponse. Non-zero `status` values seen on\nthis endpoint:\n\n- `20003` \u2014 request body bind failure (malformed JSON).\n- `2018` \u2014 parameter validation failed (e.g. missing `objectList`,\n `fileId`, `fileName`, or `fileType`); `result.data` is the\n validator error string.\n- `1012` \u2014 `mms-token` missing, invalid, expired, or revoked\n (emitted by the auth middleware before the handler runs).\n- `1013` \u2014 token lacks the required `object:sign` scope.\n- `1007` \u2014 `objectList` exceeds the per-request limit of 50.\n- `1002` \u2014 `fileType` not one of image/video/file.\n- `1009` \u2014 duplicate `fileId` within the request.\n- `1004` \u2014 S3 operation failed (bucket unavailable).\n- `1005` \u2014 presigned POST generation failed.\n- `2015` \u2014 object metadata persistence failed.\n- `20001` \u2014 unhandled internal server error.\n", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SignEnvelope" + } + } + } + }, + "401": { + "description": "Missing or invalid bearer token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GatewayError" + } + } + } + }, + "403": { + "description": "Authenticated but not permitted \u2014 either rejected by the auth service, or the account's memory API version does not match the interface version implied by the path (a v1 account calling an /api/v2 route).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GatewayError" + } + } + } + }, + "429": { + "description": "Rate limit or quota exceeded.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GatewayError" + } + } + } + }, + "503": { + "description": "The gateway could not reach the authentication service. Transient \u2014 retry with backoff.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GatewayError" + } + } + } + } + }, + "description": "Presign a direct-to-storage upload for multimodal data. POST the file to the returned URL yourself, then reference the returned object key as a message's content `uri` (/api/v2/memory/add) or as a document's content `uri` (.../documents). Uploading first and passing the key is the only path that gets a non-text item parsed \u2014 see `base64` on the content object. The Python SDK's `upload()` does both steps in one call." + } + }, + "/api/v2/tasks": { + "get": { + "description": "Paginated task list, filterable by status, session and time window. Results are scoped to the caller's tenant, resolved from the request context; a caller can only ever see its own tasks.", + "operationId": "listTasks", + "parameters": [ + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "description": "Page number, 1-based", + "type": "integer" + } + }, + { + "in": "query", + "name": "page_size", + "required": false, + "schema": { + "description": "Items per page", + "type": "integer" + } + }, + { + "in": "query", + "name": "status", + "required": false, + "schema": { + "enum": [ + "queued", + "processing", + "success", + "failed" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "session_id", + "required": false, + "schema": { + "description": "Filter by session", + "type": "string" + } + }, + { + "in": "query", + "name": "start", + "required": false, + "schema": { + "description": "Window start (RFC3339 or epoch milliseconds)", + "type": "string" + } + }, + { + "in": "query", + "name": "end", + "required": false, + "schema": { + "description": "Window end", + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TaskListResponse" + } + } + }, + "description": "Task list" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TaskErrorResponse" + } + } + }, + "description": "Invalid query parameter, or missing tenant scope" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TaskErrorResponse" + } + } + }, + "description": "Listing requires the database-backed store, which is not configured" + }, + "401": { + "description": "Missing or invalid bearer token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GatewayError" + } + } + } + }, + "403": { + "description": "Authenticated but not permitted \u2014 either rejected by the auth service, or the account's memory API version does not match the interface version implied by the path (a v1 account calling an /api/v2 route).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GatewayError" + } + } + } + }, + "429": { + "description": "Rate limit or quota exceeded.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GatewayError" + } + } + } + } + }, + "summary": "List async tasks", + "tags": [ + "Tasks" + ] + } + }, + "/api/v2/tasks/stats": { + "get": { + "description": "Counts tasks per status over a time window. All five statuses (queued, processing, pending, success, failed) are always present (0 when absent) so dashboards get a stable shape, and the response echoes the window actually used after server-side clamping. Results are scoped to the caller's tenant, resolved from the request context.", + "operationId": "getTaskStats", + "parameters": [ + { + "in": "query", "name": "start", "required": false, "schema": { @@ -2835,7 +3224,8 @@ "properties": { "message_count": { "type": "integer", - "title": "Message Count" + "title": "Message Count", + "description": "How many messages this call accepted." }, "status": { "type": "string", @@ -2860,18 +3250,21 @@ "app_id": { "type": "string", "title": "App Id", - "default": "default" + "default": "default", + "description": "Business-semantic scope for this write, defaulting to \"default\". Reads must use the same app_id / project_id pair to see what was written under it. Note this is a partition, not the security boundary \u2014 that is the tenant resolved from your API key." }, "project_id": { "type": "string", "title": "Project Id", - "default": "default" + "default": "default", + "description": "Second half of the business-semantic scope, defaulting to \"default\". See `app_id`." }, "session_id": { "type": "string", "maxLength": 128, "minLength": 1, - "title": "Session Id" + "title": "Session Id", + "description": "The conversation these messages belong to (1\u2013128 characters). It is the unit extraction works on: /api/v2/memory/flush takes this id, and a session boundary is what triggers extraction on its own." }, "messages": { "items": { @@ -2880,7 +3273,8 @@ "type": "array", "maxItems": 500, "minItems": 1, - "title": "Messages" + "title": "Messages", + "description": "The turns to append, in order \u2014 1 to 500 per call. Each carries its own sender and timestamp, so one call can hold a whole exchange." }, "async_mode": { "type": "boolean", @@ -2919,12 +3313,14 @@ "type": "null" } ], - "title": "Reason" + "title": "Reason", + "description": "Why this edit was made, up to 256 characters. Stored with the item." }, "action": { "type": "string", "const": "add", - "title": "Action" + "title": "Action", + "description": "Always \"add\" for this variant." }, "type": { "type": "string", @@ -2932,7 +3328,8 @@ "explicit_info", "implicit_traits" ], - "title": "Type" + "title": "Type", + "description": "Which profile item this edit targets \u2014 \"explicit_info\" (a stated fact, needing `category` + `description`) or \"implicit_traits\" (an inferred trait, needing `trait` + `description`)." }, "data": { "anyOf": [ @@ -2943,7 +3340,8 @@ "$ref": "#/components/schemas/ImplicitTraitData" } ], - "title": "Data" + "title": "Data", + "description": "The item to add. Its required keys depend on `type`; other keys (evidence, sources, basis, \u2026) ride through untouched." } }, "additionalProperties": false, @@ -2960,35 +3358,43 @@ "properties": { "id": { "type": "string", - "title": "Id" + "title": "Id", + "description": "Agent-case id." }, "app_id": { "type": "string", - "title": "App Id" + "title": "App Id", + "description": "The business-semantic scope this case was written under." }, "project_id": { "type": "string", - "title": "Project Id" + "title": "Project Id", + "description": "Second half of that scope." }, "agent_id": { "type": "string", - "title": "Agent Id" + "title": "Agent Id", + "description": "The agent that owns this case." }, "session_id": { "type": "string", - "title": "Session Id" + "title": "Session Id", + "description": "The session whose trajectory the case was distilled from." }, "task_intent": { "type": "string", - "title": "Task Intent" + "title": "Task Intent", + "description": "What the agent was trying to do in that trajectory." }, "approach": { "type": "string", - "title": "Approach" + "title": "Approach", + "description": "How it went about it \u2014 the reusable part of the case." }, "quality_score": { "type": "number", - "title": "Quality Score" + "title": "Quality Score", + "description": "How good this case is judged to be. Nominally 0.0\u20131.0 with 0.5 as the no-opinion default, but the value is the extractor's own and nothing on the write path enforces the range \u2014 treat an out-of-range number as possible. One threshold is real: a case scoring below 0.2 is never distilled into a skill." }, "key_insight": { "anyOf": [ @@ -2999,12 +3405,14 @@ "type": "null" } ], - "title": "Key Insight" + "title": "Key Insight", + "description": "The single takeaway distilled from the trajectory, when there is one." }, "timestamp": { "type": "string", "format": "date-time", - "title": "Timestamp" + "title": "Timestamp", + "description": "When the trajectory happened (ISO 8601)." } }, "type": "object", @@ -3025,46 +3433,82 @@ "properties": { "id": { "type": "string", - "title": "Id" + "title": "Id", + "description": "Agent-skill id." }, "app_id": { "type": "string", - "title": "App Id" + "title": "App Id", + "description": "The business-semantic scope this skill was written under." }, "project_id": { "type": "string", - "title": "Project Id" + "title": "Project Id", + "description": "Second half of that scope." }, "agent_id": { "type": "string", - "title": "Agent Id" + "title": "Agent Id", + "description": "The agent that owns this skill." }, "name": { "type": "string", - "title": "Name" + "title": "Name", + "description": "The skill's name." }, "description": { "type": "string", - "title": "Description" + "title": "Description", + "description": "What the skill is for, in a sentence." }, "content": { "type": "string", - "title": "Content" + "title": "Content", + "description": "The skill itself \u2014 the reusable procedure, ready to put in a prompt." }, "confidence": { "type": "number", - "title": "Confidence" + "title": "Confidence", + "description": "How much the distillation trusts this skill. Nominally 0.0\u20131.0, defaulting to 0.0 before anything scores it; the range is not enforced on the write path. Nothing in retrieval filters on it today, and how it divides labour with `maturity_score` is still open \u2014 so do not build a threshold on it yet." }, "maturity_score": { "type": "number", - "title": "Maturity Score" + "title": "Maturity Score", + "description": "How well-established the skill is. Nominally 0.0\u20131.0 and unenforced, and \u2014 unlike the other two scores \u2014 its default is 0.6 rather than 0.0, chosen so an unscored skill starts mid-optimistic. The cost is that an unscored 0.6 is indistinguishable from a scored 0.6: there is no \"not evaluated\" sentinel, and maturity scoring is skipped by default. Filtering near 0.6 is therefore unreliable." }, "source_case_ids": { "items": { "type": "string" }, "type": "array", - "title": "Source Case Ids" + "title": "Source Case Ids", + "description": "The agent cases this skill was distilled from. Fetch them for the underlying evidence." + }, + "created_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Created At", + "description": "When the skill was first distilled." + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At", + "description": "When it was last reinforced or rewritten." } }, "type": "object", @@ -3085,11 +3529,13 @@ "properties": { "id": { "type": "string", - "title": "Id" + "title": "Id", + "description": "Atomic-fact id." }, "content": { "type": "string", - "title": "Content" + "title": "Content", + "description": "The fact itself, as a single statement." } }, "type": "object", @@ -3133,17 +3579,20 @@ }, "name": { "type": "string", - "title": "Name" + "title": "Name", + "description": "The category's display name." }, "description": { "type": "string", "title": "Description", - "default": "" + "default": "", + "description": "What belongs in this category. The classifier matches documents against this text, so it is functional, not decorative." }, "document_count": { "type": "integer", "title": "Document Count", - "default": 0 + "default": 0, + "description": "How many documents are filed under it." }, "scope": { "type": "string", @@ -3193,7 +3642,8 @@ "$ref": "#/components/schemas/CategoryData" }, "type": "array", - "title": "Categories" + "title": "Categories", + "description": "Every category available in this knowledge base \u2014 the ones created here plus the tenant-global presets." } }, "type": "object", @@ -3212,7 +3662,8 @@ "type": "null" } ], - "title": "Name" + "title": "Name", + "description": "New category name, 1\u201350 characters. Omit to leave it unchanged." }, "description": { "anyOf": [ @@ -3223,7 +3674,8 @@ "type": "null" } ], - "title": "Description" + "title": "Description", + "description": "New category description. This is what the classifier matches documents against, so it is worth keeping accurate. Omit to leave it unchanged." } }, "additionalProperties": false, @@ -3243,7 +3695,8 @@ "html", "email" ], - "title": "Type" + "title": "Type", + "description": "What this item is: \"text\", \"image\", \"audio\", \"doc\", \"pdf\", \"html\" or \"email\". It selects how the content is parsed, so it must match the payload." }, "text": { "anyOf": [ @@ -3254,7 +3707,8 @@ "type": "null" } ], - "title": "Text" + "title": "Text", + "description": "Inline text, used when `type` is \"text\"." }, "source": { "anyOf": [ @@ -3265,7 +3719,8 @@ "type": "null" } ], - "title": "Source" + "title": "Source", + "description": "Where the item came from \u2014 an origin label carried through to the memory." }, "base64": { "anyOf": [ @@ -3276,7 +3731,8 @@ "type": "null" } ], - "title": "Base64" + "title": "Base64", + "description": "The item's bytes inline, base64-encoded. NOTE: a non-text item that carries only `base64` is skipped by the parse step \u2014 the parser reads bytes from object storage \u2014 so use `uri` for anything that must actually be understood." }, "uri": { "anyOf": [ @@ -3287,7 +3743,8 @@ "type": "null" } ], - "title": "Uri" + "title": "Uri", + "description": "Pointer to already-uploaded bytes: the object key returned by POST /api/v2/object/sign. This is the only form of a non-text item that gets parsed." }, "ext": { "anyOf": [ @@ -3298,7 +3755,8 @@ "type": "null" } ], - "title": "Ext" + "title": "Ext", + "description": "File extension of the referenced content, e.g. \"pdf\" \u2014 used when the uri carries none." }, "name": { "anyOf": [ @@ -3309,7 +3767,8 @@ "type": "null" } ], - "title": "Name" + "title": "Name", + "description": "Original file name, kept for display and passed to the parser." }, "source_info": { "anyOf": [ @@ -3321,7 +3780,8 @@ "type": "null" } ], - "title": "Source Info" + "title": "Source Info", + "description": "Free-form provenance metadata stored alongside the item; a `size` here is passed to the parser." }, "extras": { "anyOf": [ @@ -3333,7 +3793,8 @@ "type": "null" } ], - "title": "Extras" + "title": "Extras", + "description": "Free-form extra fields, passed through untouched." } }, "type": "object", @@ -3369,12 +3830,14 @@ "app_id": { "type": "string", "title": "App Id", - "default": "default" + "default": "default", + "description": "Scope to delete within, defaulting to \"default\"." }, "project_id": { "type": "string", "title": "Project Id", - "default": "default" + "default": "default", + "description": "Second half of the scope, defaulting to \"default\"." }, "user_id": { "anyOf": [ @@ -3386,7 +3849,8 @@ "type": "null" } ], - "title": "User Id" + "title": "User Id", + "description": "Delete this user's memories. At least one of `user_id` / `agent_id` / `session_id` must be given, and `user_id` / `agent_id` cannot be combined." }, "agent_id": { "anyOf": [ @@ -3398,7 +3862,8 @@ "type": "null" } ], - "title": "Agent Id" + "title": "Agent Id", + "description": "Delete this agent's memories. Cannot be combined with `user_id`." }, "session_id": { "anyOf": [ @@ -3409,7 +3874,8 @@ "type": "null" } ], - "title": "Session Id" + "title": "Session Id", + "description": "Delete the memories extracted from this session. May be given alone, without an owner." } }, "additionalProperties": false, @@ -3432,12 +3898,14 @@ "type": "null" } ], - "title": "Reason" + "title": "Reason", + "description": "Why this edit was made, up to 256 characters." }, "action": { "type": "string", "const": "delete", - "title": "Action" + "title": "Action", + "description": "Always \"delete\" for this variant." }, "type": { "type": "string", @@ -3445,11 +3913,13 @@ "explicit_info", "implicit_traits" ], - "title": "Type" + "title": "Type", + "description": "Which profile item this edit targets \u2014 \"explicit_info\" or \"implicit_traits\". It must match the `item_id` prefix." }, "item_id": { "type": "string", - "title": "Item Id" + "title": "Item Id", + "description": "The item to delete. Its prefix must match the item type (\"ei_\" / \"it_\") followed by 24 hex characters." } }, "additionalProperties": false, @@ -3471,12 +3941,14 @@ }, "kb_id": { "type": "string", - "title": "Kb Id" + "title": "Kb Id", + "description": "The knowledge base this document belongs to." }, "category_id": { "type": "string", "title": "Category Id", - "default": "" + "default": "", + "description": "The category it is filed under; empty when it is uncategorized." }, "category_name": { "anyOf": [ @@ -3492,7 +3964,8 @@ }, "title": { "type": "string", - "title": "Title" + "title": "Title", + "description": "The document's title." }, "summary": { "anyOf": [ @@ -3503,7 +3976,8 @@ "type": "null" } ], - "title": "Summary" + "title": "Summary", + "description": "Document-level summary produced during ingest." }, "source_name": { "anyOf": [ @@ -3514,7 +3988,8 @@ "type": "null" } ], - "title": "Source Name" + "title": "Source Name", + "description": "Name of the file or source it was ingested from." }, "source_type": { "anyOf": [ @@ -3525,7 +4000,16 @@ "type": "null" } ], - "title": "Source Type" + "title": "Source Type", + "description": "What kind of source it came from." + }, + "tags": { + "items": { + "$ref": "#/components/schemas/TagRef" + }, + "type": "array", + "title": "Tags", + "description": "Distinct opaque ids from the document's read-only topic-tag union. Cloud leaves name unset; KHS may validate and expand display names. This document aggregate is read-only and carries no topic ownership field." }, "topic_count": { "type": "integer", @@ -3543,7 +4027,8 @@ "type": "null" } ], - "title": "Created At" + "title": "Created At", + "description": "When the document was created." }, "updated_at": { "anyOf": [ @@ -3555,14 +4040,16 @@ "type": "null" } ], - "title": "Updated At" + "title": "Updated At", + "description": "When it last changed." } }, "type": "object", "required": [ "id", "kb_id", - "title" + "title", + "tags" ], "title": "DocData", "description": "A document as returned to clients. ``topic_count`` = the node_count (>0 = ingested).\n\nContract note \u2014 ``topic_count`` vs ``GET .../topics``: the count is of REAL topics and\nexcludes the synthetic document-root node, while the topics list INCLUDES it. So\n``len(topics) == topic_count + 1`` for an ingested document. See ``TopicListData``." @@ -3598,7 +4085,8 @@ "title": { "type": "string", "minLength": 1, - "title": "Title" + "title": "Title", + "description": "Human-readable name for the document. Until the async ingest finishes this is the only handle the caller has \u2014 the document id is minted downstream, so GET .../documents is resolved by title." }, "content": { "$ref": "#/components/schemas/ContentItem", @@ -3655,12 +4143,14 @@ "$ref": "#/components/schemas/DocData" }, "type": "array", - "title": "Documents" + "title": "Documents", + "description": "This page of documents." }, "total": { "type": "integer", "title": "Total", - "default": 0 + "default": 0, + "description": "How many documents match, across all pages." } }, "type": "object", @@ -3678,7 +4168,8 @@ "type": "null" } ], - "title": "Title" + "title": "Title", + "description": "New title. Omit to leave it unchanged." }, "category_id": { "anyOf": [ @@ -3689,7 +4180,8 @@ "type": "null" } ], - "title": "Category Id" + "title": "Category Id", + "description": "Re-file the document under another category. Omit to leave it where it is; content is unaffected either way." } }, "additionalProperties": false, @@ -3700,14 +4192,16 @@ "properties": { "id": { "type": "string", - "title": "Id" + "title": "Id", + "description": "The document that was patched." }, "updated_fields": { "items": { "type": "string" }, "type": "array", - "title": "Updated Fields" + "title": "Updated Fields", + "description": "Which fields actually changed \u2014 omitted fields are not listed." }, "updated_at": { "anyOf": [ @@ -3719,7 +4213,8 @@ "type": "null" } ], - "title": "Updated At" + "title": "Updated At", + "description": "When the change was applied." } }, "type": "object", @@ -3732,12 +4227,14 @@ "properties": { "doc_id": { "type": "string", - "title": "Doc Id" + "title": "Doc Id", + "description": "The parent document's id." }, "title": { "type": "string", "title": "Title", - "default": "" + "default": "", + "description": "Its title." }, "summary": { "anyOf": [ @@ -3748,7 +4245,8 @@ "type": "null" } ], - "title": "Summary" + "title": "Summary", + "description": "Its document-level summary." } }, "type": "object", @@ -3762,27 +4260,32 @@ "properties": { "user_id": { "type": "string", - "title": "User Id" + "title": "User Id", + "description": "The user whose profile was edited." }, "version": { "type": "integer", - "title": "Version" + "title": "Version", + "description": "The profile's version after this edit. It advances every time the profile changes." }, "applied": { "type": "integer", - "title": "Applied" + "title": "Applied", + "description": "How many of the submitted operations took effect." }, "results": { "items": { "$ref": "#/components/schemas/EditResultItem" }, "type": "array", - "title": "Results" + "title": "Results", + "description": "Per-operation outcome, in submission order \u2014 check this rather than assuming all applied." }, "profile": { "additionalProperties": true, "type": "object", - "title": "Profile" + "title": "Profile", + "description": "The profile as it stands after the edit, so no follow-up read is needed." } }, "type": "object", @@ -3799,23 +4302,27 @@ "app_id": { "type": "string", "title": "App Id", - "default": "default" + "default": "default", + "description": "Scope the profile lives in, defaulting to \"default\"." }, "project_id": { "type": "string", "title": "Project Id", - "default": "default" + "default": "default", + "description": "Second half of the scope, defaulting to \"default\"." }, "user_id": { "type": "string", "minLength": 1, - "title": "User Id" + "title": "User Id", + "description": "The user whose profile is being edited." }, "memory_type": { "type": "string", "const": "profile", "title": "Memory Type", - "default": "profile" + "default": "profile", + "description": "Pinned to \"profile\" \u2014 this endpoint edits nothing else." }, "operations": { "items": { @@ -3842,7 +4349,8 @@ "type": "array", "maxItems": 50, "minItems": 1, - "title": "Operations" + "title": "Operations", + "description": "1 to 50 edits applied in one call. \"add\" mints the item id and must not carry one; \"update\" and \"delete\" require an `item_id` whose prefix matches the item type (\"ei_\" for explicit_info, \"it_\" for implicit_traits). Each operation's outcome is reported separately, so one can be rejected while the rest apply." } }, "additionalProperties": false, @@ -3872,15 +4380,18 @@ "properties": { "op_index": { "type": "integer", - "title": "Op Index" + "title": "Op Index", + "description": "Which submitted operation this is, by 0-based position in the request." }, "action": { "type": "string", - "title": "Action" + "title": "Action", + "description": "The action that was attempted \u2014 \"add\", \"update\" or \"delete\"." }, "type": { "type": "string", - "title": "Type" + "title": "Type", + "description": "The profile item type it targeted." }, "status": { "type": "string", @@ -3888,7 +4399,8 @@ "applied", "rejected" ], - "title": "Status" + "title": "Status", + "description": "\"applied\" or \"rejected\". A rejected operation does not fail the request." }, "item_id": { "anyOf": [ @@ -3899,7 +4411,8 @@ "type": "null" } ], - "title": "Item Id" + "title": "Item Id", + "description": "The item that was updated or deleted." }, "new_item_id": { "anyOf": [ @@ -3910,7 +4423,8 @@ "type": "null" } ], - "title": "New Item Id" + "title": "New Item Id", + "description": "The id minted for an added item \u2014 this is how a caller learns it." }, "error": { "anyOf": [ @@ -3921,7 +4435,8 @@ "type": "null" } ], - "title": "Error" + "title": "Error", + "description": "Why this operation was rejected, when it was." } }, "type": "object", @@ -3938,15 +4453,18 @@ "properties": { "id": { "type": "string", - "title": "Id" + "title": "Id", + "description": "Episode id. Use it to bind tags or to fetch this episode again." }, "app_id": { "type": "string", - "title": "App Id" + "title": "App Id", + "description": "The business-semantic scope this memory was written under." }, "project_id": { "type": "string", - "title": "Project Id" + "title": "Project Id", + "description": "Second half of that scope." }, "user_id": { "anyOf": [ @@ -3957,7 +4475,8 @@ "type": "null" } ], - "title": "User Id" + "title": "User Id", + "description": "The user this episode belongs to. Null on an episode merged from several owners." }, "session_id": { "anyOf": [ @@ -3968,31 +4487,37 @@ "type": "null" } ], - "title": "Session Id" + "title": "Session Id", + "description": "The session it was extracted from. Null when the episode merges more than one session." }, "timestamp": { "type": "string", "format": "date-time", - "title": "Timestamp" + "title": "Timestamp", + "description": "When the remembered exchange happened (ISO 8601), not when it was extracted." }, "sender_ids": { "items": { "type": "string" }, "type": "array", - "title": "Sender Ids" + "title": "Sender Ids", + "description": "The senders that appear in the source exchange." }, "summary": { "type": "string", - "title": "Summary" + "title": "Summary", + "description": "Short summary of the episode \u2014 what a result list should show." }, "subject": { "type": "string", - "title": "Subject" + "title": "Subject", + "description": "What the episode is about, in a few words." }, "episode": { "type": "string", - "title": "Episode" + "title": "Episode", + "description": "The episode's stored narrative body. This is the indexed, searchable text." }, "readable_episode": { "anyOf": [ @@ -4003,25 +4528,29 @@ "type": "null" } ], - "title": "Readable Episode" + "title": "Readable Episode", + "description": "Human-readable rendering of `episode`, for display only \u2014 never indexed, filtered or scored. Present as a key but null unless the request asked for it (and the tenant is enabled for it); fall back to `episode` when it is null." }, "type": { "type": "string", - "title": "Type" + "title": "Type", + "description": "How the episode was produced \u2014 \"Conversation\" or \"AgentConversation\"." }, "atomic_facts": { "items": { "$ref": "#/components/schemas/AtomicFactItem" }, "type": "array", - "title": "Atomic Facts" + "title": "Atomic Facts", + "description": "The individual facts extracted from this episode, nested rather than returned separately." }, "tags": { "items": { "type": "string" }, "type": "array", - "title": "Tags" + "title": "Tags", + "description": "Tags attached through /api/v2/memory/tag/*." } }, "type": "object", @@ -4037,18 +4566,61 @@ ], "title": "EpisodeItem" }, + "ErrorBody": { + "properties": { + "code": { + "type": "string", + "title": "Code", + "description": "Domain error code" + }, + "message": { + "type": "string", + "title": "Message", + "description": "Human-readable error message" + } + }, + "type": "object", + "required": [ + "code", + "message" + ], + "title": "ErrorBody", + "description": "Nested error object inside the error envelope." + }, + "ErrorEnvelope": { + "properties": { + "request_id": { + "type": "string", + "title": "Request Id", + "description": "Request trace id" + }, + "error": { + "$ref": "#/components/schemas/ErrorBody", + "description": "Error detail (code + message)" + } + }, + "type": "object", + "required": [ + "request_id", + "error" + ], + "title": "ErrorEnvelope", + "description": "v1 error envelope (spec \u00a71): ``{request_id, error:{code,message}}``.\n\nUsed by ``global_exception_handler`` for both HTTPException (carrying the\ndomain code via ``InvocationHttpError``) and unhandled exceptions." + }, "ExplicitInfoData": { "properties": { "category": { "type": "string", "minLength": 1, - "title": "Category" + "title": "Category", + "description": "What kind of fact this is, e.g. \"hobby\". Required, non-empty." }, "description": { "type": "string", "maxLength": 4000, "minLength": 1, - "title": "Description" + "title": "Description", + "description": "The fact itself, up to 4000 characters. Required, non-empty." } }, "additionalProperties": true, @@ -4072,7 +4644,8 @@ "type": "null" } ], - "title": "Category" + "title": "Category", + "description": "New category. At least one of `category` / `description` must be present." }, "description": { "anyOf": [ @@ -4085,7 +4658,8 @@ "type": "null" } ], - "title": "Description" + "title": "Description", + "description": "New text, up to 4000 characters. Fields left out keep their stored value." } }, "additionalProperties": true, @@ -4107,7 +4681,8 @@ "type": "null" } ], - "title": "And" + "title": "And", + "description": "Nested conditions that must all hold." }, "OR": { "anyOf": [ @@ -4121,7 +4696,8 @@ "type": "null" } ], - "title": "Or" + "title": "Or", + "description": "Nested conditions of which at least one must hold." } }, "additionalProperties": true, @@ -4137,7 +4713,8 @@ "extracted", "no_extraction" ], - "title": "Status" + "title": "Status", + "description": "\"extracted\" when the flush distilled new memories, \"no_extraction\" when there was nothing to extract \u2014 including the case of an async add still queued." } }, "type": "object", @@ -4151,17 +4728,20 @@ "app_id": { "type": "string", "title": "App Id", - "default": "default" + "default": "default", + "description": "Scope the session lives in, defaulting to \"default\"." }, "project_id": { "type": "string", "title": "Project Id", - "default": "default" + "default": "default", + "description": "Second half of the scope, defaulting to \"default\"." }, "session_id": { "type": "string", "minLength": 1, - "title": "Session Id" + "title": "Session Id", + "description": "The session to extract from. Only messages already accumulated for this session are considered, so a still-queued async add yields \"no_extraction\"." } }, "type": "object", @@ -4177,38 +4757,44 @@ "$ref": "#/components/schemas/EpisodeItem" }, "type": "array", - "title": "Episodes" + "title": "Episodes", + "description": "Episodes, when `memory_type` was \"episode\". Empty otherwise." }, "profiles": { "items": { "$ref": "#/components/schemas/ProfileItem" }, "type": "array", - "title": "Profiles" + "title": "Profiles", + "description": "Profiles, when `memory_type` was \"profile\". Empty otherwise." }, "agent_cases": { "items": { "$ref": "#/components/schemas/AgentCaseItem" }, "type": "array", - "title": "Agent Cases" + "title": "Agent Cases", + "description": "Agent cases, when `memory_type` was \"agent_case\". Empty otherwise." }, "agent_skills": { "items": { "$ref": "#/components/schemas/AgentSkillItem" }, "type": "array", - "title": "Agent Skills" + "title": "Agent Skills", + "description": "Agent skills, when `memory_type` was \"agent_skill\". Empty otherwise." }, "total_count": { "type": "integer", "title": "Total Count", - "default": 0 + "default": 0, + "description": "How many memories match the request in total, across all pages." }, "count": { "type": "integer", "title": "Count", - "default": 0 + "default": 0, + "description": "How many are in this page." } }, "type": "object", @@ -4219,12 +4805,14 @@ "app_id": { "type": "string", "title": "App Id", - "default": "default" + "default": "default", + "description": "Scope to read from, defaulting to \"default\". Must match the pair used on write." }, "project_id": { "type": "string", "title": "Project Id", - "default": "default" + "default": "default", + "description": "Second half of the scope, defaulting to \"default\"." }, "user_id": { "anyOf": [ @@ -4236,7 +4824,8 @@ "type": "null" } ], - "title": "User Id" + "title": "User Id", + "description": "Read one user's memories. Exactly one of `user_id` / `agent_id` is required, and a user owner may only ask for \"episode\" or \"profile\"." }, "agent_id": { "anyOf": [ @@ -4248,7 +4837,8 @@ "type": "null" } ], - "title": "Agent Id" + "title": "Agent Id", + "description": "Read one agent's memories. Exactly one of `user_id` / `agent_id` is required, and an agent owner may only ask for \"agent_case\" or \"agent_skill\"." }, "memory_type": { "type": "string", @@ -4258,20 +4848,23 @@ "agent_case", "agent_skill" ], - "title": "Memory Type" + "title": "Memory Type", + "description": "Which kind of memory to list: \"episode\" (narrative summaries of past sessions), \"profile\" (stable identity and preferences), \"agent_case\" (a distilled past trajectory) or \"agent_skill\" (a reusable skill). It must match the owner \u2014 the mismatched pairings are rejected with 422." }, "page": { "type": "integer", "minimum": 1.0, "title": "Page", - "default": 1 + "default": 1, + "description": "1-based page number." }, "page_size": { "type": "integer", "maximum": 100.0, "minimum": 1.0, "title": "Page Size", - "default": 20 + "default": 20, + "description": "Items per page, 1 to 100 (default 20)." }, "sort_by": { "type": "string", @@ -4280,7 +4873,8 @@ "updated_at" ], "title": "Sort By", - "default": "timestamp" + "default": "timestamp", + "description": "Order by \"timestamp\" (when the memory happened, default) or \"updated_at\" (when it was last written). Profiles and agent skills have no temporal column and always sort by \"updated_at\"." }, "sort_order": { "type": "string", @@ -4289,12 +4883,14 @@ "desc" ], "title": "Sort Order", - "default": "desc" + "default": "desc", + "description": "\"desc\" (default, newest first) or \"asc\"." }, "with_readable_episode": { "type": "boolean", "title": "With Readable Episode", - "default": false + "default": false, + "description": "Attach a human-readable rendering to each returned episode, for display only. Ignored for every non-episode `memory_type` rather than rejected." }, "filters": { "anyOf": [ @@ -4304,7 +4900,8 @@ { "type": "null" } - ] + ], + "description": "Optional filter tree applied to the listing; same shape as on search." } }, "additionalProperties": false, @@ -4327,7 +4924,8 @@ "$ref": "#/components/schemas/ValidationError" }, "type": "array", - "title": "Detail" + "title": "Detail", + "description": "One entry per field that failed validation." } }, "type": "object", @@ -4338,13 +4936,15 @@ "trait": { "type": "string", "minLength": 1, - "title": "Trait" + "title": "Trait", + "description": "The inferred trait's name. Required, non-empty." }, "description": { "type": "string", "maxLength": 4000, "minLength": 1, - "title": "Description" + "title": "Description", + "description": "What the trait means and how it shows up, up to 4000 characters." } }, "additionalProperties": true, @@ -4368,7 +4968,8 @@ "type": "null" } ], - "title": "Trait" + "title": "Trait", + "description": "New trait name. At least one of `trait` / `description` must be present." }, "description": { "anyOf": [ @@ -4381,7 +4982,8 @@ "type": "null" } ], - "title": "Description" + "title": "Description", + "description": "New text, up to 4000 characters. Fields left out keep their stored value." } }, "additionalProperties": true, @@ -4434,12 +5036,14 @@ }, "name": { "type": "string", - "title": "Name" + "title": "Name", + "description": "The knowledge base's display name." }, "description": { "type": "string", "title": "Description", - "default": "" + "default": "", + "description": "Its description." }, "owner_id": { "anyOf": [ @@ -4450,12 +5054,14 @@ "type": "null" } ], - "title": "Owner Id" + "title": "Owner Id", + "description": "The owner it was created for, if any. A soft partition for organising bases \u2014 not a security boundary." }, "document_count": { "type": "integer", "title": "Document Count", - "default": 0 + "default": 0, + "description": "How many documents it holds." }, "created_at": { "anyOf": [ @@ -4467,7 +5073,8 @@ "type": "null" } ], - "title": "Created At" + "title": "Created At", + "description": "When it was created." }, "updated_at": { "anyOf": [ @@ -4479,7 +5086,8 @@ "type": "null" } ], - "title": "Updated At" + "title": "Updated At", + "description": "When its metadata last changed." } }, "type": "object", @@ -4517,12 +5125,14 @@ "$ref": "#/components/schemas/KbData" }, "type": "array", - "title": "Knowledge Bases" + "title": "Knowledge Bases", + "description": "This page of knowledge bases." }, "total": { "type": "integer", "title": "Total", - "default": 0 + "default": 0, + "description": "How many exist in total, across all pages." } }, "type": "object", @@ -4541,7 +5151,8 @@ "type": "null" } ], - "title": "Name" + "title": "Name", + "description": "New name, 1\u2013100 characters. Omit to leave it unchanged." }, "description": { "anyOf": [ @@ -4552,7 +5163,8 @@ "type": "null" } ], - "title": "Description" + "title": "Description", + "description": "New description. Omit to leave it unchanged." } }, "additionalProperties": false, @@ -4567,20 +5179,26 @@ "$ref": "#/components/schemas/SearchHit" }, "type": "array", - "title": "Hits" + "title": "Hits", + "description": "Matching topics, most relevant first." }, "total": { "type": "integer", "title": "Total", - "default": 0 + "description": "How many topics matched." }, "took_ms": { "type": "number", "title": "Took Ms", - "default": 0.0 + "description": "How long the search took, in milliseconds." } }, "type": "object", + "required": [ + "hits", + "total", + "took_ms" + ], "title": "KbSearchData", "description": "Knowledge search response payload. Prefixed ``Kb`` to stay distinct from\n``memory_api.SearchData`` \u2014 two same-named models under ``SuccessEnvelope[...]`` collide\nto a non-deterministic OpenAPI component name (see openapi-sync / check-openapi)." }, @@ -4588,7 +5206,8 @@ "properties": { "sender_id": { "type": "string", - "title": "Sender Id" + "title": "Sender Id", + "description": "Who produced this message \u2014 the user id for a user turn, the agent id for an assistant turn. This is the identifier /api/v2/memory/get and /api/v2/memory/search later scope by (`user_id` / `agent_id`)." }, "sender_name": { "anyOf": [ @@ -4599,7 +5218,8 @@ "type": "null" } ], - "title": "Sender Name" + "title": "Sender Name", + "description": "Optional display name for the sender; does not affect scoping." }, "role": { "type": "string", @@ -4608,11 +5228,13 @@ "assistant", "tool" ], - "title": "Role" + "title": "Role", + "description": "Turn type: \"user\", \"assistant\", or \"tool\" for a tool result. An agent trajectory uses the OpenAI shape \u2014 an \"assistant\" message carrying `tool_calls`, followed by a \"tool\" message carrying `tool_call_id`." }, "timestamp": { "type": "integer", - "title": "Timestamp" + "title": "Timestamp", + "description": "When the message was produced, as a UNIX timestamp in MILLISECONDS. A seconds-scale value is rejected with 422 rather than silently rescaled, because a window mixing the two would mis-order and mis-split." }, "content": { "anyOf": [ @@ -4626,7 +5248,8 @@ "type": "array" } ], - "title": "Content" + "title": "Content", + "description": "The message body: a plain string (shorthand for a single text item), or a list of content items for multimodal input." }, "tool_calls": { "anyOf": [ @@ -4640,7 +5263,8 @@ "type": "null" } ], - "title": "Tool Calls" + "title": "Tool Calls", + "description": "Tool calls issued by an assistant turn, in the OpenAI tool-calling shape. Only meaningful when `role` is \"assistant\"." }, "tool_call_id": { "anyOf": [ @@ -4651,85 +5275,200 @@ "type": "null" } ], - "title": "Tool Call Id" + "title": "Tool Call Id", + "description": "The id of the assistant tool call this result answers. Required when `role` is \"tool\"." + } + }, + "type": "object", + "required": [ + "sender_id", + "role", + "timestamp", + "content" + ], + "title": "MessageItem", + "description": "One message in an /add batch (spec \u00a72). ``content`` accepts a plain string\n(shorthand for a single text ContentItem) or an explicit ContentItem list." + }, + "ProfileItem": { + "properties": { + "id": { + "type": "string", + "title": "Id", + "description": "Profile id." + }, + "app_id": { + "type": "string", + "title": "App Id", + "description": "The business-semantic scope this profile was written under." + }, + "project_id": { + "type": "string", + "title": "Project Id", + "description": "Second half of that scope." + }, + "user_id": { + "type": "string", + "title": "User Id", + "description": "The user this profile describes." + }, + "profile_data": { + "additionalProperties": true, + "type": "object", + "title": "Profile Data", + "description": "The profile itself \u2014 the explicit_info and implicit_traits items maintained by extraction and by /api/v2/memory/edit. Each item's id is what an edit operation targets." + }, + "created_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Created At", + "description": "When the profile was first created." + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At", + "description": "When it last changed." + } + }, + "type": "object", + "required": [ + "id", + "app_id", + "project_id", + "user_id" + ], + "title": "ProfileItem" + }, + "RelatedTagUsageBody": { + "properties": { + "tag_ids": { + "items": { + "type": "string", + "maxLength": 128, + "minLength": 1, + "description": "Opaque semantic tag id" + }, + "type": "array", + "maxItems": 10000, + "minItems": 1, + "title": "Tag Ids", + "description": "Candidate opaque tag ids to check against the current live tree" } }, + "additionalProperties": false, "type": "object", "required": [ - "sender_id", - "role", - "timestamp", - "content" + "tag_ids" ], - "title": "MessageItem", - "description": "One message in an /add batch (spec \u00a72). ``content`` accepts a plain string\n(shorthand for a single text ContentItem) or an explicit ContentItem list." + "title": "RelatedTagUsageBody", + "description": "Candidate tag ids for ``POST /knowledge_bases/{kb_id}/tags``." }, - "ProfileItem": { + "RelatedTagUsageItem": { "properties": { "id": { "type": "string", - "title": "Id" - }, - "app_id": { - "type": "string", - "title": "App Id" - }, - "project_id": { - "type": "string", - "title": "Project Id" - }, - "user_id": { - "type": "string", - "title": "User Id" + "maxLength": 128, + "minLength": 1, + "title": "Id", + "description": "Opaque semantic tag id" }, - "profile_data": { - "additionalProperties": true, - "type": "object", - "title": "Profile Data" + "document_count": { + "type": "integer", + "exclusiveMinimum": 0.0, + "title": "Document Count", + "description": "Distinct live documents using this tag" } }, + "additionalProperties": false, "type": "object", "required": [ "id", - "app_id", - "project_id", - "user_id" + "document_count" ], - "title": "ProfileItem" + "title": "RelatedTagUsageItem", + "description": "One opaque tag id and its distinct live-document usage in the current KB." + }, + "RelatedTagUsageListData": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/RelatedTagUsageItem" + }, + "type": "array", + "title": "Items", + "description": "One entry per requested tag id that is actually in use, sorted by id." + }, + "total": { + "type": "integer", + "minimum": 0.0, + "title": "Total", + "description": "Number of returned distinct tag ids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "items", + "total" + ], + "title": "RelatedTagUsageListData", + "description": "Complete non-zero usage result for the requested candidate tag ids." }, "SearchAgentCaseItem": { "properties": { "id": { "type": "string", - "title": "Id" + "title": "Id", + "description": "Agent-case id." }, "app_id": { "type": "string", - "title": "App Id" + "title": "App Id", + "description": "The business-semantic scope this case was written under." }, "project_id": { "type": "string", - "title": "Project Id" + "title": "Project Id", + "description": "Second half of that scope." }, "agent_id": { "type": "string", - "title": "Agent Id" + "title": "Agent Id", + "description": "The agent that owns this case." }, "session_id": { "type": "string", - "title": "Session Id" + "title": "Session Id", + "description": "The session whose trajectory the case was distilled from." }, "task_intent": { "type": "string", - "title": "Task Intent" + "title": "Task Intent", + "description": "What the agent was trying to do in that trajectory." }, "approach": { "type": "string", - "title": "Approach" + "title": "Approach", + "description": "How it went about it \u2014 the reusable part of the case." }, "quality_score": { "type": "number", - "title": "Quality Score" + "title": "Quality Score", + "description": "How good this case is judged to be. Nominally 0.0\u20131.0 with 0.5 as the no-opinion default, but the value is the extractor's own and nothing on the write path enforces the range \u2014 treat an out-of-range number as possible. One threshold is real: a case scoring below 0.2 is never distilled into a skill." }, "key_insight": { "anyOf": [ @@ -4740,16 +5479,19 @@ "type": "null" } ], - "title": "Key Insight" + "title": "Key Insight", + "description": "The single takeaway distilled from the trajectory, when there is one." }, "timestamp": { "type": "string", "format": "date-time", - "title": "Timestamp" + "title": "Timestamp", + "description": "When the trajectory happened (ISO 8601)." }, "score": { "type": "number", - "title": "Score" + "title": "Score", + "description": "Relevance of this case to the query." } }, "type": "object", @@ -4771,50 +5513,87 @@ "properties": { "id": { "type": "string", - "title": "Id" + "title": "Id", + "description": "Agent-skill id." }, "app_id": { "type": "string", - "title": "App Id" + "title": "App Id", + "description": "The business-semantic scope this skill was written under." }, "project_id": { "type": "string", - "title": "Project Id" + "title": "Project Id", + "description": "Second half of that scope." }, "agent_id": { "type": "string", - "title": "Agent Id" + "title": "Agent Id", + "description": "The agent that owns this skill." }, "name": { "type": "string", - "title": "Name" + "title": "Name", + "description": "The skill's name." }, "description": { "type": "string", - "title": "Description" + "title": "Description", + "description": "What the skill is for, in a sentence." }, "content": { "type": "string", - "title": "Content" + "title": "Content", + "description": "The skill itself \u2014 the reusable procedure, ready to put in a prompt." }, "confidence": { "type": "number", - "title": "Confidence" + "title": "Confidence", + "description": "How much the distillation trusts this skill. Nominally 0.0\u20131.0, defaulting to 0.0 before anything scores it; the range is not enforced on the write path. Nothing in retrieval filters on it today, and how it divides labour with `maturity_score` is still open \u2014 so do not build a threshold on it yet." }, "maturity_score": { "type": "number", - "title": "Maturity Score" + "title": "Maturity Score", + "description": "How well-established the skill is. Nominally 0.0\u20131.0 and unenforced, and \u2014 unlike the other two scores \u2014 its default is 0.6 rather than 0.0, chosen so an unscored skill starts mid-optimistic. The cost is that an unscored 0.6 is indistinguishable from a scored 0.6: there is no \"not evaluated\" sentinel, and maturity scoring is skipped by default. Filtering near 0.6 is therefore unreliable." }, "source_case_ids": { "items": { "type": "string" }, "type": "array", - "title": "Source Case Ids" + "title": "Source Case Ids", + "description": "The agent cases this skill was distilled from. Fetch them for the underlying evidence." + }, + "created_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Created At", + "description": "When the skill was first distilled." + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At", + "description": "When it was last reinforced or rewritten." }, "score": { "type": "number", - "title": "Score" + "title": "Score", + "description": "Relevance of this skill to the query." } }, "type": "object", @@ -4836,15 +5615,18 @@ "properties": { "id": { "type": "string", - "title": "Id" + "title": "Id", + "description": "Atomic-fact id." }, "content": { "type": "string", - "title": "Content" + "title": "Content", + "description": "The fact itself, as a single statement." }, "score": { "type": "number", - "title": "Score" + "title": "Score", + "description": "Relevance of this fact to the query." } }, "type": "object", @@ -4858,10 +5640,17 @@ "SearchBody": { "properties": { "query": { - "type": "string", - "maxLength": 2000, - "minLength": 1, - "title": "Query" + "anyOf": [ + { + "type": "string", + "maxLength": 2000 + }, + { + "type": "null" + } + ], + "title": "Query", + "description": "What to retrieve against within this knowledge base, up to 2000 characters. Optional: omit it and pass `filters.tag_ids` to page through tagged topics instead, which skips retrieval entirely \u2014 every hit then scores 0.0." }, "method": { "type": "string", @@ -4871,14 +5660,23 @@ "hybrid" ], "title": "Method", - "default": "hybrid" + "default": "hybrid", + "description": "Retrieval strategy: \"keyword\" (lexical), \"vector\" (embedding similarity) or \"hybrid\" (default, both)." + }, + "page": { + "type": "integer", + "minimum": 1.0, + "title": "Page", + "description": "Filter-only page number; query search supports page 1 only", + "default": 1 }, "top_k": { "type": "integer", "maximum": 100.0, "minimum": 1.0, "title": "Top K", - "default": 10 + "default": 10, + "description": "Maximum number of topics to return, 1 to 100 (default 10). On a query search the server also bounds the result by its rerank pool \u2014 50 candidates by default \u2014 so asking for more than that returns what the pool held. On a filter-only request (tags without a query) it is the page size instead, and `page` walks the rest." }, "score_threshold": { "anyOf": [ @@ -4889,7 +5687,8 @@ "type": "null" } ], - "title": "Score Threshold" + "title": "Score Threshold", + "description": "Drop hits whose final score is below this. Mind what that score is: it is normalized within each response (see `score` on a hit), so this cuts a RELATIVE position in one result set, not an absolute relevance bar \u2014 a response whose hits are all poor still has a top hit near the top of the range. Two traps follow from the edge values: a filter-only request scores every hit 0.0, so any positive threshold empties it, and a failed rerank batch scores -100.0, which every positive threshold silently removes. Tune it against real results rather than from a BM25 or cosine intuition." }, "include": { "items": { @@ -4897,17 +5696,29 @@ }, "type": "array", "title": "Include", - "description": "e.g. ['content']" + "description": "e.g. ['content']", + "default": [] + }, + "boost_tag_ids": { + "items": { + "type": "string", + "maxLength": 128, + "minLength": 1, + "description": "Opaque semantic tag id" + }, + "type": "array", + "maxItems": 100, + "title": "Boost Tag Ids", + "description": "Reweight, do not filter: topics carrying these tags are pushed up, and topics without them still come back. Use `filters.tag_ids` when the intent is to exclude everything else.", + "default": [] }, "filters": { - "$ref": "#/components/schemas/SearchFilters" + "$ref": "#/components/schemas/SearchFilters", + "description": "Optional filters narrowing what is searched." } }, "additionalProperties": false, "type": "object", - "required": [ - "query" - ], "title": "SearchBody", "description": "POST body (kb_id rides the path, not the body)." }, @@ -4918,35 +5729,40 @@ "$ref": "#/components/schemas/SearchEpisodeItem" }, "type": "array", - "title": "Episodes" + "title": "Episodes", + "description": "Matching episodes, for a user owner. Always present, empty when not applicable." }, "profiles": { "items": { "$ref": "#/components/schemas/SearchProfileItem" }, "type": "array", - "title": "Profiles" + "title": "Profiles", + "description": "The user's profile, when `include_profile` asked for it." }, "agent_cases": { "items": { "$ref": "#/components/schemas/SearchAgentCaseItem" }, "type": "array", - "title": "Agent Cases" + "title": "Agent Cases", + "description": "Matching agent cases, for an agent owner." }, "agent_skills": { "items": { "$ref": "#/components/schemas/SearchAgentSkillItem" }, "type": "array", - "title": "Agent Skills" + "title": "Agent Skills", + "description": "Matching agent skills, for an agent owner." }, "unprocessed_messages": { "items": { "$ref": "#/components/schemas/UnprocessedMessageDTO" }, "type": "array", - "title": "Unprocessed Messages" + "title": "Unprocessed Messages", + "description": "Raw buffered messages not yet extracted. Returned only when the request filtered on a single `session_id`, so a caller can see what is still in flight." } }, "type": "object", @@ -4956,15 +5772,18 @@ "properties": { "id": { "type": "string", - "title": "Id" + "title": "Id", + "description": "Episode id. Use it to bind tags or to fetch this episode again." }, "app_id": { "type": "string", - "title": "App Id" + "title": "App Id", + "description": "The business-semantic scope this memory was written under." }, "project_id": { "type": "string", - "title": "Project Id" + "title": "Project Id", + "description": "Second half of that scope." }, "user_id": { "anyOf": [ @@ -4975,7 +5794,8 @@ "type": "null" } ], - "title": "User Id" + "title": "User Id", + "description": "The user this episode belongs to. Null on an episode merged from several owners." }, "session_id": { "anyOf": [ @@ -4986,31 +5806,37 @@ "type": "null" } ], - "title": "Session Id" + "title": "Session Id", + "description": "The session it was extracted from. Null when the episode merges more than one session." }, "timestamp": { "type": "string", "format": "date-time", - "title": "Timestamp" + "title": "Timestamp", + "description": "When the remembered exchange happened (ISO 8601), not when it was extracted." }, "sender_ids": { "items": { "type": "string" }, "type": "array", - "title": "Sender Ids" + "title": "Sender Ids", + "description": "The senders that appear in the source exchange." }, "summary": { "type": "string", - "title": "Summary" + "title": "Summary", + "description": "Short summary of the episode \u2014 what a result list should show." }, "subject": { "type": "string", - "title": "Subject" + "title": "Subject", + "description": "What the episode is about, in a few words." }, "episode": { "type": "string", - "title": "Episode" + "title": "Episode", + "description": "The episode's stored narrative body. This is the indexed, searchable text." }, "readable_episode": { "anyOf": [ @@ -5021,29 +5847,34 @@ "type": "null" } ], - "title": "Readable Episode" + "title": "Readable Episode", + "description": "Human-readable rendering of `episode`, for display only \u2014 never indexed, filtered or scored. Present as a key but null unless the request asked for it (and the tenant is enabled for it); fall back to `episode` when it is null." }, "type": { "type": "string", - "title": "Type" + "title": "Type", + "description": "How the episode was produced \u2014 \"Conversation\" or \"AgentConversation\"." }, "atomic_facts": { "items": { "$ref": "#/components/schemas/SearchAtomicFactItem" }, "type": "array", - "title": "Atomic Facts" + "title": "Atomic Facts", + "description": "The facts extracted from this episode, each with its own relevance score." }, "tags": { "items": { "type": "string" }, "type": "array", - "title": "Tags" + "title": "Tags", + "description": "Tags attached through /api/v2/memory/tag/*." }, "score": { "type": "number", - "title": "Score" + "title": "Score", + "description": "Relevance of this episode to the query. What the number means depends on `method`: the hybrid path fuses its two routes into a probability in 0.0\u20131.0 (which is what `min_score` filters on), while keyword and vector pass the underlying engine's own score through \u2014 BM25 has no upper bound and vector similarity depends on the metric. So compare scores within one method, not across methods." } }, "type": "object", @@ -5071,7 +5902,21 @@ "type": "null" } ], - "title": "Category Id" + "title": "Category Id", + "description": "Bias retrieval toward one category. This is a soft filter on recall, not a hard restriction \u2014 hits from other categories can still surface." + }, + "tag_ids": { + "items": { + "type": "string", + "maxLength": 128, + "minLength": 1, + "description": "Opaque semantic tag id" + }, + "type": "array", + "maxItems": 100, + "title": "Tag Ids", + "description": "Hard filter that does not affect scoring: only topics carrying EVERY one of these tag ids are eligible. Use `boost_tag_ids` when the intent is to reweight rather than exclude.", + "default": [] } }, "additionalProperties": false, @@ -5083,25 +5928,33 @@ "properties": { "object": { "type": "string", + "enum": [ + "topic", + "document" + ], "title": "Object", - "default": "topic" + "description": "What this hit is. Always \"topic\" today \u2014 the unit of knowledge retrieval." }, "id": { "type": "string", - "title": "Id" + "title": "Id", + "description": "The topic's id; fetch its full body with GET .../topics/{topic_id}." }, "doc_id": { "type": "string", - "title": "Doc Id" + "title": "Doc Id", + "description": "The document the topic belongs to." }, "kb_id": { "type": "string", - "title": "Kb Id" + "title": "Kb Id", + "description": "The knowledge base searched." }, "category_id": { "type": "string", "title": "Category Id", - "default": "" + "default": "", + "description": "The category that document is filed under; empty when uncategorized." }, "category_name": { "anyOf": [ @@ -5112,22 +5965,31 @@ "type": "null" } ], - "title": "Category Name" + "title": "Category Name", + "description": "That category's display name, resolved for you." }, "name": { "type": "string", "title": "Name", - "default": "" + "description": "The topic's title." }, "depth": { "type": "integer", "title": "Depth", - "default": 0 + "default": 0, + "description": "The topic's depth in the document tree." }, "summary": { - "type": "string", + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], "title": "Summary", - "default": "" + "description": "Retrieval-oriented summary of the topic \u2014 enough to render a result row." }, "content": { "anyOf": [ @@ -5138,17 +6000,24 @@ "type": "null" } ], - "title": "Content" + "title": "Content", + "description": "The topic's full body, present only when `content` was asked for in `include`." }, "score": { "type": "number", "title": "Score", - "default": 0.0 + "description": "Relevance of this topic to the query, and NOT a raw keyword or vector score: candidates from every method are reranked by a cross-encoder, min-max normalized WITHIN THIS RESPONSE, then given a category boost (up to 0.1) and, when `boost_tag_ids` was passed, a tag-coverage boost (up to 0.3). So it lands in roughly 0.0\u20131.4, the best hit of any response sits near the top of that range by construction, and scores compare inside one response but not across responses or queries. Three edge values to expect: every hit comes back at 0.5 when the reranker cannot separate the pool, every hit is 0.0 on a filter-only request (tags without a query, which never runs relevance at all), and a hit carries a synthetic -100.0 when its rerank batch failed \u2014 that is a fail-soft marker, not a relevance judgement." }, "retrieval_method": { "type": "string", + "enum": [ + "keyword", + "vector", + "hybrid", + "filter" + ], "title": "Retrieval Method", - "default": "hybrid" + "description": "The retrieval strategy this search ran with, so every hit in one response carries the same value and a stored or traced response is self-describing. It echoes the request's `method`, except on a filter-only request (tags without a query), which reports \"filter\" because no retrieval ran. It is deliberately NOT per-hit provenance: in a hybrid search the two lanes are fused, and hits recalled by only one of them still report \"hybrid\"." }, "source": { "anyOf": [ @@ -5159,7 +6028,8 @@ "type": "null" } ], - "title": "Source" + "title": "Source", + "description": "The parent document's source name." }, "document": { "anyOf": [ @@ -5169,29 +6039,58 @@ { "type": "null" } - ] + ], + "description": "The parent document's context, rolled up so a result needs no second call." + }, + "tags": { + "items": { + "$ref": "#/components/schemas/TagRef" + }, + "type": "array", + "title": "Tags", + "description": "The semantic tags materialized on this topic." + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At", + "description": "When the topic last changed." } }, "type": "object", "required": [ + "object", "id", "doc_id", - "kb_id" + "kb_id", + "name", + "score", + "retrieval_method", + "tags" ], "title": "SearchHit", - "description": "A single search hit. ``object`` self-describes the unit (currently always topic)." + "description": "A topic hit from recall or a document hit from filter-only search." }, "SearchInput": { "properties": { "app_id": { "type": "string", "title": "App Id", - "default": "default" + "default": "default", + "description": "Scope to search in, defaulting to \"default\". Must match the pair used on write." }, "project_id": { "type": "string", "title": "Project Id", - "default": "default" + "default": "default", + "description": "Second half of the scope, defaulting to \"default\"." }, "user_id": { "anyOf": [ @@ -5203,7 +6102,8 @@ "type": "null" } ], - "title": "User Id" + "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." }, "agent_id": { "anyOf": [ @@ -5215,12 +6115,14 @@ "type": "null" } ], - "title": "Agent Id" + "title": "Agent Id", + "description": "Search one agent's memories (cases and skills). Exactly one of `user_id` / `agent_id` is required." }, "query": { "type": "string", "minLength": 1, - "title": "Query" + "title": "Query", + "description": "The natural-language query to retrieve against." }, "method": { "type": "string", @@ -5231,12 +6133,14 @@ "agentic" ], "title": "Method", - "default": "hybrid" + "default": "hybrid", + "description": "Retrieval strategy. \"keyword\" is lexical, \"vector\" is embedding similarity, \"hybrid\" (default) combines both, and \"agentic\" lets the engine run a multi-round LLM-guided retrieval \u2014 more thorough, slower." }, "top_k": { "type": "integer", "title": "Top K", - "default": -1 + "default": -1, + "description": "Maximum number of hits. Either -1 (the default, letting the engine decide) or a value from 1 to 100; anything else is rejected with 422." }, "radius": { "anyOf": [ @@ -5249,7 +6153,8 @@ "type": "null" } ], - "title": "Radius" + "title": "Radius", + "description": "Vector-similarity radius, 0.0\u20131.0. Unset leaves it to the engine." }, "min_score": { "anyOf": [ @@ -5262,22 +6167,26 @@ "type": "null" } ], - "title": "Min Score" + "title": "Min Score", + "description": "Post-fusion score floor, 0.0\u20131.0. Applies to the episode hybrid (hierarchy) path only; other paths ignore it. The hybrid path fuses its two routes into a probability, so unlike a raw keyword or vector score this floor is an absolute bar and 0.0\u20131.0 is the real range." }, "include_profile": { "type": "boolean", "title": "Include Profile", - "default": false + "default": false, + "description": "Also return the user's profile alongside the hits, saving a second call. Ignored for an agent owner, whose results carry no profiles." }, "with_readable_episode": { "type": "boolean", "title": "With Readable Episode", - "default": false + "default": false, + "description": "Attach a human-readable rendering of each episode to the returned items, for display only \u2014 it is not indexed, filterable or scored, and callers fall back to `episode` when it is null. Ignored for an agent owner." }, "enable_llm_rerank": { "type": "boolean", "title": "Enable Llm Rerank", - "default": false + "default": false, + "description": "Opt-in LLM rerank, and only for hybrid agent_case / agent_skill retrieval. The episode hybrid path has its own fact eviction and ignores this, as do keyword, vector and agentic." }, "filters": { "anyOf": [ @@ -5287,7 +6196,8 @@ { "type": "null" } - ] + ], + "description": "Optional filter tree \u2014 recursive `AND` / `OR` arrays mixed with the scalar conditions being matched." } }, "additionalProperties": false, @@ -5307,24 +6217,55 @@ "properties": { "id": { "type": "string", - "title": "Id" + "title": "Id", + "description": "Profile id." }, "app_id": { "type": "string", - "title": "App Id" + "title": "App Id", + "description": "The business-semantic scope this profile was written under." }, "project_id": { "type": "string", - "title": "Project Id" + "title": "Project Id", + "description": "Second half of that scope." }, "user_id": { "type": "string", - "title": "User Id" + "title": "User Id", + "description": "The user this profile describes." }, "profile_data": { "additionalProperties": true, "type": "object", - "title": "Profile Data" + "title": "Profile Data", + "description": "The profile itself \u2014 the explicit_info and implicit_traits items maintained by extraction and by /api/v2/memory/edit. Each item's id is what an edit operation targets." + }, + "created_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Created At", + "description": "When the profile was first created." + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At", + "description": "When it last changed." }, "score": { "anyOf": [ @@ -5335,7 +6276,8 @@ "type": "null" } ], - "title": "Score" + "title": "Score", + "description": "Relevance to the query. Null when the profile was returned by `include_profile` rather than matched." } }, "type": "object", @@ -5670,6 +6612,25 @@ ], "title": "SuccessEnvelope[KbSearchData]" }, + "SuccessEnvelope_RelatedTagUsageListData_": { + "properties": { + "request_id": { + "type": "string", + "title": "Request Id", + "description": "Request trace id (peer to data)" + }, + "data": { + "$ref": "#/components/schemas/RelatedTagUsageListData", + "description": "Endpoint-defined business result" + } + }, + "type": "object", + "required": [ + "request_id", + "data" + ], + "title": "SuccessEnvelope[RelatedTagUsageListData]" + }, "SuccessEnvelope_SearchData_": { "properties": { "request_id": { @@ -5754,7 +6715,45 @@ "description": "Request trace id (peer to data)" }, "data": { - "$ref": "#/components/schemas/TopicDetailData", + "$ref": "#/components/schemas/TopicDetailData", + "description": "Endpoint-defined business result" + } + }, + "type": "object", + "required": [ + "request_id", + "data" + ], + "title": "SuccessEnvelope[TopicDetailData]" + }, + "SuccessEnvelope_TopicFilterListData_": { + "properties": { + "request_id": { + "type": "string", + "title": "Request Id", + "description": "Request trace id (peer to data)" + }, + "data": { + "$ref": "#/components/schemas/TopicFilterListData", + "description": "Endpoint-defined business result" + } + }, + "type": "object", + "required": [ + "request_id", + "data" + ], + "title": "SuccessEnvelope[TopicFilterListData]" + }, + "SuccessEnvelope_TopicListData_": { + "properties": { + "request_id": { + "type": "string", + "title": "Request Id", + "description": "Request trace id (peer to data)" + }, + "data": { + "$ref": "#/components/schemas/TopicListData", "description": "Endpoint-defined business result" } }, @@ -5763,9 +6762,9 @@ "request_id", "data" ], - "title": "SuccessEnvelope[TopicDetailData]" + "title": "SuccessEnvelope[TopicListData]" }, - "SuccessEnvelope_TopicListData_": { + "SuccessEnvelope_TopicTagWriteData_": { "properties": { "request_id": { "type": "string", @@ -5773,7 +6772,7 @@ "description": "Request trace id (peer to data)" }, "data": { - "$ref": "#/components/schemas/TopicListData", + "$ref": "#/components/schemas/TopicTagWriteData", "description": "Endpoint-defined business result" } }, @@ -5782,19 +6781,21 @@ "request_id", "data" ], - "title": "SuccessEnvelope[TopicListData]" + "title": "SuccessEnvelope[TopicTagWriteData]" }, "TagBindData": { "properties": { "matched": { "type": "integer", "title": "Matched", - "default": 0 + "default": 0, + "description": "How many of the submitted memories the operation matched. Matching is not the same as changing: re-binding a tag an item already carries matches without modifying it." }, "requested": { "type": "integer", "title": "Requested", - "default": 0 + "default": 0, + "description": "How many ids were submitted. `matched` below `requested` means some ids were not found \u2014 deleted, another tenant's, or (for bind) already at the per-memory tag limit." } }, "type": "object", @@ -5805,7 +6806,8 @@ "memory_type": { "type": "string", "minLength": 1, - "title": "Memory Type" + "title": "Memory Type", + "description": "The type of the memories being tagged. \"episode\" is what this phase supports; agent cases and skills onboard later without an API change." }, "memory_ids": { "items": { @@ -5814,7 +6816,8 @@ "type": "array", "maxItems": 200, "minItems": 1, - "title": "Memory Ids" + "title": "Memory Ids", + "description": "The memories to tag, by id (1\u2013200 per request). Ids come from /api/v2/memory/get or /api/v2/memory/search." }, "tags": { "items": { @@ -5825,7 +6828,8 @@ "type": "array", "maxItems": 100, "minItems": 1, - "title": "Tags" + "title": "Tags", + "description": "Tags to add (1\u2013100 per request, each 1\u201332 characters). Tags the memories already carry are left in place." } }, "additionalProperties": false, @@ -5837,17 +6841,47 @@ ], "title": "TagBindInput" }, + "TagRef": { + "properties": { + "id": { + "type": "string", + "title": "Id", + "description": "Opaque semantic tag id." + }, + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name", + "description": "The tag's display name when one is resolved; null when only the id is known." + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id" + ], + "title": "TagRef", + "description": "Opaque semantic tag reference; its containing topic conveys ownership." + }, "TagReplaceData": { "properties": { "matched": { "type": "integer", "title": "Matched", - "default": 0 + "default": 0, + "description": "How many of the submitted memories the operation matched. Matching is not the same as changing: re-binding a tag an item already carries matches without modifying it." }, "requested": { "type": "integer", "title": "Requested", - "default": 0 + "default": 0, + "description": "How many ids were submitted. `matched` below `requested` means some ids were not found \u2014 deleted, another tenant's, or (for bind) already at the per-memory tag limit." } }, "type": "object", @@ -5858,7 +6892,8 @@ "memory_type": { "type": "string", "minLength": 1, - "title": "Memory Type" + "title": "Memory Type", + "description": "The type of the memories being retagged, e.g. \"episode\"." }, "memory_ids": { "items": { @@ -5867,7 +6902,8 @@ "type": "array", "maxItems": 200, "minItems": 1, - "title": "Memory Ids" + "title": "Memory Ids", + "description": "The memories to retag, by id (1\u2013200 per request)." }, "tags": { "items": { @@ -5877,7 +6913,8 @@ }, "type": "array", "maxItems": 100, - "title": "Tags" + "title": "Tags", + "description": "The complete tag set to store (up to 100, each 1\u201332 characters). Tags absent from this list are dropped, and an empty list clears them all. Duplicates collapse." } }, "additionalProperties": false, @@ -5895,12 +6932,14 @@ "matched": { "type": "integer", "title": "Matched", - "default": 0 + "default": 0, + "description": "How many of the submitted memories the operation matched. Matching is not the same as changing: re-binding a tag an item already carries matches without modifying it." }, "requested": { "type": "integer", "title": "Requested", - "default": 0 + "default": 0, + "description": "How many ids were submitted. `matched` below `requested` means some ids were not found \u2014 deleted, another tenant's, or (for bind) already at the per-memory tag limit." } }, "type": "object", @@ -5911,7 +6950,8 @@ "memory_type": { "type": "string", "minLength": 1, - "title": "Memory Type" + "title": "Memory Type", + "description": "The type of the memories being untagged, e.g. \"episode\"." }, "memory_ids": { "items": { @@ -5920,7 +6960,8 @@ "type": "array", "maxItems": 200, "minItems": 1, - "title": "Memory Ids" + "title": "Memory Ids", + "description": "The memories to untag, by id (1\u2013200 per request)." }, "tags": { "items": { @@ -5931,7 +6972,8 @@ "type": "array", "maxItems": 100, "minItems": 1, - "title": "Tags" + "title": "Tags", + "description": "Tags to remove (1\u2013100 per request). Tags not listed here are left in place." } }, "additionalProperties": false, @@ -5947,15 +6989,18 @@ "properties": { "id": { "type": "string", - "title": "Id" + "title": "Id", + "description": "Tool-call id; the matching \"tool\" message echoes it as `tool_call_id`." }, "type": { "type": "string", "title": "Type", - "default": "function" + "default": "function", + "description": "Tool-call kind. Always \"function\" today." }, "function": { - "$ref": "#/components/schemas/ToolCallFunction" + "$ref": "#/components/schemas/ToolCallFunction", + "description": "The function invoked, with its arguments." } }, "type": "object", @@ -5969,11 +7014,13 @@ "properties": { "name": { "type": "string", - "title": "Name" + "title": "Name", + "description": "Name of the function the assistant called." }, "arguments": { "type": "string", - "title": "Arguments" + "title": "Arguments", + "description": "The call's arguments as a JSON-encoded string (OpenAI shape), not an object." } }, "type": "object", @@ -5987,20 +7034,34 @@ "properties": { "id": { "type": "string", - "title": "Id" + "title": "Id", + "description": "Topic id." }, "doc_id": { "type": "string", - "title": "Doc Id" + "title": "Doc Id", + "description": "The document this topic was extracted from." }, "kb_id": { "type": "string", - "title": "Kb Id" + "title": "Kb Id", + "description": "The knowledge base that document belongs to." + }, + "type": { + "type": "string", + "enum": [ + "root", + "section", + "element" + ], + "title": "Type", + "description": "Structural role of this topic node" }, "category_id": { "type": "string", "title": "Category Id", - "default": "" + "default": "", + "description": "The category the document is filed under; empty when uncategorized." }, "category_name": { "anyOf": [ @@ -6011,26 +7072,31 @@ "type": "null" } ], - "title": "Category Name" + "title": "Category Name", + "description": "That category's display name, resolved for you. Null when the document is uncategorized or the category no longer exists." }, "name": { "type": "string", - "title": "Name" + "title": "Name", + "description": "The topic's title." }, "depth": { "type": "integer", "title": "Depth", - "default": 0 + "default": 0, + "description": "Depth in the document tree \u2014 0 is the document root, 1 a top-level topic." }, "seq": { "type": "integer", "title": "Seq", - "default": 0 + "default": 0, + "description": "Depth-first position within the document. Use it as an ordering, not as an index to compute with." }, "summary": { "type": "string", "title": "Summary", - "default": "" + "default": "", + "description": "Retrieval-oriented summary covering this topic and everything under it." }, "content": { "anyOf": [ @@ -6041,14 +7107,16 @@ "type": "null" } ], - "title": "Content" + "title": "Content", + "description": "The topic's full markdown body, restored transparently whether it was stored inline or in object storage. Null on the document-root node, which has no body." }, "labels": { "items": { "type": "string" }, "type": "array", - "title": "Labels" + "title": "Labels", + "description": "Labels attached to the topic during extraction." }, "parent_id": { "anyOf": [ @@ -6059,19 +7127,40 @@ "type": "null" } ], - "title": "Parent Id" + "title": "Parent Id", + "description": "The topic above this one. Null only on the document root." }, "children_ids": { "items": { "type": "string" }, "type": "array", - "title": "Children Ids" + "title": "Children Ids", + "description": "The topics directly beneath this one." }, "metadata": { "additionalProperties": true, "type": "object", - "title": "Metadata" + "title": "Metadata", + "description": "Extraction metadata carried alongside the topic." + }, + "tag_ids": { + "items": { + "type": "string", + "maxLength": 128, + "minLength": 1, + "description": "Opaque semantic tag id" + }, + "type": "array", + "maxItems": 50, + "title": "Tag Ids", + "description": "Opaque final materialized semantic tag ids (maximum 50)" + }, + "version": { + "type": "integer", + "minimum": 0.0, + "title": "Version", + "description": "Current topic tag CAS version" }, "created_at": { "anyOf": [ @@ -6083,7 +7172,8 @@ "type": "null" } ], - "title": "Created At" + "title": "Created At", + "description": "When the topic was extracted." }, "updated_at": { "anyOf": [ @@ -6095,7 +7185,8 @@ "type": "null" } ], - "title": "Updated At" + "title": "Updated At", + "description": "When it last changed." } }, "type": "object", @@ -6103,11 +7194,137 @@ "id", "doc_id", "kb_id", - "name" + "type", + "name", + "tag_ids", + "version" ], "title": "TopicDetailData", "description": "Full topic (node), with content transparently restored (inline or from S3)." }, + "TopicFilterItem": { + "properties": { + "id": { + "type": "string", + "title": "Id", + "description": "Topic (node) id" + }, + "doc_id": { + "type": "string", + "title": "Doc Id", + "description": "Owning document id", + "default": "" + }, + "kb_id": { + "type": "string", + "title": "Kb Id", + "description": "Owning knowledge base id", + "default": "" + }, + "name": { + "type": "string", + "title": "Name", + "description": "Topic title" + }, + "type": { + "type": "string", + "enum": [ + "root", + "section", + "element" + ], + "title": "Type", + "default": "section", + "description": "Structural role of the topic \u2014 \"root\" for the synthetic document-root node, \"section\" for a real topic." + }, + "depth": { + "type": "integer", + "minimum": 0.0, + "title": "Depth", + "default": 0, + "description": "Depth in the document tree \u2014 0 is the document root, 1 a top-level topic." + }, + "seq": { + "type": "integer", + "minimum": 0.0, + "title": "Seq", + "default": 0, + "description": "Depth-first position within the document. Use it as an ordering, not as an index to compute with." + }, + "parent_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parent Id", + "description": "The topic above this one. Null only on the document root." + }, + "summary": { + "type": "string", + "title": "Summary", + "default": "", + "description": "Retrieval-oriented summary covering this topic and everything under it." + }, + "tag_ids": { + "items": { + "type": "string", + "maxLength": 128, + "minLength": 1, + "description": "Opaque semantic tag id" + }, + "type": "array", + "maxItems": 50, + "uniqueItems": true, + "title": "Tag Ids", + "description": "Opaque final materialized semantic tag ids (maximum 50)" + }, + "version": { + "type": "integer", + "minimum": 0.0, + "title": "Version", + "description": "Current topic tag CAS version" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "name", + "tag_ids", + "version" + ], + "title": "TopicFilterItem", + "description": "Slim item for the KB-wide tag-filter endpoint.\n\nThis is deliberately separate from :class:`TopicListItem`: the document-tree API\nmay hydrate content and exposes timestamps, while the cross-service tag-filter wire\nis frozen without those fields." + }, + "TopicFilterListData": { + "properties": { + "topics": { + "items": { + "$ref": "#/components/schemas/TopicFilterItem" + }, + "type": "array", + "title": "Topics", + "description": "The matching topics, one page of them." + }, + "total": { + "type": "integer", + "minimum": 0.0, + "title": "Total", + "description": "How many topics satisfy the all-tags-on-one-topic condition in total, counted before paging." + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "topics", + "total" + ], + "title": "TopicFilterListData" + }, "TopicListData": { "properties": { "topics": { @@ -6115,7 +7332,8 @@ "$ref": "#/components/schemas/TopicListItem" }, "type": "array", - "title": "Topics" + "title": "Topics", + "description": "The document's topics, flat and depth-first ordered \u2014 build the tree from `parent_id`. Includes the synthetic document-root item, so this list holds exactly one more entry than the document's `topic_count`." } }, "type": "object", @@ -6129,6 +7347,18 @@ "title": "Id", "description": "Topic (node) id" }, + "doc_id": { + "type": "string", + "title": "Doc Id", + "description": "Owning document id", + "default": "" + }, + "kb_id": { + "type": "string", + "title": "Kb Id", + "description": "Owning knowledge base id", + "default": "" + }, "name": { "type": "string", "title": "Name", @@ -6182,6 +7412,25 @@ "title": "Content", "description": "Full markdown body \u2014 populated ONLY when the request passes `include=content`, else null. Always the complete body, never a stored excerpt. Null on the document-root item, which has no body of its own" }, + "tag_ids": { + "items": { + "type": "string", + "maxLength": 128, + "minLength": 1, + "description": "Opaque semantic tag id" + }, + "type": "array", + "maxItems": 50, + "title": "Tag Ids", + "description": "Opaque final materialized semantic tag ids (maximum 50)" + }, + "version": { + "type": "integer", + "minimum": 0.0, + "title": "Version", + "description": "Current topic tag CAS version", + "default": 0 + }, "created_at": { "anyOf": [ { @@ -6192,7 +7441,8 @@ "type": "null" } ], - "title": "Created At" + "title": "Created At", + "description": "When the topic was extracted." }, "updated_at": { "anyOf": [ @@ -6204,7 +7454,8 @@ "type": "null" } ], - "title": "Updated At" + "title": "Updated At", + "description": "When it last changed." } }, "type": "object", @@ -6215,27 +7466,124 @@ "title": "TopicListItem", "description": "Node-tree overview item. ``content`` only when the caller asks for it." }, + "TopicTagReplaceBody": { + "properties": { + "tag_ids": { + "items": { + "type": "string", + "maxLength": 128, + "minLength": 1, + "description": "Opaque semantic tag id" + }, + "type": "array", + "maxItems": 100, + "title": "Tag Ids", + "description": "Complete materialized snapshot. Cloud stable-deduplicates the request, stores the first 50 ids, and reports any truncation." + }, + "version": { + "type": "integer", + "minimum": 0.0, + "title": "Version", + "description": "Expected current topic tag_version (CAS)" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "tag_ids", + "version" + ], + "title": "TopicTagReplaceBody" + }, + "TopicTagWriteData": { + "properties": { + "topic_id": { + "type": "string", + "title": "Topic Id", + "description": "The topic whose tag snapshot was written." + }, + "requested": { + "type": "integer", + "minimum": 0.0, + "title": "Requested", + "description": "Stable-distinct request id count; not vocabulary-validity count" + }, + "tag_ids": { + "items": { + "type": "string", + "maxLength": 128, + "minLength": 1, + "description": "Opaque semantic tag id" + }, + "type": "array", + "maxItems": 50, + "uniqueItems": true, + "title": "Tag Ids", + "description": "Complete materialized topic tag snapshot after the accepted write" + }, + "version": { + "type": "integer", + "minimum": 0.0, + "title": "Version", + "description": "Current topic tag version" + }, + "truncated": { + "type": "boolean", + "title": "Truncated", + "description": "Whether distinct input exceeded the store limit" + }, + "limit": { + "type": "integer", + "const": 50, + "title": "Limit", + "description": "Materialized topic tag limit" + }, + "dropped_count": { + "type": "integer", + "minimum": 0.0, + "title": "Dropped Count", + "description": "Distinct requested ids omitted by stable truncation" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "topic_id", + "requested", + "tag_ids", + "version", + "truncated", + "limit", + "dropped_count" + ], + "title": "TopicTagWriteData" + }, "UnprocessedMessageDTO": { "properties": { "id": { "type": "string", - "title": "Id" + "title": "Id", + "description": "Buffered-message id." }, "app_id": { "type": "string", - "title": "App Id" + "title": "App Id", + "description": "The business-semantic scope the message was written under." }, "project_id": { "type": "string", - "title": "Project Id" + "title": "Project Id", + "description": "Second half of that scope." }, "session_id": { "type": "string", - "title": "Session Id" + "title": "Session Id", + "description": "The session the message is buffered under." }, "sender_id": { "type": "string", - "title": "Sender Id" + "title": "Sender Id", + "description": "Who sent it." }, "sender_name": { "anyOf": [ @@ -6246,7 +7594,8 @@ "type": "null" } ], - "title": "Sender Name" + "title": "Sender Name", + "description": "The sender's display name, when one was given." }, "role": { "type": "string", @@ -6255,7 +7604,8 @@ "assistant", "tool" ], - "title": "Role" + "title": "Role", + "description": "\"user\", \"assistant\" or \"tool\", as submitted." }, "content": { "anyOf": [ @@ -6269,12 +7619,14 @@ "type": "array" } ], - "title": "Content" + "title": "Content", + "description": "The message body as submitted." }, "timestamp": { "type": "string", "format": "date-time", - "title": "Timestamp" + "title": "Timestamp", + "description": "When the message was produced (ISO 8601)." }, "tool_calls": { "anyOf": [ @@ -6288,7 +7640,8 @@ "type": "null" } ], - "title": "Tool Calls" + "title": "Tool Calls", + "description": "Tool calls on an assistant message, as submitted." }, "tool_call_id": { "anyOf": [ @@ -6299,7 +7652,8 @@ "type": "null" } ], - "title": "Tool Call Id" + "title": "Tool Call Id", + "description": "The tool call this result answers, on a \"tool\" message." } }, "type": "object", @@ -6328,12 +7682,14 @@ "type": "null" } ], - "title": "Reason" + "title": "Reason", + "description": "Why this edit was made, up to 256 characters." }, "action": { "type": "string", "const": "update", - "title": "Action" + "title": "Action", + "description": "Always \"update\" for this variant." }, "type": { "type": "string", @@ -6341,11 +7697,13 @@ "explicit_info", "implicit_traits" ], - "title": "Type" + "title": "Type", + "description": "Which profile item this edit targets \u2014 \"explicit_info\" or \"implicit_traits\". It must match the `item_id` prefix." }, "item_id": { "type": "string", - "title": "Item Id" + "title": "Item Id", + "description": "The item to update. Its prefix must match the item type \u2014 \"ei_\" for explicit_info, \"it_\" for implicit_traits \u2014 followed by 24 hex characters." }, "data": { "anyOf": [ @@ -6356,7 +7714,8 @@ "$ref": "#/components/schemas/ImplicitTraitPatch" } ], - "title": "Data" + "title": "Data", + "description": "Partial patch, shallow-merged into the stored item. At least one of the type's own keys must be present." } }, "additionalProperties": false, @@ -6384,15 +7743,18 @@ ] }, "type": "array", - "title": "Location" + "title": "Location", + "description": "Path to the offending field, from the body root." }, "msg": { "type": "string", - "title": "Message" + "title": "Message", + "description": "What is wrong with it." }, "type": { "type": "string", - "title": "Error Type" + "title": "Error Type", + "description": "Machine-readable validation-error kind." } }, "type": "object", @@ -6438,10 +7800,12 @@ ], "properties": { "fileId": { - "type": "string" + "type": "string", + "description": "Your own id for this file. It comes back on the matching response item." }, "fileName": { - "type": "string" + "type": "string", + "description": "The file's name, used to derive its type and preserved for display." }, "fileType": { "type": "string", @@ -6461,7 +7825,8 @@ "type": "array", "items": { "$ref": "#/components/schemas/SignResponseItem" - } + }, + "description": "One signed entry per requested file, in the same order." } } }, @@ -6469,23 +7834,28 @@ "type": "object", "properties": { "fileId": { - "type": "string" + "type": "string", + "description": "The id you supplied for this file." }, "fileName": { - "type": "string" + "type": "string", + "description": "The file's name, echoed back." }, "fileType": { - "type": "string" + "type": "string", + "description": "The type the service resolved for it." }, "objectKey": { - "type": "string" + "type": "string", + "description": "The stored object's key \u2014 this is the value to pass later as a content `uri` on /api/v2/memory/add or a document ingest." }, "objectUrl": { "type": "string", "description": "Present in the response struct for parity with the find endpoint,\nbut not populated on the sign path (omitted from the JSON).\n" }, "objectSignedInfo": { - "$ref": "#/components/schemas/SignedInfo" + "$ref": "#/components/schemas/SignedInfo", + "description": "Where and how to upload the bytes." } } }, @@ -6494,13 +7864,15 @@ "description": "Presigned POST form data for direct-to-S3 upload", "properties": { "url": { - "type": "string" + "type": "string", + "description": "The URL to POST the file to." }, "fields": { "type": "object", "additionalProperties": { "type": "string" - } + }, + "description": "Form fields that must accompany the upload, exactly as given, with the file itself last." }, "maxSize": { "type": "integer", @@ -6518,7 +7890,8 @@ "description": "`\"OK\"` on success, otherwise a human-readable error message\ndecoded from the business error.\n" }, "request_id": { - "type": "string" + "type": "string", + "description": "Id of this request \u2014 quote it when reporting a problem." }, "status": { "type": "integer", @@ -6528,7 +7901,8 @@ "type": "object", "properties": { "data": true - } + }, + "description": "The response payload." } } }, @@ -6574,7 +7948,8 @@ "message", "type" ], - "type": "object" + "type": "object", + "description": "What went wrong, with a machine-readable code and a message." } }, "required": [ @@ -6587,14 +7962,16 @@ "properties": { "created_at": { "format": "date-time", - "type": "string" + "type": "string", + "description": "When the task was accepted." }, "error": { "description": "Failure reason; present only when status is failed", "type": "string" }, "error_code": { - "type": "string" + "type": "string", + "description": "Machine-readable failure code, alongside the human-readable `error`." }, "finished_at": { "description": "Completion time; absent while the task is not in a terminal state", @@ -6610,7 +7987,8 @@ "type": "string" }, "object_id": { - "type": "string" + "type": "string", + "description": "Id of the resource the task produced, once there is one." }, "status": { "enum": [ @@ -6620,7 +7998,8 @@ "success", "failed" ], - "type": "string" + "type": "string", + "description": "Where the task is: \"queued\", \"processing\", \"pending\", \"success\" or \"failed\". Treat it as an open set \u2014 a value you do not recognise is terminal only when `finished_at` is set." }, "task_type": { "description": "Async interface that produced the task, e.g. memory_add / knowledge_document / batch_import", @@ -6660,10 +8039,12 @@ "page_size", "items" ], - "type": "object" + "type": "object", + "description": "The page of tasks, with its paging counters." }, "request_id": { - "type": "string" + "type": "string", + "description": "Id of this request \u2014 quote it when reporting a problem." } }, "required": [ @@ -6723,10 +8104,12 @@ "start", "end" ], - "type": "object" + "type": "object", + "description": "The per-status counts and the window they cover." }, "request_id": { - "type": "string" + "type": "string", + "description": "Id of this request \u2014 quote it when reporting a problem." } }, "required": [ @@ -6738,10 +8121,12 @@ "TaskStatusResponse": { "properties": { "data": { - "$ref": "#/components/schemas/TaskItem" + "$ref": "#/components/schemas/TaskItem", + "description": "The task." }, "request_id": { - "type": "string" + "type": "string", + "description": "Id of this request \u2014 quote it when reporting a problem." } }, "required": [ diff --git a/pyproject.toml b/pyproject.toml index aa72a00..22798a9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "everos_cloud" -version = "1.1.0-rc2" +version = "1.1.0" description = "EverOS Cloud Memory API" authors = ["EverMind AI "] license = "Apache-2.0" diff --git a/setup.py b/setup.py index c9fa506..9f014dc 100644 --- a/setup.py +++ b/setup.py @@ -24,8 +24,13 @@ # prerequisite: setuptools # http://pypi.python.org/pypi/setuptools NAME = "everos-cloud" -VERSION = "1.1.0-rc2" -PYTHON_REQUIRES = ">= 3.8" +VERSION = "1.1.0" +# 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 +# on the reversible side: lowering it later costs nobody anything, raising it later +# breaks whoever had already installed on the old floor. +PYTHON_REQUIRES = ">=3.12" # PyPI renders this as the project page body. Use the repo README (which ships in # the SDK tree — propose_sdk.sh preserves it), falling back to the spec description @@ -37,7 +42,9 @@ REQUIRES = [ "urllib3 >= 1.25.3, < 3.0.0", "python-dateutil >= 2.8.2", - "pydantic >= 2", + # Upper bound deliberate: the generated models are written against pydantic v2's + # API, so a 3.0 release would break every fresh install with no change on our side. + "pydantic >= 2, < 3", "typing-extensions >= 4.7.1", ] @@ -49,6 +56,7 @@ author_email="service@evermind.ai", url="https://github.com/EverMind-AI/everos-cloud-sdk-python", keywords=["OpenAPI", "OpenAPI-Generator", "EverOS Cloud Memory API"], + python_requires=PYTHON_REQUIRES, install_requires=REQUIRES, packages=find_packages(exclude=["test", "tests"]), include_package_data=True, diff --git a/test/test_agent_skill_item.py b/test/test_agent_skill_item.py index 3dcc9b3..bc6c046 100644 --- a/test/test_agent_skill_item.py +++ b/test/test_agent_skill_item.py @@ -47,7 +47,9 @@ def make_instance(self, include_optional) -> AgentSkillItem: maturity_score = 1.337, source_case_ids = [ '' - ] + ], + created_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), + updated_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f') ) else: return AgentSkillItem( diff --git a/test/test_content1.py b/test/test_content1.py new file mode 100644 index 0000000..318f16e --- /dev/null +++ b/test/test_content1.py @@ -0,0 +1,51 @@ +# coding: utf-8 + +""" + EverOS Cloud Memory API + + Official Python client for the EverOS Cloud Memory API. Add, search, retrieve, and manage long-term memory for your AI applications over a typed interface (pydantic v2, with full type hints). Install and usage guides: https://github.com/EverMind-AI/everos-cloud-sdk-python + + The version of the OpenAPI document: 2.0.0 + Contact: service@evermind.ai + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from everos_cloud.models.content1 import Content1 + +class TestContent1(unittest.TestCase): + """Content1 unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> Content1: + """Test Content1 + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `Content1` + """ + model = Content1() + if include_optional: + return Content1( + ) + else: + return Content1( + ) + """ + + def testContent1(self): + """Test Content1""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/test/test_doc_data.py b/test/test_doc_data.py index 82d0e86..9cb9783 100644 --- a/test/test_doc_data.py +++ b/test/test_doc_data.py @@ -44,6 +44,9 @@ def make_instance(self, include_optional) -> DocData: summary = '', source_name = '', source_type = '', + tags = [ + { } + ], topic_count = 56, created_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), updated_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f') @@ -53,6 +56,9 @@ def make_instance(self, include_optional) -> DocData: id = '', kb_id = '', title = '', + tags = [ + { } + ], ) """ diff --git a/test/test_doc_list_data.py b/test/test_doc_list_data.py index 71351c7..8548e06 100644 --- a/test/test_doc_list_data.py +++ b/test/test_doc_list_data.py @@ -46,6 +46,9 @@ def make_instance(self, include_optional) -> DocListData: summary = '', source_name = '', source_type = '', + tags = [ + { } + ], topic_count = 56, created_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), updated_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), ) diff --git a/test/test_error_body.py b/test/test_error_body.py new file mode 100644 index 0000000..5bc48ea --- /dev/null +++ b/test/test_error_body.py @@ -0,0 +1,55 @@ +# coding: utf-8 + +""" + EverOS Cloud Memory API + + Official Python client for the EverOS Cloud Memory API. Add, search, retrieve, and manage long-term memory for your AI applications over a typed interface (pydantic v2, with full type hints). Install and usage guides: https://github.com/EverMind-AI/everos-cloud-sdk-python + + The version of the OpenAPI document: 2.0.0 + Contact: service@evermind.ai + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from everos_cloud.models.error_body import ErrorBody + +class TestErrorBody(unittest.TestCase): + """ErrorBody unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> ErrorBody: + """Test ErrorBody + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `ErrorBody` + """ + model = ErrorBody() + if include_optional: + return ErrorBody( + code = '', + message = '' + ) + else: + return ErrorBody( + code = '', + message = '', + ) + """ + + def testErrorBody(self): + """Test ErrorBody""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/test/test_error_envelope.py b/test/test_error_envelope.py new file mode 100644 index 0000000..d99d956 --- /dev/null +++ b/test/test_error_envelope.py @@ -0,0 +1,59 @@ +# coding: utf-8 + +""" + EverOS Cloud Memory API + + Official Python client for the EverOS Cloud Memory API. Add, search, retrieve, and manage long-term memory for your AI applications over a typed interface (pydantic v2, with full type hints). Install and usage guides: https://github.com/EverMind-AI/everos-cloud-sdk-python + + The version of the OpenAPI document: 2.0.0 + Contact: service@evermind.ai + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from everos_cloud.models.error_envelope import ErrorEnvelope + +class TestErrorEnvelope(unittest.TestCase): + """ErrorEnvelope unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> ErrorEnvelope: + """Test ErrorEnvelope + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `ErrorEnvelope` + """ + model = ErrorEnvelope() + if include_optional: + return ErrorEnvelope( + request_id = '', + error = everos_cloud.models.error_body.ErrorBody( + code = '', + message = '', ) + ) + else: + return ErrorEnvelope( + request_id = '', + error = everos_cloud.models.error_body.ErrorBody( + code = '', + message = '', ), + ) + """ + + def testErrorEnvelope(self): + """Test ErrorEnvelope""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/test/test_get_data.py b/test/test_get_data.py index 53dd3a8..028b6b7 100644 --- a/test/test_get_data.py +++ b/test/test_get_data.py @@ -67,7 +67,9 @@ def make_instance(self, include_optional) -> GetData: app_id = '', project_id = '', user_id = '', - profile_data = { }, ) + profile_data = { }, + created_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), + updated_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), ) ], agent_cases = [ everos_cloud.models.agent_case_item.AgentCaseItem( @@ -95,7 +97,9 @@ def make_instance(self, include_optional) -> GetData: maturity_score = 1.337, source_case_ids = [ '' - ], ) + ], + created_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), + updated_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), ) ], total_count = 56, count = 56 diff --git a/test/test_kb_search_data.py b/test/test_kb_search_data.py index b5001d8..ace9404 100644 --- a/test/test_kb_search_data.py +++ b/test/test_kb_search_data.py @@ -49,18 +49,48 @@ def make_instance(self, include_optional) -> KbSearchData: summary = '', content = '', score = 1.337, - retrieval_method = 'hybrid', + retrieval_method = 'keyword', source = '', document = everos_cloud.models.document_context.DocumentContext( doc_id = '', title = '', - summary = '', ), ) + summary = '', ), + tags = [ + { } + ], + updated_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), ) ], total = 56, took_ms = 1.337 ) else: return KbSearchData( + hits = [ + everos_cloud.models.search_hit.SearchHit( + object = 'topic', + id = '', + doc_id = '', + kb_id = '', + category_id = '', + category_name = '', + name = '', + depth = 56, + summary = '', + content = '', + score = 1.337, + retrieval_method = 'keyword', + source = '', + document = everos_cloud.models.document_context.DocumentContext( + doc_id = '', + title = '', + summary = '', ), + tags = [ + { } + ], + updated_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), ) + ], + total = 56, + took_ms = 1.337, ) """ diff --git a/test/test_knowledge_api.py b/test/test_knowledge_api.py index 7692b39..a6641aa 100644 --- a/test/test_knowledge_api.py +++ b/test/test_knowledge_api.py @@ -118,6 +118,20 @@ def test_list_topics(self) -> None: """ pass + def test_list_topics_by_tags(self) -> None: + """Test case for list_topics_by_tags + + List tag-matched topics in a knowledge base + """ + pass + + def test_query_related_tags(self) -> None: + """Test case for query_related_tags + + Count candidate tags used by live documents in a knowledge base + """ + pass + def test_replace_document(self) -> None: """Test case for replace_document @@ -125,6 +139,13 @@ def test_replace_document(self) -> None: """ pass + def test_replace_topic_tags(self) -> None: + """Test case for replace_topic_tags + + Replace the complete materialized semantic tag snapshot of a topic + """ + pass + def test_search_knowledge(self) -> None: """Test case for search_knowledge diff --git a/test/test_profile_item.py b/test/test_profile_item.py index a61d517..0b914ae 100644 --- a/test/test_profile_item.py +++ b/test/test_profile_item.py @@ -40,7 +40,9 @@ def make_instance(self, include_optional) -> ProfileItem: app_id = '', project_id = '', user_id = '', - profile_data = { } + profile_data = { }, + created_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), + updated_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f') ) else: return ProfileItem( diff --git a/test/test_related_tag_usage_body.py b/test/test_related_tag_usage_body.py new file mode 100644 index 0000000..8282cf3 --- /dev/null +++ b/test/test_related_tag_usage_body.py @@ -0,0 +1,57 @@ +# coding: utf-8 + +""" + EverOS Cloud Memory API + + Official Python client for the EverOS Cloud Memory API. Add, search, retrieve, and manage long-term memory for your AI applications over a typed interface (pydantic v2, with full type hints). Install and usage guides: https://github.com/EverMind-AI/everos-cloud-sdk-python + + The version of the OpenAPI document: 2.0.0 + Contact: service@evermind.ai + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from everos_cloud.models.related_tag_usage_body import RelatedTagUsageBody + +class TestRelatedTagUsageBody(unittest.TestCase): + """RelatedTagUsageBody unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> RelatedTagUsageBody: + """Test RelatedTagUsageBody + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `RelatedTagUsageBody` + """ + model = RelatedTagUsageBody() + if include_optional: + return RelatedTagUsageBody( + tag_ids = [ + '0' + ] + ) + else: + return RelatedTagUsageBody( + tag_ids = [ + '0' + ], + ) + """ + + def testRelatedTagUsageBody(self): + """Test RelatedTagUsageBody""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/test/test_related_tag_usage_item.py b/test/test_related_tag_usage_item.py new file mode 100644 index 0000000..e8b6568 --- /dev/null +++ b/test/test_related_tag_usage_item.py @@ -0,0 +1,55 @@ +# coding: utf-8 + +""" + EverOS Cloud Memory API + + Official Python client for the EverOS Cloud Memory API. Add, search, retrieve, and manage long-term memory for your AI applications over a typed interface (pydantic v2, with full type hints). Install and usage guides: https://github.com/EverMind-AI/everos-cloud-sdk-python + + The version of the OpenAPI document: 2.0.0 + Contact: service@evermind.ai + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from everos_cloud.models.related_tag_usage_item import RelatedTagUsageItem + +class TestRelatedTagUsageItem(unittest.TestCase): + """RelatedTagUsageItem unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> RelatedTagUsageItem: + """Test RelatedTagUsageItem + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `RelatedTagUsageItem` + """ + model = RelatedTagUsageItem() + if include_optional: + return RelatedTagUsageItem( + id = '0', + document_count = 56 + ) + else: + return RelatedTagUsageItem( + id = '0', + document_count = 56, + ) + """ + + def testRelatedTagUsageItem(self): + """Test RelatedTagUsageItem""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/test/test_related_tag_usage_list_data.py b/test/test_related_tag_usage_list_data.py new file mode 100644 index 0000000..0385696 --- /dev/null +++ b/test/test_related_tag_usage_list_data.py @@ -0,0 +1,59 @@ +# coding: utf-8 + +""" + EverOS Cloud Memory API + + Official Python client for the EverOS Cloud Memory API. Add, search, retrieve, and manage long-term memory for your AI applications over a typed interface (pydantic v2, with full type hints). Install and usage guides: https://github.com/EverMind-AI/everos-cloud-sdk-python + + The version of the OpenAPI document: 2.0.0 + Contact: service@evermind.ai + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from everos_cloud.models.related_tag_usage_list_data import RelatedTagUsageListData + +class TestRelatedTagUsageListData(unittest.TestCase): + """RelatedTagUsageListData unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> RelatedTagUsageListData: + """Test RelatedTagUsageListData + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `RelatedTagUsageListData` + """ + model = RelatedTagUsageListData() + if include_optional: + return RelatedTagUsageListData( + items = [ + { } + ], + total = 0.0 + ) + else: + return RelatedTagUsageListData( + items = [ + { } + ], + total = 0.0, + ) + """ + + def testRelatedTagUsageListData(self): + """Test RelatedTagUsageListData""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/test/test_search_agent_skill_item.py b/test/test_search_agent_skill_item.py index 7489de1..15e3f4a 100644 --- a/test/test_search_agent_skill_item.py +++ b/test/test_search_agent_skill_item.py @@ -48,6 +48,8 @@ def make_instance(self, include_optional) -> SearchAgentSkillItem: source_case_ids = [ '' ], + created_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), + updated_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), score = 1.337 ) else: diff --git a/test/test_search_body.py b/test/test_search_body.py index 856db31..8fba6eb 100644 --- a/test/test_search_body.py +++ b/test/test_search_body.py @@ -36,18 +36,21 @@ def make_instance(self, include_optional) -> SearchBody: model = SearchBody() if include_optional: return SearchBody( - query = '0', + query = '', method = 'hybrid', + page = 1.0, top_k = 1.0, score_threshold = 1.337, include = [ '' ], + boost_tag_ids = [ + '0' + ], filters = { } ) else: return SearchBody( - query = '0', ) """ diff --git a/test/test_search_data.py b/test/test_search_data.py index a9d9b69..5f00bb0 100644 --- a/test/test_search_data.py +++ b/test/test_search_data.py @@ -70,6 +70,8 @@ def make_instance(self, include_optional) -> SearchData: project_id = '', user_id = '', profile_data = { }, + created_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), + updated_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), score = 1.337, ) ], agent_cases = [ @@ -100,6 +102,8 @@ def make_instance(self, include_optional) -> SearchData: source_case_ids = [ '' ], + created_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), + updated_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), score = 1.337, ) ], unprocessed_messages = [ diff --git a/test/test_search_filters.py b/test/test_search_filters.py index a24d852..72a51e9 100644 --- a/test/test_search_filters.py +++ b/test/test_search_filters.py @@ -36,7 +36,10 @@ def make_instance(self, include_optional) -> SearchFilters: model = SearchFilters() if include_optional: return SearchFilters( - category_id = '' + category_id = '', + tag_ids = [ + '0' + ] ) else: return SearchFilters( diff --git a/test/test_search_hit.py b/test/test_search_hit.py index dd7f1ad..61f5c9f 100644 --- a/test/test_search_hit.py +++ b/test/test_search_hit.py @@ -47,18 +47,29 @@ def make_instance(self, include_optional) -> SearchHit: summary = '', content = '', score = 1.337, - retrieval_method = 'hybrid', + retrieval_method = 'keyword', source = '', document = everos_cloud.models.document_context.DocumentContext( doc_id = '', title = '', - summary = '', ) + summary = '', ), + tags = [ + { } + ], + updated_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f') ) else: return SearchHit( + object = 'topic', id = '', doc_id = '', kb_id = '', + name = '', + score = 1.337, + retrieval_method = 'keyword', + tags = [ + { } + ], ) """ diff --git a/test/test_search_profile_item.py b/test/test_search_profile_item.py index 5d08ac1..ca78ba4 100644 --- a/test/test_search_profile_item.py +++ b/test/test_search_profile_item.py @@ -41,6 +41,8 @@ def make_instance(self, include_optional) -> SearchProfileItem: project_id = '', user_id = '', profile_data = { }, + created_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), + updated_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), score = 1.337 ) else: diff --git a/test/test_success_envelope_doc_data.py b/test/test_success_envelope_doc_data.py index 098028c..db6a3a6 100644 --- a/test/test_success_envelope_doc_data.py +++ b/test/test_success_envelope_doc_data.py @@ -46,6 +46,9 @@ def make_instance(self, include_optional) -> SuccessEnvelopeDocData: summary = '', source_name = '', source_type = '', + tags = [ + { } + ], topic_count = 56, created_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), updated_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), ) @@ -62,6 +65,9 @@ def make_instance(self, include_optional) -> SuccessEnvelopeDocData: summary = '', source_name = '', source_type = '', + tags = [ + { } + ], topic_count = 56, created_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), updated_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), ), diff --git a/test/test_success_envelope_doc_list_data.py b/test/test_success_envelope_doc_list_data.py index 3d8182f..08d94fe 100644 --- a/test/test_success_envelope_doc_list_data.py +++ b/test/test_success_envelope_doc_list_data.py @@ -48,6 +48,9 @@ def make_instance(self, include_optional) -> SuccessEnvelopeDocListData: summary = '', source_name = '', source_type = '', + tags = [ + { } + ], topic_count = 56, created_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), updated_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), ) @@ -68,6 +71,9 @@ def make_instance(self, include_optional) -> SuccessEnvelopeDocListData: summary = '', source_name = '', source_type = '', + tags = [ + { } + ], topic_count = 56, created_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), updated_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), ) diff --git a/test/test_success_envelope_get_data.py b/test/test_success_envelope_get_data.py index 57005eb..3b6578c 100644 --- a/test/test_success_envelope_get_data.py +++ b/test/test_success_envelope_get_data.py @@ -69,7 +69,9 @@ def make_instance(self, include_optional) -> SuccessEnvelopeGetData: app_id = '', project_id = '', user_id = '', - profile_data = { }, ) + profile_data = { }, + created_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), + updated_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), ) ], agent_cases = [ everos_cloud.models.agent_case_item.AgentCaseItem( @@ -97,7 +99,9 @@ def make_instance(self, include_optional) -> SuccessEnvelopeGetData: maturity_score = 1.337, source_case_ids = [ '' - ], ) + ], + created_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), + updated_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), ) ], total_count = 56, count = 56, ) @@ -137,7 +141,9 @@ def make_instance(self, include_optional) -> SuccessEnvelopeGetData: app_id = '', project_id = '', user_id = '', - profile_data = { }, ) + profile_data = { }, + created_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), + updated_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), ) ], agent_cases = [ everos_cloud.models.agent_case_item.AgentCaseItem( @@ -165,7 +171,9 @@ def make_instance(self, include_optional) -> SuccessEnvelopeGetData: maturity_score = 1.337, source_case_ids = [ '' - ], ) + ], + created_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), + updated_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), ) ], total_count = 56, count = 56, ), diff --git a/test/test_success_envelope_kb_search_data.py b/test/test_success_envelope_kb_search_data.py index fab6adb..ee080ac 100644 --- a/test/test_success_envelope_kb_search_data.py +++ b/test/test_success_envelope_kb_search_data.py @@ -51,12 +51,16 @@ def make_instance(self, include_optional) -> SuccessEnvelopeKbSearchData: summary = '', content = '', score = 1.337, - retrieval_method = 'hybrid', + retrieval_method = 'keyword', source = '', document = everos_cloud.models.document_context.DocumentContext( doc_id = '', title = '', - summary = '', ), ) + summary = '', ), + tags = [ + { } + ], + updated_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), ) ], total = 56, took_ms = 1.337, ) @@ -78,12 +82,16 @@ def make_instance(self, include_optional) -> SuccessEnvelopeKbSearchData: summary = '', content = '', score = 1.337, - retrieval_method = 'hybrid', + retrieval_method = 'keyword', source = '', document = everos_cloud.models.document_context.DocumentContext( doc_id = '', title = '', - summary = '', ), ) + summary = '', ), + tags = [ + { } + ], + updated_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), ) ], total = 56, took_ms = 1.337, ), diff --git a/test/test_success_envelope_related_tag_usage_list_data.py b/test/test_success_envelope_related_tag_usage_list_data.py new file mode 100644 index 0000000..10f3a1e --- /dev/null +++ b/test/test_success_envelope_related_tag_usage_list_data.py @@ -0,0 +1,55 @@ +# coding: utf-8 + +""" + EverOS Cloud Memory API + + Official Python client for the EverOS Cloud Memory API. Add, search, retrieve, and manage long-term memory for your AI applications over a typed interface (pydantic v2, with full type hints). Install and usage guides: https://github.com/EverMind-AI/everos-cloud-sdk-python + + The version of the OpenAPI document: 2.0.0 + Contact: service@evermind.ai + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from everos_cloud.models.success_envelope_related_tag_usage_list_data import SuccessEnvelopeRelatedTagUsageListData + +class TestSuccessEnvelopeRelatedTagUsageListData(unittest.TestCase): + """SuccessEnvelopeRelatedTagUsageListData unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> SuccessEnvelopeRelatedTagUsageListData: + """Test SuccessEnvelopeRelatedTagUsageListData + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `SuccessEnvelopeRelatedTagUsageListData` + """ + model = SuccessEnvelopeRelatedTagUsageListData() + if include_optional: + return SuccessEnvelopeRelatedTagUsageListData( + request_id = '', + data = { } + ) + else: + return SuccessEnvelopeRelatedTagUsageListData( + request_id = '', + data = { }, + ) + """ + + def testSuccessEnvelopeRelatedTagUsageListData(self): + """Test SuccessEnvelopeRelatedTagUsageListData""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/test/test_success_envelope_search_data.py b/test/test_success_envelope_search_data.py index d9bcac8..acba23c 100644 --- a/test/test_success_envelope_search_data.py +++ b/test/test_success_envelope_search_data.py @@ -72,6 +72,8 @@ def make_instance(self, include_optional) -> SuccessEnvelopeSearchData: project_id = '', user_id = '', profile_data = { }, + created_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), + updated_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), score = 1.337, ) ], agent_cases = [ @@ -102,6 +104,8 @@ def make_instance(self, include_optional) -> SuccessEnvelopeSearchData: source_case_ids = [ '' ], + created_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), + updated_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), score = 1.337, ) ], unprocessed_messages = [ @@ -164,6 +168,8 @@ def make_instance(self, include_optional) -> SuccessEnvelopeSearchData: project_id = '', user_id = '', profile_data = { }, + created_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), + updated_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), score = 1.337, ) ], agent_cases = [ @@ -194,6 +200,8 @@ def make_instance(self, include_optional) -> SuccessEnvelopeSearchData: source_case_ids = [ '' ], + created_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), + updated_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), score = 1.337, ) ], unprocessed_messages = [ diff --git a/test/test_success_envelope_topic_detail_data.py b/test/test_success_envelope_topic_detail_data.py index d8617ad..1e2bb74 100644 --- a/test/test_success_envelope_topic_detail_data.py +++ b/test/test_success_envelope_topic_detail_data.py @@ -41,6 +41,7 @@ def make_instance(self, include_optional) -> SuccessEnvelopeTopicDetailData: id = '', doc_id = '', kb_id = '', + type = 'root', category_id = '', category_name = '', name = '', @@ -56,6 +57,10 @@ def make_instance(self, include_optional) -> SuccessEnvelopeTopicDetailData: '' ], metadata = { }, + tag_ids = [ + '0' + ], + version = 0.0, created_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), updated_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), ) ) @@ -66,6 +71,7 @@ def make_instance(self, include_optional) -> SuccessEnvelopeTopicDetailData: id = '', doc_id = '', kb_id = '', + type = 'root', category_id = '', category_name = '', name = '', @@ -81,6 +87,10 @@ def make_instance(self, include_optional) -> SuccessEnvelopeTopicDetailData: '' ], metadata = { }, + tag_ids = [ + '0' + ], + version = 0.0, created_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), updated_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), ), ) diff --git a/test/test_success_envelope_topic_filter_list_data.py b/test/test_success_envelope_topic_filter_list_data.py new file mode 100644 index 0000000..fea024c --- /dev/null +++ b/test/test_success_envelope_topic_filter_list_data.py @@ -0,0 +1,55 @@ +# coding: utf-8 + +""" + EverOS Cloud Memory API + + Official Python client for the EverOS Cloud Memory API. Add, search, retrieve, and manage long-term memory for your AI applications over a typed interface (pydantic v2, with full type hints). Install and usage guides: https://github.com/EverMind-AI/everos-cloud-sdk-python + + The version of the OpenAPI document: 2.0.0 + Contact: service@evermind.ai + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from everos_cloud.models.success_envelope_topic_filter_list_data import SuccessEnvelopeTopicFilterListData + +class TestSuccessEnvelopeTopicFilterListData(unittest.TestCase): + """SuccessEnvelopeTopicFilterListData unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> SuccessEnvelopeTopicFilterListData: + """Test SuccessEnvelopeTopicFilterListData + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `SuccessEnvelopeTopicFilterListData` + """ + model = SuccessEnvelopeTopicFilterListData() + if include_optional: + return SuccessEnvelopeTopicFilterListData( + request_id = '', + data = { } + ) + else: + return SuccessEnvelopeTopicFilterListData( + request_id = '', + data = { }, + ) + """ + + def testSuccessEnvelopeTopicFilterListData(self): + """Test SuccessEnvelopeTopicFilterListData""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/test/test_success_envelope_topic_list_data.py b/test/test_success_envelope_topic_list_data.py index 913305d..9a6f254 100644 --- a/test/test_success_envelope_topic_list_data.py +++ b/test/test_success_envelope_topic_list_data.py @@ -41,6 +41,8 @@ def make_instance(self, include_optional) -> SuccessEnvelopeTopicListData: topics = [ everos_cloud.models.topic_list_item.TopicListItem( id = '', + doc_id = '', + kb_id = '', name = '', type = 'section', depth = 56, @@ -48,6 +50,10 @@ def make_instance(self, include_optional) -> SuccessEnvelopeTopicListData: parent_id = '', summary = '', content = '', + tag_ids = [ + '0' + ], + version = 0.0, created_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), updated_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), ) ], ) @@ -59,6 +65,8 @@ def make_instance(self, include_optional) -> SuccessEnvelopeTopicListData: topics = [ everos_cloud.models.topic_list_item.TopicListItem( id = '', + doc_id = '', + kb_id = '', name = '', type = 'section', depth = 56, @@ -66,6 +74,10 @@ def make_instance(self, include_optional) -> SuccessEnvelopeTopicListData: parent_id = '', summary = '', content = '', + tag_ids = [ + '0' + ], + version = 0.0, created_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), updated_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), ) ], ), diff --git a/test/test_success_envelope_topic_tag_write_data.py b/test/test_success_envelope_topic_tag_write_data.py new file mode 100644 index 0000000..a23252f --- /dev/null +++ b/test/test_success_envelope_topic_tag_write_data.py @@ -0,0 +1,55 @@ +# coding: utf-8 + +""" + EverOS Cloud Memory API + + Official Python client for the EverOS Cloud Memory API. Add, search, retrieve, and manage long-term memory for your AI applications over a typed interface (pydantic v2, with full type hints). Install and usage guides: https://github.com/EverMind-AI/everos-cloud-sdk-python + + The version of the OpenAPI document: 2.0.0 + Contact: service@evermind.ai + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from everos_cloud.models.success_envelope_topic_tag_write_data import SuccessEnvelopeTopicTagWriteData + +class TestSuccessEnvelopeTopicTagWriteData(unittest.TestCase): + """SuccessEnvelopeTopicTagWriteData unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> SuccessEnvelopeTopicTagWriteData: + """Test SuccessEnvelopeTopicTagWriteData + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `SuccessEnvelopeTopicTagWriteData` + """ + model = SuccessEnvelopeTopicTagWriteData() + if include_optional: + return SuccessEnvelopeTopicTagWriteData( + request_id = '', + data = { } + ) + else: + return SuccessEnvelopeTopicTagWriteData( + request_id = '', + data = { }, + ) + """ + + def testSuccessEnvelopeTopicTagWriteData(self): + """Test SuccessEnvelopeTopicTagWriteData""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/test/test_tag_ref.py b/test/test_tag_ref.py new file mode 100644 index 0000000..41fe720 --- /dev/null +++ b/test/test_tag_ref.py @@ -0,0 +1,54 @@ +# coding: utf-8 + +""" + EverOS Cloud Memory API + + Official Python client for the EverOS Cloud Memory API. Add, search, retrieve, and manage long-term memory for your AI applications over a typed interface (pydantic v2, with full type hints). Install and usage guides: https://github.com/EverMind-AI/everos-cloud-sdk-python + + The version of the OpenAPI document: 2.0.0 + Contact: service@evermind.ai + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from everos_cloud.models.tag_ref import TagRef + +class TestTagRef(unittest.TestCase): + """TagRef unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> TagRef: + """Test TagRef + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `TagRef` + """ + model = TagRef() + if include_optional: + return TagRef( + id = '', + name = '' + ) + else: + return TagRef( + id = '', + ) + """ + + def testTagRef(self): + """Test TagRef""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/test/test_topic_detail_data.py b/test/test_topic_detail_data.py index 68180ba..70d513a 100644 --- a/test/test_topic_detail_data.py +++ b/test/test_topic_detail_data.py @@ -39,6 +39,7 @@ def make_instance(self, include_optional) -> TopicDetailData: id = '', doc_id = '', kb_id = '', + type = 'root', category_id = '', category_name = '', name = '', @@ -54,6 +55,10 @@ def make_instance(self, include_optional) -> TopicDetailData: '' ], metadata = { }, + tag_ids = [ + '0' + ], + version = 0.0, created_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), updated_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f') ) @@ -62,7 +67,12 @@ def make_instance(self, include_optional) -> TopicDetailData: id = '', doc_id = '', kb_id = '', + type = 'root', name = '', + tag_ids = [ + '0' + ], + version = 0.0, ) """ diff --git a/test/test_topic_filter_item.py b/test/test_topic_filter_item.py new file mode 100644 index 0000000..0f49a43 --- /dev/null +++ b/test/test_topic_filter_item.py @@ -0,0 +1,70 @@ +# coding: utf-8 + +""" + EverOS Cloud Memory API + + Official Python client for the EverOS Cloud Memory API. Add, search, retrieve, and manage long-term memory for your AI applications over a typed interface (pydantic v2, with full type hints). Install and usage guides: https://github.com/EverMind-AI/everos-cloud-sdk-python + + The version of the OpenAPI document: 2.0.0 + Contact: service@evermind.ai + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from everos_cloud.models.topic_filter_item import TopicFilterItem + +class TestTopicFilterItem(unittest.TestCase): + """TopicFilterItem unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> TopicFilterItem: + """Test TopicFilterItem + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `TopicFilterItem` + """ + model = TopicFilterItem() + if include_optional: + return TopicFilterItem( + id = '', + doc_id = '', + kb_id = '', + name = '', + type = 'section', + depth = 0.0, + seq = 0.0, + parent_id = '', + summary = '', + tag_ids = [ + '0' + ], + version = 0.0 + ) + else: + return TopicFilterItem( + id = '', + name = '', + tag_ids = [ + '0' + ], + version = 0.0, + ) + """ + + def testTopicFilterItem(self): + """Test TopicFilterItem""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/test/test_topic_filter_list_data.py b/test/test_topic_filter_list_data.py new file mode 100644 index 0000000..f51c73d --- /dev/null +++ b/test/test_topic_filter_list_data.py @@ -0,0 +1,59 @@ +# coding: utf-8 + +""" + EverOS Cloud Memory API + + Official Python client for the EverOS Cloud Memory API. Add, search, retrieve, and manage long-term memory for your AI applications over a typed interface (pydantic v2, with full type hints). Install and usage guides: https://github.com/EverMind-AI/everos-cloud-sdk-python + + The version of the OpenAPI document: 2.0.0 + Contact: service@evermind.ai + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from everos_cloud.models.topic_filter_list_data import TopicFilterListData + +class TestTopicFilterListData(unittest.TestCase): + """TopicFilterListData unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> TopicFilterListData: + """Test TopicFilterListData + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `TopicFilterListData` + """ + model = TopicFilterListData() + if include_optional: + return TopicFilterListData( + topics = [ + { } + ], + total = 0.0 + ) + else: + return TopicFilterListData( + topics = [ + { } + ], + total = 0.0, + ) + """ + + def testTopicFilterListData(self): + """Test TopicFilterListData""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/test/test_topic_list_data.py b/test/test_topic_list_data.py index 5f16231..8bf9963 100644 --- a/test/test_topic_list_data.py +++ b/test/test_topic_list_data.py @@ -39,6 +39,8 @@ def make_instance(self, include_optional) -> TopicListData: topics = [ everos_cloud.models.topic_list_item.TopicListItem( id = '', + doc_id = '', + kb_id = '', name = '', type = 'section', depth = 56, @@ -46,6 +48,10 @@ def make_instance(self, include_optional) -> TopicListData: parent_id = '', summary = '', content = '', + tag_ids = [ + '0' + ], + version = 0.0, created_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), updated_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), ) ] diff --git a/test/test_topic_list_item.py b/test/test_topic_list_item.py index 443d271..50ca1da 100644 --- a/test/test_topic_list_item.py +++ b/test/test_topic_list_item.py @@ -37,6 +37,8 @@ def make_instance(self, include_optional) -> TopicListItem: if include_optional: return TopicListItem( id = '', + doc_id = '', + kb_id = '', name = '', type = 'section', depth = 56, @@ -44,6 +46,10 @@ def make_instance(self, include_optional) -> TopicListItem: parent_id = '', summary = '', content = '', + tag_ids = [ + '0' + ], + version = 0.0, created_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), updated_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f') ) diff --git a/test/test_topic_tag_replace_body.py b/test/test_topic_tag_replace_body.py new file mode 100644 index 0000000..af1ce98 --- /dev/null +++ b/test/test_topic_tag_replace_body.py @@ -0,0 +1,59 @@ +# coding: utf-8 + +""" + EverOS Cloud Memory API + + Official Python client for the EverOS Cloud Memory API. Add, search, retrieve, and manage long-term memory for your AI applications over a typed interface (pydantic v2, with full type hints). Install and usage guides: https://github.com/EverMind-AI/everos-cloud-sdk-python + + The version of the OpenAPI document: 2.0.0 + Contact: service@evermind.ai + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from everos_cloud.models.topic_tag_replace_body import TopicTagReplaceBody + +class TestTopicTagReplaceBody(unittest.TestCase): + """TopicTagReplaceBody unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> TopicTagReplaceBody: + """Test TopicTagReplaceBody + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `TopicTagReplaceBody` + """ + model = TopicTagReplaceBody() + if include_optional: + return TopicTagReplaceBody( + tag_ids = [ + '0' + ], + version = 0.0 + ) + else: + return TopicTagReplaceBody( + tag_ids = [ + '0' + ], + version = 0.0, + ) + """ + + def testTopicTagReplaceBody(self): + """Test TopicTagReplaceBody""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/test/test_topic_tag_write_data.py b/test/test_topic_tag_write_data.py new file mode 100644 index 0000000..61ad408 --- /dev/null +++ b/test/test_topic_tag_write_data.py @@ -0,0 +1,69 @@ +# coding: utf-8 + +""" + EverOS Cloud Memory API + + Official Python client for the EverOS Cloud Memory API. Add, search, retrieve, and manage long-term memory for your AI applications over a typed interface (pydantic v2, with full type hints). Install and usage guides: https://github.com/EverMind-AI/everos-cloud-sdk-python + + The version of the OpenAPI document: 2.0.0 + Contact: service@evermind.ai + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from everos_cloud.models.topic_tag_write_data import TopicTagWriteData + +class TestTopicTagWriteData(unittest.TestCase): + """TopicTagWriteData unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> TopicTagWriteData: + """Test TopicTagWriteData + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `TopicTagWriteData` + """ + model = TopicTagWriteData() + if include_optional: + return TopicTagWriteData( + topic_id = '', + requested = 0.0, + tag_ids = [ + '0' + ], + version = 0.0, + truncated = True, + limit = 50, + dropped_count = 0.0 + ) + else: + return TopicTagWriteData( + topic_id = '', + requested = 0.0, + tag_ids = [ + '0' + ], + version = 0.0, + truncated = True, + limit = 50, + dropped_count = 0.0, + ) + """ + + def testTopicTagWriteData(self): + """Test TopicTagWriteData""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main()