From e1f8642bda5ff280cacb1b37a01e60cecf587f63 Mon Sep 17 00:00:00 2001 From: "fern-api[bot]" <115122769+fern-api[bot]@users.noreply.github.com> Date: Tue, 6 Oct 2026 17:55:32 +0000 Subject: [PATCH 1/3] [fern-generated] Update SDK Generated by Fern CLI Version: unknown Generators: - fernapi/fern-python-sdk: 5.34.3 --- .fern/metadata.json | 15 +- CONTRIBUTING.md | 125 + README.md | 118 +- poetry.lock | 1370 +- pyproject.toml | 24 +- reference.md | 11213 ++++++++++++++-- requirements.txt | 2 +- src/zep_cloud/__init__.py | 695 +- src/zep_cloud/_default_clients.py | 30 + src/zep_cloud/agent/__init__.py | 62 + src/zep_cloud/agent/client.py | 1086 ++ src/zep_cloud/agent/learning/__init__.py | 4 + src/zep_cloud/agent/learning/client.py | 234 + src/zep_cloud/agent/learning/raw_client.py | 419 + .../agent/literal_policy/__init__.py | 34 + src/zep_cloud/agent/literal_policy/client.py | 266 + .../agent/literal_policy/raw_client.py | 490 + .../agent/literal_policy/types/__init__.py | 36 + ...te_agent_literal_policy_request_default.py | 5 + src/zep_cloud/agent/raw_client.py | 1889 +++ src/zep_cloud/agent/skill/__init__.py | 80 + .../agent/skill/candidate/__init__.py | 4 + src/zep_cloud/agent/skill/candidate/client.py | 222 + .../agent/skill/candidate/raw_client.py | 513 + src/zep_cloud/agent/skill/client.py | 1127 ++ .../agent/skill/evaluation/__init__.py | 49 + .../agent/skill/evaluation/client.py | 420 + .../agent/skill/evaluation/raw_client.py | 678 + .../agent/skill/evaluation/types/__init__.py | 51 + ...ndidate_evaluation_request_evaluated_by.py | 7 + ...ll_candidate_evaluation_request_verdict.py | 7 + ...t_skill_evaluation_request_evaluated_by.py | 7 + ..._agent_skill_evaluation_request_verdict.py | 7 + .../agent/skill/evidence/__init__.py | 4 + src/zep_cloud/agent/skill/evidence/client.py | 157 + .../agent/skill/evidence/raw_client.py | 292 + src/zep_cloud/agent/skill/export/__init__.py | 4 + src/zep_cloud/agent/skill/export/client.py | 255 + .../agent/skill/export/raw_client.py | 507 + .../agent/skill/publication/__init__.py | 4 + .../agent/skill/publication/client.py | 244 + .../agent/skill/publication/raw_client.py | 484 + src/zep_cloud/agent/skill/raw_client.py | 2206 +++ .../agent/skill/relation/__init__.py | 34 + src/zep_cloud/agent/skill/relation/client.py | 170 + .../agent/skill/relation/raw_client.py | 309 + .../agent/skill/relation/types/__init__.py | 34 + .../types/relation_list_request_kind_item.py | 20 + src/zep_cloud/agent/skill/types/__init__.py | 36 + ...nt_skill_search_request_markdown_format.py | 5 + src/zep_cloud/agent/skill/use/__init__.py | 34 + src/zep_cloud/agent/skill/use/client.py | 319 + src/zep_cloud/agent/skill/use/raw_client.py | 479 + .../agent/skill/use/types/__init__.py | 34 + .../create_agent_skill_use_request_usage.py | 7 + src/zep_cloud/agent/skill/version/__init__.py | 37 + src/zep_cloud/agent/skill/version/client.py | 517 + .../agent/skill/version/raw_client.py | 1065 ++ .../agent/skill/version/types/__init__.py | 38 + .../version_get_request_markdown_format.py | 5 + .../version_list_request_markdown_format.py | 5 + src/zep_cloud/agent/split/__init__.py | 4 + src/zep_cloud/agent/split/client.py | 206 + src/zep_cloud/agent/split/raw_client.py | 296 + src/zep_cloud/agent/trajectory/__init__.py | 34 + src/zep_cloud/agent/trajectory/client.py | 1887 +++ src/zep_cloud/agent/trajectory/raw_client.py | 3002 +++++ .../agent/trajectory/types/__init__.py | 34 + .../trajectory_list_request_source_kind.py | 5 + .../agent/trajectory_import/__init__.py | 35 + .../agent/trajectory_import/client.py | 947 ++ .../agent/trajectory_import/raw_client.py | 1724 +++ .../agent/trajectory_import/run/__init__.py | 34 + .../agent/trajectory_import/run/client.py | 387 + .../trajectory_import/run/item/__init__.py | 4 + .../trajectory_import/run/item/client.py | 171 + .../trajectory_import/run/item/raw_client.py | 260 + .../agent/trajectory_import/run/raw_client.py | 644 + .../agent/trajectory_import/types/__init__.py | 36 + ...tory_import_delete_request_trajectories.py | 5 + src/zep_cloud/agent/verifier/__init__.py | 4 + src/zep_cloud/agent/verifier/client.py | 682 + src/zep_cloud/agent/verifier/raw_client.py | 1096 ++ src/zep_cloud/base_client.py | 125 +- src/zep_cloud/batch/__init__.py | 30 + src/zep_cloud/batch/client.py | 25 +- src/zep_cloud/batch/raw_client.py | 48 +- src/zep_cloud/batch/types/__init__.py | 34 + .../batch/types/batch_list_request_status.py | 7 + src/zep_cloud/client.py | 17 +- src/zep_cloud/context/client.py | 22 +- src/zep_cloud/context/raw_client.py | 61 +- src/zep_cloud/core/__init__.py | 7 +- src/zep_cloud/core/client_wrapper.py | 49 +- src/zep_cloud/core/http_client.py | 307 +- src/zep_cloud/core/http_response.py | 4 + src/zep_cloud/core/http_sse/_api.py | 409 +- src/zep_cloud/core/http_sse/_decoders.py | 13 + src/zep_cloud/core/idempotency.py | 7 + src/zep_cloud/core/jsonable_encoder.py | 25 + src/zep_cloud/core/pagination.py | 85 +- src/zep_cloud/core/pydantic_utilities.py | 320 +- src/zep_cloud/core/request_options.py | 7 +- src/zep_cloud/core/serialization.py | 87 +- src/zep_cloud/debug_log/__init__.py | 4 + src/zep_cloud/debug_log/client.py | 108 + src/zep_cloud/debug_log/raw_client.py | 192 + src/zep_cloud/errors/__init__.py | 20 +- src/zep_cloud/errors/bad_gateway_error.py | 11 + .../errors/content_too_large_error.py | 11 + .../errors/service_unavailable_error.py | 11 + .../errors/unprocessable_entity_error.py | 11 + src/zep_cloud/graph/__init__.py | 58 +- src/zep_cloud/graph/client.py | 481 +- .../graph/document_summary/client.py | 24 +- .../graph/document_summary/raw_client.py | 19 +- src/zep_cloud/graph/edge/client.py | 192 +- src/zep_cloud/graph/edge/raw_client.py | 203 +- src/zep_cloud/graph/episode/__init__.py | 10 +- src/zep_cloud/graph/episode/client.py | 274 +- src/zep_cloud/graph/episode/raw_client.py | 543 +- src/zep_cloud/graph/episode/types/__init__.py | 12 +- .../episode/types/add_episode_request_type.py | 5 + .../types/episode_list_request_order.py | 5 + .../types/episode_list_request_order_by.py | 5 + .../types/v4add_episode_request_type.py | 5 - src/zep_cloud/graph/hyperedge/__init__.py | 37 + src/zep_cloud/graph/hyperedge/client.py | 959 ++ src/zep_cloud/graph/hyperedge/raw_client.py | 1786 +++ .../graph/hyperedge/types/__init__.py | 38 + .../types/hyperedge_list_request_order.py | 5 + .../types/hyperedge_list_request_order_by.py | 5 + src/zep_cloud/graph/node/__init__.py | 24 +- src/zep_cloud/graph/node/client.py | 78 +- src/zep_cloud/graph/node/raw_client.py | 125 +- src/zep_cloud/graph/node/types/__init__.py | 22 +- .../node/types/neighbors_request_direction.py | 5 + .../node_list_neighbors_request_order.py | 5 + .../node_list_neighbors_request_order_by.py | 5 + .../node/types/node_list_request_order.py | 5 + .../node/types/node_list_request_order_by.py | 5 + .../types/v4neighbors_request_direction.py | 5 - src/zep_cloud/graph/observation/client.py | 24 +- src/zep_cloud/graph/observation/raw_client.py | 23 +- src/zep_cloud/graph/raw_client.py | 791 +- src/zep_cloud/graph/thread_summary/client.py | 24 +- .../graph/thread_summary/raw_client.py | 19 +- src/zep_cloud/graph/types/__init__.py | 19 +- .../graph_context_request_recency_bias.py | 5 + .../graph/types/graph_list_request_order.py | 5 + .../types/graph_list_request_order_by.py | 5 + .../graph/types/subgraph_request_direction.py | 5 + .../v4graph_context_request_recency_bias.py | 5 - .../types/v4subgraph_request_direction.py | 5 - src/zep_cloud/lookup/client.py | 20 +- src/zep_cloud/lookup/raw_client.py | 11 +- src/zep_cloud/project/client.py | 362 +- src/zep_cloud/project/raw_client.py | 1097 +- src/zep_cloud/task/client.py | 10 +- src/zep_cloud/task/raw_client.py | 6 +- src/zep_cloud/thread/__init__.py | 10 +- src/zep_cloud/thread/client.py | 97 +- src/zep_cloud/thread/message/client.py | 4 +- src/zep_cloud/thread/message/raw_client.py | 19 +- src/zep_cloud/thread/raw_client.py | 106 +- src/zep_cloud/thread/types/__init__.py | 40 + .../thread_list_messages_request_order.py | 5 + .../thread/types/thread_list_request_order.py | 5 + .../types/thread_list_request_order_by.py | 5 + src/zep_cloud/trace_connection/__init__.py | 34 + src/zep_cloud/trace_connection/client.py | 715 + .../trace_connection/project/__init__.py | 4 + .../trace_connection/project/client.py | 147 + .../trace_connection/project/raw_client.py | 263 + src/zep_cloud/trace_connection/raw_client.py | 1344 ++ .../trace_connection/trace/__init__.py | 4 + .../trace_connection/trace/client.py | 305 + .../trace_connection/trace/raw_client.py | 595 + src/zep_cloud/types/__init__.py | 615 +- .../add_agent_skill_use_outcome_request.py | 20 + ...agent_skill_use_outcome_request_outcome.py | 7 + src/zep_cloud/types/add_edges_result.py | 29 + ...result.py => add_hyperedge_edge_result.py} | 9 +- src/zep_cloud/types/add_hyperedge_result.py | 29 + src/zep_cloud/types/add_message.py | 12 +- src/zep_cloud/types/added_edge.py | 18 + src/zep_cloud/types/added_hyperedge.py | 64 + src/zep_cloud/types/added_hyperedge_edge.py | 44 + src/zep_cloud/types/added_node.py | 3 + src/zep_cloud/types/agent.py | 90 + src/zep_cloud/types/agent_breaking_change.py | 31 + src/zep_cloud/types/agent_context.py | 30 + .../types/agent_context_evidence_counts.py | 21 + .../types/agent_context_partial_source.py | 21 + src/zep_cloud/types/agent_context_resource.py | 20 + .../types/agent_context_skill_snapshot.py | 25 + .../types/agent_context_skipped_skill.py | 21 + src/zep_cloud/types/agent_delete_result.py | 23 + src/zep_cloud/types/agent_learning_state.py | 35 + src/zep_cloud/types/agent_literal_policy.py | 59 + .../types/agent_literal_policy_classes.py | 27 + .../types/agent_literal_policy_values.py | 27 + .../types/agent_memory_evaluation_policy.py | 21 + .../agent_memory_evaluation_requirement.py | 23 + src/zep_cloud/types/agent_memory_settings.py | 48 + .../types/agent_memory_settings_approval.py | 5 + .../agent_memory_settings_compilation_mode.py | 5 + src/zep_cloud/types/agent_page.py | 34 + src/zep_cloud/types/agent_skill.py | 34 + .../types/agent_skill_admission_decision.py | 24 + src/zep_cloud/types/agent_skill_candidate.py | 37 + .../agent_skill_candidate_base_version.py | 25 + .../types/agent_skill_candidate_evaluation.py | 34 + .../types/agent_skill_candidate_evidence.py | 29 + .../types/agent_skill_candidate_review.py | 39 + .../agent_skill_candidate_review_result.py | 28 + .../agent_skill_candidate_review_summary.py | 30 + .../types/agent_skill_compilation_outcome.py | 43 + ...ill_compilation_outcome_rejection_class.py | 18 + src/zep_cloud/types/agent_skill_evaluation.py | 35 + src/zep_cloud/types/agent_skill_evidence.py | 27 + .../types/agent_skill_publication_lineage.py | 67 + .../types/agent_skill_relationship.py | 33 + src/zep_cloud/types/agent_skill_search_hit.py | 62 + .../types/agent_skill_search_hit_maturity.py | 7 + .../types/agent_skill_search_response.py | 22 + src/zep_cloud/types/agent_skill_use.py | 32 + .../types/agent_skill_use_outcome.py | 29 + src/zep_cloud/types/agent_skill_version.py | 30 + .../types/agent_skill_version_comparison.py | 26 + src/zep_cloud/types/agent_split_plan.py | 31 + .../types/agent_split_plan_destination.py | 22 + .../agent_split_plan_destination_request.py | 22 + .../types/agent_split_plan_skill_reference.py | 24 + ...gent_split_plan_skill_selection_request.py | 21 + .../types/agent_split_plan_source.py | 20 + src/zep_cloud/types/agent_status.py | 5 + src/zep_cloud/types/agent_trajectory.py | 128 + .../types/agent_trajectory_close_verifier.py | 28 + src/zep_cloud/types/agent_trajectory_event.py | 42 + .../types/agent_trajectory_event_context.py | 24 + .../types/agent_trajectory_event_page.py | 22 + ...agent_trajectory_event_processing_state.py | 7 + .../types/agent_trajectory_event_source.py | 26 + ...agent_trajectory_event_source_copy_mode.py | 5 + ..._trajectory_event_source_retention_mode.py | 5 + .../types/agent_trajectory_event_type.py | 20 + .../agent_trajectory_finalization_result.py | 22 + .../types/agent_trajectory_internal.py | 25 + .../types/agent_trajectory_lifecycle.py | 5 + .../types/agent_trajectory_outcome.py | 7 + src/zep_cloud/types/agent_trajectory_page.py | 33 + .../agent_trajectory_processing_state.py | 5 + .../types/agent_trajectory_resource_ref.py | 20 + .../types/agent_trajectory_sequence_range.py | 20 + .../types/agent_trajectory_source.py | 36 + ...agent_trajectory_source_deletion_result.py | 25 + ...gent_trajectory_summary_creation_reason.py | 8 + ...gent_trajectory_summary_omission_reason.py | 10 + .../agent_trajectory_summary_omitted_range.py | 22 + .../types/agent_trajectory_summary_page.py | 22 + .../types/agent_trajectory_summary_version.py | 43 + .../types/agent_trajectory_verification.py | 5 + .../types/agent_verification_strength.py | 7 + src/zep_cloud/types/agent_verifier.py | 101 + .../types/agent_verifier_assertion_outcome.py | 7 + ...t_verifier_evidence_invalidation_result.py | 33 + .../types/agent_verifier_principal.py | 27 + .../types/agent_verifier_principal_binding.py | 38 + .../agent_verifier_principal_binding_input.py | 33 + src/zep_cloud/types/agent_verifier_status.py | 5 + src/zep_cloud/types/batch.py | 3 + src/zep_cloud/types/batch_item.py | 10 + src/zep_cloud/types/batch_item_input.py | 20 +- .../types/batch_item_input_data_type.py | 5 + src/zep_cloud/types/batch_item_input_role.py | 5 + src/zep_cloud/types/batch_item_input_type.py | 5 + src/zep_cloud/types/clone_graph_request.py | 5 + src/zep_cloud/types/comparison_operator.py | 7 - src/zep_cloud/types/content_policy.py | 54 + ...a_filter.py => content_policy_category.py} | 16 +- .../types/content_policy_category_request.py | 28 + src/zep_cloud/types/content_policy_event.py | 61 + .../content_policy_event_artifact_kind.py | 17 + .../types/content_policy_event_drop_reason.py | 7 + .../types/content_policy_event_page.py | 34 + .../types/content_policy_revision_page.py | 34 + src/zep_cloud/types/content_policy_rule.py | 43 + .../types/content_policy_rule_request.py | 41 + src/zep_cloud/types/context_edge.py | 10 + src/zep_cloud/types/context_episode.py | 11 + src/zep_cloud/types/context_node.py | 24 + src/zep_cloud/types/context_observation.py | 3 + src/zep_cloud/types/context_template.py | 3 + src/zep_cloud/types/context_thread_summary.py | 3 + src/zep_cloud/types/create_agent_request.py | 58 + src/zep_cloud/types/date_filter.py | 18 +- src/zep_cloud/types/date_filter_field.py | 5 + src/zep_cloud/types/date_filter_group.py | 23 + src/zep_cloud/types/date_filter_operator.py | 7 + src/zep_cloud/types/date_filters.py | 23 + src/zep_cloud/types/debug_log_entry.py | 33 + src/zep_cloud/types/debug_log_level.py | 5 + src/zep_cloud/types/debug_log_status.py | 5 + .../types/debug_logging_enablement.py | 28 + .../types/delete_agent_trajectory_request.py | 19 + src/zep_cloud/types/document_summary.py | 3 + src/zep_cloud/types/edge.py | 10 + src/zep_cloud/types/edge_input.py | 66 + src/zep_cloud/types/edge_node_ref.py | 5 +- src/zep_cloud/types/episode.py | 11 + src/zep_cloud/types/episode_content_policy.py | 51 + .../types/episode_content_policy_status.py | 5 + src/zep_cloud/types/episode_debug_log.py | 44 + src/zep_cloud/types/graph.py | 3 + src/zep_cloud/types/graph_content_policy.py | 65 + .../types/graph_content_policy_request.py | 37 + src/zep_cloud/types/graph_context_response.py | 7 +- .../graphiti_metadata_filter_group_type.py | 5 - src/zep_cloud/types/hyperedge.py | 66 + src/zep_cloud/types/hyperedge_edge.py | 43 + src/zep_cloud/types/hyperedge_input.py | 35 + src/zep_cloud/types/hyperedge_page.py | 21 + .../types/imported_trajectory_reference.py | 32 + src/zep_cloud/types/ingestion_trace.py | 62 + src/zep_cloud/types/ingestion_trace_edge.py | 84 + .../ingestion_trace_edge_invalidation.py | 28 + .../types/ingestion_trace_edge_reference.py | 33 + .../types/ingestion_trace_entity_type.py | 44 + .../types/ingestion_trace_episode.py | 43 + src/zep_cloud/types/ingestion_trace_input.py | 89 + src/zep_cloud/types/ingestion_trace_node.py | 65 + .../types/ingestion_trace_node_duplicate.py | 28 + .../types/ingestion_trace_node_resolution.py | 32 + src/zep_cloud/types/ingestion_trace_output.py | 71 + src/zep_cloud/types/ingestion_trace_page.py | 29 + src/zep_cloud/types/ingestion_trace_status.py | 5 + src/zep_cloud/types/ingestion_trace_step.py | 5 + src/zep_cloud/types/lookup_item.py | 3 + src/zep_cloud/types/message.py | 3 + src/zep_cloud/types/metadata_filter.py | 34 + src/zep_cloud/types/metadata_filter_group.py | 14 +- .../types/metadata_filter_group_type.py | 5 + .../types/metadata_filter_operator.py | 7 + src/zep_cloud/types/metadata_filter_value.py | 7 + .../types/metadata_filter_value_three_item.py | 5 + src/zep_cloud/types/node.py | 24 + src/zep_cloud/types/objective_mapping_rule.py | 28 + .../types/objective_mapping_rule_source.py | 5 + src/zep_cloud/types/observation.py | 3 + src/zep_cloud/types/ontology.py | 5 + src/zep_cloud/types/outcome_mapping_rule.py | 48 + .../types/outcome_mapping_rule_rule.py | 5 + ...ev4agent_skill_candidate_review_summary.py | 22 + .../pagev4agent_skill_compilation_outcome.py | 22 + .../types/pagev4agent_skill_evidence.py | 22 + .../types/pagev4agent_skill_relationship.py | 22 + .../types/pagev4agent_skill_search_hit.py | 22 + .../types/pagev4agent_skill_version.py | 22 + src/zep_cloud/types/pagev4agent_verifier.py | 22 + src/zep_cloud/types/project.py | 9 + src/zep_cloud/types/property_filter.py | 17 +- .../types/property_filter_operator.py | 7 + src/zep_cloud/types/property_filter_value.py | 7 + .../types/property_filter_value_three_item.py | 5 + src/zep_cloud/types/search_filters.py | 74 +- src/zep_cloud/types/search_request.py | 4 +- ...reranker.py => search_request_reranker.py} | 2 +- src/zep_cloud/types/skill_definition.py | 42 + .../types/skill_definition_section.py | 21 + src/zep_cloud/types/skill_failure.py | 20 + src/zep_cloud/types/skill_procedure_step.py | 21 + src/zep_cloud/types/skill_relation.py | 21 + src/zep_cloud/types/skill_resource.py | 21 + src/zep_cloud/types/source_span.py | 82 + src/zep_cloud/types/source_trace.py | 94 + src/zep_cloud/types/source_trace_page.py | 28 + src/zep_cloud/types/source_trace_response.py | 29 + src/zep_cloud/types/source_trace_summary.py | 88 + src/zep_cloud/types/task.py | 3 + .../types/task_family_mapping_rule.py | 43 + .../types/task_family_mapping_rule_source.py | 5 + src/zep_cloud/types/thread.py | 3 + .../types/thread_context_response.py | 4 +- src/zep_cloud/types/thread_summary.py | 3 + src/zep_cloud/types/trace_connection.py | 89 + src/zep_cloud/types/trace_connection_page.py | 33 + .../types/trace_connection_settings.py | 32 + src/zep_cloud/types/trace_filter.py | 58 + src/zep_cloud/types/trace_preview.py | 33 + src/zep_cloud/types/trace_provider_project.py | 32 + .../types/trace_provider_project_page.py | 28 + src/zep_cloud/types/trace_score_range.py | 32 + .../types/trajectory_content_mapping.py | 27 + src/zep_cloud/types/trajectory_import.py | 138 + src/zep_cloud/types/trajectory_import_page.py | 33 + .../types/trajectory_import_pause_reason.py | 7 + src/zep_cloud/types/trajectory_import_run.py | 88 + .../types/trajectory_import_run_item.py | 47 + .../types/trajectory_import_run_item_page.py | 33 + .../types/trajectory_import_run_page.py | 33 + .../types/trajectory_import_run_reference.py | 50 + .../trajectory_import_run_reference_status.py | 7 + ...trajectory_import_run_reference_trigger.py | 5 + .../types/trajectory_import_schedule.py | 37 + .../types/trajectory_import_selection.py | 28 + src/zep_cloud/types/trajectory_mapping.py | 52 + ...rajectory_mapping_include_outcomes_item.py | 7 + .../types/trajectory_mapping_result.py | 54 + .../trajectory_mapping_result_outcome.py | 7 + .../trajectory_mapping_result_outcome_rule.py | 5 + src/zep_cloud/types/user.py | 3 + src/zep_cloud/types/user_group.py | 4 + .../types/v4batch_item_input_data_type.py | 5 - .../types/v4batch_item_input_role.py | 5 - .../types/v4batch_item_input_type.py | 5 - src/zep_cloud/user/__init__.py | 30 + src/zep_cloud/user/client.py | 97 +- src/zep_cloud/user/raw_client.py | 112 +- src/zep_cloud/user/types/__init__.py | 38 + .../user/types/user_list_request_order.py | 5 + .../user/types/user_list_request_order_by.py | 5 + src/zep_cloud/user_group/client.py | 76 +- src/zep_cloud/user_group/raw_client.py | 99 +- tests/conftest.py | 21 + tests/test_aiohttp_autodetect.py | 116 + tests/utils/test_http_client.py | 582 +- 427 files changed, 57576 insertions(+), 3794 deletions(-) create mode 100644 CONTRIBUTING.md create mode 100644 src/zep_cloud/_default_clients.py create mode 100644 src/zep_cloud/agent/__init__.py create mode 100644 src/zep_cloud/agent/client.py create mode 100644 src/zep_cloud/agent/learning/__init__.py create mode 100644 src/zep_cloud/agent/learning/client.py create mode 100644 src/zep_cloud/agent/learning/raw_client.py create mode 100644 src/zep_cloud/agent/literal_policy/__init__.py create mode 100644 src/zep_cloud/agent/literal_policy/client.py create mode 100644 src/zep_cloud/agent/literal_policy/raw_client.py create mode 100644 src/zep_cloud/agent/literal_policy/types/__init__.py create mode 100644 src/zep_cloud/agent/literal_policy/types/update_agent_literal_policy_request_default.py create mode 100644 src/zep_cloud/agent/raw_client.py create mode 100644 src/zep_cloud/agent/skill/__init__.py create mode 100644 src/zep_cloud/agent/skill/candidate/__init__.py create mode 100644 src/zep_cloud/agent/skill/candidate/client.py create mode 100644 src/zep_cloud/agent/skill/candidate/raw_client.py create mode 100644 src/zep_cloud/agent/skill/client.py create mode 100644 src/zep_cloud/agent/skill/evaluation/__init__.py create mode 100644 src/zep_cloud/agent/skill/evaluation/client.py create mode 100644 src/zep_cloud/agent/skill/evaluation/raw_client.py create mode 100644 src/zep_cloud/agent/skill/evaluation/types/__init__.py create mode 100644 src/zep_cloud/agent/skill/evaluation/types/create_agent_skill_candidate_evaluation_request_evaluated_by.py create mode 100644 src/zep_cloud/agent/skill/evaluation/types/create_agent_skill_candidate_evaluation_request_verdict.py create mode 100644 src/zep_cloud/agent/skill/evaluation/types/create_agent_skill_evaluation_request_evaluated_by.py create mode 100644 src/zep_cloud/agent/skill/evaluation/types/create_agent_skill_evaluation_request_verdict.py create mode 100644 src/zep_cloud/agent/skill/evidence/__init__.py create mode 100644 src/zep_cloud/agent/skill/evidence/client.py create mode 100644 src/zep_cloud/agent/skill/evidence/raw_client.py create mode 100644 src/zep_cloud/agent/skill/export/__init__.py create mode 100644 src/zep_cloud/agent/skill/export/client.py create mode 100644 src/zep_cloud/agent/skill/export/raw_client.py create mode 100644 src/zep_cloud/agent/skill/publication/__init__.py create mode 100644 src/zep_cloud/agent/skill/publication/client.py create mode 100644 src/zep_cloud/agent/skill/publication/raw_client.py create mode 100644 src/zep_cloud/agent/skill/raw_client.py create mode 100644 src/zep_cloud/agent/skill/relation/__init__.py create mode 100644 src/zep_cloud/agent/skill/relation/client.py create mode 100644 src/zep_cloud/agent/skill/relation/raw_client.py create mode 100644 src/zep_cloud/agent/skill/relation/types/__init__.py create mode 100644 src/zep_cloud/agent/skill/relation/types/relation_list_request_kind_item.py create mode 100644 src/zep_cloud/agent/skill/types/__init__.py create mode 100644 src/zep_cloud/agent/skill/types/agent_skill_search_request_markdown_format.py create mode 100644 src/zep_cloud/agent/skill/use/__init__.py create mode 100644 src/zep_cloud/agent/skill/use/client.py create mode 100644 src/zep_cloud/agent/skill/use/raw_client.py create mode 100644 src/zep_cloud/agent/skill/use/types/__init__.py create mode 100644 src/zep_cloud/agent/skill/use/types/create_agent_skill_use_request_usage.py create mode 100644 src/zep_cloud/agent/skill/version/__init__.py create mode 100644 src/zep_cloud/agent/skill/version/client.py create mode 100644 src/zep_cloud/agent/skill/version/raw_client.py create mode 100644 src/zep_cloud/agent/skill/version/types/__init__.py create mode 100644 src/zep_cloud/agent/skill/version/types/version_get_request_markdown_format.py create mode 100644 src/zep_cloud/agent/skill/version/types/version_list_request_markdown_format.py create mode 100644 src/zep_cloud/agent/split/__init__.py create mode 100644 src/zep_cloud/agent/split/client.py create mode 100644 src/zep_cloud/agent/split/raw_client.py create mode 100644 src/zep_cloud/agent/trajectory/__init__.py create mode 100644 src/zep_cloud/agent/trajectory/client.py create mode 100644 src/zep_cloud/agent/trajectory/raw_client.py create mode 100644 src/zep_cloud/agent/trajectory/types/__init__.py create mode 100644 src/zep_cloud/agent/trajectory/types/trajectory_list_request_source_kind.py create mode 100644 src/zep_cloud/agent/trajectory_import/__init__.py create mode 100644 src/zep_cloud/agent/trajectory_import/client.py create mode 100644 src/zep_cloud/agent/trajectory_import/raw_client.py create mode 100644 src/zep_cloud/agent/trajectory_import/run/__init__.py create mode 100644 src/zep_cloud/agent/trajectory_import/run/client.py create mode 100644 src/zep_cloud/agent/trajectory_import/run/item/__init__.py create mode 100644 src/zep_cloud/agent/trajectory_import/run/item/client.py create mode 100644 src/zep_cloud/agent/trajectory_import/run/item/raw_client.py create mode 100644 src/zep_cloud/agent/trajectory_import/run/raw_client.py create mode 100644 src/zep_cloud/agent/trajectory_import/types/__init__.py create mode 100644 src/zep_cloud/agent/trajectory_import/types/trajectory_import_delete_request_trajectories.py create mode 100644 src/zep_cloud/agent/verifier/__init__.py create mode 100644 src/zep_cloud/agent/verifier/client.py create mode 100644 src/zep_cloud/agent/verifier/raw_client.py create mode 100644 src/zep_cloud/batch/types/__init__.py create mode 100644 src/zep_cloud/batch/types/batch_list_request_status.py create mode 100644 src/zep_cloud/core/idempotency.py create mode 100644 src/zep_cloud/debug_log/__init__.py create mode 100644 src/zep_cloud/debug_log/client.py create mode 100644 src/zep_cloud/debug_log/raw_client.py create mode 100644 src/zep_cloud/errors/bad_gateway_error.py create mode 100644 src/zep_cloud/errors/content_too_large_error.py create mode 100644 src/zep_cloud/errors/service_unavailable_error.py create mode 100644 src/zep_cloud/errors/unprocessable_entity_error.py create mode 100644 src/zep_cloud/graph/episode/types/add_episode_request_type.py create mode 100644 src/zep_cloud/graph/episode/types/episode_list_request_order.py create mode 100644 src/zep_cloud/graph/episode/types/episode_list_request_order_by.py delete mode 100644 src/zep_cloud/graph/episode/types/v4add_episode_request_type.py create mode 100644 src/zep_cloud/graph/hyperedge/__init__.py create mode 100644 src/zep_cloud/graph/hyperedge/client.py create mode 100644 src/zep_cloud/graph/hyperedge/raw_client.py create mode 100644 src/zep_cloud/graph/hyperedge/types/__init__.py create mode 100644 src/zep_cloud/graph/hyperedge/types/hyperedge_list_request_order.py create mode 100644 src/zep_cloud/graph/hyperedge/types/hyperedge_list_request_order_by.py create mode 100644 src/zep_cloud/graph/node/types/neighbors_request_direction.py create mode 100644 src/zep_cloud/graph/node/types/node_list_neighbors_request_order.py create mode 100644 src/zep_cloud/graph/node/types/node_list_neighbors_request_order_by.py create mode 100644 src/zep_cloud/graph/node/types/node_list_request_order.py create mode 100644 src/zep_cloud/graph/node/types/node_list_request_order_by.py delete mode 100644 src/zep_cloud/graph/node/types/v4neighbors_request_direction.py create mode 100644 src/zep_cloud/graph/types/graph_context_request_recency_bias.py create mode 100644 src/zep_cloud/graph/types/graph_list_request_order.py create mode 100644 src/zep_cloud/graph/types/graph_list_request_order_by.py create mode 100644 src/zep_cloud/graph/types/subgraph_request_direction.py delete mode 100644 src/zep_cloud/graph/types/v4graph_context_request_recency_bias.py delete mode 100644 src/zep_cloud/graph/types/v4subgraph_request_direction.py create mode 100644 src/zep_cloud/thread/types/__init__.py create mode 100644 src/zep_cloud/thread/types/thread_list_messages_request_order.py create mode 100644 src/zep_cloud/thread/types/thread_list_request_order.py create mode 100644 src/zep_cloud/thread/types/thread_list_request_order_by.py create mode 100644 src/zep_cloud/trace_connection/__init__.py create mode 100644 src/zep_cloud/trace_connection/client.py create mode 100644 src/zep_cloud/trace_connection/project/__init__.py create mode 100644 src/zep_cloud/trace_connection/project/client.py create mode 100644 src/zep_cloud/trace_connection/project/raw_client.py create mode 100644 src/zep_cloud/trace_connection/raw_client.py create mode 100644 src/zep_cloud/trace_connection/trace/__init__.py create mode 100644 src/zep_cloud/trace_connection/trace/client.py create mode 100644 src/zep_cloud/trace_connection/trace/raw_client.py create mode 100644 src/zep_cloud/types/add_agent_skill_use_outcome_request.py create mode 100644 src/zep_cloud/types/add_agent_skill_use_outcome_request_outcome.py create mode 100644 src/zep_cloud/types/add_edges_result.py rename src/zep_cloud/types/{add_edge_result.py => add_hyperedge_edge_result.py} (70%) create mode 100644 src/zep_cloud/types/add_hyperedge_result.py create mode 100644 src/zep_cloud/types/added_hyperedge.py create mode 100644 src/zep_cloud/types/added_hyperedge_edge.py create mode 100644 src/zep_cloud/types/agent.py create mode 100644 src/zep_cloud/types/agent_breaking_change.py create mode 100644 src/zep_cloud/types/agent_context.py create mode 100644 src/zep_cloud/types/agent_context_evidence_counts.py create mode 100644 src/zep_cloud/types/agent_context_partial_source.py create mode 100644 src/zep_cloud/types/agent_context_resource.py create mode 100644 src/zep_cloud/types/agent_context_skill_snapshot.py create mode 100644 src/zep_cloud/types/agent_context_skipped_skill.py create mode 100644 src/zep_cloud/types/agent_delete_result.py create mode 100644 src/zep_cloud/types/agent_learning_state.py create mode 100644 src/zep_cloud/types/agent_literal_policy.py create mode 100644 src/zep_cloud/types/agent_literal_policy_classes.py create mode 100644 src/zep_cloud/types/agent_literal_policy_values.py create mode 100644 src/zep_cloud/types/agent_memory_evaluation_policy.py create mode 100644 src/zep_cloud/types/agent_memory_evaluation_requirement.py create mode 100644 src/zep_cloud/types/agent_memory_settings.py create mode 100644 src/zep_cloud/types/agent_memory_settings_approval.py create mode 100644 src/zep_cloud/types/agent_memory_settings_compilation_mode.py create mode 100644 src/zep_cloud/types/agent_page.py create mode 100644 src/zep_cloud/types/agent_skill.py create mode 100644 src/zep_cloud/types/agent_skill_admission_decision.py create mode 100644 src/zep_cloud/types/agent_skill_candidate.py create mode 100644 src/zep_cloud/types/agent_skill_candidate_base_version.py create mode 100644 src/zep_cloud/types/agent_skill_candidate_evaluation.py create mode 100644 src/zep_cloud/types/agent_skill_candidate_evidence.py create mode 100644 src/zep_cloud/types/agent_skill_candidate_review.py create mode 100644 src/zep_cloud/types/agent_skill_candidate_review_result.py create mode 100644 src/zep_cloud/types/agent_skill_candidate_review_summary.py create mode 100644 src/zep_cloud/types/agent_skill_compilation_outcome.py create mode 100644 src/zep_cloud/types/agent_skill_compilation_outcome_rejection_class.py create mode 100644 src/zep_cloud/types/agent_skill_evaluation.py create mode 100644 src/zep_cloud/types/agent_skill_evidence.py create mode 100644 src/zep_cloud/types/agent_skill_publication_lineage.py create mode 100644 src/zep_cloud/types/agent_skill_relationship.py create mode 100644 src/zep_cloud/types/agent_skill_search_hit.py create mode 100644 src/zep_cloud/types/agent_skill_search_hit_maturity.py create mode 100644 src/zep_cloud/types/agent_skill_search_response.py create mode 100644 src/zep_cloud/types/agent_skill_use.py create mode 100644 src/zep_cloud/types/agent_skill_use_outcome.py create mode 100644 src/zep_cloud/types/agent_skill_version.py create mode 100644 src/zep_cloud/types/agent_skill_version_comparison.py create mode 100644 src/zep_cloud/types/agent_split_plan.py create mode 100644 src/zep_cloud/types/agent_split_plan_destination.py create mode 100644 src/zep_cloud/types/agent_split_plan_destination_request.py create mode 100644 src/zep_cloud/types/agent_split_plan_skill_reference.py create mode 100644 src/zep_cloud/types/agent_split_plan_skill_selection_request.py create mode 100644 src/zep_cloud/types/agent_split_plan_source.py create mode 100644 src/zep_cloud/types/agent_status.py create mode 100644 src/zep_cloud/types/agent_trajectory.py create mode 100644 src/zep_cloud/types/agent_trajectory_close_verifier.py create mode 100644 src/zep_cloud/types/agent_trajectory_event.py create mode 100644 src/zep_cloud/types/agent_trajectory_event_context.py create mode 100644 src/zep_cloud/types/agent_trajectory_event_page.py create mode 100644 src/zep_cloud/types/agent_trajectory_event_processing_state.py create mode 100644 src/zep_cloud/types/agent_trajectory_event_source.py create mode 100644 src/zep_cloud/types/agent_trajectory_event_source_copy_mode.py create mode 100644 src/zep_cloud/types/agent_trajectory_event_source_retention_mode.py create mode 100644 src/zep_cloud/types/agent_trajectory_event_type.py create mode 100644 src/zep_cloud/types/agent_trajectory_finalization_result.py create mode 100644 src/zep_cloud/types/agent_trajectory_internal.py create mode 100644 src/zep_cloud/types/agent_trajectory_lifecycle.py create mode 100644 src/zep_cloud/types/agent_trajectory_outcome.py create mode 100644 src/zep_cloud/types/agent_trajectory_page.py create mode 100644 src/zep_cloud/types/agent_trajectory_processing_state.py create mode 100644 src/zep_cloud/types/agent_trajectory_resource_ref.py create mode 100644 src/zep_cloud/types/agent_trajectory_sequence_range.py create mode 100644 src/zep_cloud/types/agent_trajectory_source.py create mode 100644 src/zep_cloud/types/agent_trajectory_source_deletion_result.py create mode 100644 src/zep_cloud/types/agent_trajectory_summary_creation_reason.py create mode 100644 src/zep_cloud/types/agent_trajectory_summary_omission_reason.py create mode 100644 src/zep_cloud/types/agent_trajectory_summary_omitted_range.py create mode 100644 src/zep_cloud/types/agent_trajectory_summary_page.py create mode 100644 src/zep_cloud/types/agent_trajectory_summary_version.py create mode 100644 src/zep_cloud/types/agent_trajectory_verification.py create mode 100644 src/zep_cloud/types/agent_verification_strength.py create mode 100644 src/zep_cloud/types/agent_verifier.py create mode 100644 src/zep_cloud/types/agent_verifier_assertion_outcome.py create mode 100644 src/zep_cloud/types/agent_verifier_evidence_invalidation_result.py create mode 100644 src/zep_cloud/types/agent_verifier_principal.py create mode 100644 src/zep_cloud/types/agent_verifier_principal_binding.py create mode 100644 src/zep_cloud/types/agent_verifier_principal_binding_input.py create mode 100644 src/zep_cloud/types/agent_verifier_status.py create mode 100644 src/zep_cloud/types/batch_item_input_data_type.py create mode 100644 src/zep_cloud/types/batch_item_input_role.py create mode 100644 src/zep_cloud/types/batch_item_input_type.py create mode 100644 src/zep_cloud/types/clone_graph_request.py delete mode 100644 src/zep_cloud/types/comparison_operator.py create mode 100644 src/zep_cloud/types/content_policy.py rename src/zep_cloud/types/{episode_metadata_filter.py => content_policy_category.py} (51%) create mode 100644 src/zep_cloud/types/content_policy_category_request.py create mode 100644 src/zep_cloud/types/content_policy_event.py create mode 100644 src/zep_cloud/types/content_policy_event_artifact_kind.py create mode 100644 src/zep_cloud/types/content_policy_event_drop_reason.py create mode 100644 src/zep_cloud/types/content_policy_event_page.py create mode 100644 src/zep_cloud/types/content_policy_revision_page.py create mode 100644 src/zep_cloud/types/content_policy_rule.py create mode 100644 src/zep_cloud/types/content_policy_rule_request.py create mode 100644 src/zep_cloud/types/create_agent_request.py create mode 100644 src/zep_cloud/types/date_filter_field.py create mode 100644 src/zep_cloud/types/date_filter_group.py create mode 100644 src/zep_cloud/types/date_filter_operator.py create mode 100644 src/zep_cloud/types/date_filters.py create mode 100644 src/zep_cloud/types/debug_log_entry.py create mode 100644 src/zep_cloud/types/debug_log_level.py create mode 100644 src/zep_cloud/types/debug_log_status.py create mode 100644 src/zep_cloud/types/debug_logging_enablement.py create mode 100644 src/zep_cloud/types/delete_agent_trajectory_request.py create mode 100644 src/zep_cloud/types/edge_input.py create mode 100644 src/zep_cloud/types/episode_content_policy.py create mode 100644 src/zep_cloud/types/episode_content_policy_status.py create mode 100644 src/zep_cloud/types/episode_debug_log.py create mode 100644 src/zep_cloud/types/graph_content_policy.py create mode 100644 src/zep_cloud/types/graph_content_policy_request.py delete mode 100644 src/zep_cloud/types/graphiti_metadata_filter_group_type.py create mode 100644 src/zep_cloud/types/hyperedge.py create mode 100644 src/zep_cloud/types/hyperedge_edge.py create mode 100644 src/zep_cloud/types/hyperedge_input.py create mode 100644 src/zep_cloud/types/hyperedge_page.py create mode 100644 src/zep_cloud/types/imported_trajectory_reference.py create mode 100644 src/zep_cloud/types/ingestion_trace.py create mode 100644 src/zep_cloud/types/ingestion_trace_edge.py create mode 100644 src/zep_cloud/types/ingestion_trace_edge_invalidation.py create mode 100644 src/zep_cloud/types/ingestion_trace_edge_reference.py create mode 100644 src/zep_cloud/types/ingestion_trace_entity_type.py create mode 100644 src/zep_cloud/types/ingestion_trace_episode.py create mode 100644 src/zep_cloud/types/ingestion_trace_input.py create mode 100644 src/zep_cloud/types/ingestion_trace_node.py create mode 100644 src/zep_cloud/types/ingestion_trace_node_duplicate.py create mode 100644 src/zep_cloud/types/ingestion_trace_node_resolution.py create mode 100644 src/zep_cloud/types/ingestion_trace_output.py create mode 100644 src/zep_cloud/types/ingestion_trace_page.py create mode 100644 src/zep_cloud/types/ingestion_trace_status.py create mode 100644 src/zep_cloud/types/ingestion_trace_step.py create mode 100644 src/zep_cloud/types/metadata_filter.py create mode 100644 src/zep_cloud/types/metadata_filter_group_type.py create mode 100644 src/zep_cloud/types/metadata_filter_operator.py create mode 100644 src/zep_cloud/types/metadata_filter_value.py create mode 100644 src/zep_cloud/types/metadata_filter_value_three_item.py create mode 100644 src/zep_cloud/types/objective_mapping_rule.py create mode 100644 src/zep_cloud/types/objective_mapping_rule_source.py create mode 100644 src/zep_cloud/types/outcome_mapping_rule.py create mode 100644 src/zep_cloud/types/outcome_mapping_rule_rule.py create mode 100644 src/zep_cloud/types/pagev4agent_skill_candidate_review_summary.py create mode 100644 src/zep_cloud/types/pagev4agent_skill_compilation_outcome.py create mode 100644 src/zep_cloud/types/pagev4agent_skill_evidence.py create mode 100644 src/zep_cloud/types/pagev4agent_skill_relationship.py create mode 100644 src/zep_cloud/types/pagev4agent_skill_search_hit.py create mode 100644 src/zep_cloud/types/pagev4agent_skill_version.py create mode 100644 src/zep_cloud/types/pagev4agent_verifier.py create mode 100644 src/zep_cloud/types/property_filter_operator.py create mode 100644 src/zep_cloud/types/property_filter_value.py create mode 100644 src/zep_cloud/types/property_filter_value_three_item.py rename src/zep_cloud/types/{v4search_request_reranker.py => search_request_reranker.py} (81%) create mode 100644 src/zep_cloud/types/skill_definition.py create mode 100644 src/zep_cloud/types/skill_definition_section.py create mode 100644 src/zep_cloud/types/skill_failure.py create mode 100644 src/zep_cloud/types/skill_procedure_step.py create mode 100644 src/zep_cloud/types/skill_relation.py create mode 100644 src/zep_cloud/types/skill_resource.py create mode 100644 src/zep_cloud/types/source_span.py create mode 100644 src/zep_cloud/types/source_trace.py create mode 100644 src/zep_cloud/types/source_trace_page.py create mode 100644 src/zep_cloud/types/source_trace_response.py create mode 100644 src/zep_cloud/types/source_trace_summary.py create mode 100644 src/zep_cloud/types/task_family_mapping_rule.py create mode 100644 src/zep_cloud/types/task_family_mapping_rule_source.py create mode 100644 src/zep_cloud/types/trace_connection.py create mode 100644 src/zep_cloud/types/trace_connection_page.py create mode 100644 src/zep_cloud/types/trace_connection_settings.py create mode 100644 src/zep_cloud/types/trace_filter.py create mode 100644 src/zep_cloud/types/trace_preview.py create mode 100644 src/zep_cloud/types/trace_provider_project.py create mode 100644 src/zep_cloud/types/trace_provider_project_page.py create mode 100644 src/zep_cloud/types/trace_score_range.py create mode 100644 src/zep_cloud/types/trajectory_content_mapping.py create mode 100644 src/zep_cloud/types/trajectory_import.py create mode 100644 src/zep_cloud/types/trajectory_import_page.py create mode 100644 src/zep_cloud/types/trajectory_import_pause_reason.py create mode 100644 src/zep_cloud/types/trajectory_import_run.py create mode 100644 src/zep_cloud/types/trajectory_import_run_item.py create mode 100644 src/zep_cloud/types/trajectory_import_run_item_page.py create mode 100644 src/zep_cloud/types/trajectory_import_run_page.py create mode 100644 src/zep_cloud/types/trajectory_import_run_reference.py create mode 100644 src/zep_cloud/types/trajectory_import_run_reference_status.py create mode 100644 src/zep_cloud/types/trajectory_import_run_reference_trigger.py create mode 100644 src/zep_cloud/types/trajectory_import_schedule.py create mode 100644 src/zep_cloud/types/trajectory_import_selection.py create mode 100644 src/zep_cloud/types/trajectory_mapping.py create mode 100644 src/zep_cloud/types/trajectory_mapping_include_outcomes_item.py create mode 100644 src/zep_cloud/types/trajectory_mapping_result.py create mode 100644 src/zep_cloud/types/trajectory_mapping_result_outcome.py create mode 100644 src/zep_cloud/types/trajectory_mapping_result_outcome_rule.py delete mode 100644 src/zep_cloud/types/v4batch_item_input_data_type.py delete mode 100644 src/zep_cloud/types/v4batch_item_input_role.py delete mode 100644 src/zep_cloud/types/v4batch_item_input_type.py create mode 100644 src/zep_cloud/user/types/__init__.py create mode 100644 src/zep_cloud/user/types/user_list_request_order.py create mode 100644 src/zep_cloud/user/types/user_list_request_order_by.py create mode 100644 tests/conftest.py create mode 100644 tests/test_aiohttp_autodetect.py diff --git a/.fern/metadata.json b/.fern/metadata.json index e17d2693..1eab89dd 100644 --- a/.fern/metadata.json +++ b/.fern/metadata.json @@ -1,7 +1,7 @@ { - "cliVersion": "5.50.1", + "cliVersion": "5.146.2", "generatorName": "fernapi/fern-python-sdk", - "generatorVersion": "4.64.1", + "generatorVersion": "5.34.3", "generatorConfig": { "package_name": "zep_cloud", "client": { @@ -9,8 +9,13 @@ "class_name": "BaseClient", "exported_filename": "client.py", "exported_class_name": "Zep" - } + }, + "pyproject_python_version": "^3.10" }, - "originGitCommit": "70d7aaa9c19f07072ca0c09b2e89a8f3c87001d4", - "sdkVersion": "4.0.0a5" + "originGitCommit": "26e9820bad75494d5ac535a7f939856d42587c22", + "originGitCommitIsDirty": true, + "invokedBy": "ci", + "requestedVersion": "4.0.0b1", + "ciProvider": "github", + "sdkVersion": "4.0.0b1" } \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..af948ce7 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,125 @@ +# Contributing + +Thanks for your interest in contributing to this SDK! This document provides guidelines for contributing to the project. + +## Getting Started + +### Prerequisites + +- Python 3.9+ +- pip +- poetry + +### Installation + +Install the project dependencies: + +```bash +poetry install +``` + +### Building + +Build the project: + +```bash +poetry build +``` + +### Testing + +Run the test suite: + +```bash +poetry run pytest +``` + +### Linting and Formatting + +Check code style: + +```bash +poetry run ruff check . +poetry run ruff format . +``` + +### Type Checking + +Run the type checker: + +```bash +poetry run mypy . +``` + +## About Generated Code + +**Important**: Most files in this SDK are automatically generated by [Fern](https://buildwithfern.com) from the API definition. Direct modifications to generated files will be overwritten the next time the SDK is generated. + +### Generated Files + +The following directories contain generated code: +- `src/` - API client classes and types +- Most Python files in the project + +### How to Customize + +If you need to customize the SDK, you have two options: + +#### Option 1: Use `.fernignore` + +For custom code that should persist across SDK regenerations: + +1. Create a `.fernignore` file in the project root +2. Add file patterns for files you want to preserve (similar to `.gitignore` syntax) +3. Add your custom code to those files + +Files listed in `.fernignore` will not be overwritten when the SDK is regenerated. + +For more information, see the [Fern documentation on custom code](https://buildwithfern.com/learn/sdks/overview/custom-code). + +#### Option 2: Contribute to the Generator + +If you want to change how code is generated for all users of this SDK: + +1. The Python SDK generator lives in the [Fern repository](https://github.com/fern-api/fern) +2. Generator code is located at `generators/python-v2/` +3. Follow the [Fern contributing guidelines](https://github.com/fern-api/fern/blob/main/CONTRIBUTING.md) +4. Submit a pull request with your changes to the generator + +This approach is best for: +- Bug fixes in generated code +- New features that would benefit all users +- Improvements to code generation patterns + +## Making Changes + +### Workflow + +1. Create a new branch for your changes +2. Make your modifications +3. Run tests to ensure nothing breaks: `poetry run pytest` +4. Run linting and formatting: `poetry run ruff check .` and `poetry run ruff format .` +5. Run type checking: `poetry run mypy .` +6. Build the project: `poetry build` +7. Commit your changes with a clear commit message +8. Push your branch and create a pull request + +### Commit Messages + +Write clear, descriptive commit messages that explain what changed and why. + +### Code Style + +This project uses automated code formatting and linting. Run `poetry run ruff format .` and `poetry run ruff check .` before committing to ensure your code meets the project's style guidelines. + +## Questions or Issues? + +If you have questions or run into issues: + +1. Check the [Fern documentation](https://buildwithfern.com) +2. Search existing [GitHub issues](https://github.com/fern-api/fern/issues) +3. Open a new issue if your question hasn't been addressed + +## License + +By contributing to this project, you agree that your contributions will be licensed under the same license as the project. diff --git a/README.md b/README.md index 7775bfb4..c775b5f8 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ The Zep Python library provides convenient access to the Zep APIs from Python. - [Installation](#installation) - [Reference](#reference) - [Usage](#usage) +- [Environments](#environments) - [Async Client](#async-client) - [Exception Handling](#exception-handling) - [Pagination](#pagination) @@ -32,18 +33,78 @@ pip install zep-cloud > [!NOTE] > Zep Cloud [overview](https://help.getzep.com/concepts) and [cloud sdk guide](https://help.getzep.com/sdks). +### Community Installation +```bash +pip install zep-python +``` +> [!NOTE] +> Zep Community Edition [quick start](https://help.getzep.com/ce/quickstart) and [sdk guide](https://help.getzep.com/ce/sdks). + +### Zep v0.x Compatible SDK +You can install Zep v0.x compatible sdk by running: +```bash +pip install "zep-python>=1.5.0,<2.0.0" +``` +> [!NOTE] +> Zep v0.x [quick start](https://help.getzep.com/ce/legacy/deployment/quickstart) and [sdk guide](https://help.getzep.com/ce/legacy/sdk). + ### How Zep works Zep persists and recalls chat histories, and automatically generates summaries and other artifacts from these chat histories. It also embeds messages and summaries, enabling you to search Zep for relevant context from past conversations. Zep does all of this asynchronously, ensuring these operations don't impact your user's chat experience. Data is persisted to database, allowing you to scale out when growth demands. +Zep also provides a simple, easy to use abstraction for document vector search called Document Collections. This is designed to complement Zep's core context features, but is not designed to be a general purpose vector database. + Zep allows you to be more intentional about constructing your prompt: 1. automatically adding a few recent messages, with the number customized for your app; 2. a summary of recent conversations prior to the messages above; 3. and/or contextually relevant summaries or messages surfaced from the entire chat session. +4. and/or relevant Business data from Zep Document Collections. + +Zep Cloud offers: +- **Fact Extraction:** Automatically build fact tables from conversations, without having to define a data schema upfront. +- **Dialog Classification:** Instantly and accurately classify chat dialog. Understand user intent and emotion, segment users, and more. Route chains based on semantic context, and trigger events. +- **Structured Data Extraction:** Quickly extract business data from chat conversations using a schema you define. Understand what your Assistant should ask for next in order to complete its task. You will also need to provide a Zep Project API key to your zep client. You can find out about zep projects in our [cloud docs](https://help.getzep.com/projects.html) +### Using LangChain Zep Classes with `zep-python` + +(Currently only available on release candidate versions) + +In the pre-release version `zep-python` sdk comes with `ZepChatMessageHistory` and `ZepVectorStore` +classes that are compatible with [LangChain's Python expression language](https://python.langchain.com/docs/expression_language/) + +In order to use these classes in your application, you need to make sure that you have +`langchain_core` package installed, please refer to [Langchain's docs installation section](https://python.langchain.com/docs/get_started/installation#langchain-core). + +We support `langchain_core@>=0.1.3<0.2.0` + +You can import these classes in the following way: + +```python +from zep_cloud.langchain import ZepChatMessageHistory, ZepVectorStore +``` + +### Running Examples +You will need to set the following environment variables to run examples in the `examples` directory: + +```dotenv +# Please use examples/.env.example as a template for .env file + +# Required +ZEP_API_KEY=# Your Zep Project API Key +ZEP_COLLECTION=# used in ingestion script and in vector store examples +OPENAI_API_KEY=# Your OpenAI API Key + +# Optional (If you want to use langsmith with LangServe Sample App) +LANGCHAIN_TRACING_V2=true +LANGCHAIN_API_KEY= +LANGCHAIN_PROJECT=# If not specified, defaults to "default" +``` + + + ## Installation ```sh @@ -65,7 +126,24 @@ client = Zep( api_key="", ) -client.batch.create() +client.agent.create( + agent_id="agent_id", + name="name", + security_domain="security_domain", +) +``` + +## Environments + +This SDK allows you to configure different environments for API requests. + +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + environment=ZepEnvironment.DEFAULT, +) ``` ## Async Client @@ -83,7 +161,11 @@ client = AsyncZep( async def main() -> None: - await client.batch.create() + await client.agent.create( + agent_id="agent_id", + name="name", + security_domain="security_domain", + ) asyncio.run(main()) @@ -98,7 +180,7 @@ will be thrown. from zep_cloud.core.api_error import ApiError try: - client.batch.create(...) + client.agent.create(...) except ApiError as e: print(e.status_code) print(e.body) @@ -115,16 +197,12 @@ client = Zep( api_key="", ) -client.batch.list( - limit=1, - cursor="cursor", - status="status", -) +client.agent.list() ``` ```python # You can also iterate through pages and access the typed response per page -pager = client.batch.list(...) +pager = client.agent.list(...) for page in pager.iter_pages(): print(page.response) # access the typed response for each page for item in page: @@ -142,7 +220,7 @@ The `.with_raw_response` property returns a "raw" client that can be used to acc from zep_cloud import Zep client = Zep(...) -response = client.batch.with_raw_response.create(...) +response = client.agent.with_raw_response.create(...) print(response.headers) # access the response headers print(response.status_code) # access the response status code print(response.data) # access the underlying object @@ -154,16 +232,26 @@ The SDK is instrumented with automatic retries with exponential backoff. A reque as the request is deemed retryable and the number of retry attempts has not grown larger than the configured retry limit (default: 2). -A request is deemed retryable when any of the following HTTP status codes is returned: +Which status codes are retried depends on the `retryStatusCodes` generator configuration: + +**`legacy`** (current default): retries on +- [408](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/408) (Timeout) +- [409](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/409) (Conflict) +- [429](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429) (Too Many Requests) +- [5XX](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#server_error_responses) (All server errors, including 500) +**`recommended`**: retries on - [408](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/408) (Timeout) +- [409](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/409) (Conflict) - [429](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429) (Too Many Requests) -- [5XX](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500) (Internal Server Errors) +- [502](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502) (Bad Gateway) +- [503](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/503) (Service Unavailable) +- [504](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/504) (Gateway Timeout) Use the `max_retries` request option to configure this behavior. ```python -client.batch.create(..., request_options={ +client.agent.create(..., request_options={ "max_retries": 1 }) ``` @@ -178,8 +266,8 @@ from zep_cloud import Zep client = Zep(..., timeout=20.0) # Override timeout for a specific method -client.batch.create(..., request_options={ - "timeout_in_seconds": 1 +client.agent.create(..., request_options={ + "timeout": 1 }) ``` diff --git a/poetry.lock b/poetry.lock index 9d0c35a8..33bf4d20 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,40 +1,291 @@ -# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.4.1 and should not be changed by hand. + +[[package]] +name = "aiohappyeyeballs" +version = "2.7.1" +description = "Happy Eyeballs for asyncio" +optional = true +python-versions = ">=3.10" +groups = ["main"] +markers = "extra == \"aiohttp\"" +files = [ + {file = "aiohappyeyeballs-2.7.1-py3-none-any.whl", hash = "sha256:9243213661e29250eb41368e5daa826fc017156c3b8a11440826b2e3ed376472"}, + {file = "aiohappyeyeballs-2.7.1.tar.gz", hash = "sha256:065665c041c42a5938ed220bdcd7230f22527fbec085e1853d2402c8a3615d9d"}, +] + +[[package]] +name = "aiohttp" +version = "3.14.4" +description = "Async http client/server framework (asyncio)" +optional = true +python-versions = ">=3.10" +groups = ["main"] +markers = "extra == \"aiohttp\"" +files = [ + {file = "aiohttp-3.14.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:dea3b3653c1d0d6babd8ce09cb9e5a7776864315d9cfb1c569f926389874a261"}, + {file = "aiohttp-3.14.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3099a389e5b5900fc79c6f613015ff3f8fa06a519744e6001cc68a31ba418cac"}, + {file = "aiohttp-3.14.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:70247156fc76e92919f9aacb820556cb30289a54784299a31714d030bb604d84"}, + {file = "aiohttp-3.14.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fdf2d2a6ad402797422949f4a200a60d43e3a021695c8a7804aa1d5bbef22652"}, + {file = "aiohttp-3.14.4-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:ba835fad8d4b5eaea0d34f9461cf499737a720a5f8bc6768d2f6d98a1d3ba8b5"}, + {file = "aiohttp-3.14.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0d4415ca5c9c8b24bc2f5733f870d4eab4929e680203559ba60131dd1a27852a"}, + {file = "aiohttp-3.14.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f6757e02c2c2b0d7985f57be87cf4a7c5b35708f849e1feaea3f77656ddb9dff"}, + {file = "aiohttp-3.14.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2a950bd8418ef54eccf5f9f517f08e37c1adab4bc50a470a0422ee1cc1032e29"}, + {file = "aiohttp-3.14.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:34cf6f2fe4fc1d7183e8cc0d8c48bbdda828a740bc372d8278126149714d343c"}, + {file = "aiohttp-3.14.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:bc0fbe4f79c3b156d754dd062718ffe404c3b31ca878d9d2b88ecdbc72ef8369"}, + {file = "aiohttp-3.14.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:d3d50a5a07a2b31a4369b86dd4a3acf3c2577c45091dbd5e884b198dec56480b"}, + {file = "aiohttp-3.14.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:de15c46a63f46da881d219e44a04778c40114c756e5575b5ea38143b20eb3713"}, + {file = "aiohttp-3.14.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:caa4c0fc9b25e8c679baac68337e9c00deb6baf6601fe6f07e8511469cc1ceba"}, + {file = "aiohttp-3.14.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:3647f8c090632c70abb1e80826e4ee24faea3f895f0283b60e91a0b17aea5e34"}, + {file = "aiohttp-3.14.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3f3e8030169843fb652a60a3d32c206e03f260198aa398985a48b41cd7e42f0a"}, + {file = "aiohttp-3.14.4-cp310-cp310-win32.whl", hash = "sha256:a1205cbdddfca1428129bb6d23e0b292b09e681df951fa828145d83a63ffc0ca"}, + {file = "aiohttp-3.14.4-cp310-cp310-win_amd64.whl", hash = "sha256:e90980e0454a043f81b435309a089ac5deab883779557eb58d004f33990f61e4"}, + {file = "aiohttp-3.14.4-cp310-cp310-win_arm64.whl", hash = "sha256:e63eecf9a4b670a24055d5c0486128af16f83b02d9817abd685d3238940f8752"}, + {file = "aiohttp-3.14.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:eb0093ca0817019d539f0d27bdf98e823944e05bb7efd9d2337a45b92e4d1b06"}, + {file = "aiohttp-3.14.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f482dc9c8309801b4259dd218609d3dae0a7bcdedeac56d90500eabaa0c23465"}, + {file = "aiohttp-3.14.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:aa800bb7c1d00e166493931f2ddacb982db913292503dc2f4884db1f2bc5f105"}, + {file = "aiohttp-3.14.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d90e4dae71b26597f6d1fd12af7d092ae67551edf0e524b73e0687214b79ee33"}, + {file = "aiohttp-3.14.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5b681054b8c3b86aa6a0384b6ad7f5cb78dccbabab1f4a3a6793f98ad1378959"}, + {file = "aiohttp-3.14.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6dfe80b41bcf8d80d2125fb99a171adeb86db2fcb35c1a68e0226acba0ba7f03"}, + {file = "aiohttp-3.14.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:71e4a59c6a8c5a6ae8b0b696c32635913e8f526cc01448762eaf5a3c59df8a4f"}, + {file = "aiohttp-3.14.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f887c3b7fb3058fc1ccd917f52078540c18d938d12018cb9edd64b6811d20c57"}, + {file = "aiohttp-3.14.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0da4525e9ba145a11617d2cd7e44fe1acaf471f9c72a0cad28e72879c1020fbb"}, + {file = "aiohttp-3.14.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f7e8d3c5caa44fdbee3eba1aa1417aa58c74c95d4089fe3c451911117fcbb2f3"}, + {file = "aiohttp-3.14.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:09092cf906c18c824b6b16881da5a89cc9cfa9b15344e496bcf880e9045bee33"}, + {file = "aiohttp-3.14.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:dfd144837e92264878bba6d3a7ffa8206668b21e87748740afd45d193e48c87e"}, + {file = "aiohttp-3.14.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:9413cffe4e0d654b9b524f9c99dde8cbdb37e0ed9a2c4edd2e63adbac6b374e8"}, + {file = "aiohttp-3.14.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:f50d719f97ba488dfb8e306cf8c8cc172ff0683ec0af53917b288229aa555ba5"}, + {file = "aiohttp-3.14.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:68ed4824d96b7afec1f3a8d7fba190fe282718041c5772e20298003e1e3e5d66"}, + {file = "aiohttp-3.14.4-cp311-cp311-win32.whl", hash = "sha256:d7a41d1427136828e6b11d3f3fd194d4357d5205a5b610be7ae07b1ba52ab974"}, + {file = "aiohttp-3.14.4-cp311-cp311-win_amd64.whl", hash = "sha256:2efbdb87e79d596325c4eefaef0f4495d701145e882351310ebc538e854dc7a3"}, + {file = "aiohttp-3.14.4-cp311-cp311-win_arm64.whl", hash = "sha256:ac6e6f90d9360e460c873f945f11dc8698db0a71fec6612823f1aaaab2c11faa"}, + {file = "aiohttp-3.14.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:55b0b335982b0db7117dff7f6a8e3aad43c4105f9e392ca04f9fc8d958a95cce"}, + {file = "aiohttp-3.14.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2d0d8e435582b0d53009dac99e26a3d2be932ed7c9dbfcfc70f3fce1cf943bd5"}, + {file = "aiohttp-3.14.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bf734016932d68e1324cfb638cac7a0866a83933a33badf15e836a7e24efb8c0"}, + {file = "aiohttp-3.14.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:322e3d741b3133bcbb981a41d4f9b8ac3545c18de49c662c2b1f4e1c770b98ad"}, + {file = "aiohttp-3.14.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:15a3bb5f90a4e515071f3617a45dfe26560beb834a6b6e108cdf4bc9e9719ec3"}, + {file = "aiohttp-3.14.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6c044e52df1a466af82cad3518c92ea80cc4ddcfea86966ff083bb34bab29bf4"}, + {file = "aiohttp-3.14.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d613d7d51bf06fe9a5e3aab86ce06d835bb0ceb1a31ea9e8766df4a403ae62a6"}, + {file = "aiohttp-3.14.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c5e93ab6e6330dce40f5b43996f1fc5f2543296d263a5e4b59ff09e73870b7d8"}, + {file = "aiohttp-3.14.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:20134dc8e68c67e7478124d516449428684c0545b2d3faa575691c8bcbd56678"}, + {file = "aiohttp-3.14.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f0daef5ef012369dddc391c61f604111424aa9a96313a69fb899018b09d1b01e"}, + {file = "aiohttp-3.14.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:19290a108de0718b73bc69b86e788975c6a59855c671ebe2a98a07a6f968328f"}, + {file = "aiohttp-3.14.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1494877625baeffab669f4a25a09ec4eea721b49e35363081a2a8e4231fe141f"}, + {file = "aiohttp-3.14.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:a779ce4bf099ce4ad2cdfed62f1ca536d435f53237c54ff40172fddada24d1b5"}, + {file = "aiohttp-3.14.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:0b4cec9fca876e2d4f4c6cb32b177390132d04618867689f43fefabf3f5c3980"}, + {file = "aiohttp-3.14.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:217707313e23aedde9bea67cf8365c7b138b549ae179121ef3f476cf67e3173a"}, + {file = "aiohttp-3.14.4-cp312-cp312-win32.whl", hash = "sha256:18a9fb9a3f6e6e63f4d27f9adeef313a2d3c69a84d31170a844623824e722534"}, + {file = "aiohttp-3.14.4-cp312-cp312-win_amd64.whl", hash = "sha256:69dcb02d33dfe415d5ee342cc63b7d320efcaf4b761701c7bd7bfb91c715481a"}, + {file = "aiohttp-3.14.4-cp312-cp312-win_arm64.whl", hash = "sha256:d36b0263e7c2fbf1750b9f35d4e7e48b0442d8c45e4a89e3e74168821fb014bb"}, + {file = "aiohttp-3.14.4-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:264b5a7568306590c44ae4a0237ad1715e35d447ea44ebf324e4c8fd9f78f67a"}, + {file = "aiohttp-3.14.4-cp313-cp313-android_24_x86_64.whl", hash = "sha256:17e5d7c7775d8dd8e894c7ef6ebfa26509de36868a9a6c7c4fcfaf6a1bf43d60"}, + {file = "aiohttp-3.14.4-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:e91dc8fe9cbd052d16f7f1267e285cf8bbac4d2194bd5741f05ef201c77ed09e"}, + {file = "aiohttp-3.14.4-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:8df6157d31703972aec9e3b93963f039ff06318301e30b007c3e941ff8a7ac42"}, + {file = "aiohttp-3.14.4-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:220912b351549dc736c59d104dc443fa615753102bb778a4e98f86e4d94bff6a"}, + {file = "aiohttp-3.14.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:2efa42b39bb3f524d5eca3760639b584afdd1143a6b047fda29910ffb75e4993"}, + {file = "aiohttp-3.14.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7e7356059c8262d2c1fd95242e2b7b70fbc6eee3135bf470049cbec3e968b5b0"}, + {file = "aiohttp-3.14.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:fac247d0cc956d732df1211ac2d8a9999ec8dc1a92a90401de9d52e4ead546f7"}, + {file = "aiohttp-3.14.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e2eb0f8b03b4f2bd154ed8cf7c1a119a1ad04808c258bf58f90138c83b8c6d5"}, + {file = "aiohttp-3.14.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7fbe827d27e0e369fd7bb88ceeaa5b46ea006e73e015b9dd77e3723a53162293"}, + {file = "aiohttp-3.14.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a70387146d03af9f047c629b71aa27d9594b3b31ec4c9c91e1a73d0d8bf38e0e"}, + {file = "aiohttp-3.14.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0d0934926fc65744e2fdd44ce68b2d79d5ee608a1e23f0596b35dd696519bb7c"}, + {file = "aiohttp-3.14.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ff4b366510c733974adb7a4102c094e4a6308e6f369315a4cf14d2d0a619cf82"}, + {file = "aiohttp-3.14.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:85fac7c99e0ac3dcbd6ae1c33774e0603bfc732ddb967a6fce4a731103c1888e"}, + {file = "aiohttp-3.14.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ef1e9c3b4a2300023a5dc865889ce532cfaf6798ba4ef78fbbefe738a9d23efa"}, + {file = "aiohttp-3.14.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:97e65916588be0f952b3307aaa8460c0771fa98dbea2dd27dabc9f5d84d53c3b"}, + {file = "aiohttp-3.14.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:840775cb39a9424f9edf142133a1192263ac5bd79117ad2a16602cef6a0c1e9d"}, + {file = "aiohttp-3.14.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:54f9256430ca040d58affbd551513de13a5cff7d065204fc52b9a1b0af09a049"}, + {file = "aiohttp-3.14.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:6112d5931bf12c776188cab81b82bbb17d86e2e1381f2ade6edc43e6b240f0cb"}, + {file = "aiohttp-3.14.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:facc6df39047c4732cbd885bb62e40df20885fcd709fc399e11f81b45ce0fff9"}, + {file = "aiohttp-3.14.4-cp313-cp313-win32.whl", hash = "sha256:7968634fa3a967a2bc0b9aeba1d5a1955501dcd7d0de44b96f7ebfb662797735"}, + {file = "aiohttp-3.14.4-cp313-cp313-win_amd64.whl", hash = "sha256:c0a894b0265d139cd4c2c8bd4643822cc289a4a5331e21e810881bd000ffb2dc"}, + {file = "aiohttp-3.14.4-cp313-cp313-win_arm64.whl", hash = "sha256:da16c3037178e72589d91de59536d271dffc92c2be2b47c38a45538cba54fd29"}, + {file = "aiohttp-3.14.4-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:749bfc43bb1df71bbe6ed215044d5412d786698fc5771d2037436ca49622f3c9"}, + {file = "aiohttp-3.14.4-cp314-cp314-android_24_x86_64.whl", hash = "sha256:c113e4b489d711f606ca278cd8dc89179746244ea841aa0638b1b134600afad0"}, + {file = "aiohttp-3.14.4-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:50969522bc7022026a2c7968e67da5c789f6b716b988edac55dc630390efd5df"}, + {file = "aiohttp-3.14.4-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:cbf92cd7a1c800cee244558dd5630abb45c1c1093ef7b0d546a99f526ff7a9eb"}, + {file = "aiohttp-3.14.4-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:fc76be08ff407fba717a769aff04ca1b4bf9ecfdcb5caadef84a563fdbbd146d"}, + {file = "aiohttp-3.14.4-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:9b416f995b68a921069e6ec61fa07f2ac3ff033d92e97a69f673af89f5bb954d"}, + {file = "aiohttp-3.14.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2c9585101cfca10e74a07cc0ef2bdc6d90616e6750926b20456f429d0608f740"}, + {file = "aiohttp-3.14.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3c4dcf611b095e7983421f49d01ffbed7ed574891533d606ea115fc23e7c4e90"}, + {file = "aiohttp-3.14.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f8f61a9b5fa56c58e3441f9dc64137f786232d40fb89127190d0e0f84e1e5865"}, + {file = "aiohttp-3.14.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d43e538dfc85b705fd832620d050970ef5613b3869a7169b44a554b9dab9eee9"}, + {file = "aiohttp-3.14.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4135c4bb4b7682a7633fadc7170ea969d843f83aa7224e70111a20675105c985"}, + {file = "aiohttp-3.14.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:9055324f156a94fdf6dc9a825ae60f9a2947b88f591ea81ee80826633de62ae7"}, + {file = "aiohttp-3.14.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fb22c8e4b60385a9b414c70c6e8b2d0f4b23ff7fc4bb572ceb58297b228169f1"}, + {file = "aiohttp-3.14.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3b6945559a260112742ed58cde2165488d2fc51aeea34afbaa99d9371b43e1b5"}, + {file = "aiohttp-3.14.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8f4078a90b174f15efb2c8725e8720c40dbd3b2cf6350dbc085c964a938d9de7"}, + {file = "aiohttp-3.14.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:f433c5654e32f72de3ef074d715eb5c7604eb6d28a5c2f3c9e5056f20fe6b306"}, + {file = "aiohttp-3.14.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:871035fe79c636b6bc126ed78df37d72b830dfc751612cb4b1040360edf2719f"}, + {file = "aiohttp-3.14.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2617132524f66338f6c1d218cd16081576aefc40df4f2bcba338a99fbf67fec1"}, + {file = "aiohttp-3.14.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d8bc326133272deee8ef337581550450e4bb735c0520be893b950a1f5baaf41a"}, + {file = "aiohttp-3.14.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:3ec57223e261b7fa9979c12dbce009ca53439be76cac3af27f860d3e4b1d6f7a"}, + {file = "aiohttp-3.14.4-cp314-cp314-win32.whl", hash = "sha256:7242043e71fc449a19a47d92f4e9fd1e0ae8d3f88488982381f422bf6d651218"}, + {file = "aiohttp-3.14.4-cp314-cp314-win_amd64.whl", hash = "sha256:019587c7b3a44917dd61bcb312fd5c034f341dc9851b83e7b41b65e08b68ca0f"}, + {file = "aiohttp-3.14.4-cp314-cp314-win_arm64.whl", hash = "sha256:60dc71d38db0988f37e78f6ad4a010a2f6355cfac3fff5f130cf5ef2231f3f0d"}, + {file = "aiohttp-3.14.4-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:674f53ab9d2794e2dd767619a3384bf1006f8d075e43c19d449a645f8ff641c2"}, + {file = "aiohttp-3.14.4-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:6d243221f73e5ac546c2ed9255100423e4bc092b08b944f23498e8cf3096c26c"}, + {file = "aiohttp-3.14.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0daa016eb74e7888ed5f9ceec6eea3158999c1c4a115ef5cbe88baa8d924f94c"}, + {file = "aiohttp-3.14.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70c031a622aa20add05ebd234b90adaf6bf51c1c88cc305ec760721af83308c3"}, + {file = "aiohttp-3.14.4-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7df363fa7c38945a896e12c69af4a1a56cbd4152791d9e41fd0bac396b72de38"}, + {file = "aiohttp-3.14.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:02a508ba5ad91c4d730523584c0adc65882274bba5e37c33bc2f475e37577256"}, + {file = "aiohttp-3.14.4-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0cb3edece6fe6a944eaf97d803b88f606da6bc1600b1894c2969e78ffdc1fc29"}, + {file = "aiohttp-3.14.4-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:21ce1223b461bcc5fb389a7204001578f1c0b85c2da60a84d915ebb021294245"}, + {file = "aiohttp-3.14.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:35d5432f0dc1c8b71307e9112461b52f336da225e344283eec4779222c0a1dff"}, + {file = "aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d6ec364493057c118d08292f7cd60865965c209167d8657b45643a26aef77495"}, + {file = "aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:70492983b7aed9e61bda82fe1ce80bcba9199610886443133783a288638923c0"}, + {file = "aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:a77776673331577147e9d25cd7833a72e8891b47556336cff06ba1569e488b99"}, + {file = "aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:73799000dd6fd5247094fd8e6d3e1eb871e41aab5cc35dff9d9f654cd230bc24"}, + {file = "aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:27b370fb532e707e8c96d04fa0c96301fb7dba2d50aaca57f6c456cdfffec5bd"}, + {file = "aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:884e0d1c707b6217fee3080b9b4029eee7551af788ee761010df19be158414b7"}, + {file = "aiohttp-3.14.4-cp314-cp314t-win32.whl", hash = "sha256:f2e3d34edb151d3e27f93a8338e2da33e2c7261cd4c879ce5f5fe280cc190ea5"}, + {file = "aiohttp-3.14.4-cp314-cp314t-win_amd64.whl", hash = "sha256:88cf889e51092537fe44adfbff96c2a22d6479d6f92b97b3d413fbfd0a4decf4"}, + {file = "aiohttp-3.14.4-cp314-cp314t-win_arm64.whl", hash = "sha256:ca450c6d42fda7c0bfaf0e200f32f77c5f2c960a33be1e14d197c84588b7f5f6"}, + {file = "aiohttp-3.14.4-cp315-cp315-android_24_arm64_v8a.whl", hash = "sha256:3b10799df72f66c30935bc661cb89e5ac2918debfc575e350e226fbaa846cbb7"}, + {file = "aiohttp-3.14.4-cp315-cp315-android_24_x86_64.whl", hash = "sha256:7ffd7f9dd39caccc6b2f68ec0339435ecad2b20f6ea2e2b3de91bbe464ac7137"}, + {file = "aiohttp-3.14.4-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:a0a7a227353f7693f73878ad14cd2623cafadd656ababcd20e2adfb7225172ea"}, + {file = "aiohttp-3.14.4-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:1c43b6af8e4708e8b3812a9ee4f79895207e12d555b7f6d70deb838e0011e12d"}, + {file = "aiohttp-3.14.4-cp315-cp315-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:97416b2b997e5e9b817e322b2f0a89b76c54cde22471f51ac17ac15e10901ba0"}, + {file = "aiohttp-3.14.4-cp315-cp315-macosx_10_15_universal2.whl", hash = "sha256:ee2a5aa31e507c17841d592364f2148393b17f83bc2766e9211e1eb31ea72a70"}, + {file = "aiohttp-3.14.4-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:5d5d9843c34866e986dd24eef713452609e304550c471320ce7b54b3cfb1391e"}, + {file = "aiohttp-3.14.4-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:efcbf93e31b52c21665b6ebc489eb6fdb0dfd86b592edc677b5cffdfa7b11677"}, + {file = "aiohttp-3.14.4-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2f1a79977794592dcf6485ed964ec2448db527a1bc0c72ec89663658dad3a739"}, + {file = "aiohttp-3.14.4-cp315-cp315-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:515e7ac6d27509dc3ba2c35fb88970b00b9e7b07ee7cc947c8733dcd54ef5def"}, + {file = "aiohttp-3.14.4-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:185154ffa3b54765b5de96f464f41cfa476f8815a03854ae5e0fe4d48fb06e9c"}, + {file = "aiohttp-3.14.4-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6aece59f77959628a22cd2ffe48b102cda9611d680e090f204385b3998a1190f"}, + {file = "aiohttp-3.14.4-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7205aa6589f1ad1306c6994ff2e1ab5efabacf938f9ffd7682fb225c197b06a"}, + {file = "aiohttp-3.14.4-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f38c7b3ce60d55ac0f2a9fd2edc194789d043fefea15cfb7dcb40b7d5f561146"}, + {file = "aiohttp-3.14.4-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:b0a1274ee4ee6203c15a341cce87f9f3df8151d5496047b3608bb62bd969cffc"}, + {file = "aiohttp-3.14.4-cp315-cp315-musllinux_1_2_armv7l.whl", hash = "sha256:69ce2407951516f413adf3132b88451eababd710ce631f83c81a9603a3640253"}, + {file = "aiohttp-3.14.4-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:b84d3d057c60eb8e0c2b457a1203e868d82709d3f0c272a4975dfd88c2414939"}, + {file = "aiohttp-3.14.4-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:4ecc84f69c9e217984f6877e832e4786a74567432c0bf2b7512919fbdfe18ade"}, + {file = "aiohttp-3.14.4-cp315-cp315-musllinux_1_2_s390x.whl", hash = "sha256:878f2d7950238b2b0a8cbb88054444a125f0cfbc77f54c811aca0483132a9be3"}, + {file = "aiohttp-3.14.4-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:6ff9d3a0e6935f1cb0a6685f9f4b3f0d3e406456d7a434a03cf309b8cd5d7a2e"}, + {file = "aiohttp-3.14.4-cp315-cp315-win32.whl", hash = "sha256:e07dfd7cd360f20be26dc2487ad4c7f21b0b39fdd593e9ebf37d2424ad52defb"}, + {file = "aiohttp-3.14.4-cp315-cp315-win_amd64.whl", hash = "sha256:921fc4f1ad549091bfc39cb5e93925b04f307f83517756a3111843851130efce"}, + {file = "aiohttp-3.14.4-cp315-cp315-win_arm64.whl", hash = "sha256:5be8af106f96fd625f6c264fa9faaaa9e0104089684d9015d2fa5b6eba6407c7"}, + {file = "aiohttp-3.14.4-cp315-cp315t-macosx_10_15_universal2.whl", hash = "sha256:e69727ec04a4608200ff32ec29478299df7657e2eb78c416ae338d0ca6662596"}, + {file = "aiohttp-3.14.4-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:f8b658dd3ef2ebd7708b311ed96ff7cb5edaca001a30018a091504ef492bcb1c"}, + {file = "aiohttp-3.14.4-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:3749e018123df1205161a73ba96d336e17e9cf6b947295e53a43571de420e7b1"}, + {file = "aiohttp-3.14.4-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8f28a3c4fca436b2e594090e7cd22558f5e93a30ca18516c436de982da6fc25a"}, + {file = "aiohttp-3.14.4-cp315-cp315t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e099aae21246992a1d84303ff262262d054c474e46cace33b0d5a69810c71877"}, + {file = "aiohttp-3.14.4-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fafb521891e646d9cf5da89f01c75e7159d08be7254a024149630a698be28251"}, + {file = "aiohttp-3.14.4-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1d385db2cd154bce0b3dd451cf2a52bec91ebb7be2c3a5d06b14b4391631d807"}, + {file = "aiohttp-3.14.4-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ae8a244889d8a53549851bf595b9f382f64acca57e8762da1ecb26ba786828f7"}, + {file = "aiohttp-3.14.4-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:681dde68ff8d8d5e7d5abcad4feb45bfb457a218310c919825e21fc36cac3d0b"}, + {file = "aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:b91a6441fcaed88ca7bca67726b189332df3ceb6ac0dfc98dcb9654bb723288c"}, + {file = "aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_armv7l.whl", hash = "sha256:f15dbbac49bc15eaff95c0b8166525c4050996af578c7be141e145f40ee2cf24"}, + {file = "aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:7abae043e87692d1c2adda1fab501bb0612d28c4a23eb082005c1e684f792dac"}, + {file = "aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:21f4624fb1051fc1aa10d57a636a80e829f7d0417462d6f1ce380b08fe1a904c"}, + {file = "aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_s390x.whl", hash = "sha256:2e8dc3a0fdaf9d12b954d3d06cc4c355d91b17fb6c671715b593624ca4c379f8"}, + {file = "aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:1410b6f6e3d52ea7c02c950496522ce6e85d5543bf154bc80a6141e505251cfa"}, + {file = "aiohttp-3.14.4-cp315-cp315t-win32.whl", hash = "sha256:a65189a89f3e621f7c27a968b5131bbca29126e2b8517dc72b205747a39d4c96"}, + {file = "aiohttp-3.14.4-cp315-cp315t-win_amd64.whl", hash = "sha256:2b2c95f5f769eec92b552969db1f79ea0282058ce5131ed0f2fa540b4af3f14e"}, + {file = "aiohttp-3.14.4-cp315-cp315t-win_arm64.whl", hash = "sha256:54209fff79346ee1ef0d5cbf92fa80a5bb37396406bb4d932e5107f9c29b2d3f"}, + {file = "aiohttp-3.14.4-py3-none-any.whl", hash = "sha256:5c6758ba62aea282c537179cfc8474a90f2b5f7b089cc5ff66d8920d86a9bfdd"}, + {file = "aiohttp-3.14.4.tar.gz", hash = "sha256:831fc5bd39ec2517851e348f613ddb5447a47cf4b71cb09845af7ad7ed45d8f9"}, +] + +[package.dependencies] +aiohappyeyeballs = ">=2.5.0" +aiosignal = ">=1.4.0" +async-timeout = {version = ">=4.0,<6.0", markers = "python_version < \"3.11\""} +attrs = ">=17.3.0" +frozenlist = ">=1.1.1" +multidict = ">=4.5,<7.0" +propcache = ">=0.2.0" +typing_extensions = {version = ">=4.4", markers = "python_version < \"3.13\""} +yarl = ">=1.25.1,<2.0" + +[package.extras] +speedups = ["Brotli (>=1.2) ; platform_python_implementation == \"CPython\" and sys_platform != \"android\" and sys_platform != \"ios\"", "aiodns (>=3.3.0) ; sys_platform != \"android\" and sys_platform != \"ios\"", "backports.zstd ; platform_python_implementation == \"CPython\" and python_version < \"3.14\" and sys_platform != \"android\" and sys_platform != \"ios\"", "brotlicffi (>=1.2) ; platform_python_implementation != \"CPython\""] + +[[package]] +name = "aiosignal" +version = "1.4.0" +description = "aiosignal: a list of registered asynchronous callbacks" +optional = true +python-versions = ">=3.9" +groups = ["main"] +markers = "extra == \"aiohttp\"" +files = [ + {file = "aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e"}, + {file = "aiosignal-1.4.0.tar.gz", hash = "sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7"}, +] + +[package.dependencies] +frozenlist = ">=1.1.0" +typing-extensions = {version = ">=4.2", markers = "python_version < \"3.13\""} [[package]] name = "annotated-types" -version = "0.7.0" +version = "0.8.0" description = "Reusable constraint types to use with typing.Annotated" optional = false -python-versions = ">=3.8" +python-versions = ">=3.10" +groups = ["main"] files = [ - {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, - {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, + {file = "annotated_types-0.8.0-py3-none-any.whl", hash = "sha256:f072f4d804ea359e4eaf198b1af7a8b0943881a87f31bb764f8bf219bb9419e0"}, + {file = "annotated_types-0.8.0.tar.gz", hash = "sha256:13b2beaad985e05e2d6407ee4c4f35590b11f8d693a258a561055cac8f64cab7"}, ] -[package.dependencies] -typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.9\""} - [[package]] name = "anyio" -version = "4.5.2" -description = "High level compatibility layer for multiple asynchronous event loop implementations" +version = "4.15.1" +description = "High-level concurrency and networking framework on top of asyncio or Trio" optional = false -python-versions = ">=3.8" +python-versions = ">=3.10" +groups = ["main"] files = [ - {file = "anyio-4.5.2-py3-none-any.whl", hash = "sha256:c011ee36bc1e8ba40e5a81cb9df91925c218fe9b778554e0b56a21e1b5d4716f"}, - {file = "anyio-4.5.2.tar.gz", hash = "sha256:23009af4ed04ce05991845451e11ef02fc7c5ed29179ac9a420e5ad0ac7ddc5b"}, + {file = "anyio-4.15.1-py3-none-any.whl", hash = "sha256:6152fdbbf9a77fdec97731721bebf7c4c44f7c29b424b0065826173efc7ed101"}, + {file = "anyio-4.15.1.tar.gz", hash = "sha256:9f28306018cbd6d329e64a36d58256edff76dd996fe423bc957326e578b82a94"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" -sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.16.0", markers = "python_version < \"3.15\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] -trio = ["trio (>=0.26.1)"] +trio = ["trio (>=0.32.0)"] + +[[package]] +name = "async-timeout" +version = "5.0.1" +description = "Timeout context manager for asyncio programs" +optional = true +python-versions = ">=3.8" +groups = ["main"] +markers = "python_version == \"3.10\" and extra == \"aiohttp\"" +files = [ + {file = "async_timeout-5.0.1-py3-none-any.whl", hash = "sha256:39e3809566ff85354557ec2398b55e096c8364bacac9405a7a1fa429e77fe76c"}, + {file = "async_timeout-5.0.1.tar.gz", hash = "sha256:d9321a7a3d5a6a5e187e824d2fa0793ce379a202935782d555d6e9d2735677d3"}, +] + +[[package]] +name = "attrs" +version = "26.1.0" +description = "Classes Without Boilerplate" +optional = true +python-versions = ">=3.9" +groups = ["main"] +markers = "extra == \"aiohttp\"" +files = [ + {file = "attrs-26.1.0-py3-none-any.whl", hash = "sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309"}, + {file = "attrs-26.1.0.tar.gz", hash = "sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32"}, +] + +[[package]] +name = "backports-asyncio-runner" +version = "1.2.0" +description = "Backport of asyncio.Runner, a context manager that controls event loop life cycle." +optional = false +python-versions = "<3.11,>=3.8" +groups = ["dev"] +markers = "python_version == \"3.10\"" +files = [ + {file = "backports_asyncio_runner-1.2.0-py3-none-any.whl", hash = "sha256:0da0a936a8aeb554eccb426dc55af3ba63bcdc69fa1a600b5bb305413a4477b5"}, + {file = "backports_asyncio_runner-1.2.0.tar.gz", hash = "sha256:a5aa7b2b7d8f8bfcaa2b57313f70792df84e32a2a746f585213373f900b42162"}, +] [[package]] name = "certifi" @@ -42,6 +293,7 @@ version = "2026.7.22" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "certifi-2026.7.22-py3-none-any.whl", hash = "sha256:62f22742b58a1a33014a2b6b706588a8d7e2a88ae7bd1a6ebe8c992928483775"}, {file = "certifi-2026.7.22.tar.gz", hash = "sha256:741e2c3b351ddf169a738da9f2c048608ff7f2c5cc02f1ebc6b118bb090d5d55"}, @@ -53,6 +305,8 @@ version = "0.4.6" description = "Cross-platform colored terminal text." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +groups = ["dev"] +markers = "sys_platform == \"win32\"" files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, @@ -64,6 +318,8 @@ version = "1.3.1" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" +groups = ["main", "dev"] +markers = "python_version == \"3.10\"" files = [ {file = "exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598"}, {file = "exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219"}, @@ -81,6 +337,7 @@ version = "2.1.2" description = "execnet: rapid multi-Python deployment" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "execnet-2.1.2-py3-none-any.whl", hash = "sha256:67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec"}, {file = "execnet-2.1.2.tar.gz", hash = "sha256:63d83bfdd9a23e35b9c6a3261412324f964c2ec8dcd8d3c6916ee9373e0befcd"}, @@ -89,12 +346,154 @@ files = [ [package.extras] testing = ["hatch", "pre-commit", "pytest", "tox"] +[[package]] +name = "frozenlist" +version = "1.8.0" +description = "A list-like structure which implements collections.abc.MutableSequence" +optional = true +python-versions = ">=3.9" +groups = ["main"] +markers = "extra == \"aiohttp\"" +files = [ + {file = "frozenlist-1.8.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b37f6d31b3dcea7deb5e9696e529a6aa4a898adc33db82da12e4c60a7c4d2011"}, + {file = "frozenlist-1.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ef2b7b394f208233e471abc541cc6991f907ffd47dc72584acee3147899d6565"}, + {file = "frozenlist-1.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a88f062f072d1589b7b46e951698950e7da00442fc1cacbe17e19e025dc327ad"}, + {file = "frozenlist-1.8.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f57fb59d9f385710aa7060e89410aeb5058b99e62f4d16b08b91986b9a2140c2"}, + {file = "frozenlist-1.8.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:799345ab092bee59f01a915620b5d014698547afd011e691a208637312db9186"}, + {file = "frozenlist-1.8.0-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c23c3ff005322a6e16f71bf8692fcf4d5a304aaafe1e262c98c6d4adc7be863e"}, + {file = "frozenlist-1.8.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8a76ea0f0b9dfa06f254ee06053d93a600865b3274358ca48a352ce4f0798450"}, + {file = "frozenlist-1.8.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c7366fe1418a6133d5aa824ee53d406550110984de7637d65a178010f759c6ef"}, + {file = "frozenlist-1.8.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:13d23a45c4cebade99340c4165bd90eeb4a56c6d8a9d8aa49568cac19a6d0dc4"}, + {file = "frozenlist-1.8.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:e4a3408834f65da56c83528fb52ce7911484f0d1eaf7b761fc66001db1646eff"}, + {file = "frozenlist-1.8.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:42145cd2748ca39f32801dad54aeea10039da6f86e303659db90db1c4b614c8c"}, + {file = "frozenlist-1.8.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:e2de870d16a7a53901e41b64ffdf26f2fbb8917b3e6ebf398098d72c5b20bd7f"}, + {file = "frozenlist-1.8.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:20e63c9493d33ee48536600d1a5c95eefc870cd71e7ab037763d1fbb89cc51e7"}, + {file = "frozenlist-1.8.0-cp310-cp310-win32.whl", hash = "sha256:adbeebaebae3526afc3c96fad434367cafbfd1b25d72369a9e5858453b1bb71a"}, + {file = "frozenlist-1.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:667c3777ca571e5dbeb76f331562ff98b957431df140b54c85fd4d52eea8d8f6"}, + {file = "frozenlist-1.8.0-cp310-cp310-win_arm64.whl", hash = "sha256:80f85f0a7cc86e7a54c46d99c9e1318ff01f4687c172ede30fd52d19d1da1c8e"}, + {file = "frozenlist-1.8.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:09474e9831bc2b2199fad6da3c14c7b0fbdd377cce9d3d77131be28906cb7d84"}, + {file = "frozenlist-1.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:17c883ab0ab67200b5f964d2b9ed6b00971917d5d8a92df149dc2c9779208ee9"}, + {file = "frozenlist-1.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fa47e444b8ba08fffd1c18e8cdb9a75db1b6a27f17507522834ad13ed5922b93"}, + {file = "frozenlist-1.8.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2552f44204b744fba866e573be4c1f9048d6a324dfe14475103fd51613eb1d1f"}, + {file = "frozenlist-1.8.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:957e7c38f250991e48a9a73e6423db1bb9dd14e722a10f6b8bb8e16a0f55f695"}, + {file = "frozenlist-1.8.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8585e3bb2cdea02fc88ffa245069c36555557ad3609e83be0ec71f54fd4abb52"}, + {file = "frozenlist-1.8.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:edee74874ce20a373d62dc28b0b18b93f645633c2943fd90ee9d898550770581"}, + {file = "frozenlist-1.8.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c9a63152fe95756b85f31186bddf42e4c02c6321207fd6601a1c89ebac4fe567"}, + {file = "frozenlist-1.8.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b6db2185db9be0a04fecf2f241c70b63b1a242e2805be291855078f2b404dd6b"}, + {file = "frozenlist-1.8.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:f4be2e3d8bc8aabd566f8d5b8ba7ecc09249d74ba3c9ed52e54dc23a293f0b92"}, + {file = "frozenlist-1.8.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c8d1634419f39ea6f5c427ea2f90ca85126b54b50837f31497f3bf38266e853d"}, + {file = "frozenlist-1.8.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:1a7fa382a4a223773ed64242dbe1c9c326ec09457e6b8428efb4118c685c3dfd"}, + {file = "frozenlist-1.8.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:11847b53d722050808926e785df837353bd4d75f1d494377e59b23594d834967"}, + {file = "frozenlist-1.8.0-cp311-cp311-win32.whl", hash = "sha256:27c6e8077956cf73eadd514be8fb04d77fc946a7fe9f7fe167648b0b9085cc25"}, + {file = "frozenlist-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:ac913f8403b36a2c8610bbfd25b8013488533e71e62b4b4adce9c86c8cea905b"}, + {file = "frozenlist-1.8.0-cp311-cp311-win_arm64.whl", hash = "sha256:d4d3214a0f8394edfa3e303136d0575eece0745ff2b47bd2cb2e66dd92d4351a"}, + {file = "frozenlist-1.8.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:78f7b9e5d6f2fdb88cdde9440dc147259b62b9d3b019924def9f6478be254ac1"}, + {file = "frozenlist-1.8.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:229bf37d2e4acdaf808fd3f06e854a4a7a3661e871b10dc1f8f1896a3b05f18b"}, + {file = "frozenlist-1.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f833670942247a14eafbb675458b4e61c82e002a148f49e68257b79296e865c4"}, + {file = "frozenlist-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:494a5952b1c597ba44e0e78113a7266e656b9794eec897b19ead706bd7074383"}, + {file = "frozenlist-1.8.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96f423a119f4777a4a056b66ce11527366a8bb92f54e541ade21f2374433f6d4"}, + {file = "frozenlist-1.8.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3462dd9475af2025c31cc61be6652dfa25cbfb56cbbf52f4ccfe029f38decaf8"}, + {file = "frozenlist-1.8.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c4c800524c9cd9bac5166cd6f55285957fcfc907db323e193f2afcd4d9abd69b"}, + {file = "frozenlist-1.8.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d6a5df73acd3399d893dafc71663ad22534b5aa4f94e8a2fabfe856c3c1b6a52"}, + {file = "frozenlist-1.8.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:405e8fe955c2280ce66428b3ca55e12b3c4e9c336fb2103a4937e891c69a4a29"}, + {file = "frozenlist-1.8.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:908bd3f6439f2fef9e85031b59fd4f1297af54415fb60e4254a95f75b3cab3f3"}, + {file = "frozenlist-1.8.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:294e487f9ec720bd8ffcebc99d575f7eff3568a08a253d1ee1a0378754b74143"}, + {file = "frozenlist-1.8.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:74c51543498289c0c43656701be6b077f4b265868fa7f8a8859c197006efb608"}, + {file = "frozenlist-1.8.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:776f352e8329135506a1d6bf16ac3f87bc25b28e765949282dcc627af36123aa"}, + {file = "frozenlist-1.8.0-cp312-cp312-win32.whl", hash = "sha256:433403ae80709741ce34038da08511d4a77062aa924baf411ef73d1146e74faf"}, + {file = "frozenlist-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:34187385b08f866104f0c0617404c8eb08165ab1272e884abc89c112e9c00746"}, + {file = "frozenlist-1.8.0-cp312-cp312-win_arm64.whl", hash = "sha256:fe3c58d2f5db5fbd18c2987cba06d51b0529f52bc3a6cdc33d3f4eab725104bd"}, + {file = "frozenlist-1.8.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8d92f1a84bb12d9e56f818b3a746f3efba93c1b63c8387a73dde655e1e42282a"}, + {file = "frozenlist-1.8.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:96153e77a591c8adc2ee805756c61f59fef4cf4073a9275ee86fe8cba41241f7"}, + {file = "frozenlist-1.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f21f00a91358803399890ab167098c131ec2ddd5f8f5fd5fe9c9f2c6fcd91e40"}, + {file = "frozenlist-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fb30f9626572a76dfe4293c7194a09fb1fe93ba94c7d4f720dfae3b646b45027"}, + {file = "frozenlist-1.8.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eaa352d7047a31d87dafcacbabe89df0aa506abb5b1b85a2fb91bc3faa02d822"}, + {file = "frozenlist-1.8.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:03ae967b4e297f58f8c774c7eabcce57fe3c2434817d4385c50661845a058121"}, + {file = "frozenlist-1.8.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f6292f1de555ffcc675941d65fffffb0a5bcd992905015f85d0592201793e0e5"}, + {file = "frozenlist-1.8.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29548f9b5b5e3460ce7378144c3010363d8035cea44bc0bf02d57f5a685e084e"}, + {file = "frozenlist-1.8.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ec3cc8c5d4084591b4237c0a272cc4f50a5b03396a47d9caaf76f5d7b38a4f11"}, + {file = "frozenlist-1.8.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:517279f58009d0b1f2e7c1b130b377a349405da3f7621ed6bfae50b10adf20c1"}, + {file = "frozenlist-1.8.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:db1e72ede2d0d7ccb213f218df6a078a9c09a7de257c2fe8fcef16d5925230b1"}, + {file = "frozenlist-1.8.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b4dec9482a65c54a5044486847b8a66bf10c9cb4926d42927ec4e8fd5db7fed8"}, + {file = "frozenlist-1.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:21900c48ae04d13d416f0e1e0c4d81f7931f73a9dfa0b7a8746fb2fe7dd970ed"}, + {file = "frozenlist-1.8.0-cp313-cp313-win32.whl", hash = "sha256:8b7b94a067d1c504ee0b16def57ad5738701e4ba10cec90529f13fa03c833496"}, + {file = "frozenlist-1.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:878be833caa6a3821caf85eb39c5ba92d28e85df26d57afb06b35b2efd937231"}, + {file = "frozenlist-1.8.0-cp313-cp313-win_arm64.whl", hash = "sha256:44389d135b3ff43ba8cc89ff7f51f5a0bb6b63d829c8300f79a2fe4fe61bcc62"}, + {file = "frozenlist-1.8.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:e25ac20a2ef37e91c1b39938b591457666a0fa835c7783c3a8f33ea42870db94"}, + {file = "frozenlist-1.8.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:07cdca25a91a4386d2e76ad992916a85038a9b97561bf7a3fd12d5d9ce31870c"}, + {file = "frozenlist-1.8.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4e0c11f2cc6717e0a741f84a527c52616140741cd812a50422f83dc31749fb52"}, + {file = "frozenlist-1.8.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b3210649ee28062ea6099cfda39e147fa1bc039583c8ee4481cb7811e2448c51"}, + {file = "frozenlist-1.8.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:581ef5194c48035a7de2aefc72ac6539823bb71508189e5de01d60c9dcd5fa65"}, + {file = "frozenlist-1.8.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3ef2d026f16a2b1866e1d86fc4e1291e1ed8a387b2c333809419a2f8b3a77b82"}, + {file = "frozenlist-1.8.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5500ef82073f599ac84d888e3a8c1f77ac831183244bfd7f11eaa0289fb30714"}, + {file = "frozenlist-1.8.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:50066c3997d0091c411a66e710f4e11752251e6d2d73d70d8d5d4c76442a199d"}, + {file = "frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:5c1c8e78426e59b3f8005e9b19f6ff46e5845895adbde20ece9218319eca6506"}, + {file = "frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:eefdba20de0d938cec6a89bd4d70f346a03108a19b9df4248d3cf0d88f1b0f51"}, + {file = "frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:cf253e0e1c3ceb4aaff6df637ce033ff6535fb8c70a764a8f46aafd3d6ab798e"}, + {file = "frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:032efa2674356903cd0261c4317a561a6850f3ac864a63fc1583147fb05a79b0"}, + {file = "frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6da155091429aeba16851ecb10a9104a108bcd32f6c1642867eadaee401c1c41"}, + {file = "frozenlist-1.8.0-cp313-cp313t-win32.whl", hash = "sha256:0f96534f8bfebc1a394209427d0f8a63d343c9779cda6fc25e8e121b5fd8555b"}, + {file = "frozenlist-1.8.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5d63a068f978fc69421fb0e6eb91a9603187527c86b7cd3f534a5b77a592b888"}, + {file = "frozenlist-1.8.0-cp313-cp313t-win_arm64.whl", hash = "sha256:bf0a7e10b077bf5fb9380ad3ae8ce20ef919a6ad93b4552896419ac7e1d8e042"}, + {file = "frozenlist-1.8.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:cee686f1f4cadeb2136007ddedd0aaf928ab95216e7691c63e50a8ec066336d0"}, + {file = "frozenlist-1.8.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:119fb2a1bd47307e899c2fac7f28e85b9a543864df47aa7ec9d3c1b4545f096f"}, + {file = "frozenlist-1.8.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4970ece02dbc8c3a92fcc5228e36a3e933a01a999f7094ff7c23fbd2beeaa67c"}, + {file = "frozenlist-1.8.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:cba69cb73723c3f329622e34bdbf5ce1f80c21c290ff04256cff1cd3c2036ed2"}, + {file = "frozenlist-1.8.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:778a11b15673f6f1df23d9586f83c4846c471a8af693a22e066508b77d201ec8"}, + {file = "frozenlist-1.8.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0325024fe97f94c41c08872db482cf8ac4800d80e79222c6b0b7b162d5b13686"}, + {file = "frozenlist-1.8.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:97260ff46b207a82a7567b581ab4190bd4dfa09f4db8a8b49d1a958f6aa4940e"}, + {file = "frozenlist-1.8.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:54b2077180eb7f83dd52c40b2750d0a9f175e06a42e3213ce047219de902717a"}, + {file = "frozenlist-1.8.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2f05983daecab868a31e1da44462873306d3cbfd76d1f0b5b69c473d21dbb128"}, + {file = "frozenlist-1.8.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:33f48f51a446114bc5d251fb2954ab0164d5be02ad3382abcbfe07e2531d650f"}, + {file = "frozenlist-1.8.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:154e55ec0655291b5dd1b8731c637ecdb50975a2ae70c606d100750a540082f7"}, + {file = "frozenlist-1.8.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:4314debad13beb564b708b4a496020e5306c7333fa9a3ab90374169a20ffab30"}, + {file = "frozenlist-1.8.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:073f8bf8becba60aa931eb3bc420b217bb7d5b8f4750e6f8b3be7f3da85d38b7"}, + {file = "frozenlist-1.8.0-cp314-cp314-win32.whl", hash = "sha256:bac9c42ba2ac65ddc115d930c78d24ab8d4f465fd3fc473cdedfccadb9429806"}, + {file = "frozenlist-1.8.0-cp314-cp314-win_amd64.whl", hash = "sha256:3e0761f4d1a44f1d1a47996511752cf3dcec5bbdd9cc2b4fe595caf97754b7a0"}, + {file = "frozenlist-1.8.0-cp314-cp314-win_arm64.whl", hash = "sha256:d1eaff1d00c7751b7c6662e9c5ba6eb2c17a2306ba5e2a37f24ddf3cc953402b"}, + {file = "frozenlist-1.8.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:d3bb933317c52d7ea5004a1c442eef86f426886fba134ef8cf4226ea6ee1821d"}, + {file = "frozenlist-1.8.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:8009897cdef112072f93a0efdce29cd819e717fd2f649ee3016efd3cd885a7ed"}, + {file = "frozenlist-1.8.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2c5dcbbc55383e5883246d11fd179782a9d07a986c40f49abe89ddf865913930"}, + {file = "frozenlist-1.8.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:39ecbc32f1390387d2aa4f5a995e465e9e2f79ba3adcac92d68e3e0afae6657c"}, + {file = "frozenlist-1.8.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92db2bf818d5cc8d9c1f1fc56b897662e24ea5adb36ad1f1d82875bd64e03c24"}, + {file = "frozenlist-1.8.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2dc43a022e555de94c3b68a4ef0b11c4f747d12c024a520c7101709a2144fb37"}, + {file = "frozenlist-1.8.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb89a7f2de3602cfed448095bab3f178399646ab7c61454315089787df07733a"}, + {file = "frozenlist-1.8.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:33139dc858c580ea50e7e60a1b0ea003efa1fd42e6ec7fdbad78fff65fad2fd2"}, + {file = "frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:168c0969a329b416119507ba30b9ea13688fafffac1b7822802537569a1cb0ef"}, + {file = "frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:28bd570e8e189d7f7b001966435f9dac6718324b5be2990ac496cf1ea9ddb7fe"}, + {file = "frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:b2a095d45c5d46e5e79ba1e5b9cb787f541a8dee0433836cea4b96a2c439dcd8"}, + {file = "frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:eab8145831a0d56ec9c4139b6c3e594c7a83c2c8be25d5bcf2d86136a532287a"}, + {file = "frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:974b28cf63cc99dfb2188d8d222bc6843656188164848c4f679e63dae4b0708e"}, + {file = "frozenlist-1.8.0-cp314-cp314t-win32.whl", hash = "sha256:342c97bf697ac5480c0a7ec73cd700ecfa5a8a40ac923bd035484616efecc2df"}, + {file = "frozenlist-1.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:06be8f67f39c8b1dc671f5d83aaefd3358ae5cdcf8314552c57e7ed3e6475bdd"}, + {file = "frozenlist-1.8.0-cp314-cp314t-win_arm64.whl", hash = "sha256:102e6314ca4da683dca92e3b1355490fed5f313b768500084fbe6371fddfdb79"}, + {file = "frozenlist-1.8.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d8b7138e5cd0647e4523d6685b0eac5d4be9a184ae9634492f25c6eb38c12a47"}, + {file = "frozenlist-1.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a6483e309ca809f1efd154b4d37dc6d9f61037d6c6a81c2dc7a15cb22c8c5dca"}, + {file = "frozenlist-1.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1b9290cf81e95e93fdf90548ce9d3c1211cf574b8e3f4b3b7cb0537cf2227068"}, + {file = "frozenlist-1.8.0-cp39-cp39-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:59a6a5876ca59d1b63af8cd5e7ffffb024c3dc1e9cf9301b21a2e76286505c95"}, + {file = "frozenlist-1.8.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6dc4126390929823e2d2d9dc79ab4046ed74680360fc5f38b585c12c66cdf459"}, + {file = "frozenlist-1.8.0-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:332db6b2563333c5671fecacd085141b5800cb866be16d5e3eb15a2086476675"}, + {file = "frozenlist-1.8.0-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9ff15928d62a0b80bb875655c39bf517938c7d589554cbd2669be42d97c2cb61"}, + {file = "frozenlist-1.8.0-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7bf6cdf8e07c8151fba6fe85735441240ec7f619f935a5205953d58009aef8c6"}, + {file = "frozenlist-1.8.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:48e6d3f4ec5c7273dfe83ff27c91083c6c9065af655dc2684d2c200c94308bb5"}, + {file = "frozenlist-1.8.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:1a7607e17ad33361677adcd1443edf6f5da0ce5e5377b798fba20fae194825f3"}, + {file = "frozenlist-1.8.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:5a3a935c3a4e89c733303a2d5a7c257ea44af3a56c8202df486b7f5de40f37e1"}, + {file = "frozenlist-1.8.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:940d4a017dbfed9daf46a3b086e1d2167e7012ee297fef9e1c545c4d022f5178"}, + {file = "frozenlist-1.8.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b9be22a69a014bc47e78072d0ecae716f5eb56c15238acca0f43d6eb8e4a5bda"}, + {file = "frozenlist-1.8.0-cp39-cp39-win32.whl", hash = "sha256:1aa77cb5697069af47472e39612976ed05343ff2e84a3dcf15437b232cbfd087"}, + {file = "frozenlist-1.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:7398c222d1d405e796970320036b1b563892b65809d9e5261487bb2c7f7b5c6a"}, + {file = "frozenlist-1.8.0-cp39-cp39-win_arm64.whl", hash = "sha256:b4f3b365f31c6cd4af24545ca0a244a53688cad8834e32f56831c4923b50a103"}, + {file = "frozenlist-1.8.0-py3-none-any.whl", hash = "sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d"}, + {file = "frozenlist-1.8.0.tar.gz", hash = "sha256:3ede829ed8d842f6cd48fc7081d7a41001a56f1f38603f9d49bf3020d59a31ad"}, +] + [[package]] name = "h11" version = "0.16.0" description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86"}, {file = "h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1"}, @@ -106,6 +505,7 @@ version = "1.0.9" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55"}, {file = "httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8"}, @@ -127,6 +527,7 @@ version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, @@ -139,43 +540,248 @@ httpcore = "==1.*" idna = "*" [package.extras] -brotli = ["brotli", "brotlicffi"] +brotli = ["brotli ; platform_python_implementation == \"CPython\"", "brotlicffi ; platform_python_implementation != \"CPython\""] cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] http2 = ["h2 (>=3,<5)"] socks = ["socksio (==1.*)"] zstd = ["zstandard (>=0.18.0)"] +[[package]] +name = "httpx-aiohttp" +version = "0.1.12" +description = "Aiohttp transport for HTTPX" +optional = true +python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"aiohttp\"" +files = [ + {file = "httpx_aiohttp-0.1.12-py3-none-any.whl", hash = "sha256:5b0eac39a7f360fa7867a60bcb46bb1024eada9c01cbfecdb54dc1edb3fb7141"}, + {file = "httpx_aiohttp-0.1.12.tar.gz", hash = "sha256:81feec51fd82c0ecfa0e9aaf1b1a6c2591260d5e2bcbeb7eb0277a78e610df2c"}, +] + +[package.dependencies] +aiohttp = ">=3.10.0,<4" +httpx = ">=0.27.0" + [[package]] name = "idna" -version = "3.15" +version = "3.20" description = "Internationalized Domain Names in Applications (IDNA)" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" +groups = ["main"] files = [ - {file = "idna-3.15-py3-none-any.whl", hash = "sha256:048adeaf8c2d788c40fee287673ccaa74c24ffd8dcf09ffa555a2fbb59f10ac8"}, - {file = "idna-3.15.tar.gz", hash = "sha256:ca962446ea538f7092a95e057da437618e886f4d349216d2b1e294abfdb65fdc"}, + {file = "idna-3.20-py3-none-any.whl", hash = "sha256:ab7ae7122974553370f0bdb919e1a960b2cd1bc1ef0276416d896db81c14582c"}, + {file = "idna-3.20.tar.gz", hash = "sha256:a7db850025b95ded1eae8a46181a1a6c56c92c96f0e2b005d9ff8dc0210cab44"}, ] [package.extras] -all = ["mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] +all = ["coverage (>=7.10.0)", "hypothesis (>=6.141.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.16.0)", "ty (>=0.0.37)"] [[package]] name = "iniconfig" -version = "2.1.0" +version = "2.3.0" description = "brain-dead simple config-ini parsing" optional = false -python-versions = ">=3.8" +python-versions = ">=3.10" +groups = ["dev"] files = [ - {file = "iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760"}, - {file = "iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7"}, + {file = "iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12"}, + {file = "iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730"}, ] +[[package]] +name = "multidict" +version = "6.9.1" +description = "multidict implementation" +optional = true +python-versions = ">=3.10" +groups = ["main"] +markers = "extra == \"aiohttp\"" +files = [ + {file = "multidict-6.9.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:aef74e9beabbd6c4aafc091dabff86d046ccf013ce1e4396c0fbb01b4cad9de8"}, + {file = "multidict-6.9.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1ca5ebe6d454f1e5496cf052386a559f1080bf2de75bf327ebca0a6003b79f19"}, + {file = "multidict-6.9.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02f6d0c4b70f783305e73f9944d8efe6be1022550f0974ba0ae9d8893c0350fa"}, + {file = "multidict-6.9.1-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:8050e75af7e4c6e2d5260b84eeedb618f3e452e66473432e085b5d1b81429299"}, + {file = "multidict-6.9.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4736d350371337825cac1793c9f7c40701c32a03912548c2a7608e51679cbb96"}, + {file = "multidict-6.9.1-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:02fe09dc197b8ae7e355371e51e5dce2f39060cd5a8badf94904527e23a3f188"}, + {file = "multidict-6.9.1-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ad4528cdce058b684f75fad1faf4a6a6c992fe2f08376370ca66e4ce5916a84a"}, + {file = "multidict-6.9.1-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8885e3808aedbd6725b921fb67dacaae0678933561ddd47c2b01315198c70e2e"}, + {file = "multidict-6.9.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d3b6e6840421c83ccb60398e333b44f910b0907bb409597685ab2eedd1e22eab"}, + {file = "multidict-6.9.1-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c9648ed33dc8179e4ec04bbc73bd7f0038e1e81217a69467f61f02a78bf07e88"}, + {file = "multidict-6.9.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d9d6544790ba50438a9c1a903c3c4afb1ec8a7832db5518549275b40ef0dd4b1"}, + {file = "multidict-6.9.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:1c9f3c25df6c9d3bbae4f6fd3f514b1c5c740a2110f56ccf36069c85417e289c"}, + {file = "multidict-6.9.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:cf22b43f35b7dbb9f71e8ee2041b5c00029cdfc28ede3a2f31cf8906f9a6c126"}, + {file = "multidict-6.9.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8ed78ccad4c7b421804f5d524b7740946a7ef75d89dc0dac52e9d7c24c472410"}, + {file = "multidict-6.9.1-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:e3b1aa25f01238886a6baed9e13b9a9240ed344346c79ae280ae65e8603b21d5"}, + {file = "multidict-6.9.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:bc94a68ea5e18f8e85dc6b522bcb53093f692c8eb62b4837ac047da73956cbe4"}, + {file = "multidict-6.9.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:73533644e1f69ea1164d56cc6505f564c6c44072b646b66d67df2d31fed0348c"}, + {file = "multidict-6.9.1-cp310-cp310-win32.whl", hash = "sha256:66987aa68b0f7c2a1cc5f388ca962b8ed92b10f79de38d6d0d8c716154f519d9"}, + {file = "multidict-6.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:a32b78c1e52ebd8e247bb68300b90b233300d8816faa008ed0713bc539fb6af0"}, + {file = "multidict-6.9.1-cp310-cp310-win_arm64.whl", hash = "sha256:ab64ace1a68682d191d9bedd9d4c939406ad86b1d9f628180410644249ad46c2"}, + {file = "multidict-6.9.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:910d4260512660484c0dc1588a316fbb35a40c081c36fc51d1225351af17cfe4"}, + {file = "multidict-6.9.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:33fa55b990f81c2927e01399ace0d18926c69d69baa8cdaa819424132fb97987"}, + {file = "multidict-6.9.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:369b5aa01b241cd3fea6890bdbb11a1425d87bf1515831500d518f4223e9d72c"}, + {file = "multidict-6.9.1-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:803f8b575a71b1b299d677c28db0653459c79b5308874efec813f17b7457c7f1"}, + {file = "multidict-6.9.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b8a65621b98984a62e59403009591b8a5a7736273aefe1cab64cfb85b365cc07"}, + {file = "multidict-6.9.1-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:13849a1d4f54c3809ae721e9e83ab28f5ea602f33660cb84eb6ef261eac706c1"}, + {file = "multidict-6.9.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:dd9a137a4a9becda3094f3831cd026380f75f6855e051eefe4c73ade524f1cc3"}, + {file = "multidict-6.9.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:9ae9614c317c50836689ce2dfde07c05fe0b16378562e2221746c3913ede3c80"}, + {file = "multidict-6.9.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e8f1e362c9352b50ed120f001046fdbb80810c9d56580f4c3fc13bbe30823387"}, + {file = "multidict-6.9.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0dd655518f136febd96c05131a76a863e32fc2a1d7acd4e3c959e3ceb77d8345"}, + {file = "multidict-6.9.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2c5d675da8f1cb5650271c8ad5e95c0a3e5a183c105e72d953b12877b1c8d0fd"}, + {file = "multidict-6.9.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:658f90f49cf5af2441cad0a2b801c3ef520471989a1ec55bcb25b255b2ca8d2f"}, + {file = "multidict-6.9.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:43124fe172ada86d03ac3c8dc8179091341f6724d5e5d5b160e1587e4cd3761b"}, + {file = "multidict-6.9.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:b2f0adc22a4eb31e545221d93fc73a0f6a8cc2379d0f4309f71d1d17ba938b82"}, + {file = "multidict-6.9.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:7fc59e9ba821b220944ccfe0f89c9dc4745f6d097569992356eb03869f21e953"}, + {file = "multidict-6.9.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:87cc632c88ee5dc80e12681047839304d98ee5c9a708d686505767001c9b8b9a"}, + {file = "multidict-6.9.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b828cf64d62dc09ac183f03c1aeedd164ade96a2ce4934109452edf29de1dd13"}, + {file = "multidict-6.9.1-cp311-cp311-win32.whl", hash = "sha256:2c1aeb92eea59d824f004341b26d5e4b47a8a441cf9726769b9a90abf9d0e08f"}, + {file = "multidict-6.9.1-cp311-cp311-win_amd64.whl", hash = "sha256:5f89dad732280e7a10b74d40b91364f88e13c3f2c08c2ef83a8cd42f7a61af2e"}, + {file = "multidict-6.9.1-cp311-cp311-win_arm64.whl", hash = "sha256:5800368526647146978389dfaa46da3356291e9f0fff9a4ef12e8c2bef964a0d"}, + {file = "multidict-6.9.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:29138fef49828542e859828107e42e50d0e587c513b7eb4b2d92bade2b0860fe"}, + {file = "multidict-6.9.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:19e31815d41cefc365489e591d105d2baceb2f65aa75d29471fbdbda8651e006"}, + {file = "multidict-6.9.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6ed30be8918e18c8bed0a2e8b70639ecf02feb61ed00ca2e41cfcb2a50fa3f42"}, + {file = "multidict-6.9.1-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:637f4ae36264bd7b8d9a60193acddc1d735ad52e8ed53a19931ea6d921fea8e5"}, + {file = "multidict-6.9.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:35fc236507fb1b3138f0af5ecd5f94ed752d4d6d826248eae425f86204013eea"}, + {file = "multidict-6.9.1-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e58952f04772f59f11c6e007471449809a30165188669bca8fdb19dde40a8f24"}, + {file = "multidict-6.9.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d35a4f1c63f07fbb8c8f9946dea98b21eddf6c57421585f71d91864be3ba2a24"}, + {file = "multidict-6.9.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b5f8771aaaed7f80e84a4e471d2f29ab6721e4595075e54d03ae1ed951b2000a"}, + {file = "multidict-6.9.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:976fd7689d69ec78d67d31d38d396d8adb562f7e8368279f76aed4aa451fa06d"}, + {file = "multidict-6.9.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:95052e8777a86bae87c0bd0b5ab22d809e3d1d02bf69e3e66ddda5ba75a05805"}, + {file = "multidict-6.9.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1a8adfcaf96f587ab138476eaddef95f29b8a2a8a9afbfea8d2fd62180995d02"}, + {file = "multidict-6.9.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:1a53de2772cfb74559df2eb4456ec4eeb908435ec55a84b69370d9d745d62aa8"}, + {file = "multidict-6.9.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f2ce963299d42fa3f22a90adc0fdf174792ffef5ff4c7ffb68260548fb05580"}, + {file = "multidict-6.9.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5b30ddf7234e611ca877575b62840e6af5977f92f1f9d532eedbb05a44ff8004"}, + {file = "multidict-6.9.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:63ada7ee2e9345695f9e9bc4c65d72222253f07b1ac94fd0e37555cc6f3c7f60"}, + {file = "multidict-6.9.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3c95601ed98fad3f6e2f8fe809c3b526b0fab31ef525e00a155e227f3d17f58a"}, + {file = "multidict-6.9.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c148e8b596000dd3e4bfe206e70f3e666be18d72032e0012555f2373c52e35d6"}, + {file = "multidict-6.9.1-cp312-cp312-win32.whl", hash = "sha256:f9dad513626a33670f17cddc6078e30e311f444c957e8dbfc5b2b4603c8b4edb"}, + {file = "multidict-6.9.1-cp312-cp312-win_amd64.whl", hash = "sha256:a16a1dc8529f9e734a41c3b856f3eae7ebacdc061dde3f8a844e0c7889c97203"}, + {file = "multidict-6.9.1-cp312-cp312-win_arm64.whl", hash = "sha256:361f7206cf341ba94fb015688f5c8b480f8e63bd58a4c14a48aeca7851a241cc"}, + {file = "multidict-6.9.1-cp313-cp313-android_24_x86_64.whl", hash = "sha256:d7bf9e43282d69561618e8a0ea33368d532ebef42f15c096f427090521dd74f3"}, + {file = "multidict-6.9.1-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:03d47df72f084f757c1cb771188d5f4e3a805e4abc4d67e32509272343ae9382"}, + {file = "multidict-6.9.1-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:6bc94fe17c3c56e5418f79515b786b101845f70609b0d19d0c1ba13448e5633a"}, + {file = "multidict-6.9.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8f2973bbd2bebd9d2e0cd6394c1292a1a19ccd56bdcbe1e174059f1a39be5b40"}, + {file = "multidict-6.9.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:de7738b8c0bb74c4cc16bbd7fb49fc2bcf6430dba11b3432cd52768ae40933e8"}, + {file = "multidict-6.9.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e5ccad4b7bac125722f48d6f862bed3b514d8526deea06316bb72f152cd30a7c"}, + {file = "multidict-6.9.1-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:a49ff5cdb33654cb7d6a3c377aa2a83ddefaa1db31eb10bcf3c180aa84f9af8a"}, + {file = "multidict-6.9.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b22ff30006a2f28f8bff878fb93413cbe3a4d1fd517c28081d848c90e9cfd2c8"}, + {file = "multidict-6.9.1-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3adf06c66041aa21eeb8a71e82379b74773298c8e6d3d839b151aae441a99b94"}, + {file = "multidict-6.9.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:963a8d8f97057082679523d0fd4c53a38f86bc58cabe4556faef682ae53fa2fa"}, + {file = "multidict-6.9.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b66ccc5c2cdd26e74fa5d4c29ffae424cc6148bf93ce574821783fb3b6d452c5"}, + {file = "multidict-6.9.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7fd79c521f6290c69125fa2b85fa65d9e657e6a8ffaf722dc881b926bef4aa5c"}, + {file = "multidict-6.9.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:1d804e4caf5d5da37d6dac1325da5629ebef1e27a294c2b568b295814aa36c7b"}, + {file = "multidict-6.9.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bb0d664505f4b112f384cffeee82e91e3f6448d8e574989479db4439b68cba05"}, + {file = "multidict-6.9.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:9e14d17773b1b3c758ff153659a1824608a0cb562c45f484b5ed8a433428444a"}, + {file = "multidict-6.9.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:083735b7f395894e43adb278d5dae901448883a835ff8f1977e285fefdb10418"}, + {file = "multidict-6.9.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:b65121091567847a8cb520d364ab22ba90e00d3cc55fa9eb34bb439f0684bcd1"}, + {file = "multidict-6.9.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:ea999ae6e80e66ad5eea287860951b033d0104ca34d6d87c7b5125ebe0e12721"}, + {file = "multidict-6.9.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:095d900c242e00fbe5f321ee072e7278b4153e78c5ce9c1efde167d62c1e4771"}, + {file = "multidict-6.9.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6441cc837aea58be7d9baef1b2383eb8311ab9303f500f99ac90b584cd78bb14"}, + {file = "multidict-6.9.1-cp313-cp313-win32.whl", hash = "sha256:9c4880d017555d70dea367dd49271830842d48e3891c2da97da7ce8c4abcee40"}, + {file = "multidict-6.9.1-cp313-cp313-win_amd64.whl", hash = "sha256:ac51cd64bae51c462ea58ad2492c9b8209667a4ef60c45c4a304518b67598d5d"}, + {file = "multidict-6.9.1-cp313-cp313-win_arm64.whl", hash = "sha256:37a9ebe00c698279213d56e6c64e1962ab1e092918270649b397cac3dc196ca4"}, + {file = "multidict-6.9.1-cp314-cp314-android_24_x86_64.whl", hash = "sha256:fc0dcb22fa9aeabfe3fa4e0430099acff985ec5d77a851382f76cc6146e780e5"}, + {file = "multidict-6.9.1-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:024123f0ab402ab33828e24eb80fa8f25167d0d3783ba5f287e39ed741e6abf9"}, + {file = "multidict-6.9.1-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:af1b5a92315048c3e36bbebfa7d4760a9c3e910bc4166f11b20d77d20d6bcfca"}, + {file = "multidict-6.9.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:b2483da477932ad1983d1d33c18bc3771c6fb00cfbaaed70a875fd547ef8e840"}, + {file = "multidict-6.9.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:db4d697b18b6ef5528b1f36bfa25072cd2a421869f5963bc0e92c8a34b9e2800"}, + {file = "multidict-6.9.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:854fd2f1bc6e8a56b89910b5cd7261a8b40f13ebb31572da985ce59c7da0886d"}, + {file = "multidict-6.9.1-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:03731f6fc036180700c9dc2308205a48e5ca6f3ff03087739ab746f294022201"}, + {file = "multidict-6.9.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:989261c5f1735a165f2e4e87cf6d5f17ab734fa18f9ad0383d5adfcdaefce701"}, + {file = "multidict-6.9.1-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b4c9e5d05b126b267ac048a89a0e2d9b48b1b648add62d4872906304a8590610"}, + {file = "multidict-6.9.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9d0a21cf76153de8f2d96a877991d6bc59b9ab5180b949e50db73cc193b4a694"}, + {file = "multidict-6.9.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e7386aa18d98d6b8af44b92173654ec469237fda35f8e8523e43b581a86f476a"}, + {file = "multidict-6.9.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b69651732c64afb691e50cdc3387cae305e0eeff8804fe3e3ce203876494932a"}, + {file = "multidict-6.9.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:1fee9a16d88a1c4865610de31ef5c666671020d7a81d1f510eaf3c97d00ebeba"}, + {file = "multidict-6.9.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7814bbee202acd3bd240204c17d8b87a4c48c81064fd8674dbe527d94d5a4290"}, + {file = "multidict-6.9.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:95f273bea318a194f656527ee2ed19494327bc500b8e87d9358e3222579aa28d"}, + {file = "multidict-6.9.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:73bcafa21a78d0776b3ee7cd2a63c66f968eb7db8e8d594e32d7329950f6e828"}, + {file = "multidict-6.9.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:1a938761c77e0e6edb0c93d02f4e988d44a69e5195e5a3b893e5553311347132"}, + {file = "multidict-6.9.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:37245ca4105386194dd1d292a6f2aae09bfe1bd7ac6f9ec25093e3cf8e9b143b"}, + {file = "multidict-6.9.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:f0700527dd5bfa8b7204b08330542f4f388899d3c14d885d8a368992e0eb562d"}, + {file = "multidict-6.9.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6b7e54fd883671d1a8810704851c044b7173287c552b9f5c3d9e0eb9f00ae194"}, + {file = "multidict-6.9.1-cp314-cp314-win32.whl", hash = "sha256:e81ae656b9935ac4528a71f96bb7a14d949778ed1897c573d3e7ebb9187f8841"}, + {file = "multidict-6.9.1-cp314-cp314-win_amd64.whl", hash = "sha256:acddcac38adc8342ba48aba98896faa7928854bebb62542362138655b5367ee3"}, + {file = "multidict-6.9.1-cp314-cp314-win_arm64.whl", hash = "sha256:32217133dddc58c927805cf6c0731d8144584176b768042ee886d51e71860bc9"}, + {file = "multidict-6.9.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:0b2fb8c349d1103863750b5d8cb5ace766917f4b35f3d883c8f778853eaa9f76"}, + {file = "multidict-6.9.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:56d834b74c993a7d7cb2b8ab33a0d55c3e0d4a3d2f2da2808a4ad3d79189711b"}, + {file = "multidict-6.9.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:783ba7d845d79ce976afd9c1e91a4e5714671defa198ee789e8b23316083a485"}, + {file = "multidict-6.9.1-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:4d718fa1b5f0d0dd75e86fbbc5b0c93ea3a5d65216c85c61cd5d7cdddfe08455"}, + {file = "multidict-6.9.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a313bad717dde740959d50850c315b75fd4eb0c5e6b4dc8535db0f1c369be125"}, + {file = "multidict-6.9.1-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:ef01d29fca550ab871fd99154f82c6472aacf8e7def272dfb07b460123850390"}, + {file = "multidict-6.9.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0f3bd290711c6e9486173a6ee7cd4e7f00c3971c7908c1ec1b6e5437c5e4c6f9"}, + {file = "multidict-6.9.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:81cdc537e0a42e3c0170752fcadbe450246d5c3b4b7231d6eb9672456605ac94"}, + {file = "multidict-6.9.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8b193bf7a443c97d81c47052f60c486071a4bdef4a573fa2514f920089414d45"}, + {file = "multidict-6.9.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7a0c98f6a636adf0d7edd60c61589eaf52d149239af754d0bfeb0effedba53a8"}, + {file = "multidict-6.9.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:6e6b7e3a1520c39a2772f414cd9ddf5995f77e4e823dfa1522af383addd465a3"}, + {file = "multidict-6.9.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:ca65cced0d67a9039e93bcd98a369920e499bf98296844ff56ead01c9085321f"}, + {file = "multidict-6.9.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:372c063f37480f62c1ae32dc3a1a0a5942b180c883f99789075a8a8ec3c4e709"}, + {file = "multidict-6.9.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:827c92145b3b976b39430129c89d213b250dacbe5fce678e9a03940e6e848983"}, + {file = "multidict-6.9.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:9b0124b9c17e9890f0819b2e7a5f65ec9a2f5aabd6c8e7ad090c1675cf70dee6"}, + {file = "multidict-6.9.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:23136f5a564654eb61061ec6d5620a4c1ea32c8f552b65e9982a12b72bff601b"}, + {file = "multidict-6.9.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f2524ec55b3e65cbe235a8b3c36e2af3b635be02ed05e20c94e70c5c943c009e"}, + {file = "multidict-6.9.1-cp314-cp314t-win32.whl", hash = "sha256:35ba0263bae5dd3ad5aad767cc9afc01a8598c7dae30f1b3b2de98b1b32c28bd"}, + {file = "multidict-6.9.1-cp314-cp314t-win_amd64.whl", hash = "sha256:7c8d5882ba25ac0282258be435d8a05aa0cbcacfce15799154a338f847f159b9"}, + {file = "multidict-6.9.1-cp314-cp314t-win_arm64.whl", hash = "sha256:ac348379cf4de5538a0a213be1532d289aa801ec5d267c5909446b9ea2f8e2c3"}, + {file = "multidict-6.9.1-cp315-cp315-android_24_x86_64.whl", hash = "sha256:f04551dce5a7db8c9659f2e4245494c182d0663b83661803e08d46bfcae5eda1"}, + {file = "multidict-6.9.1-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:c0c88085affd35c33e124e36930c5ad96aff9294ce195eaa0fd9cec962b64a82"}, + {file = "multidict-6.9.1-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:a8b75dd3d3638d9a19f23e84af4ffab3b8940422c0df2da2a77005ef5aa3d7ea"}, + {file = "multidict-6.9.1-cp315-cp315-macosx_10_15_universal2.whl", hash = "sha256:006c4478de0a1876f4834e14255776286f09b9846b505fe63f67f9d173a9487c"}, + {file = "multidict-6.9.1-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:2784090c30a586d5b45197bd9c32f87fb927216cde302f6cfd76d76577e90f08"}, + {file = "multidict-6.9.1-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:7c708566da8014b120a64b1eb6d200c6c0c8cb36296383723cdb6fc82038270b"}, + {file = "multidict-6.9.1-cp315-cp315-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:042fb0196047e786936a730bd302de83143950da45f2c16078da8f35e1cf7919"}, + {file = "multidict-6.9.1-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a2212a0c842c723d919ea4a22a9296cb6b244b386e4e6ea92adfc7fbf3095519"}, + {file = "multidict-6.9.1-cp315-cp315-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:fd882aa29bf402b62bf1fd7c19fd5df4b6528cf468a908864b39368572b662a9"}, + {file = "multidict-6.9.1-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c57541034d12b215ab0a2bfa371d1a8a198da18176d0426c27105b9161a6862d"}, + {file = "multidict-6.9.1-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d73fed4e37158ff00cd271871170b79e40138db51e625fd352fa17c6acb34f67"}, + {file = "multidict-6.9.1-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:79da2491348b30810728050b4a8ec0416f85884125c2fd44655b3d01150d9c3e"}, + {file = "multidict-6.9.1-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b4da208a63434d21a3df64d29758e650fc4aa8cb05848554b76949c296539cca"}, + {file = "multidict-6.9.1-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:877ca17fdcfdf5c397493a71e5ff97a87bb181417fe717fdadc77c08c09301ac"}, + {file = "multidict-6.9.1-cp315-cp315-musllinux_1_2_armv7l.whl", hash = "sha256:40aec5299e1ed71fbb988389059da381c3c1a60e0c649acceb2a35d9b128848e"}, + {file = "multidict-6.9.1-cp315-cp315-musllinux_1_2_i686.whl", hash = "sha256:4a409ccc42aefec904038695d5d7fd6d8f3af2721b7b6401d55135ec7d6d298e"}, + {file = "multidict-6.9.1-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:0a5769559e3312dd96731fbe15b4abb6033368ac1cad5a98dadd21946a4c7d6c"}, + {file = "multidict-6.9.1-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:03fac50ddfd8302175b77863a015eccfae76767cda5506eef86df559ba861e1f"}, + {file = "multidict-6.9.1-cp315-cp315-musllinux_1_2_s390x.whl", hash = "sha256:5ecace251ccfa705bf3d7d35c5032cf750f5c629809740405697bce5c118c4a4"}, + {file = "multidict-6.9.1-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:ecc89dbd4155b2f8a47f4bbd89242a35ed15e8e0ec581cab5ac65fa38407329d"}, + {file = "multidict-6.9.1-cp315-cp315-win32.whl", hash = "sha256:a3ffe881246d28a862f1985824f484cb7361f44d6b99c4c620436ef56462f38d"}, + {file = "multidict-6.9.1-cp315-cp315-win_amd64.whl", hash = "sha256:59c123d0e948d760a5f930f316cfefa07e8d632ab84327c0693ee6a88171154f"}, + {file = "multidict-6.9.1-cp315-cp315-win_arm64.whl", hash = "sha256:31199204b3ced121ff5407a2c342326a5d27e3870abbf94bd80dbd2451b7bc8f"}, + {file = "multidict-6.9.1-cp315-cp315t-macosx_10_15_universal2.whl", hash = "sha256:8879510a76940670517ea1cb589978da44b86e286ec3e50d664ef330817afce7"}, + {file = "multidict-6.9.1-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:aec65b53a07f580606593f877eefbb29a45939bfc0d3fe6e6d9f42b41b749f68"}, + {file = "multidict-6.9.1-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:14c56f73e78faa1f68bbb826197cd5871994e70e841b8590829c35912ece5c64"}, + {file = "multidict-6.9.1-cp315-cp315t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:38c9986f9ce50c459b10de216a05f4bd7ed5ac63887d56e500a52bb464b861ce"}, + {file = "multidict-6.9.1-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:15db6a102cbaf1949cf028ecf080aac76d20bcd29ad4e092574db6c6b7af78a5"}, + {file = "multidict-6.9.1-cp315-cp315t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:bd82c4977196681a499bb6ca9e462afbc5c91c1c15b6a991dfbd72733fea4dd2"}, + {file = "multidict-6.9.1-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:bb58ba73a3f96f9a3e46b1fab69929d7edbbddb3133ee74b5c3c54074a53c4f1"}, + {file = "multidict-6.9.1-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7c6eecfab7ce4cd9487ff8ba936fe38cdfd68c04faf3d5c710363c6a8e695659"}, + {file = "multidict-6.9.1-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9c62e71e6289d78c0108d8aeb495f8bd3cad4bc1632fedddc9297ddf287ecc20"}, + {file = "multidict-6.9.1-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:539c2cd5fed0947c135cd7eabaaac55f48300dfa1de0f3ca4edb5efa6606f471"}, + {file = "multidict-6.9.1-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:3100d169ceb7bc8f05f89a6db11d1b21f119975fc26f29dc45a472e3569f0879"}, + {file = "multidict-6.9.1-cp315-cp315t-musllinux_1_2_armv7l.whl", hash = "sha256:696477ad71385c4795e3b8e4cf10b0d2c28c2a1ca6a955e031cb1e62993e9ee3"}, + {file = "multidict-6.9.1-cp315-cp315t-musllinux_1_2_i686.whl", hash = "sha256:f5844e7befc707367807586f550fa97e23dcfef0728f02b98c7bc498a961a5df"}, + {file = "multidict-6.9.1-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:abc7c2e4b47bfe6a9aea434d3fdebb9597ee636e914e92ba352f2068b9142f4c"}, + {file = "multidict-6.9.1-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:7ab379f95caee071a37cbd8be86d4c65accc651d391f9f97748fef006f38769c"}, + {file = "multidict-6.9.1-cp315-cp315t-musllinux_1_2_s390x.whl", hash = "sha256:557a4e1708df428ebe6c3081c83a273d275dad2446ce0d81fc648ac71afdb18d"}, + {file = "multidict-6.9.1-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:475d04d5192eba487a3e2f935976340baa24529046e9c1c9c7a3b7bf80445ae1"}, + {file = "multidict-6.9.1-cp315-cp315t-win32.whl", hash = "sha256:10083a8a0f4e1b26b599889e90b9802504ce5d3f7722f925bbb7ca47dd22a7c1"}, + {file = "multidict-6.9.1-cp315-cp315t-win_amd64.whl", hash = "sha256:e96ca64383efa107262ee3949f047af5ee4f1845ba09463466c04d35a83bd3ec"}, + {file = "multidict-6.9.1-cp315-cp315t-win_arm64.whl", hash = "sha256:501ed8b02a5990c67a91c732843609d43a6be1f7576fcdfc867331239f37fbd3"}, + {file = "multidict-6.9.1-py3-none-any.whl", hash = "sha256:7bf6478188f4e47bf5686e8a33da4ae28bf43b1b2528d9ee144d28492bfac60b"}, + {file = "multidict-6.9.1.tar.gz", hash = "sha256:0f06e60fa190aa7abd0914c2a766736fdc8e9f34878c4346338534b73d1b20e2"}, +] + +[package.dependencies] +typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.11\""} + [[package]] name = "mypy" version = "1.13.0" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "mypy-1.13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6607e0f1dd1fb7f0aca14d936d13fd19eba5e17e1cd2a14f808fa5f8f6d8f60a"}, {file = "mypy-1.13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8a21be69bd26fa81b1f80a61ee7ab05b076c674d9b18fb56239d72e21d9f4c80"}, @@ -229,6 +835,7 @@ version = "1.1.0" description = "Type system extensions for programs checked with the mypy type checker." optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505"}, {file = "mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558"}, @@ -236,211 +843,406 @@ files = [ [[package]] name = "packaging" -version = "26.2" +version = "26.3" description = "Core utilities for Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" +groups = ["dev"] files = [ - {file = "packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e"}, - {file = "packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661"}, + {file = "packaging-26.3-py3-none-any.whl", hash = "sha256:d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c"}, + {file = "packaging-26.3.tar.gz", hash = "sha256:94edc256424af38762eb31306eed28beb9f0efc50a8837492c9d6fd6004aed79"}, ] [[package]] name = "pluggy" -version = "1.5.0" +version = "1.6.0" description = "plugin and hook calling mechanisms for python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" +groups = ["dev"] files = [ - {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, - {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, + {file = "pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746"}, + {file = "pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3"}, ] [package.extras] dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] +testing = ["coverage", "pytest", "pytest-benchmark"] + +[[package]] +name = "propcache" +version = "0.5.4" +description = "Accelerated property cache" +optional = true +python-versions = ">=3.10" +groups = ["main"] +markers = "extra == \"aiohttp\"" +files = [ + {file = "propcache-0.5.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b77c313314524ca9c38fbd70f73515d04597ac58c40c939bc0e71eeb4abff680"}, + {file = "propcache-0.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8f911c395cef73c510bac566da9507bb6a43e7763d0c79138dc60ee53f11207e"}, + {file = "propcache-0.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d83b12902eb8bce151259c86c03ba746600b2d994543de46e370cecf96c452f2"}, + {file = "propcache-0.5.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c9281e922c072158c91974d4589f1dbe0fee6d467f284c28e463f9f5a4d933f4"}, + {file = "propcache-0.5.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9f3551b8a35c1df3e7ea4d2d86edee15f0dde1bddd434a71744048683544d0ef"}, + {file = "propcache-0.5.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ec6a85f424afa8d23e0d9a094e5dbb6eda01da91c92b9183cd433768247ffc97"}, + {file = "propcache-0.5.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f574e460d1c8a08384a016fdb09ccf3543433263ed6b2f97104f979e64ea57c2"}, + {file = "propcache-0.5.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d8e017eeb7482bed34cdb0d61cf2bcfc88d104bbab296a17cd16a6af8aabc70e"}, + {file = "propcache-0.5.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f273dcf7149a50527c4fd1f55cfe9eac0f60753f5af544b4c9352578e20c0874"}, + {file = "propcache-0.5.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:fc2461ecc45f17893f8207e73b46ea8ba93e33630e51cf4af3fbc21d47462b1a"}, + {file = "propcache-0.5.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:279655a16973f1ee2bd2fe79973137681642fd9ae0d89215bba263726eb0dc3a"}, + {file = "propcache-0.5.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:e9f165403b81fea7e89c932d89046a1e3d9a3a60e8d7ef2f249dccdcb0982bf5"}, + {file = "propcache-0.5.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:1783582065a1f07f9d9ee1e992e13f15d7dc8fb1eb3a7476d43eb3f2e69d26bb"}, + {file = "propcache-0.5.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3d605bb239b796e82a81c6709548b2bd460ab73b4590cb0c83de8a2dd9694d0f"}, + {file = "propcache-0.5.4-cp310-cp310-win32.whl", hash = "sha256:141fdbd73748db0cf7636035030aaac383d2efde8f34e7bc24594cc776d225b8"}, + {file = "propcache-0.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:146f48a9e4812611a7581003b1a39de56c34967046310c4171a68ef908c9a745"}, + {file = "propcache-0.5.4-cp310-cp310-win_arm64.whl", hash = "sha256:6c7599df2b57ebeea8de011b5f2f7b85de95e76037d43d34b95e328430275487"}, + {file = "propcache-0.5.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:897d1ddf6716e8f47200f7aad9a0efa6cc7586df66c6defa572f9eab379c078e"}, + {file = "propcache-0.5.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9cbfff4423eef4cc6cafc021469641a2b835f610b2647a6c5281903e21b8670d"}, + {file = "propcache-0.5.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3fc24f209c1b7f7f688b66b98293954f5504279760999b58920ee12dd8471c1d"}, + {file = "propcache-0.5.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:62530ca89187827e4a4fe733f971abe81a7542eeea48ff61995f19b64d7199c8"}, + {file = "propcache-0.5.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:56fc3f7599528db40b1efa0889a620116e2704144495273d66066e8164e45838"}, + {file = "propcache-0.5.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4f2d880ff60f45898f4acfa152aac8d04e3ee627d90ff4003491bf92239d5757"}, + {file = "propcache-0.5.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6e9368e87a3efc285e559131092c5db643eb8e56de4ee42064d5baec22ef2bb5"}, + {file = "propcache-0.5.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:004e685b315646c410771836e72a44f143bbe624f29653a42687815069a303d5"}, + {file = "propcache-0.5.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:594eb4c6ec35e7179b058481f4e9f02521b56de16fa577c4b85c76fb1bf8a9f8"}, + {file = "propcache-0.5.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:2dba2f02d2d5c09ef8a0e6c1a42aeaa451f4be9898cb00b04fe98717da2eb23b"}, + {file = "propcache-0.5.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c3ef2818d63bc86071e9d2989ae75a1bc32b8f7059cfd9f5abbbee70c32e2ed6"}, + {file = "propcache-0.5.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:dd2ac8f5b643454c2cc6b6118b13da16e88f4a6434fc3ba61aca384029f04f36"}, + {file = "propcache-0.5.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:4054acf80d40456a0537f2913b349718649d8d6458a14ab7f48d0ce28c30869d"}, + {file = "propcache-0.5.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:40e94adb1e7d39ff28a8bd8d8b8fbd1df6b9f40976dbe379134f1ce058e532dd"}, + {file = "propcache-0.5.4-cp311-cp311-win32.whl", hash = "sha256:9f86f7259efe2c951f43e57d471c9b41daa5bfc7db9f67189059cf1ae6d77fd9"}, + {file = "propcache-0.5.4-cp311-cp311-win_amd64.whl", hash = "sha256:e904d4d01f36bd6e197590be1533c44e06058771e0746dd073a8ebb3ef880858"}, + {file = "propcache-0.5.4-cp311-cp311-win_arm64.whl", hash = "sha256:d42a9a856a4a6e2f6c10f1318c07e7daa498d6593abe745c71dae4521a26ca39"}, + {file = "propcache-0.5.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:b28f41fa3b8c6900457f858ec5b03998f3a6d535fbc1bb2edec5961ea05ec429"}, + {file = "propcache-0.5.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:dcbf346a318a5e30063f547630b02bb787ce2f45b6368d5da143660b6a3835d8"}, + {file = "propcache-0.5.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:87a3caecf8095e48dc72f84bfa42e23a848cf410cc9cc13031fba4869b706a21"}, + {file = "propcache-0.5.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:60a64cbccaa11b7760ce705a14ada17ba459e7ca9f23ba587eb013821032d7ef"}, + {file = "propcache-0.5.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a74bfa37147cc08fb29df10bd9c16f40fa7f860cd3a6d2fff853323a94f6e17f"}, + {file = "propcache-0.5.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a4d7a54719b67338a305dca2ce6aafe366817df94ddfd4b5514374356f5ca546"}, + {file = "propcache-0.5.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2814ecd8e818f487bee4b0f921bc4d1c176cc5fc71ac0f072d0fa67eda4ac14b"}, + {file = "propcache-0.5.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6af4693716bfb03f1752ef1b30faa593db2c01d5272e9b8564a1549452a979ab"}, + {file = "propcache-0.5.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4fbc1a15dc8cd1689508758d626b372b1f09d28d9577667feaf9e6bfcd8efcbc"}, + {file = "propcache-0.5.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:cdee8205a44d0be91bbac4c41b95d86641b72dfc7aef1279400e4fda3f26a937"}, + {file = "propcache-0.5.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:9a2a8a50a93dee0268a860a07fa3b4bd968f8ce4dbd794957da772f395368526"}, + {file = "propcache-0.5.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:7ffafcbfc7b549ab940047e505c831eabac5e67de53e1bc174adbc5285c55944"}, + {file = "propcache-0.5.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:d1f5a500bfcbb2c0ab85e98a0dcd70f5899d34efe365a0187700369a79603031"}, + {file = "propcache-0.5.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a235f73d6e020855dc29dff012d920c02ee0feab8d73a24185a7569f4be1161"}, + {file = "propcache-0.5.4-cp312-cp312-win32.whl", hash = "sha256:b3083bfe87f95c756e610bd8025f26cbd1cd4aaa03a422f2d65efb7a97cd53d8"}, + {file = "propcache-0.5.4-cp312-cp312-win_amd64.whl", hash = "sha256:98914de2c4d7f0f9f4a8c6ea4bf05841f4175796941e3ef7d47eb718f22311fb"}, + {file = "propcache-0.5.4-cp312-cp312-win_arm64.whl", hash = "sha256:8876b39961e33d912afe3c1bee18ee564fdad0206f873cc15d522756b7f50737"}, + {file = "propcache-0.5.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:36c0d9db44b523ef93d03341b1c42d69ff01d673c053d1b1c6c3a363bcaa39ba"}, + {file = "propcache-0.5.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1d52a05dc417279f7e5c7618c5dfbbc29923aaf9bc0a5c1802ddcebf54c61a0"}, + {file = "propcache-0.5.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:44149f46500a0a41b95b4d99c2e586a77319539730607b9892974a092788b111"}, + {file = "propcache-0.5.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dbab5f5ff6897c81f355d079010cdae85b02e5a0b518b5251523b8ad8ae9ac3c"}, + {file = "propcache-0.5.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c3e98c55bde2bcf7db3c70d1aed7ae9aa8aebbf19a250c66645cde44cdb8b867"}, + {file = "propcache-0.5.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:db3ae52ccc150dbc84704e9d642743897f3e1c54742ff34cacb661e52e3818a9"}, + {file = "propcache-0.5.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f85915e00dcb1cd9f2f890ead064ed40a27df06f0db65be427b29482ae357572"}, + {file = "propcache-0.5.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c2ba30a89035b57b73e00475de948521602f543d79ce01db10b04b36c4c76fc8"}, + {file = "propcache-0.5.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ae58f361bd5dae942717c65d3413b478c70aea9c462599e7b9adad3731db3894"}, + {file = "propcache-0.5.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:96f7c5c15656040ddcbc51e56dc59b58aa25999d743c126abd425b9766ab43e9"}, + {file = "propcache-0.5.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7cc528e760a8af06f2b13e9b9f362cd90c7c718ea61228a96dbd31ba16ed7f47"}, + {file = "propcache-0.5.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:425f8cc86ab5018b4b8d4a23bc8e74d964bd3d757c3702e301aa79be76c53f6c"}, + {file = "propcache-0.5.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:a5793c7698a53f56f4a1889a4737c7eeb1b7ad0842fa6b1abca22913ff79c8c1"}, + {file = "propcache-0.5.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c02c0e570c5c7e077b0181a9f3cdb7d4c3617d1cda6b5c95bd5d34022923d82c"}, + {file = "propcache-0.5.4-cp313-cp313-win32.whl", hash = "sha256:3e413d7a4a9b4866b7a761d6060d434b64d23cd35122eda3b026a0bbe8196b25"}, + {file = "propcache-0.5.4-cp313-cp313-win_amd64.whl", hash = "sha256:0c889f6fa84957bc7e8b4eab71fd16a0455068d5045e3aa40c733071d2b2fd77"}, + {file = "propcache-0.5.4-cp313-cp313-win_arm64.whl", hash = "sha256:69fc35c0779522da366c563e5faf203ffc1f8ff0021d5b1337fa4efa5be73177"}, + {file = "propcache-0.5.4-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:e6720ba44ad7e72174314d0e1fb0172494cff5c73a3a8a2159c3d2402ff15565"}, + {file = "propcache-0.5.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:4cfe0a92ae30151869e67a4b5f5e105e4e03ad30b3f38e5211b5bf77d0881993"}, + {file = "propcache-0.5.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1d759d05634f1b038fb625a66662a8c85e5a8fec912da381b5149ddac107482b"}, + {file = "propcache-0.5.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:251c63dd46a0659bb875cb254dc4c1e79ee91a847c737cd62373295afc2235dc"}, + {file = "propcache-0.5.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7a8d5ff04eb1f85698a78d20c62a14676e7b960dcafde09a388d60ad377d355d"}, + {file = "propcache-0.5.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7b9100a93b372418d8688f3f2a3e5b45c64d70ca4d6176e121aca1e3bfc1e32f"}, + {file = "propcache-0.5.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cc07876cfb079b6f6f36d21ce75784ad6c2c6b563eeac0ed26c2fa2669b85df9"}, + {file = "propcache-0.5.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0951315a6b3142ee2167404d707743f0157c110091342b1aa0accac5cf0e4acf"}, + {file = "propcache-0.5.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:bee7d3aed13d56f54e681df38c3a23031bc9e3863f687d9d598825c9146acd7d"}, + {file = "propcache-0.5.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:4e985382be6d15da8d0c2710a6fa7b9070fc9ecdeefb7f580e88373984ec8be3"}, + {file = "propcache-0.5.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:9e9ab13760aa8b6d0881ae7cb04fd891d8d490cd2554ea8e79bb278399169bcc"}, + {file = "propcache-0.5.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:1b2f3bec4261a94019575481c726c29850f72e27907773c75b1de421e20e9f9d"}, + {file = "propcache-0.5.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:720cf832eb2d0b0dfee129cb3335a26f6ce3cc45ee1187e8f0731758caa16792"}, + {file = "propcache-0.5.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:9fb0a5be8d9aa213150e8d8148a42aca4984b285bcad1e69587dc4298edd929b"}, + {file = "propcache-0.5.4-cp314-cp314-win32.whl", hash = "sha256:30cc1cebaf9aef49db06357a50398323ae04d70460c0491837d026ab7d6452ea"}, + {file = "propcache-0.5.4-cp314-cp314-win_amd64.whl", hash = "sha256:0a095db8e15a6020db149ecbed6461939fe74f6acaa3ae8b702a1fe8c38cd983"}, + {file = "propcache-0.5.4-cp314-cp314-win_arm64.whl", hash = "sha256:45488d1a5f9ab5bd90aaa1ca20f50fe1922b8ffad71a2009d2adf41355897aac"}, + {file = "propcache-0.5.4-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:53eaa697c4d0422ff4cb714d00231b43352064d97b944033b30c1d57cc506ec0"}, + {file = "propcache-0.5.4-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:886b59c4d28ca97dd23b025fdfc50a0356be934efbbbca89ad26230067f86fe5"}, + {file = "propcache-0.5.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:3fa15757fea1dfcd5b7745cad9f4638929605531bd4018ab2adff7955f1a403d"}, + {file = "propcache-0.5.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6f0093ac3e9daada202c2082439d414a625c57184727a46e112a3fb2a81cb788"}, + {file = "propcache-0.5.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3cd3a7edb6b95b9b33998135ebfa18d709da82290fb8f27c858970b5a12c8b56"}, + {file = "propcache-0.5.4-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c174bfd1c48a1b51a3078e95586dde718374bac79719ab3541ec9e74aec40574"}, + {file = "propcache-0.5.4-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a219f0ac59817a9114dd2aa57c13180f993e819ba658c7ddab4b66ed1ee0d370"}, + {file = "propcache-0.5.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:17a7400cec0256f0a71ae71f9da398f9894c956ff6668a1c9d317b3367316320"}, + {file = "propcache-0.5.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:978f28401afbc76cdc3df9e1717b4229a06b626a1dcc75db4e1f2beb3884c3e9"}, + {file = "propcache-0.5.4-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:4a1f4f5ffa55dce6307631f3cb2948e117e665966ea512e0d502b16c24f567e7"}, + {file = "propcache-0.5.4-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:213bb68d9ced5cf2bf717b1071bf2b09b4b04c426256f9fe6d054c60318424c4"}, + {file = "propcache-0.5.4-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:286867fb156488c251a3721766e380ac4495e4fd6b51aaa1403d89ce7f4359d9"}, + {file = "propcache-0.5.4-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:445ee3bfb46e85838387fb3c536a73cc0b994dc192b004e40e170adc54aa2a7e"}, + {file = "propcache-0.5.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:48cb48c5346a97de792254af77715aa2529c2a1ebc5f586aa0aae44a02f1fe57"}, + {file = "propcache-0.5.4-cp314-cp314t-win32.whl", hash = "sha256:03b229037d25b801e7af53fd52b9fc49d9439b036fca1e087e02780631adfa97"}, + {file = "propcache-0.5.4-cp314-cp314t-win_amd64.whl", hash = "sha256:8a1fc236528c457cd739c88abe823da851b7ab645d72792f88658114cc340c12"}, + {file = "propcache-0.5.4-cp314-cp314t-win_arm64.whl", hash = "sha256:135036c5cfc93864affb0f9af9a27e5d7a71cb7bd745e7b6dbfc2d56cc30e827"}, + {file = "propcache-0.5.4-cp315-cp315-macosx_10_15_universal2.whl", hash = "sha256:45bf2e730ab8905d0527fe05a86500f406e64305c34cc81ebe64b4617cab9760"}, + {file = "propcache-0.5.4-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:31eb43ba2edc704ab2ec27815315dd8a19def0fb16215be4cfe8d32fe78ffd51"}, + {file = "propcache-0.5.4-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:174507f82d3594622acb1dd2dafecf2d899d6d506335494e7107767bf05f3aae"}, + {file = "propcache-0.5.4-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:50e337653721d20ead710da33bf44487fbe8a0db8782714b60306481e9f95b51"}, + {file = "propcache-0.5.4-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0d21d0d2c82bbfeb1677a9711f38df968f9837576102bb4add1bd449d28d88f1"}, + {file = "propcache-0.5.4-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ccf4f7a79e26bb7efb06ecd50c177833b71df05cbc748701372325e6bcc17f6f"}, + {file = "propcache-0.5.4-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23278f808cd81d5ada7184a76606b925fb3389c60e1077b2cd7da7b1fcf0553c"}, + {file = "propcache-0.5.4-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e738ab81179510ce79b2eac9a6ecf47feffd9e76d1c72e403005dddb6e36c06c"}, + {file = "propcache-0.5.4-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:a419ee85e654927baabda3929c03c0cc1112bf472ff0dfd6142f4e3a81ca4162"}, + {file = "propcache-0.5.4-cp315-cp315-musllinux_1_2_armv7l.whl", hash = "sha256:b61805357d966680acf68b3b6d49772631ed9df44ebece10ff1460e117a7da8a"}, + {file = "propcache-0.5.4-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:58134228927cee6c047d626c08e60a81be604a20578a12ce752cc5c9a84d4826"}, + {file = "propcache-0.5.4-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:350b272b2279f4135a64fc0c304a5d08e28a137c9573442c606152446638a831"}, + {file = "propcache-0.5.4-cp315-cp315-musllinux_1_2_s390x.whl", hash = "sha256:45bebbe252550fec975ba3b62bc6f931643cfd3b5464ef47619cf3fef154e01c"}, + {file = "propcache-0.5.4-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:ada748108a43d29b7c328ba7db3755327cd94f028bcc1a7ee3f0addcfacd9c38"}, + {file = "propcache-0.5.4-cp315-cp315-win32.whl", hash = "sha256:ee19113bce2f3acd46432050688b70f61acd6857d75abb9ec96341b7e9ced123"}, + {file = "propcache-0.5.4-cp315-cp315-win_amd64.whl", hash = "sha256:ceb3e879afac028f93d272c957814695dc5569e4904262dbee92f6c41bd5e4a3"}, + {file = "propcache-0.5.4-cp315-cp315-win_arm64.whl", hash = "sha256:c83acbce9f2b5e3f5f5eda9e53d2001fed22fcdfef81274a9e02d8fd53b70a30"}, + {file = "propcache-0.5.4-cp315-cp315t-macosx_10_15_universal2.whl", hash = "sha256:a5e8ef588c109725dc713ba69aadcac00a1ef90c2ce9c0a8c7075128f569f47f"}, + {file = "propcache-0.5.4-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:4d86476a935c88963d9b8e1a9a0d38188790e9622169bfbafa173046846709d3"}, + {file = "propcache-0.5.4-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:f5470694918830da62fac9e69133b53d23b736d7070e587b27a4a2be37e08e68"}, + {file = "propcache-0.5.4-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10ef33a68a61ce317e095fd2e202a592ea92392b90944a78c993f0d9a73ab06c"}, + {file = "propcache-0.5.4-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5cacf3c9efd09df409dc33654dd077e1c245ba8fb747b0f0236ef41b7c49b589"}, + {file = "propcache-0.5.4-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:770e8209d018175fc0063936fa9583b6d27e88c5ad31543f3383d66080efdd62"}, + {file = "propcache-0.5.4-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:03969626faf0783a592dfa17e28eac06018bd0b44dafae6943d53b92421a7f72"}, + {file = "propcache-0.5.4-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ef3b928d9c984322b5c44e6964d8dbc653da87d2d8ee1647fa6da43072e650a9"}, + {file = "propcache-0.5.4-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:7177c43eddf10a0893c4fec52ebb408fdcd7f7d63962caace9180d8f81b14ece"}, + {file = "propcache-0.5.4-cp315-cp315t-musllinux_1_2_armv7l.whl", hash = "sha256:420162a77f94eb1cf5ef7893f500016dabd548e73de956785a1dd899cc73006a"}, + {file = "propcache-0.5.4-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:3eb2e820e8e2101407da93f17c57cbb7d225461955fc60105daaba14cd421ee2"}, + {file = "propcache-0.5.4-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:13e52b6e0bde97dee98ab66552dbff2931649c96f1ac432eac299fe689ec373b"}, + {file = "propcache-0.5.4-cp315-cp315t-musllinux_1_2_s390x.whl", hash = "sha256:12682126712ddc19b70ff819debbd279e58adf1f0c8f8f8138c18ade2044b284"}, + {file = "propcache-0.5.4-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:3af0c8642b2da4815d86e631232ac8286e17644fad907c19508aa8e7cb4ba8ad"}, + {file = "propcache-0.5.4-cp315-cp315t-win32.whl", hash = "sha256:1df8d8561b21465c5dd56110a01caf897e026d065b4b84e98a488209094272ec"}, + {file = "propcache-0.5.4-cp315-cp315t-win_amd64.whl", hash = "sha256:02c0a34f16889cf800f10f0247a564d8ce6eeab6ffcd7c87198f769067eb8432"}, + {file = "propcache-0.5.4-cp315-cp315t-win_arm64.whl", hash = "sha256:dc4242ca653c9b30ab51c5f8193323e7bc0928f897ee9103201e59a43abcb72e"}, + {file = "propcache-0.5.4-py3-none-any.whl", hash = "sha256:62c60aec739ed00124573cce1178138fd690c7676352d67a37328c1cf51d7468"}, + {file = "propcache-0.5.4.tar.gz", hash = "sha256:ff6b113f50bc066a698db5d944d2c6dc7507168dd3341e255a8892fd0715a558"}, +] [[package]] name = "pydantic" -version = "2.10.6" +version = "2.13.5" description = "Data validation using Python type hints" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" +groups = ["main"] files = [ - {file = "pydantic-2.10.6-py3-none-any.whl", hash = "sha256:427d664bf0b8a2b34ff5dd0f5a18df00591adcee7198fbd71981054cef37b584"}, - {file = "pydantic-2.10.6.tar.gz", hash = "sha256:ca5daa827cce33de7a42be142548b0096bf05a7e7b365aebfa5f8eeec7128236"}, + {file = "pydantic-2.13.5-py3-none-any.whl", hash = "sha256:346a034f080da3755d8e9cb5e00e8b07de1d39e4f6e2c87d8ab7cafa0b269a73"}, + {file = "pydantic-2.13.5.tar.gz", hash = "sha256:51a9c5f7b2f8e636f04c6cada605d9b6a3bf1348fdf945a3d8869b19bba0ee08"}, ] [package.dependencies] annotated-types = ">=0.6.0" -pydantic-core = "2.27.2" -typing-extensions = ">=4.12.2" +pydantic-core = "2.46.5" +typing-extensions = ">=4.14.1" +typing-inspection = ">=0.4.2" [package.extras] email = ["email-validator (>=2.0.0)"] -timezone = ["tzdata"] +timezone = ["tzdata ; python_version >= \"3.9\" and platform_system == \"Windows\""] [[package]] name = "pydantic-core" -version = "2.27.2" +version = "2.46.5" description = "Core functionality for Pydantic validation and serialization" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" +groups = ["main"] files = [ - {file = "pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa"}, - {file = "pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c"}, - {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7969e133a6f183be60e9f6f56bfae753585680f3b7307a8e555a948d443cc05a"}, - {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3de9961f2a346257caf0aa508a4da705467f53778e9ef6fe744c038119737ef5"}, - {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2bb4d3e5873c37bb3dd58714d4cd0b0e6238cebc4177ac8fe878f8b3aa8e74c"}, - {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:280d219beebb0752699480fe8f1dc61ab6615c2046d76b7ab7ee38858de0a4e7"}, - {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47956ae78b6422cbd46f772f1746799cbb862de838fd8d1fbd34a82e05b0983a"}, - {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:14d4a5c49d2f009d62a2a7140d3064f686d17a5d1a268bc641954ba181880236"}, - {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:337b443af21d488716f8d0b6164de833e788aa6bd7e3a39c005febc1284f4962"}, - {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:03d0f86ea3184a12f41a2d23f7ccb79cdb5a18e06993f8a45baa8dfec746f0e9"}, - {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7041c36f5680c6e0f08d922aed302e98b3745d97fe1589db0a3eebf6624523af"}, - {file = "pydantic_core-2.27.2-cp310-cp310-win32.whl", hash = "sha256:50a68f3e3819077be2c98110c1f9dcb3817e93f267ba80a2c05bb4f8799e2ff4"}, - {file = "pydantic_core-2.27.2-cp310-cp310-win_amd64.whl", hash = "sha256:e0fd26b16394ead34a424eecf8a31a1f5137094cabe84a1bcb10fa6ba39d3d31"}, - {file = "pydantic_core-2.27.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc"}, - {file = "pydantic_core-2.27.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7"}, - {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15"}, - {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306"}, - {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99"}, - {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459"}, - {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048"}, - {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d"}, - {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b"}, - {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474"}, - {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6"}, - {file = "pydantic_core-2.27.2-cp311-cp311-win32.whl", hash = "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c"}, - {file = "pydantic_core-2.27.2-cp311-cp311-win_amd64.whl", hash = "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc"}, - {file = "pydantic_core-2.27.2-cp311-cp311-win_arm64.whl", hash = "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4"}, - {file = "pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0"}, - {file = "pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef"}, - {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7"}, - {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934"}, - {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6"}, - {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c"}, - {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2"}, - {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4"}, - {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3"}, - {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4"}, - {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57"}, - {file = "pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc"}, - {file = "pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9"}, - {file = "pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b"}, - {file = "pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b"}, - {file = "pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154"}, - {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9"}, - {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9"}, - {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1"}, - {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a"}, - {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e"}, - {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4"}, - {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27"}, - {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee"}, - {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1"}, - {file = "pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130"}, - {file = "pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee"}, - {file = "pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b"}, - {file = "pydantic_core-2.27.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d3e8d504bdd3f10835468f29008d72fc8359d95c9c415ce6e767203db6127506"}, - {file = "pydantic_core-2.27.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:521eb9b7f036c9b6187f0b47318ab0d7ca14bd87f776240b90b21c1f4f149320"}, - {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85210c4d99a0114f5a9481b44560d7d1e35e32cc5634c656bc48e590b669b145"}, - {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d716e2e30c6f140d7560ef1538953a5cd1a87264c737643d481f2779fc247fe1"}, - {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f66d89ba397d92f840f8654756196d93804278457b5fbede59598a1f9f90b228"}, - {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:669e193c1c576a58f132e3158f9dfa9662969edb1a250c54d8fa52590045f046"}, - {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdbe7629b996647b99c01b37f11170a57ae675375b14b8c13b8518b8320ced5"}, - {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d262606bf386a5ba0b0af3b97f37c83d7011439e3dc1a9298f21efb292e42f1a"}, - {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cabb9bcb7e0d97f74df8646f34fc76fbf793b7f6dc2438517d7a9e50eee4f14d"}, - {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:d2d63f1215638d28221f664596b1ccb3944f6e25dd18cd3b86b0a4c408d5ebb9"}, - {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bca101c00bff0adb45a833f8451b9105d9df18accb8743b08107d7ada14bd7da"}, - {file = "pydantic_core-2.27.2-cp38-cp38-win32.whl", hash = "sha256:f6f8e111843bbb0dee4cb6594cdc73e79b3329b526037ec242a3e49012495b3b"}, - {file = "pydantic_core-2.27.2-cp38-cp38-win_amd64.whl", hash = "sha256:fd1aea04935a508f62e0d0ef1f5ae968774a32afc306fb8545e06f5ff5cdf3ad"}, - {file = "pydantic_core-2.27.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c10eb4f1659290b523af58fa7cffb452a61ad6ae5613404519aee4bfbf1df993"}, - {file = "pydantic_core-2.27.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef592d4bad47296fb11f96cd7dc898b92e795032b4894dfb4076cfccd43a9308"}, - {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c61709a844acc6bf0b7dce7daae75195a10aac96a596ea1b776996414791ede4"}, - {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c5f762659e47fdb7b16956c71598292f60a03aa92f8b6351504359dbdba6cf"}, - {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c9775e339e42e79ec99c441d9730fccf07414af63eac2f0e48e08fd38a64d76"}, - {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57762139821c31847cfb2df63c12f725788bd9f04bc2fb392790959b8f70f118"}, - {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d1e85068e818c73e048fe28cfc769040bb1f475524f4745a5dc621f75ac7630"}, - {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:097830ed52fd9e427942ff3b9bc17fab52913b2f50f2880dc4a5611446606a54"}, - {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:044a50963a614ecfae59bb1eaf7ea7efc4bc62f49ed594e18fa1e5d953c40e9f"}, - {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:4e0b4220ba5b40d727c7f879eac379b822eee5d8fff418e9d3381ee45b3b0362"}, - {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5e4f4bb20d75e9325cc9696c6802657b58bc1dbbe3022f32cc2b2b632c3fbb96"}, - {file = "pydantic_core-2.27.2-cp39-cp39-win32.whl", hash = "sha256:cca63613e90d001b9f2f9a9ceb276c308bfa2a43fafb75c8031c4f66039e8c6e"}, - {file = "pydantic_core-2.27.2-cp39-cp39-win_amd64.whl", hash = "sha256:77d1bca19b0f7021b3a982e6f903dcd5b2b06076def36a652e3907f596e29f67"}, - {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2bf14caea37e91198329b828eae1618c068dfb8ef17bb33287a7ad4b61ac314e"}, - {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0cb791f5b45307caae8810c2023a184c74605ec3bcbb67d13846c28ff731ff8"}, - {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:688d3fd9fcb71f41c4c015c023d12a79d1c4c0732ec9eb35d96e3388a120dcf3"}, - {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d591580c34f4d731592f0e9fe40f9cc1b430d297eecc70b962e93c5c668f15f"}, - {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:82f986faf4e644ffc189a7f1aafc86e46ef70372bb153e7001e8afccc6e54133"}, - {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bec317a27290e2537f922639cafd54990551725fc844249e64c523301d0822fc"}, - {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50"}, - {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0d75070718e369e452075a6017fbf187f788e17ed67a3abd47fa934d001863d9"}, - {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7e17b560be3c98a8e3aa66ce828bdebb9e9ac6ad5466fba92eb74c4c95cb1151"}, - {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c33939a82924da9ed65dab5a65d427205a73181d8098e79b6b426bdf8ad4e656"}, - {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:00bad2484fa6bda1e216e7345a798bd37c68fb2d97558edd584942aa41b7d278"}, - {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c817e2b40aba42bac6f457498dacabc568c3b7a986fc9ba7c8d9d260b71485fb"}, - {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:251136cdad0cb722e93732cb45ca5299fb56e1344a833640bf93b2803f8d1bfd"}, - {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d2088237af596f0a524d3afc39ab3b036e8adb054ee57cbb1dcf8e09da5b29cc"}, - {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d4041c0b966a84b4ae7a09832eb691a35aec90910cd2dbe7a208de59be77965b"}, - {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:8083d4e875ebe0b864ffef72a4304827015cff328a1be6e22cc850753bfb122b"}, - {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f141ee28a0ad2123b6611b6ceff018039df17f32ada8b534e6aa039545a3efb2"}, - {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7d0c8399fcc1848491f00e0314bd59fb34a9c008761bcb422a057670c3f65e35"}, - {file = "pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39"}, + {file = "pydantic_core-2.46.5-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:657b40d6240c0a7b6a64b30f22d1e3aa631c7e846c621b0c0f6d1d75e2e15ea6"}, + {file = "pydantic_core-2.46.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ecb42011e12ee19cafbc312887cbf3546959fe02fbad44f272d4be5baa997615"}, + {file = "pydantic_core-2.46.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4dedce55295becb61921e386b99d4f2706045306e7fa52249a33004c837379fb"}, + {file = "pydantic_core-2.46.5-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9f47b8a949e60f027f0aa0a6f6c7b7e9c55cbf4380d10b344e282fa4e7ab1e1b"}, + {file = "pydantic_core-2.46.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:200aa3dc9f8d54f0754f43247c0bad0999fdcfbfd2488384dd44f37279271fe6"}, + {file = "pydantic_core-2.46.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6d30e1a4f138b8951063e9a394752a9179b51da288ffa507b1e659222f4c1793"}, + {file = "pydantic_core-2.46.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:850a08d167dde16db8702c274f320c7be9d7da6f6dff2b58b18f9e815bd94f5b"}, + {file = "pydantic_core-2.46.5-cp310-cp310-manylinux_2_31_riscv64.whl", hash = "sha256:c3471e5c4a949c26ec00a77f01df59096aa9495877de76fd60a980f8ee6be461"}, + {file = "pydantic_core-2.46.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3a3e26b6a8274211bddee2d0e4d0d42778f17a34510f49d2ec44b58abfc41736"}, + {file = "pydantic_core-2.46.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:fc5d783bd4a2387e97b8a2d5ec781cfb92b3d893bf82370548e99db5915935d3"}, + {file = "pydantic_core-2.46.5-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:356c8368cbc321050b169595683a2e1d63413b1e0e2868b330af9fc14c616d3f"}, + {file = "pydantic_core-2.46.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:eb7d8d0e5886a89a55d2eef490e272fa965a9d57c6b29a5b5088a7997ec2cad1"}, + {file = "pydantic_core-2.46.5-cp310-cp310-win32.whl", hash = "sha256:4d44cf99ddebf875f9b68cc267aa684c99b7b44fe63ee1cac4ec163807290069"}, + {file = "pydantic_core-2.46.5-cp310-cp310-win_amd64.whl", hash = "sha256:1e5aad1220a1192c42341c8fd4a8686657e73ab2a920c970bdc4de334fe3193d"}, + {file = "pydantic_core-2.46.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:a1dee1b804ff4d11c663636cf15d2ea47e9f79cd56c033fb1cbf08924842a48f"}, + {file = "pydantic_core-2.46.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d625a186a65201c23a9e3b8ed9c47e90a026e03256608cc91851c6709096844f"}, + {file = "pydantic_core-2.46.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f8507560a9284e1370bb048ed4282012fbef4e8d109875b95e884d228552061"}, + {file = "pydantic_core-2.46.5-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f93c5fe914d75fbec9a49209b00da5f08e9e467d69da2b1510c81940cfd10be"}, + {file = "pydantic_core-2.46.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aca6c767f552b21b10f774aeac128e828eafb796adfa1b666a18bf6321453c3a"}, + {file = "pydantic_core-2.46.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:701b2e04b560eeb4bddf7a25ab8ca476176e34fdbd9a0e18196f0d12d4685f0b"}, + {file = "pydantic_core-2.46.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49776eab08766a08dfff7012f8b422dcd7e25e43b316eedf0477c24fcfa84b7c"}, + {file = "pydantic_core-2.46.5-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:a2468d93d181667a7abd66e1b64bb9f76f361b0fef8faddf687456453576f5ee"}, + {file = "pydantic_core-2.46.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:53feb344243bb9510a9dec7bf3cf1b64d88a98af5dc7872a5160465f8b198c8e"}, + {file = "pydantic_core-2.46.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:cd5214352ae68f3b5e9af7768bdc5253695ee069675db3480518420b3be881f2"}, + {file = "pydantic_core-2.46.5-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:9432f3598db432cb51c5b37fdbf29a60fcccc79e30d37a05022776a6bc4ab689"}, + {file = "pydantic_core-2.46.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8feeac04b5794e513e710af2f9c87d49f31a6dc47967bb264a1fed61a8989bec"}, + {file = "pydantic_core-2.46.5-cp311-cp311-win32.whl", hash = "sha256:892a881d5f68c2b9ea304b7a6c2c60d9343df578a311b0f86b94bc8f1ffe8129"}, + {file = "pydantic_core-2.46.5-cp311-cp311-win_amd64.whl", hash = "sha256:40375c2d05acec10323e45dfe2077ac44bc74659008614af5069034e2cfc781c"}, + {file = "pydantic_core-2.46.5-cp311-cp311-win_arm64.whl", hash = "sha256:28a6a556cd3b6066bea827857f9d9cce027c96f776e512f544a581f9e42161f8"}, + {file = "pydantic_core-2.46.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:b9fe6fb92520e3fd61f2e49000b6911b188824f089b75973ea06d6267f0b476d"}, + {file = "pydantic_core-2.46.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a39ac25a9a2fa4072efdb429833c4a4c8009a51ff9eea3eeae131713cd27991e"}, + {file = "pydantic_core-2.46.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4fdc8b93a41521988916eeaa271173fcca7fa0803d62f87675aac8dcec1c8e29"}, + {file = "pydantic_core-2.46.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b98134087d9de723658d17a42c7d0da8d6e2ef08015dee7dc93889047315f5e4"}, + {file = "pydantic_core-2.46.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e652ab17569c94bff5475520f907b7148b8c24036a8ebbe5cf7cf7493d28579a"}, + {file = "pydantic_core-2.46.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d925f3d9afd05a8c0fb3a1031463a8d59ebe5e2afad297e29c78be19e13b4e62"}, + {file = "pydantic_core-2.46.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0fc5be0abd4a407e200d844b404e33639a554e7bd0d448e7b9ae181be4789ac2"}, + {file = "pydantic_core-2.46.5-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:816ff0a6550ffc06c098ccd2e0698600f9aa7da192a79eaa6f9af504a35db869"}, + {file = "pydantic_core-2.46.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c7ea57fc63aa7da93a1bd2d644e6577befae10c52c4e36377635eea1056a74f5"}, + {file = "pydantic_core-2.46.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:efd62a42486f1bda5d24cb4f63d15a3c7768375fe83d36f9417b4ad7a2fb20b3"}, + {file = "pydantic_core-2.46.5-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:2bc9419666990c06d7397831f2126a1ecc3594aaa3ff7de5bf2d066802f4e07b"}, + {file = "pydantic_core-2.46.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:18a09e1e1011b462f2e32774f25859ef1223d5c2b0546a633cf56654710721e0"}, + {file = "pydantic_core-2.46.5-cp312-cp312-win32.whl", hash = "sha256:5cb482e9e84c851f4e623fe4acc1ced89168cf1fe18f7089db4548c8f5bbb65b"}, + {file = "pydantic_core-2.46.5-cp312-cp312-win_amd64.whl", hash = "sha256:5e81740c09e310f5aa5cbd3e434a01c154d4bef93241c7877b39f211d2b78ba8"}, + {file = "pydantic_core-2.46.5-cp312-cp312-win_arm64.whl", hash = "sha256:f7b0ec93a2893de856652154d73b7ba622f26fa97726487dcac373de5f4c6084"}, + {file = "pydantic_core-2.46.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:b7ca9034437b6022f941f4857459562ee00a560b97e7cce8a0ec5a74fc6766e0"}, + {file = "pydantic_core-2.46.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f332f0e72a5a0400141f830744e141bf9f97917878dbe968669e8a7fefea78ff"}, + {file = "pydantic_core-2.46.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:193375f3548919d3f0b60936ca113ada3e38f264f91b9b8e0508efaad57be931"}, + {file = "pydantic_core-2.46.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:79bdfa52f843137045b2d081cc05c120ba6665d29b7559c2c47690906f39279f"}, + {file = "pydantic_core-2.46.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:24922243639cbdac66c75fcb6fd6495a9cb52b213d62f9a0d16f0310b1ff8038"}, + {file = "pydantic_core-2.46.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c76fe65e607be28c7fd4d56fc3c42b1583aa058ce3408b7ad0fd540171d31f9f"}, + {file = "pydantic_core-2.46.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f7b393a8b3da82f5c1fc0751e6d01ac6c55b93c18226a60bdfba4a724efafd1"}, + {file = "pydantic_core-2.46.5-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:7ac031912d54f3d83ef3b3eb98dfabc1608802e2202263d25957eeed40b94761"}, + {file = "pydantic_core-2.46.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:837b396ca3d7b74091ca623f6cbd8351bd42d670a79c2683e79fb089f06a2de5"}, + {file = "pydantic_core-2.46.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:5ee239d575f80b08eca11f6e20f90c4c695de7825c67eefe6091fbf20dda648e"}, + {file = "pydantic_core-2.46.5-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:e80675d75ae2cd14372cb65cad5400d9347a3d3f6c13000183f22dfd027283ed"}, + {file = "pydantic_core-2.46.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:9c4b71f10dd532fb7a5cbc8f58707779e64f03a258c2bf8bfbaecfcd9970b519"}, + {file = "pydantic_core-2.46.5-cp313-cp313-win32.whl", hash = "sha256:97bf8de4d541598c94a59344eeb988a94c08ff76b5723c41f6567ec18c7892ea"}, + {file = "pydantic_core-2.46.5-cp313-cp313-win_amd64.whl", hash = "sha256:15f4a94963c95accac15b7b657bb177d3ad82bb90b0d0526d9a9b85079925db5"}, + {file = "pydantic_core-2.46.5-cp313-cp313-win_arm64.whl", hash = "sha256:d22a945598fb91236b4dd793a6e42e4f3dd7740bb5aace5ebd7d4c08d13bb575"}, + {file = "pydantic_core-2.46.5-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:c1c43ad4339643d70ebb8124e1305a7dab423001eff58bb41a0f731adbc98355"}, + {file = "pydantic_core-2.46.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1a353f84de772f423b5ffb11d7ae352fbbef0f446f3c0b0af0f8236d7233606e"}, + {file = "pydantic_core-2.46.5-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5086029a57366b8cf81b130a43908738095c270c21a8d7f0e8bdfdb89718e2f3"}, + {file = "pydantic_core-2.46.5-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:46c25dda9d092a06c08db76ffe0a197107904d0dfac653f7d5306bbcd6d6119c"}, + {file = "pydantic_core-2.46.5-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:37ea7b83c935e5b0d68c9449b82651accf78a10828b2c02b2f2d9e9496446c21"}, + {file = "pydantic_core-2.46.5-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e64e88d5585bea9ce95861079de72006c7fa6d3df4e3a3b65ba31eb979c15c9f"}, + {file = "pydantic_core-2.46.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54d510bac3ee52247af28ed4bb18a1e799f040ac60fd2bf5ccd4c92f1fbe786f"}, + {file = "pydantic_core-2.46.5-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:a2a5e1d0ff29adddc9f6d6821a66302e4493f8ca898b715b6b1182c2c201ea0a"}, + {file = "pydantic_core-2.46.5-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:03b9666e41e35d8909852ba191a0607520f81b74eaf12ccf8737005dbb313821"}, + {file = "pydantic_core-2.46.5-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:a91c17edf6eea2402cb5457b4c89e99bc5ed1004aa34c4adf1d4258c1a5c22c2"}, + {file = "pydantic_core-2.46.5-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:b49924c73a235e969511bf2aabdff3beebf9820931f646c80274d5d780010c47"}, + {file = "pydantic_core-2.46.5-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:2cbd9a5eff05e51c447c34dfa4632145b26b09120cf04bd0c871e44c1a5e1c9a"}, + {file = "pydantic_core-2.46.5-cp314-cp314-win32.whl", hash = "sha256:2d5d76654becf5efd62c9e51c3756c67b49498b0c9a40884934c40807adbd074"}, + {file = "pydantic_core-2.46.5-cp314-cp314-win_amd64.whl", hash = "sha256:fa10ef4112775900e7a0661068635eb67b2ab824fbde764de6e0e21982a93db0"}, + {file = "pydantic_core-2.46.5-cp314-cp314-win_arm64.whl", hash = "sha256:045ab3b6d308439e32b81cc173bba5b9018bc6ed896afd0c65b3b009b1699af5"}, + {file = "pydantic_core-2.46.5-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8816f3d218beb4b787de5c9759c259b8fa61f9dec42dc7811f320a33771778b7"}, + {file = "pydantic_core-2.46.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:bce57638e08ac148e5778cce7feb968307a727d66f8e2274a543d0cf0c9ad6a3"}, + {file = "pydantic_core-2.46.5-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:976e1128455aa595ea04c79ccfedff1aaeab96ee013fcc916bed120c4f0ad94f"}, + {file = "pydantic_core-2.46.5-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7b891faeedeafba41b2983e5001a81b6a915b69544c7e7570d1989ce1c36ac7"}, + {file = "pydantic_core-2.46.5-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5f194189415698233dd1114a093a9b56e61e2c57e11b469be3b0506f46f0771c"}, + {file = "pydantic_core-2.46.5-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:82a36973cf8a2ef5406f4fe2edbf8ed0c99629535d959e0b100c76a32535a111"}, + {file = "pydantic_core-2.46.5-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdbb78909f52b981d3b2d56b97328d71eb0b974c36bd77c920123a7ebb192829"}, + {file = "pydantic_core-2.46.5-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:52e24eacdb536cade636aa90fb851835222becff8484b7001fdc78cb0290f2aa"}, + {file = "pydantic_core-2.46.5-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:37ae34309d7bd8c0d61ab839668058f2a7962ea1fc51d105d2db228fe0618034"}, + {file = "pydantic_core-2.46.5-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:0cdbada856a1c69a7624a64d3d9aefe79300bd6ef827b43a4f265010b9b55184"}, + {file = "pydantic_core-2.46.5-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:545f26c504b27c3758439a5e6d9349931f0a04f855668d5fe323c89e82300a38"}, + {file = "pydantic_core-2.46.5-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:ff218293c9c806138dca139765e3b067621be52bcd93cdc14c7711be7ddc90a9"}, + {file = "pydantic_core-2.46.5-cp314-cp314t-win32.whl", hash = "sha256:97cf3eb53a8cccacf9d46686a0926186c9bfb5574f2ed66d3639d5fe117cd3a9"}, + {file = "pydantic_core-2.46.5-cp314-cp314t-win_amd64.whl", hash = "sha256:d2f9fc07a8042a8f95925b35c4f04f469707c981fc33245b6ca187cf5d2dd290"}, + {file = "pydantic_core-2.46.5-cp314-cp314t-win_arm64.whl", hash = "sha256:acf8a67ba51f4ca9ddbd0e6b3000a65ac51ab734661778b3e7ba64d99a710f2f"}, + {file = "pydantic_core-2.46.5-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c583b927a8838dab890706a6fa7573fbb8b70e24000ef9f7238e2d6f6435a5ed"}, + {file = "pydantic_core-2.46.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cdc8b74ecc48c0cb1e9607a05ec4e9e88db60a19ffcc9a1d5f9088ede40c8dc0"}, + {file = "pydantic_core-2.46.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b10e3e8fd7ddc2bd915848a2768e44c15b22936f1cc54c462ad1164deb02655"}, + {file = "pydantic_core-2.46.5-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f077d0b97ab11fa7dcc633fca53515f290bca8a8a633e966d5b6d1879d9ed01a"}, + {file = "pydantic_core-2.46.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7b0fc826b16c55e561e5d2a0c5c77b051ba1d92808118c4e4b5390f5e0cf191d"}, + {file = "pydantic_core-2.46.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ef3fbbf161dc9351a2fe0422e51b129f9e97e42385bd0320b309c15f7d287dd8"}, + {file = "pydantic_core-2.46.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:978e7b97d4824b5be09c69fb70507cbde3b0323fc147332ca40a94d9a6a0ebbf"}, + {file = "pydantic_core-2.46.5-cp39-cp39-manylinux_2_31_riscv64.whl", hash = "sha256:9b68938dd5b0c783d88ff8e2dcc69451b5eb936fe212d516b21b9d5567f6d464"}, + {file = "pydantic_core-2.46.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:771cf63ae0b1b50dd22e5f3e3549fab5f3f4ff1635d352a9e1a97fe01c7b2e64"}, + {file = "pydantic_core-2.46.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7c6be839a5a8312626b32029a415644a0846b420bc8b52b95b28cd92da162168"}, + {file = "pydantic_core-2.46.5-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:895395f8918627b04efb1ad2a4cf605387143300ba03304cd1dfa6d03f5e095e"}, + {file = "pydantic_core-2.46.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:fc8515076c11f3cfdf4fb142dcca0fe384b1230a3b5415458ac84f3e0903ec13"}, + {file = "pydantic_core-2.46.5-cp39-cp39-win32.whl", hash = "sha256:3d2652072b2d774947ba5cf78a9e59644ac62ee572daf6dd2e1dfe905e15b2b7"}, + {file = "pydantic_core-2.46.5-cp39-cp39-win_amd64.whl", hash = "sha256:3aa166e99c4f2985407fb8714aebede877ecb5455cf321b606adca926d30d5a0"}, + {file = "pydantic_core-2.46.5-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:c14ad3bdc85ee7f318742c457ca3968a92126d144b15721c759033bfb06296c2"}, + {file = "pydantic_core-2.46.5-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:0bddb4020d8f04175865ccd17eff3040874fc11fb593f424edb452653b4b947c"}, + {file = "pydantic_core-2.46.5-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2471fd51c61c610e1dcf7de44d7299283661654d11264ab4802b303368d69c47"}, + {file = "pydantic_core-2.46.5-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b10ec717381bdbfafef34607824db4c91de69ff085e4fca3b2af91b4fa17e68a"}, + {file = "pydantic_core-2.46.5-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:013d6f3483d81e02e7c328831808f336c8596ee33b4bd4026b9ffb1e960b8942"}, + {file = "pydantic_core-2.46.5-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:e9c134bb666dd54b778b9fc0d2b50cbb7f979b9e3716f26a88c9ab3b6fc1dd0f"}, + {file = "pydantic_core-2.46.5-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:347ec774390c87326a2e4929d58d3f7e8763a104d5d35f4cd595a4c952366433"}, + {file = "pydantic_core-2.46.5-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e24d8f05fa2d28513d94e877e9c75ad66175376209b3977f916e240e623193c"}, + {file = "pydantic_core-2.46.5-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ab4b66edffb32d9e951efb3814bd104b8367a7501b81b955cacb5726d897389f"}, + {file = "pydantic_core-2.46.5-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:337639ba62a11acde6ef3aeb08c8ea755f8ef1fe5e513356c0f36a2b0d7568b0"}, + {file = "pydantic_core-2.46.5-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:413a717a410d0c817ef5b786a059415550b3794e1d0c2abffd9efb93a3d9f7b4"}, + {file = "pydantic_core-2.46.5-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1e449def1945a462c464331254e5a44fca7c3b4f9aedf59ec2f50f8066dd8e25"}, + {file = "pydantic_core-2.46.5-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:a445486499897b88a7d6c310c88ed64dd37b1b59bfd7ae9107490bbb362f47d6"}, + {file = "pydantic_core-2.46.5-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:2d330aaba8621b1edcec8ae2c4050f63b84ccf6d98723a8f212e9684713abf0e"}, + {file = "pydantic_core-2.46.5-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:b6acfb46a814762367fb7ba0828b0a17d441b92ce249a0e007474c9072662dda"}, + {file = "pydantic_core-2.46.5-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:d0a24b40877af2de4950252be9d21eaf7fb07660f3c2cae1f56c6b599ada5266"}, + {file = "pydantic_core-2.46.5.tar.gz", hash = "sha256:10416c15b8839ecc4ef4d0885da76da6fd0f67333a0eb8aff6d93c4b8f2910fc"}, ] [package.dependencies] -typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" +typing-extensions = ">=4.14.1" + +[[package]] +name = "pygments" +version = "2.21.0" +description = "Pygments is a syntax highlighting package written in Python." +optional = false +python-versions = ">=3.9" +groups = ["dev"] +files = [ + {file = "pygments-2.21.0-py3-none-any.whl", hash = "sha256:2363c69b61c4a97c838da3b130dcd6468f4848992b21a82f2a63ec34377137d9"}, + {file = "pygments-2.21.0.tar.gz", hash = "sha256:610ca751c9bc2492b38eb9a38a7fbc93edbbb2d7182edaf34e66ae493dee5c8c"}, +] + +[package.extras] +windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pytest" -version = "7.4.4" +version = "9.1.1" description = "pytest: simple powerful testing with Python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.10" +groups = ["dev"] files = [ - {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, - {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, + {file = "pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c"}, + {file = "pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313"}, ] [package.dependencies] -colorama = {version = "*", markers = "sys_platform == \"win32\""} -exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=0.12,<2.0" -tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} +colorama = {version = ">=0.4", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1", markers = "python_version < \"3.11\""} +iniconfig = ">=1.0.1" +packaging = ">=22" +pluggy = ">=1.5,<2" +pygments = ">=2.7.2" +tomli = {version = ">=1", markers = "python_version < \"3.11\""} [package.extras] -testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] +dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "requests", "setuptools", "xmlschema"] [[package]] name = "pytest-asyncio" -version = "0.23.8" +version = "1.4.0" description = "Pytest support for asyncio" optional = false -python-versions = ">=3.8" +python-versions = ">=3.10" +groups = ["dev"] files = [ - {file = "pytest_asyncio-0.23.8-py3-none-any.whl", hash = "sha256:50265d892689a5faefb84df80819d1ecef566eb3549cf915dfb33569359d1ce2"}, - {file = "pytest_asyncio-0.23.8.tar.gz", hash = "sha256:759b10b33a6dc61cce40a8bd5205e302978bbbcc00e279a8b61d9a6a3c82e4d3"}, + {file = "pytest_asyncio-1.4.0-py3-none-any.whl", hash = "sha256:933ca923a23075a87fb7070c0ec272a6848489824d887c85c812670932835aa1"}, + {file = "pytest_asyncio-1.4.0.tar.gz", hash = "sha256:c6c0d2259945122819f171a32ecea2c349ead889ee28176caaf492143424be42"}, ] [package.dependencies] -pytest = ">=7.0.0,<9" +backports-asyncio-runner = {version = ">=1.1,<2", markers = "python_version < \"3.11\""} +pytest = ">=8.4,<10" +typing-extensions = {version = ">=4.12", markers = "python_version < \"3.13\""} [package.extras] -docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"] +docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1)", "sphinx-tabs (>=3.5)"] testing = ["coverage (>=6.2)", "hypothesis (>=5.7.1)"] [[package]] name = "pytest-xdist" -version = "3.6.1" +version = "3.8.0" description = "pytest xdist plugin for distributed testing, most importantly across multiple CPUs" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" +groups = ["dev"] files = [ - {file = "pytest_xdist-3.6.1-py3-none-any.whl", hash = "sha256:9ed4adfb68a016610848639bb7e02c9352d5d9f03d04809919e2dafc3be4cca7"}, - {file = "pytest_xdist-3.6.1.tar.gz", hash = "sha256:ead156a4db231eec769737f57668ef58a2084a34b2e55c4a8fa20d861107300d"}, + {file = "pytest_xdist-3.8.0-py3-none-any.whl", hash = "sha256:202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88"}, + {file = "pytest_xdist-3.8.0.tar.gz", hash = "sha256:7e578125ec9bc6050861aa93f2d59f1d8d085595d6551c2c90b6f4fad8d3a9f1"}, ] [package.dependencies] @@ -458,6 +1260,7 @@ version = "2.9.0.post0" description = "Extensions to the standard Python datetime module" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["dev"] files = [ {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, @@ -472,6 +1275,7 @@ version = "0.11.5" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" +groups = ["dev"] files = [ {file = "ruff-0.11.5-py3-none-linux_armv6l.whl", hash = "sha256:2561294e108eb648e50f210671cc56aee590fb6167b594144401532138c66c7b"}, {file = "ruff-0.11.5-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ac12884b9e005c12d0bd121f56ccf8033e1614f736f766c118ad60780882a077"}, @@ -499,28 +1303,20 @@ version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["dev"] files = [ {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] -[[package]] -name = "sniffio" -version = "1.3.1" -description = "Sniff out which async library your code is running under" -optional = false -python-versions = ">=3.7" -files = [ - {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, - {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, -] - [[package]] name = "tomli" version = "2.4.1" description = "A lil' TOML parser" optional = false python-versions = ">=3.8" +groups = ["dev"] +markers = "python_version == \"3.10\"" files = [ {file = "tomli-2.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30"}, {file = "tomli-2.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a"}, @@ -573,27 +1369,219 @@ files = [ [[package]] name = "types-python-dateutil" -version = "2.9.0.20241206" +version = "2.9.0.20260807" description = "Typing stubs for python-dateutil" optional = false -python-versions = ">=3.8" +python-versions = ">=3.10" +groups = ["dev"] files = [ - {file = "types_python_dateutil-2.9.0.20241206-py3-none-any.whl", hash = "sha256:e248a4bc70a486d3e3ec84d0dc30eec3a5f979d6e7ee4123ae043eedbb987f53"}, - {file = "types_python_dateutil-2.9.0.20241206.tar.gz", hash = "sha256:18f493414c26ffba692a72369fea7a154c502646301ebfe3d56a04b3767284cb"}, + {file = "types_python_dateutil-2.9.0.20260807-py3-none-any.whl", hash = "sha256:54aa3707350ed7a9cc0776fd2f6739679d6967d11b40150985e81edcb86df4db"}, + {file = "types_python_dateutil-2.9.0.20260807.tar.gz", hash = "sha256:e0b8a90d464c8684c66b7b8e4556d9074afdddcc56ca45323f0987134f9e7034"}, ] [[package]] name = "typing-extensions" -version = "4.13.2" -description = "Backported and Experimental Type Hints for Python 3.8+" +version = "4.16.0" +description = "Backported and Experimental Type Hints for Python 3.9+" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" +groups = ["main", "dev"] files = [ - {file = "typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c"}, - {file = "typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef"}, + {file = "typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8"}, + {file = "typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5"}, ] +[[package]] +name = "typing-inspection" +version = "0.4.4" +description = "Runtime typing introspection tools" +optional = false +python-versions = ">=3.10" +groups = ["main"] +files = [ + {file = "typing_inspection-0.4.4-py3-none-any.whl", hash = "sha256:65b8397ba37ccbce054456aaccddfc91e6e3083c92824df348d96ca832f3f147"}, + {file = "typing_inspection-0.4.4.tar.gz", hash = "sha256:547274fa6b0a561ccf549cc9524b999a578e737d015d8709d021f9d0d13bea47"}, +] + +[package.dependencies] +typing-extensions = ">=4.15.0" + +[[package]] +name = "urllib3" +version = "2.8.0" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.10" +groups = ["dev"] +files = [ + {file = "urllib3-2.8.0-py3-none-any.whl", hash = "sha256:0cf3cae568d36aa9576b28dfb35f11328f1cb974ca7647d9475ebb86c75ac6e3"}, + {file = "urllib3-2.8.0.tar.gz", hash = "sha256:63bf2ead4c879426ebf22ef2a781eeb4aa3b4ae798a0435506f8687fd5bb9b63"}, +] + +[package.extras] +brotli = ["brotli (>=1.2.0) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=1.2.0.0) ; platform_python_implementation != \"CPython\""] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["backports-zstd (>=1.0.0) ; python_version < \"3.14\""] + +[[package]] +name = "yarl" +version = "1.25.1" +description = "Yet another URL library" +optional = true +python-versions = ">=3.10" +groups = ["main"] +markers = "extra == \"aiohttp\"" +files = [ + {file = "yarl-1.25.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:142c06c4d6a35ee3ec5da08499805e879cb3ca7c1fbfbecb0140fe72403818d6"}, + {file = "yarl-1.25.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:24ce942011a61953e7d313438038f4d32ff21387b775f58a957f7a07dd55ef95"}, + {file = "yarl-1.25.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e23c82b63cd7652fc24d33ed6cc17099d607aa3b4fc4ddc75e95062f3d82df4"}, + {file = "yarl-1.25.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8ee202350cf57abf0e9502a41601841019c25d3db7ff52d980aaf31446254059"}, + {file = "yarl-1.25.1-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5df89f769cc8ff94c3d7e7603386fba309d25ce5240132d26c15baa8d0e96c4c"}, + {file = "yarl-1.25.1-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:83e9f4a25085bd4b7214701a0794ff1f50fc633ffb8bdfebf07abdd81c2db126"}, + {file = "yarl-1.25.1-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e636b64d24fd9c38053c5e389a1174c66361fa49dcfd220f4dd35b4abde7cb89"}, + {file = "yarl-1.25.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e5637ca8d0bd7fb72648a6c7934af4baaccb697657f7438c9d264fc2abb8b0b1"}, + {file = "yarl-1.25.1-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:683e362b8ba453080f7489c66f4ea794e751c35b72e7eab3575ef784c2fbc7fb"}, + {file = "yarl-1.25.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:df23df54b5114a17c2d0ef192433e2e5a9f0c5178c32375e90b7cfc965f349d0"}, + {file = "yarl-1.25.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:f53dcd26694f148f738edc052b5a69234833e739f10f4c3287bdfd8ec0f7b326"}, + {file = "yarl-1.25.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:b8075fe90bc08e40b8b8a1874fab42ee4c7b56af05c5886e9cc841397f916908"}, + {file = "yarl-1.25.1-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:a8c2b841478068440d8b733005d13a5ef535b9928cbc05f17182d410f32ba449"}, + {file = "yarl-1.25.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:ca32926d7d77bcc8838425c4c95e040a3ace1cb7dfdae599013458dcda2607ca"}, + {file = "yarl-1.25.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:192a866877a49993949ef1975864ad8728bea28ee810f6abe1a0729c2b500426"}, + {file = "yarl-1.25.1-cp310-cp310-win_amd64.whl", hash = "sha256:3f4d48a6112712973e676bd792121fee470e432d749177162d9949d5c9460a1b"}, + {file = "yarl-1.25.1-cp310-cp310-win_arm64.whl", hash = "sha256:48796ea00a303961507dc6c8437c4b325a6fc3f95f7c36c71b91ea9a8150963c"}, + {file = "yarl-1.25.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9d693bf4bf534e9ba3ae2780cfd577f5135629f7b5ac653490859d0b77864865"}, + {file = "yarl-1.25.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ab2054c5531af2a9ba7b69b8ec91e4f884420e83a8c5e579b013084cb57e5e5d"}, + {file = "yarl-1.25.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:564fdc7085d2245ab84f88882fdb1d6ac0723124bff6ded35bfb1c00f812630d"}, + {file = "yarl-1.25.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:acae6b45d1ace09b6ba3876da43b88366ef368f73b988c7f57e14231753d4420"}, + {file = "yarl-1.25.1-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:1fb2a01ba8cd9c5d2c5dc1ec35e0fc951d04b4f037541d4ac090c993ce58b3d7"}, + {file = "yarl-1.25.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e92b6bcc741b86d67606c40d3cb9c7cc8e6c737f81e31f4a94efc204456c92e3"}, + {file = "yarl-1.25.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:72c34ac7ad4314c19362d5ce27626dcc8429bd30bbf8c179f4234078851f9492"}, + {file = "yarl-1.25.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5add7b4ca7afeea91d52e4d4e4db3b1fe9885b71f07054560d8c4296b7441a2"}, + {file = "yarl-1.25.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:def538065f9e4d4cf1ae164bd59aba00dfa84f03923e0de4c3788f252d6bcd17"}, + {file = "yarl-1.25.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a191bfdb30a79b98e5d175d75285f9fcb78bf0e46ba5efda042e1c72071a0de"}, + {file = "yarl-1.25.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:71f42c5b9a948c113bbdebfa544598321431d064ff959d32e99b1feb61d68345"}, + {file = "yarl-1.25.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:72849d892954be4d09e569b8b831ac39ce58417fedc767d4308a0fe542018a40"}, + {file = "yarl-1.25.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:efb01a106f971cb3752856bca2318bbdf7f01bd8823779c461586cbe5ffd5258"}, + {file = "yarl-1.25.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a1daf47cd95a7c3a63456336bc5aaa8c86dd3a47d07ed3d0e76132ae4666a5a1"}, + {file = "yarl-1.25.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9489e6abf47ba37f332075a91444c7cfedb03e6ce99fbb2f116bfe1ce810da3b"}, + {file = "yarl-1.25.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7306dee25b8a0e737363f347362b875094b4dc4e367311470656ae420fdbf8e"}, + {file = "yarl-1.25.1-cp311-cp311-win_arm64.whl", hash = "sha256:abb1384477f5901d436b5d2e5465954de46ea6098f59163d243660b5c4461d35"}, + {file = "yarl-1.25.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:94d7aa6debf92a1dd14cb5280b083a764169a13cfb23a452111160274ed989f4"}, + {file = "yarl-1.25.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:83d4a37e4b95da4d8bda930d6d35b75b4cdadbacbb4980cae290ea3100b5d51d"}, + {file = "yarl-1.25.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e029648f9c951db30e98a7d7ec90835db88ec4b32820efe2a9bdc2287e032eb6"}, + {file = "yarl-1.25.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4d781294bb815ecb5ea57ff6bbf8038e0a31a95fdf3e1788f66e0dc100d64b58"}, + {file = "yarl-1.25.1-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e12c538e00e7c1b286a07061046b90e8124e6a9793efae2c70db6a4aad07faad"}, + {file = "yarl-1.25.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7e4de3ac4adbad3d0bc7c6f4360a7dbff5de2f15e3b723be3198074e17fd9c40"}, + {file = "yarl-1.25.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:419f392a1da624877975709e3864dfe833af6cc7671b39318086d456e288380c"}, + {file = "yarl-1.25.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c6f117789d22dce188e5754e8bc65b7e6ebf8cb73963b9fa761f672a5883769d"}, + {file = "yarl-1.25.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:80e47012e730da131c9f059c80936783f9659aae22dc31c03c0595590d11ed54"}, + {file = "yarl-1.25.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e80f557716fd765439577131e526b8942ffc2c07bdbc5e39fa62f660ba1e963f"}, + {file = "yarl-1.25.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:f61964f235a43738bfac50da46fc4254943a7eea3051aeb0b6fc7c992c29fadc"}, + {file = "yarl-1.25.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:e546fe1d4a93ebc2910f0d768baff19faa09843ab3f2036a67ed6e69fae4419d"}, + {file = "yarl-1.25.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:cce0727fd5ac04d372fa9bbfde9febc2bcf209aadfcf0468e45dec72719895d1"}, + {file = "yarl-1.25.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af4ea5b37403ef4e30f3927eaed540db942bde01d8d3ff083527c0704d1c9c68"}, + {file = "yarl-1.25.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:68782fdb4027b8d1eee25ec35e9a6db05e863b899eb0310b3a33b6c3fef55707"}, + {file = "yarl-1.25.1-cp312-cp312-win_amd64.whl", hash = "sha256:7d575b54cb3863ef9bc290ea4b009999d55dc237326131e4853cf33e888fee03"}, + {file = "yarl-1.25.1-cp312-cp312-win_arm64.whl", hash = "sha256:bc3ac7bf569f6b64dad04dd7808c7872dae8a97df657856eac05e9b7e3614a85"}, + {file = "yarl-1.25.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:25868beca8b6765f8f7d0e11fe6dd7c66dd4b0793b9500286d20cc92352126a5"}, + {file = "yarl-1.25.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:10b2fd95332f0d716d5eee3c9fb2ce8eada19082de7fee83d32e37992fd75c26"}, + {file = "yarl-1.25.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0f12afda4eea8c8994a76d4df1875c765194f5fbe8a9d197929ea303caee29ec"}, + {file = "yarl-1.25.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:14b79a30a93a3ce2e8832603fd0ab780ada281b0ba5110b519a634f2d7d7d1fc"}, + {file = "yarl-1.25.1-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4bd6340d20ae2c7ca719b87b426e808e90743b676d05d4c26c4fb5ca71f41184"}, + {file = "yarl-1.25.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:126a2533570c554719ca40a1288fdee1700b6bc82e7131aa69fa85252d92e651"}, + {file = "yarl-1.25.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a3faadac7d812ddac258feb57b9846b60c1b437c4f4b9ad42595c6f6fe4390df"}, + {file = "yarl-1.25.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:be80550d9bfe83d9b62398a37081a90434e6df2d978ec345c3d2820de6beddab"}, + {file = "yarl-1.25.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e07595c7d6f4db270ceede356a1bd1c07a34f1c26f958d1ed0cd7b48e0d2bba3"}, + {file = "yarl-1.25.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:eb96ed1ae6c7d072d60840c0434aef07a2df611812810807fbc54263a6053e9a"}, + {file = "yarl-1.25.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3feb99222553a8cbedfa52c2f59dd84c3f50d5b582c728d522caf8d72769a54b"}, + {file = "yarl-1.25.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a2ed0ba415ccdf08f14bf544cb78346d0f76086707ffee24921a2c84dbf1305a"}, + {file = "yarl-1.25.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:2b49375d22299b0a834c2bca72f39aaecc270d96fb24c30424899676f487b22a"}, + {file = "yarl-1.25.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:ef74070ac553c59eb4f04258722066d6c6135b7baa03b2e9f2da65c096e96d98"}, + {file = "yarl-1.25.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0a66db89ea473abeac4b70523cafd94db3772380e565f9d28af7a179b7af71fa"}, + {file = "yarl-1.25.1-cp313-cp313-win_amd64.whl", hash = "sha256:1f51020b2eb8a003c84925638ec63c21a750a4bddd3a22ec8eac6a742dadf1b9"}, + {file = "yarl-1.25.1-cp313-cp313-win_arm64.whl", hash = "sha256:b10dd0557ba422715b5206b3743192135a6022acca8baec51aa127d0a75db8fe"}, + {file = "yarl-1.25.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:a9ca696eb02e5c02a8afd872ada510eba9b7fe6e68b9572c2e9a9b1941e31e2e"}, + {file = "yarl-1.25.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:a5877f2255aab518ebe528289037699201d5dc5f045f2396cb30aa02db22f57f"}, + {file = "yarl-1.25.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7a5c3115595995779ee21f2567035793911c3802a43c74f3fbb0314929ec67ac"}, + {file = "yarl-1.25.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:77e5099b99b37f3cf79c246998ca9f7313a78054cd1809ec46bc1afad47e1c4c"}, + {file = "yarl-1.25.1-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6efaf45df6a849cef613a03a94c845647456662f85438c886bb67a9c027c8c2c"}, + {file = "yarl-1.25.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d5f90e44653c4e0f78501ed9bb7d3fce835a8d62b7c6ed0cb16557534087e743"}, + {file = "yarl-1.25.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:632da579b2d879f6bad20f2cfa35ded1efe2f4f77f8abb26a6234a5b236acd2f"}, + {file = "yarl-1.25.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:30eec96e8a91bd588ce897c9543f6d5d8d34b28fbcba28a4dedf20ebeae9fe57"}, + {file = "yarl-1.25.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:12b6bc4906e11f5e1a1cdcb12296e7afbd366c783cc8073403cd2fb74334e453"}, + {file = "yarl-1.25.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9d6ed3d17bccce4c05343e1ca8da13bc5c02c812a4e7282ddd05e8769322d3fc"}, + {file = "yarl-1.25.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:f38a70074041d3b7e138e452799f5174198bae5bd5ab2000917badf403908c5f"}, + {file = "yarl-1.25.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:4ca89e4e21854ed27ec753297dde84b16c9f8e53b14a4866fb44457d643c19f8"}, + {file = "yarl-1.25.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:1ab7618921a93767387a4b83776f751588f5b5ae9bb5bc96620e2e2e00bca868"}, + {file = "yarl-1.25.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:0ae12ff2b805fa02c4dab838005caef735e39986322698c48588d3beacb65c62"}, + {file = "yarl-1.25.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:90c30ed53546da833c700115c0064c22120d1b1560f474699fd31f22dd668233"}, + {file = "yarl-1.25.1-cp314-cp314-win_amd64.whl", hash = "sha256:acfa7e22aa6c6e7a5996a41d275bfa01efa7ea56ab890590280e9063e2cf5c1b"}, + {file = "yarl-1.25.1-cp314-cp314-win_arm64.whl", hash = "sha256:8e7d98cdbb6d71e726f7d525952867096053d1f290dd4e3c50d7d313a136f414"}, + {file = "yarl-1.25.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:d21f0fa80a02d05299207eeaafef345d812ace96d5306e4ef265e1d419a615fa"}, + {file = "yarl-1.25.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:17c9877a89fb6e2bca6f9087eb24cd7fb434653946ef5075e470d23d49b52287"}, + {file = "yarl-1.25.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:29273edf1530e397bd07cb784db1fbe0d2590b77569f2e24679a9c0a2d763b94"}, + {file = "yarl-1.25.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b7abffdf37af1cec6a2ad69b827aa84320db5894791bc8ed932dc93fb274b7e9"}, + {file = "yarl-1.25.1-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2239a02249d9326655419e0168a28ca9008938eaab31dc29fc875c217927a6c0"}, + {file = "yarl-1.25.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:664ec6a520b74a1df2810666eb67695fcb77fa663e6ea0a25aaf2e529cb24dfa"}, + {file = "yarl-1.25.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4f1c91f5a5980a937ff8e238e98e6897e1ad74a4b1e2c0d68c73b5ffbb3f5c0b"}, + {file = "yarl-1.25.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7c88edaec8c349ad4c5ad4c486a3defcc4b80ceb2f074436ffa0a87caf5e76a6"}, + {file = "yarl-1.25.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:35dcbea443fafb3eece757ad4e514560ddeb6c34cfae1582c620d7b293d7feee"}, + {file = "yarl-1.25.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:882569ff613758cac762a457a5d72d6e211b28d4bcfea89d1d71ea942b02eac0"}, + {file = "yarl-1.25.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:d0f1489233a254bb3643d2f05de7d59019254d81daeca6b9162fe9edef57e0c7"}, + {file = "yarl-1.25.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:f41753a76f4f63927d03a0d8ba8f5ce0f2083bec29a8cfaccc55371b1564b96b"}, + {file = "yarl-1.25.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:8fb0eb4955adf0579001581f2f71a126e8781ba61bcd120f127b0401163c6c2d"}, + {file = "yarl-1.25.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:a1e32763e641a1566507d90a8d3b19bfc3cc04a9d4e5ae3e32189874ed4b58a3"}, + {file = "yarl-1.25.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:65b5b2066651b7432d389e9799d979c703bcc6ef44266bb8153ef54e91e4aab3"}, + {file = "yarl-1.25.1-cp314-cp314t-win_amd64.whl", hash = "sha256:734f6e5400352ac4254456003d462866c684703570929cff7a7bde015d0cb371"}, + {file = "yarl-1.25.1-cp314-cp314t-win_arm64.whl", hash = "sha256:287e99ff5aa4dc1c7630bfc683ded6f106d756c99dec432a2d7f197a784f51c6"}, + {file = "yarl-1.25.1-cp315-cp315-macosx_10_15_universal2.whl", hash = "sha256:9b1bdaae98bc016825dd3c9d8ee1832f829b3341f9cc6ebd1a1b0a7fef7367cc"}, + {file = "yarl-1.25.1-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:e7011b8fb8c4054bf0c12e5edc6cd83778b0028e99ce59b18586ed036f92cfdc"}, + {file = "yarl-1.25.1-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:f074e8d4aa0a5798920ddb6de3d08b228c614ff3724c3e8bd7577f4bafea867b"}, + {file = "yarl-1.25.1-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7d42e7e3ca399555578b4d617e3a6ecf13371b3743a115995fa010c7bf341459"}, + {file = "yarl-1.25.1-cp315-cp315-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:aa4ed3dd308548f9e707d9caaf005d2d7f8c1e7868f858dfeb47fe76e16b391d"}, + {file = "yarl-1.25.1-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:42a66563d8cc056ee32e6191e05097a7b2b3bc302e0bc3133daf8710eb18bd26"}, + {file = "yarl-1.25.1-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:98d370568f393215d605304cdb77b3d5539bd192c75b623c7304c42c8d6d8273"}, + {file = "yarl-1.25.1-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23bf5b403c879a54964e0feac7285688e04bb220074878d737d331522da0a5bf"}, + {file = "yarl-1.25.1-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d45673badd08456d0340e9364eddafe1c53a9d2896424294de4d7dd71ad3ee57"}, + {file = "yarl-1.25.1-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:0136d640dfa9b0523853e411430a99f8a91eca85774c6420285a33b755bc6de3"}, + {file = "yarl-1.25.1-cp315-cp315-musllinux_1_2_armv7l.whl", hash = "sha256:59ba3a6e1aa8cfe5adf4bd270fd965db21955401b7ca6f1696010c55ed4daec2"}, + {file = "yarl-1.25.1-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:87796fedc3ba97ec14fab55acb48584276e6c1e4c1e89c422bda62c838e754a9"}, + {file = "yarl-1.25.1-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:bd0912757081f89b107d6c00b2ff8a194401b0b87eadcf4481de2b865a8fd44f"}, + {file = "yarl-1.25.1-cp315-cp315-musllinux_1_2_s390x.whl", hash = "sha256:b51c159a9794633f5e0db7ecec7b2b6e3734eca1f5d17dc989ff3552a43ff78b"}, + {file = "yarl-1.25.1-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:319e070a01db9920fb63761843f96a104c8e2b9427266731810dc1e22595b17c"}, + {file = "yarl-1.25.1-cp315-cp315-win_amd64.whl", hash = "sha256:a2059a2d891bd156bc5184e7ab7a56e78a84dfcfdeac8c501b552533ad1c36ee"}, + {file = "yarl-1.25.1-cp315-cp315-win_arm64.whl", hash = "sha256:a78b50b4f7918a3de71105d5c0b93bbc57bb8339a4d03a9dfd449f9068e76f3d"}, + {file = "yarl-1.25.1-cp315-cp315t-macosx_10_15_universal2.whl", hash = "sha256:b5402a340723fa7da00b5cff987ddab61276be6d11251ea71ae02bcac54890d8"}, + {file = "yarl-1.25.1-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:eda19ea5ee88742f47a2340816e6f2d40b53bed3ab5b69794769f36af9f35bb4"}, + {file = "yarl-1.25.1-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:75baa6cf9b6d1c52f3e111a130e202fd8cf0a5b3a066c3f73d615e885092e4ec"}, + {file = "yarl-1.25.1-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dbcef5a9119ef653653132cccaf999b30a0af6f33bb0a4ba80bec30056868487"}, + {file = "yarl-1.25.1-cp315-cp315t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7efc9f082dfed77c316edffa9deb52888e1bc6789171887cc1f68e06d65465c8"}, + {file = "yarl-1.25.1-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fe01645169a2112aa1d4ebc3e4c5f029c5c8f97adfc32e5d37c993b39a994d75"}, + {file = "yarl-1.25.1-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1c557dfd5e3db046053a0bdc72261ade790ebe8e2c7a41b36b0ca1f14cb95f3"}, + {file = "yarl-1.25.1-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8ce4d6ccafb33d39bd78444612d14938ead674c25702ded2ee9c54a47735d225"}, + {file = "yarl-1.25.1-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:80a063f8297fc796296f00f100be520f209b23dc98f93ce8eba6ee7122598209"}, + {file = "yarl-1.25.1-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:7cb414a73e21a7ab58254926073f2930cb22f5b4314ea4260a687e2b3fd4dce3"}, + {file = "yarl-1.25.1-cp315-cp315t-musllinux_1_2_armv7l.whl", hash = "sha256:85a18376073f8a39aa07be34f9fc77e2869aa72c55c441efdd2cf79a0407504d"}, + {file = "yarl-1.25.1-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:77716e245c90f058466a05e6a465bb8600f767a8f4b18b4d40f3aff958e5f73c"}, + {file = "yarl-1.25.1-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:1e80dcf1446e1b080b1932b0d103c464a04112f5bc31f0f983ad418172063cde"}, + {file = "yarl-1.25.1-cp315-cp315t-musllinux_1_2_s390x.whl", hash = "sha256:bdc8d8b8c22e9e43ac68316b5e6cf083dec537f4ec213cb4aa967b583bc3fa64"}, + {file = "yarl-1.25.1-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:dfbf531053a0935f2e871bcd4753f90313688772ff8c017f5ea402e315a78c1f"}, + {file = "yarl-1.25.1-cp315-cp315t-win_amd64.whl", hash = "sha256:b13b88747769537f3d32e89e3a735da10c0a9e35d7322928c701b5f93d3afffd"}, + {file = "yarl-1.25.1-cp315-cp315t-win_arm64.whl", hash = "sha256:783dd1467083f4d3f7722ad6a313f24c173e7571372738fcb7a6e6d1ba48df25"}, + {file = "yarl-1.25.1-py3-none-any.whl", hash = "sha256:681c758b0490f9e96b78e5fa8e8dc6e648e9185bb6eaebe73183c33ea0c445f3"}, + {file = "yarl-1.25.1.tar.gz", hash = "sha256:03dd38de09bc213e9a8b29761eec33ee1d5318dac0e49d8af36e4d27830e23a7"}, +] + +[package.dependencies] +idna = ">=2.0" +multidict = ">=4.0" +propcache = ">=0.2.1" + +[extras] +aiohttp = ["aiohttp", "httpx-aiohttp"] + [metadata] -lock-version = "2.0" -python-versions = "^3.8" -content-hash = "bcf31a142c86d9e556553c8c260a93b563ac64a043076dbd48b26111d422c26e" +lock-version = "2.1" +python-versions = "^3.10" +content-hash = "4eaeff06fb8e558535aa3729ed6f99c2398eaaba665bcdf9c096bb08d9cb5fc6" diff --git a/pyproject.toml b/pyproject.toml index 44c0dec5..48ed0a49 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,22 +1,18 @@ [project] name = "zep-cloud" dynamic = ["version"] -version = "4.0.0a5" [tool.poetry] name = "zep-cloud" -version = "4.0.0a5" +version = "4.0.0b1" description = "" readme = "README.md" authors = [] keywords = [] - classifiers = [ "Intended Audience :: Developers", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", @@ -39,24 +35,31 @@ packages = [ Repository = 'https://github.com/getzep/zep-python' [tool.poetry.dependencies] -python = "^3.8" +python = "^3.10" +aiohttp = { version = ">=3.14.1,<4", optional = true, python = ">=3.10"} httpx = ">=0.21.2" +httpx-aiohttp = { version = "^0.1.8", optional = true, python = ">=3.10"} pydantic = ">= 1.9.2" -pydantic-core = ">=2.18.2" +pydantic-core = ">=2.18.2,<3.0.0" typing_extensions = ">= 4.0.0" [tool.poetry.group.dev.dependencies] mypy = "==1.13.0" -pytest = "^7.4.0" -pytest-asyncio = "^0.23.5" +pytest = "^9.0.3" +pytest-asyncio = "^1.0.0" pytest-xdist = "^3.6.1" python-dateutil = "^2.9.0" types-python-dateutil = "^2.9.0.20240316" +urllib3 = ">=2.6.3,<3.0.0" ruff = "==0.11.5" [tool.pytest.ini_options] testpaths = [ "tests" ] asyncio_mode = "auto" +norecursedirs = [ "src" ] +markers = [ + "aiohttp: tests that require httpx_aiohttp to be installed", +] [tool.mypy] plugins = ["pydantic.mypy"] @@ -88,3 +91,6 @@ section-order = ["future", "standard-library", "third-party", "first-party"] [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" + +[tool.poetry.extras] +aiohttp=["aiohttp", "httpx-aiohttp"] diff --git a/reference.md b/reference.md index 3da22a1d..1c724b43 100644 --- a/reference.md +++ b/reference.md @@ -1,6 +1,6 @@ # Reference -## Batch -
client.batch.list(...) -> BatchPage +## Agent +
client.agent.create(...) -> Agent
@@ -21,10 +21,10 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.batch.list( - limit=1, - cursor="cursor", - status="status", +client.agent.create( + agent_id="agent_id", + name="name", + security_domain="security_domain", ) ``` @@ -41,23 +41,7 @@ client.batch.list(
-**limit:** `typing.Optional[int]` — Page size - -
-
- -
-
- -**cursor:** `typing.Optional[str]` — Opaque page cursor - -
-
- -
-
- -**status:** `typing.Optional[str]` — Batch status filter +**request:** `CreateAgentRequest`
@@ -77,7 +61,7 @@ client.batch.list(
-
client.batch.create(...) -> Batch +
client.agent.list(...) -> AgentPage
@@ -98,7 +82,7 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.batch.create() +client.agent.list() ```
@@ -114,10 +98,15 @@ client.batch.create()
-**ignore_roles:** `typing.Optional[typing.List[str]]` +**limit:** `typing.Optional[int]` — Page size (maximum 100) + +
+
-Message roles to skip during graph extraction for thread message items in -this batch. +
+
+ +**cursor:** `typing.Optional[str]` — Opaque page cursor
@@ -125,7 +114,7 @@ this batch.
-**metadata:** `typing.Optional[typing.Dict[str, typing.Any]]` — Metadata to store on the batch. +**agent_id:** `typing.Optional[str]` — Filters to the exact developer-assigned Agent identifier.
@@ -133,10 +122,31 @@ this batch.
-**strict_ontology:** `typing.Optional[bool]` +**deployment_id:** `typing.Optional[str]` — Filters to the exact deployment identifier. + +
+
-When true, prevents extraction of generic entity nodes that do not match -the configured ontology for episodes in this batch. +
+
+ +**metadata:** `typing.Optional[typing.Dict[str, typing.Any]]` — Filters to Agents whose metadata contains these key-value pairs. + +
+
+ +
+
+ +**status:** `typing.Optional[AgentStatus]` — Filters to lifecycle status. Omit to include every status. + +
+
+ +
+
+ +**version:** `typing.Optional[str]` — Filters to the exact deployment version.
@@ -156,7 +166,7 @@ the configured ontology for episodes in this batch.
-
client.batch.get(...) -> Batch +
client.agent.get(...) -> Agent
@@ -177,8 +187,8 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.batch.get( - batch_uuid="batch_uuid", +client.agent.get( + agent_uuid="agent_uuid", ) ``` @@ -195,7 +205,7 @@ client.batch.get(
-**batch_uuid:** `str` — Batch UUID +**agent_uuid:** `str` — Agent UUID
@@ -215,7 +225,7 @@ client.batch.get(
-
client.batch.delete(...) +
client.agent.delete(...) -> AgentDeleteResult
@@ -236,8 +246,9 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.batch.delete( - batch_uuid="batch_uuid", +client.agent.delete( + agent_uuid="agent_uuid", + expected_revision=1, ) ``` @@ -254,7 +265,15 @@ client.batch.delete(
-**batch_uuid:** `str` — Batch UUID +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**expected_revision:** `int` — The current Agent revision used for optimistic concurrency.
@@ -274,7 +293,7 @@ client.batch.delete(
-
client.batch.list_items(...) -> BatchItemPage +
client.agent.update(...) -> Agent
@@ -295,10 +314,9 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.batch.list_items( - batch_uuid="batch_uuid", - limit=1, - cursor="cursor", +client.agent.update( + agent_uuid="agent_uuid", + expected_revision=1, ) ``` @@ -315,7 +333,7 @@ client.batch.list_items(
-**batch_uuid:** `str` — Batch UUID +**agent_uuid:** `str` — Agent UUID
@@ -323,7 +341,7 @@ client.batch.list_items(
-**limit:** `typing.Optional[int]` — Page size +**expected_revision:** `int` — The current Agent revision used for optimistic concurrency.
@@ -331,7 +349,47 @@ client.batch.list_items(
-**cursor:** `typing.Optional[str]` — Opaque page cursor +**deployment_id:** `typing.Optional[str]` — The customer deployment this Agent represents. Set to null to clear it. + +
+
+ +
+
+ +**description:** `typing.Optional[str]` — A human-readable description of the Agent. Set to null to clear it. + +
+
+ +
+
+ +**memory_settings:** `typing.Optional[AgentMemorySettings]` — Replacement Agent Memory settings. Set to null to restore defaults. + +
+
+ +
+
+ +**metadata:** `typing.Optional[typing.Dict[str, typing.Any]]` — Replacement developer metadata. Set to null to clear it. + +
+
+ +
+
+ +**name:** `typing.Optional[str]` — The Agent's display name. + +
+
+ +
+
+ +**version:** `typing.Optional[str]` — The customer deployment version this Agent represents. Set to null to clear it.
@@ -351,7 +409,7 @@ client.batch.list_items(
-
client.batch.add_items(...) -> BatchItemsResponse +
client.agent.declare_breaking_change(...) -> AgentBreakingChange
@@ -364,7 +422,7 @@ client.batch.list_items(
```python -from zep_cloud import Zep, BatchItemInput +from zep_cloud import Zep from zep_cloud.environment import ZepEnvironment client = Zep( @@ -372,13 +430,10 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.batch.add_items( - batch_uuid="batch_uuid", - items=[ - BatchItemInput( - type="graph_episode", - ) - ], +client.agent.declare_breaking_change( + agent_uuid="agent_uuid", + expected_revision=1, + version="version", ) ``` @@ -395,7 +450,7 @@ client.batch.add_items(
-**batch_uuid:** `str` — Batch UUID +**agent_uuid:** `str` — Agent UUID
@@ -403,7 +458,15 @@ client.batch.add_items(
-**items:** `typing.List[BatchItemInput]` — The batch items to append, each identified by its type field. +**expected_revision:** `int` + +
+
+ +
+
+ +**version:** `str`
@@ -423,7 +486,7 @@ client.batch.add_items(
-
client.batch.process(...) -> ProcessBatchResult +
client.agent.get_context(...) -> AgentContext
@@ -444,8 +507,8 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.batch.process( - batch_uuid="batch_uuid", +client.agent.get_context( + agent_uuid="agent_uuid", ) ``` @@ -462,7 +525,7 @@ client.batch.process(
-**batch_uuid:** `str` — Batch UUID +**agent_uuid:** `str` — Agent UUID
@@ -470,57 +533,63 @@ client.batch.process(
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**environments:** `typing.Optional[typing.List[AgentContextResource]]`
-
-
+
+
+**kind:** `typing.Optional[str]` +
-
-## Context -
client.context.create_template(...) -> ContextTemplate
-#### 🔌 Usage +**max_characters:** `typing.Optional[int]` + +
+
+**models:** `typing.Optional[typing.List[AgentContextResource]]` + +
+
+
-```python -from zep_cloud import Zep -from zep_cloud.environment import ZepEnvironment - -client = Zep( - api_key="", - environment=ZepEnvironment.DEFAULT, -) - -client.context.create_template() - -``` +**objective:** `typing.Optional[str]` +
+ +
+
+ +**task_family:** `typing.Optional[str]` +
-#### ⚙️ Parameters -
+**tools:** `typing.Optional[typing.List[AgentContextResource]]` + +
+
+
-**request:** `CreateContextTemplateRequest` +**trajectory_uuid:** `typing.Optional[str]`
@@ -540,7 +609,8 @@ client.context.create_template()
-
client.context.list_templates(...) -> ContextTemplatePage +## Batch +
client.batch.list(...) -> BatchPage
@@ -561,10 +631,7 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.context.list_templates( - limit=1, - cursor="cursor", -) +client.batch.list() ```
@@ -596,7 +663,7 @@ client.context.list_templates(
-**name:** `typing.Optional[str]` — Filters results to the context template with this exact name. +**status:** `typing.Optional[BatchListRequestStatus]` — Batch status filter
@@ -616,7 +683,7 @@ client.context.list_templates(
-
client.context.get_template(...) -> ContextTemplate +
client.batch.create(...) -> Batch
@@ -637,9 +704,7 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.context.get_template( - template_uuid="template_uuid", -) +client.batch.create() ```
@@ -655,7 +720,29 @@ client.context.get_template(
-**template_uuid:** `str` — Template UUID +**ignore_roles:** `typing.Optional[typing.List[str]]` + +Message roles to skip during graph extraction for thread message items in +this batch. + +
+
+ +
+
+ +**metadata:** `typing.Optional[typing.Dict[str, typing.Any]]` — Metadata to store on the batch. + +
+
+ +
+
+ +**strict_ontology:** `typing.Optional[bool]` + +When true, prevents extraction of generic entity nodes that do not match +the configured ontology for episodes in this batch.
@@ -675,7 +762,7 @@ client.context.get_template(
-
client.context.update_template(...) -> ContextTemplate +
client.batch.get(...) -> Batch
@@ -696,8 +783,8 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.context.update_template( - template_uuid="template_uuid", +client.batch.get( + batch_uuid="batch_uuid", ) ``` @@ -714,15 +801,7 @@ client.context.update_template(
-**template_uuid:** `str` — Template UUID - -
-
- -
-
- -**request:** `CreateContextTemplateRequest` +**batch_uuid:** `str` — Batch UUID
@@ -742,7 +821,7 @@ client.context.update_template(
-
client.context.delete_template(...) +
client.batch.delete(...)
@@ -763,8 +842,8 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.context.delete_template( - template_uuid="template_uuid", +client.batch.delete( + batch_uuid="batch_uuid", ) ``` @@ -781,7 +860,7 @@ client.context.delete_template(
-**template_uuid:** `str` — Template UUID +**batch_uuid:** `str` — Batch UUID
@@ -801,8 +880,7 @@ client.context.delete_template(
-## Graph -
client.graph.create(...) -> Graph +
client.batch.list_items(...) -> BatchItemPage
@@ -823,7 +901,9 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.create() +client.batch.list_items( + batch_uuid="batch_uuid", +) ```
@@ -839,15 +919,7 @@ client.graph.create()
-**description:** `typing.Optional[str]` — A description of the graph. - -
-
- -
-
- -**graph_id:** `typing.Optional[str]` — An optional developer-assigned identifier for the graph. +**batch_uuid:** `str` — Batch UUID
@@ -855,7 +927,7 @@ client.graph.create()
-**name:** `typing.Optional[str]` — A display name for the graph. +**limit:** `typing.Optional[int]` — Page size
@@ -863,7 +935,7 @@ client.graph.create()
-**time_zone:** `typing.Optional[str]` — The graph's IANA time zone. +**cursor:** `typing.Optional[str]` — Opaque page cursor
@@ -883,7 +955,7 @@ client.graph.create()
-
client.graph.list(...) -> GraphPage +
client.batch.add_items(...) -> BatchItemsResponse
@@ -896,7 +968,7 @@ client.graph.create()
```python -from zep_cloud import Zep +from zep_cloud import Zep, BatchItemInput from zep_cloud.environment import ZepEnvironment client = Zep( @@ -904,11 +976,13 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.list( - limit=1, - cursor="cursor", - order_by="order_by", - order="order", +client.batch.add_items( + batch_uuid="batch_uuid", + items=[ + BatchItemInput( + type="graph_episode", + ) + ], ) ``` @@ -925,31 +999,7 @@ client.graph.list(
-**limit:** `typing.Optional[int]` — Page size - -
-
- -
-
- -**cursor:** `typing.Optional[str]` — Opaque page cursor - -
-
- -
-
- -**order_by:** `typing.Optional[str]` — Sort field - -
-
- -
-
- -**order:** `typing.Optional[str]` — asc or desc +**batch_uuid:** `str` — Batch UUID
@@ -957,10 +1007,7 @@ client.graph.list(
-**search:** `typing.Optional[str]` - -Filters results to graphs whose name, description, or graph ID contains -this text. +**items:** `typing.List[BatchItemInput]` — The batch items to append, each identified by its type field.
@@ -980,7 +1027,7 @@ this text.
-
client.graph.lookup(...) -> Graph +
client.batch.process(...) -> ProcessBatchResult
@@ -1001,7 +1048,9 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.lookup() +client.batch.process( + batch_uuid="batch_uuid", +) ```
@@ -1017,7 +1066,7 @@ client.graph.lookup()
-**request:** `LookupRequest` +**batch_uuid:** `str` — Batch UUID
@@ -1037,7 +1086,8 @@ client.graph.lookup()
-
client.graph.get(...) -> Graph +## Context +
client.context.create_template(...) -> ContextTemplate
@@ -1058,9 +1108,7 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.get( - graph_uuid="graph_uuid", -) +client.context.create_template() ```
@@ -1076,7 +1124,7 @@ client.graph.get(
-**graph_uuid:** `str` — Graph UUID +**request:** `CreateContextTemplateRequest`
@@ -1096,7 +1144,7 @@ client.graph.get(
-
client.graph.delete(...) -> GraphDeleteResult +
client.context.list_templates(...) -> ContextTemplatePage
@@ -1117,9 +1165,7 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.delete( - graph_uuid="graph_uuid", -) +client.context.list_templates() ```
@@ -1135,7 +1181,23 @@ client.graph.delete(
-**graph_uuid:** `str` — Graph UUID +**limit:** `typing.Optional[int]` — Page size + +
+
+ +
+
+ +**cursor:** `typing.Optional[str]` — Opaque page cursor + +
+
+ +
+
+ +**name:** `typing.Optional[str]` — Filters results to the context template with this exact name.
@@ -1155,7 +1217,7 @@ client.graph.delete(
-
client.graph.update(...) -> Graph +
client.context.get_template(...) -> ContextTemplate
@@ -1176,8 +1238,8 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.update( - graph_uuid="graph_uuid", +client.context.get_template( + template_uuid="template_uuid", ) ``` @@ -1194,31 +1256,7 @@ client.graph.update(
-**graph_uuid:** `str` — Graph UUID - -
-
- -
-
- -**description:** `typing.Optional[str]` — A description of the graph. - -
-
- -
-
- -**name:** `typing.Optional[str]` — The graph's display name. - -
-
- -
-
- -**time_zone:** `typing.Optional[str]` — The graph's IANA time zone. +**template_uuid:** `str` — Template UUID
@@ -1238,7 +1276,7 @@ client.graph.update(
-
client.graph.clone(...) -> CloneGraphResult +
client.context.update_template(...) -> ContextTemplate
@@ -1259,8 +1297,8 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.clone( - graph_uuid="graph_uuid", +client.context.update_template( + template_uuid="template_uuid", ) ``` @@ -1277,7 +1315,7 @@ client.graph.clone(
-**graph_uuid:** `str` — Graph UUID +**template_uuid:** `str` — Template UUID
@@ -1285,7 +1323,7 @@ client.graph.clone(
-**target_graph_id:** `typing.Optional[str]` — An optional name for the cloned graph. +**request:** `CreateContextTemplateRequest`
@@ -1305,7 +1343,7 @@ client.graph.clone(
-
client.graph.get_context(...) -> GraphContextResponse +
client.context.delete_template(...)
@@ -1326,9 +1364,8 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.get_context( - graph_uuid="graph_uuid", - query="query", +client.context.delete_template( + template_uuid="template_uuid", ) ``` @@ -1345,7 +1382,7 @@ client.graph.get_context(
-**graph_uuid:** `str` — Graph UUID +**template_uuid:** `str` — Template UUID
@@ -1353,53 +1390,66 @@ client.graph.get_context(
-**query:** `str` — The search query used to assemble the context block. +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
-
-
- -**filters:** `typing.Optional[SearchFilters]` -Filters constraining which graph data can be selected for the context -block. -
+
+## DebugLog +
client.debug_log.enable() -> DebugLoggingEnablement
-**include_results:** `typing.Optional[bool]` — When true, includes the raw graph results selected for the context block. - -
-
+#### 📝 Description
-**max_characters:** `typing.Optional[int]` — The maximum number of characters in the assembled context block. - -
-
-
-**recency_bias:** `typing.Optional[V4GraphContextRequestRecencyBias]` — Adjusts result selection to favor more recent graph data. - +Enables debug logging for the project for one hour, or for 24 hours on the Enterprise plan. Episodes ingested while debug logging is enabled have a debug log (see `graph.episode.get_debug_logs`). On the Flex, Flex Plus, and Enterprise plans, the operation also enables ingestion tracing (see `graph.episode.list_ingestion_traces`); `ingestion_trace_enabled` reports the result. A repeated call starts the duration again.
+ + + +#### 🔌 Usage
-**template_uuid:** `typing.Optional[str]` — The UUID of a context template used to render the context block. - +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.debug_log.enable() + +```
+
+
+ +#### ⚙️ Parameters + +
+
@@ -1416,7 +1466,8 @@ block.
-
client.graph.get_instructions(...) -> Instructions +## Graph +
client.graph.create(...) -> Graph
@@ -1437,9 +1488,7 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.get_instructions( - graph_uuid="graph_uuid", -) +client.graph.create() ```
@@ -1455,7 +1504,35 @@ client.graph.get_instructions(
-**graph_uuid:** `str` — Graph UUID +**content_policy:** `typing.Optional[GraphContentPolicyRequest]` + +Content policy additions for the graph. The graph binds the current +project content policy plus these additions, and the binding does not +change after creation. + +
+
+ +
+
+ +**description:** `typing.Optional[str]` — A description of the graph. + +
+
+ +
+
+ +**name:** `typing.Optional[str]` — A display name for the graph. + +
+
+ +
+
+ +**time_zone:** `typing.Optional[str]` — The graph's IANA time zone.
@@ -1475,7 +1552,7 @@ client.graph.get_instructions(
-
client.graph.set_instructions(...) -> Instructions +
client.graph.list(...) -> GraphPage
@@ -1496,9 +1573,7 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.set_instructions( - graph_uuid="graph_uuid", -) +client.graph.list() ```
@@ -1514,7 +1589,7 @@ client.graph.set_instructions(
-**graph_uuid:** `str` — Graph UUID +**limit:** `typing.Optional[int]` — Page size
@@ -1522,7 +1597,34 @@ client.graph.set_instructions(
-**request:** `Instructions` +**cursor:** `typing.Optional[str]` — Opaque page cursor + +
+
+ +
+
+ +**order_by:** `typing.Optional[GraphListRequestOrderBy]` — Sort field + +
+
+ +
+
+ +**order:** `typing.Optional[GraphListRequestOrder]` — asc or desc + +
+
+ +
+
+ +**search:** `typing.Optional[str]` + +Filters results to graphs whose name, description, or graph ID contains +this text.
@@ -1542,7 +1644,7 @@ client.graph.set_instructions(
-
client.graph.get_observation_steering(...) -> ObservationSteering +
client.graph.lookup(...) -> Graph
@@ -1563,9 +1665,7 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.get_observation_steering( - graph_uuid="graph_uuid", -) +client.graph.lookup() ```
@@ -1581,7 +1681,7 @@ client.graph.get_observation_steering(
-**graph_uuid:** `str` — Graph UUID +**request:** `LookupRequest`
@@ -1601,7 +1701,7 @@ client.graph.get_observation_steering(
-
client.graph.set_observation_steering(...) -> ObservationSteering +
client.graph.get(...) -> Graph
@@ -1622,7 +1722,7 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.set_observation_steering( +client.graph.get( graph_uuid="graph_uuid", ) @@ -1648,14 +1748,6 @@ client.graph.set_observation_steering(
-**request:** `ObservationSteering` - -
-
- -
-
- **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -1668,7 +1760,7 @@ client.graph.set_observation_steering(
-
client.graph.get_ontology(...) -> Ontology +
client.graph.delete(...) -> GraphDeleteResult
@@ -1689,7 +1781,7 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.get_ontology( +client.graph.delete( graph_uuid="graph_uuid", ) @@ -1727,7 +1819,7 @@ client.graph.get_ontology(
-
client.graph.set_ontology(...) -> Ontology +
client.graph.update(...) -> Graph
@@ -1748,7 +1840,7 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.set_ontology( +client.graph.update( graph_uuid="graph_uuid", ) @@ -1774,7 +1866,23 @@ client.graph.set_ontology(
-**request:** `Ontology` +**description:** `typing.Optional[str]` — A description of the graph. + +
+
+ +
+
+ +**name:** `typing.Optional[str]` — The graph's display name. + +
+
+ +
+
+ +**time_zone:** `typing.Optional[str]` — The graph's IANA time zone.
@@ -1794,7 +1902,7 @@ client.graph.set_ontology(
-
client.graph.search_edges(...) -> EdgePage +
client.graph.clone(...) -> CloneGraphResult
@@ -1815,11 +1923,11 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.search_edges( +client.graph.clone( graph_uuid="graph_uuid", - limit=1, - cursor="cursor", - query="query", + request={ + "key": "value" + }, ) ``` @@ -1844,7 +1952,7 @@ client.graph.search_edges(
-**request:** `SearchRequest` +**request:** `CloneGraphRequest`
@@ -1852,38 +1960,36 @@ client.graph.search_edges(
-**limit:** `typing.Optional[int]` — Page size +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
-
-
-**cursor:** `typing.Optional[str]` — Opaque page cursor -
+
+
client.graph.get_content_policy(...) -> GraphContentPolicy
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. - -
-
- - - +#### 📝 Description - - -
+
+
-
client.graph.search_episodes(...) -> EpisodePage
+Returns the content policy the graph bound at creation. The policy of a graph does not change after creation. A graph without a content policy returns revision 0 with no categories and no rules. +
+
+
+
+ #### 🔌 Usage
@@ -1901,11 +2007,8 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.search_episodes( +client.graph.get_content_policy( graph_uuid="graph_uuid", - limit=1, - cursor="cursor", - query="query", ) ``` @@ -1930,45 +2033,35 @@ client.graph.search_episodes(
-**request:** `SearchRequest` +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+ +
-
-
-**limit:** `typing.Optional[int]` — Page size -
+
+
client.graph.list_content_policy_events(...) -> ContentPolicyEventPage
-**cursor:** `typing.Optional[str]` — Opaque page cursor - -
-
+#### 📝 Description
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. - -
-
+
+
+ +Lists the content policy decisions recorded for a graph, newest first. Each event carries identifiers only. A graph without a content policy returns an empty list.
- - -
- -
client.graph.search_nodes(...) -> NodePage -
-
#### 🔌 Usage @@ -1987,11 +2080,8 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.search_nodes( +client.graph.list_content_policy_events( graph_uuid="graph_uuid", - limit=1, - cursor="cursor", - query="query", ) ``` @@ -2016,7 +2106,7 @@ client.graph.search_nodes(
-**request:** `SearchRequest` +**limit:** `typing.Optional[int]` — Page size
@@ -2024,7 +2114,7 @@ client.graph.search_nodes(
-**limit:** `typing.Optional[int]` — Page size +**cursor:** `typing.Optional[str]` — Opaque page cursor
@@ -2032,7 +2122,7 @@ client.graph.search_nodes(
-**cursor:** `typing.Optional[str]` — Opaque page cursor +**filters:** `typing.Optional[typing.Dict[str, typing.Any]]` — Exact-match filters. Supported keys: episode_uuid and drop_reason.
@@ -2052,7 +2142,7 @@ client.graph.search_nodes(
-
client.graph.search_observations(...) -> ObservationPage +
client.graph.get_context(...) -> GraphContextResponse
@@ -2073,10 +2163,8 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.search_observations( +client.graph.get_context( graph_uuid="graph_uuid", - limit=1, - cursor="cursor", query="query", ) @@ -2102,7 +2190,7 @@ client.graph.search_observations(
-**request:** `SearchRequest` +**query:** `str` — The search query used to assemble the context block.
@@ -2110,7 +2198,10 @@ client.graph.search_observations(
-**limit:** `typing.Optional[int]` — Page size +**filters:** `typing.Optional[SearchFilters]` + +Filters constraining which graph data can be selected for the context +block.
@@ -2118,7 +2209,31 @@ client.graph.search_observations(
-**cursor:** `typing.Optional[str]` — Opaque page cursor +**include_results:** `typing.Optional[bool]` — When true, includes the raw graph results selected for the context block. + +
+
+ +
+
+ +**max_characters:** `typing.Optional[int]` — The maximum number of characters in the assembled context block. + +
+
+ +
+
+ +**recency_bias:** `typing.Optional[GraphContextRequestRecencyBias]` — Adjusts result selection to favor more recent graph data. + +
+
+ +
+
+ +**template_uuid:** `typing.Optional[str]` — The UUID of a context template used to render the context block.
@@ -2138,7 +2253,7 @@ client.graph.search_observations(
-
client.graph.search_thread_summaries(...) -> ThreadSummaryPage +
client.graph.get_instructions(...) -> Instructions
@@ -2159,11 +2274,8 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.search_thread_summaries( +client.graph.get_instructions( graph_uuid="graph_uuid", - limit=1, - cursor="cursor", - query="query", ) ``` @@ -2188,30 +2300,6 @@ client.graph.search_thread_summaries(
-**request:** `SearchRequest` - -
-
- -
-
- -**limit:** `typing.Optional[int]` — Page size - -
-
- -
-
- -**cursor:** `typing.Optional[str]` — Opaque page cursor - -
-
- -
-
- **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -2224,7 +2312,7 @@ client.graph.search_thread_summaries(
-
client.graph.get_subgraph(...) -> SubgraphResponse +
client.graph.set_instructions(...) -> Instructions
@@ -2245,11 +2333,8 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.get_subgraph( +client.graph.set_instructions( graph_uuid="graph_uuid", - seed_node_uuids=[ - "seed_node_uuids" - ], ) ``` @@ -2274,50 +2359,7 @@ client.graph.get_subgraph(
-**seed_node_uuids:** `typing.List[str]` — The node UUIDs to expand from, in traversal-priority order. - -
-
- -
-
- -**depth:** `typing.Optional[int]` — The maximum traversal depth from the seed nodes. Defaults to 1. - -
-
- -
-
- -**direction:** `typing.Optional[V4SubgraphRequestDirection]` - -The edge orientation to follow during expansion: in, out, or both. -Defaults to both. - -
-
- -
-
- -**filters:** `typing.Optional[SearchFilters]` — Filters constraining the traversed edges and included nodes. - -
-
- -
-
- -**max_edges:** `typing.Optional[int]` — The maximum number of edges in the response. Defaults to 200. - -
-
- -
-
- -**max_nodes:** `typing.Optional[int]` — The maximum number of nodes in the response. Defaults to 100. +**request:** `Instructions`
@@ -2337,7 +2379,7 @@ Defaults to both.
-
client.graph.warm(...) -> AsyncResult +
client.graph.get_observation_steering(...) -> ObservationSteering
@@ -2358,7 +2400,7 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.warm( +client.graph.get_observation_steering( graph_uuid="graph_uuid", ) @@ -2396,8 +2438,7 @@ client.graph.warm(
-## Lookup -
client.lookup.batch(...) -> LookupBatchResponse +
client.graph.set_observation_steering(...) -> ObservationSteering
@@ -2418,7 +2459,9 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.lookup.batch() +client.graph.set_observation_steering( + graph_uuid="graph_uuid", +) ```
@@ -2434,15 +2477,7 @@ client.lookup.batch()
-**graphs:** `typing.Optional[typing.List[str]]` — Developer-assigned graph IDs to resolve to UUIDs. - -
-
- -
-
- -**threads:** `typing.Optional[typing.List[str]]` — Developer-assigned thread IDs to resolve to UUIDs. +**graph_uuid:** `str` — Graph UUID
@@ -2450,7 +2485,7 @@ client.lookup.batch()
-**users:** `typing.Optional[typing.List[str]]` — Developer-assigned user IDs to resolve to UUIDs. +**request:** `ObservationSteering`
@@ -2470,8 +2505,7 @@ client.lookup.batch()
-## Project -
client.project.get() -> Project +
client.graph.get_ontology(...) -> Ontology
@@ -2492,7 +2526,9 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.project.get() +client.graph.get_ontology( + graph_uuid="graph_uuid", +) ```
@@ -2508,11 +2544,19 @@ client.project.get()
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**graph_uuid:** `str` — Graph UUID
- + +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
@@ -2520,7 +2564,7 @@ client.project.get()
-
client.project.update(...) -> Project +
client.graph.set_ontology(...) -> Ontology
@@ -2541,7 +2585,9 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.project.update() +client.graph.set_ontology( + graph_uuid="graph_uuid", +) ```
@@ -2557,10 +2603,15 @@ client.project.update()
-**default_time_zone:** `typing.Optional[str]` +**graph_uuid:** `str` — Graph UUID + +
+
-The project's IANA fallback time zone. Set to null to clear the existing -value. +
+
+ +**request:** `Ontology`
@@ -2580,7 +2631,7 @@ value.
-
client.project.get_instructions() -> Instructions +
client.graph.search_edges(...) -> EdgePage
@@ -2601,7 +2652,10 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.project.get_instructions() +client.graph.search_edges( + graph_uuid="graph_uuid", + query="query", +) ```
@@ -2617,56 +2671,31 @@ client.project.get_instructions()
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**graph_uuid:** `str` — Graph UUID
- -
- - - - -
-
client.project.set_instructions(...) -> Instructions
-#### 🔌 Usage - -
-
+**request:** `SearchRequest` + +
+
-```python -from zep_cloud import Zep -from zep_cloud.environment import ZepEnvironment - -client = Zep( - api_key="", - environment=ZepEnvironment.DEFAULT, -) - -client.project.set_instructions() - -``` -
-
+**limit:** `typing.Optional[int]` — Page size +
-#### ⚙️ Parameters - -
-
-
-**request:** `Instructions` +**cursor:** `typing.Optional[str]` — Opaque page cursor
@@ -2686,7 +2715,7 @@ client.project.set_instructions()
-
client.project.get_observation_steering() -> ObservationSteering +
client.graph.search_episodes(...) -> EpisodePage
@@ -2707,7 +2736,10 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.project.get_observation_steering() +client.graph.search_episodes( + graph_uuid="graph_uuid", + query="query", +) ```
@@ -2723,56 +2755,31 @@ client.project.get_observation_steering()
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**graph_uuid:** `str` — Graph UUID
- -
- - - - -
-
client.project.set_observation_steering(...) -> ObservationSteering
-#### 🔌 Usage - -
-
+**request:** `SearchRequest` + +
+
-```python -from zep_cloud import Zep -from zep_cloud.environment import ZepEnvironment - -client = Zep( - api_key="", - environment=ZepEnvironment.DEFAULT, -) - -client.project.set_observation_steering() - -``` -
-
+**limit:** `typing.Optional[int]` — Page size +
-#### ⚙️ Parameters - -
-
-
-**request:** `ObservationSteering` +**cursor:** `typing.Optional[str]` — Opaque page cursor
@@ -2792,7 +2799,7 @@ client.project.set_observation_steering()
-
client.project.get_ontology() -> Ontology +
client.graph.search_nodes(...) -> NodePage
@@ -2813,7 +2820,10 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.project.get_ontology() +client.graph.search_nodes( + graph_uuid="graph_uuid", + query="query", +) ```
@@ -2829,56 +2839,31 @@ client.project.get_ontology()
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**graph_uuid:** `str` — Graph UUID
- -
- - - - -
-
client.project.set_ontology(...) -> Ontology
-#### 🔌 Usage - -
-
+**request:** `SearchRequest` + +
+
-```python -from zep_cloud import Zep -from zep_cloud.environment import ZepEnvironment - -client = Zep( - api_key="", - environment=ZepEnvironment.DEFAULT, -) - -client.project.set_ontology() - -``` -
-
+**limit:** `typing.Optional[int]` — Page size +
-#### ⚙️ Parameters - -
-
-
-**request:** `Ontology` +**cursor:** `typing.Optional[str]` — Opaque page cursor
@@ -2898,7 +2883,7 @@ client.project.set_ontology()
-
client.project.get_user_summary_instructions() -> UserSummaryInstructions +
client.graph.search_observations(...) -> ObservationPage
@@ -2919,7 +2904,10 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.project.get_user_summary_instructions() +client.graph.search_observations( + graph_uuid="graph_uuid", + query="query", +) ```
@@ -2935,56 +2923,31 @@ client.project.get_user_summary_instructions()
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**graph_uuid:** `str` — Graph UUID
- -
- - - - -
-
client.project.set_user_summary_instructions(...) -> UserSummaryInstructions
-#### 🔌 Usage - -
-
+**request:** `SearchRequest` + +
+
-```python -from zep_cloud import Zep -from zep_cloud.environment import ZepEnvironment - -client = Zep( - api_key="", - environment=ZepEnvironment.DEFAULT, -) - -client.project.set_user_summary_instructions() - -``` -
-
+**limit:** `typing.Optional[int]` — Page size +
-#### ⚙️ Parameters - -
-
-
-**request:** `UserSummaryInstructions` +**cursor:** `typing.Optional[str]` — Opaque page cursor
@@ -3004,8 +2967,7 @@ client.project.set_user_summary_instructions()
-## Task -
client.task.list(...) -> TaskPage +
client.graph.search_thread_summaries(...) -> ThreadSummaryPage
@@ -3026,9 +2988,9 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.task.list( - limit=1, - cursor="cursor", +client.graph.search_thread_summaries( + graph_uuid="graph_uuid", + query="query", ) ``` @@ -3045,6 +3007,22 @@ client.task.list(
+**graph_uuid:** `str` — Graph UUID + +
+
+ +
+
+ +**request:** `SearchRequest` + +
+
+ +
+
+ **limit:** `typing.Optional[int]` — Page size
@@ -3073,7 +3051,7 @@ client.task.list(
-
client.task.get(...) -> Task +
client.graph.get_subgraph(...) -> SubgraphResponse
@@ -3094,8 +3072,11 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.task.get( - task_uuid="task_uuid", +client.graph.get_subgraph( + graph_uuid="graph_uuid", + seed_node_uuids=[ + "seed_node_uuids" + ], ) ``` @@ -3112,7 +3093,7 @@ client.task.get(
-**task_uuid:** `str` — Task UUID +**graph_uuid:** `str` — Graph UUID
@@ -3120,63 +3101,42 @@ client.task.get(
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**seed_node_uuids:** `typing.List[str]` — The node UUIDs to expand from, in traversal-priority order.
-
-
- - - -
- -## Thread -
client.thread.list(...) -> ThreadPage
-#### 🔌 Usage - -
-
+**depth:** `typing.Optional[int]` — The maximum traversal depth from the seed nodes. Defaults to 1. + +
+
-```python -from zep_cloud import Zep -from zep_cloud.environment import ZepEnvironment - -client = Zep( - api_key="", - environment=ZepEnvironment.DEFAULT, -) - -client.thread.list( - limit=1, - cursor="cursor", - order_by="order_by", - order="order", - user_uuid="user_uuid", -) +**direction:** `typing.Optional[SubgraphRequestDirection]` -``` -
-
+The edge orientation to follow during expansion: in, out, or both. +Defaults to both. +
-#### ⚙️ Parameters -
+**filters:** `typing.Optional[SearchFilters]` — Filters constraining the traversed edges and included nodes. + +
+
+
-**limit:** `typing.Optional[int]` — Page size +**max_edges:** `typing.Optional[int]` — The maximum number of edges in the response. Defaults to 200.
@@ -3184,7 +3144,7 @@ client.thread.list(
-**cursor:** `typing.Optional[str]` — Opaque page cursor +**max_nodes:** `typing.Optional[int]` — The maximum number of nodes in the response. Defaults to 100.
@@ -3192,23 +3152,58 @@ client.thread.list(
-**order_by:** `typing.Optional[str]` — Sort field +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+ + + + + + +
+
client.graph.warm(...) -> AsyncResult
-**order:** `typing.Optional[str]` — asc or desc - +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.graph.warm( + graph_uuid="graph_uuid", +) + +``` +
+
+#### ⚙️ Parameters +
-**user_uuid:** `typing.Optional[str]` — Filter by user UUID +
+
+ +**graph_uuid:** `str` — Graph UUID
@@ -3228,7 +3223,8 @@ client.thread.list(
-
client.thread.create(...) -> Thread +## Lookup +
client.lookup.batch(...) -> LookupBatchResponse
@@ -3249,9 +3245,7 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.thread.create( - user_uuid="user_uuid", -) +client.lookup.batch() ```
@@ -3267,7 +3261,15 @@ client.thread.create(
-**user_uuid:** `str` — The UUID of the user this thread belongs to. +**graphs:** `typing.Optional[typing.List[str]]` — Developer-assigned graph IDs to resolve to UUIDs. + +
+
+ +
+
+ +**threads:** `typing.Optional[typing.List[str]]` — Developer-assigned thread IDs to resolve to UUIDs.
@@ -3275,7 +3277,7 @@ client.thread.create(
-**thread_id:** `typing.Optional[str]` — An optional developer-assigned identifier for the thread. +**users:** `typing.Optional[typing.List[str]]` — Developer-assigned user IDs to resolve to UUIDs.
@@ -3295,7 +3297,8 @@ client.thread.create(
-
client.thread.lookup(...) -> Thread +## Project +
client.project.get() -> Project
@@ -3316,7 +3319,7 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.thread.lookup() +client.project.get() ```
@@ -3332,14 +3335,6 @@ client.thread.lookup()
-**request:** `LookupRequest` - -
-
- -
-
- **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -3352,7 +3347,7 @@ client.thread.lookup()
-
client.thread.get(...) -> Thread +
client.project.update(...) -> Project
@@ -3373,9 +3368,7 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.thread.get( - thread_uuid="thread_uuid", -) +client.project.update() ```
@@ -3391,7 +3384,21 @@ client.thread.get(
-**thread_uuid:** `str` — Thread UUID +**default_time_zone:** `typing.Optional[str]` + +The project's IANA fallback time zone. Set to null to clear the existing +value. + +
+
+ +
+
+ +**include_policy_violating_episodes:** `typing.Optional[bool]` + +When true, episode reads on graphs with a content policy include the +episodes that violated the policy.
@@ -3411,10 +3418,24 @@ client.thread.get(
-
client.thread.delete(...) -> ThreadDeleteResult +
client.project.get_content_policy() -> ContentPolicy +
+
+ +#### 📝 Description + +
+
+
+Returns the current content policy revision of the project. A new graph binds this revision at creation. +
+
+
+
+ #### 🔌 Usage
@@ -3432,9 +3453,7 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.thread.delete( - thread_uuid="thread_uuid", -) +client.project.get_content_policy() ```
@@ -3450,14 +3469,6 @@ client.thread.delete(
-**thread_uuid:** `str` — Thread UUID - -
-
- -
-
- **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -3470,10 +3481,24 @@ client.thread.delete(
-
client.thread.get_context(...) -> ThreadContextResponse +
client.project.set_content_policy(...) -> ContentPolicy +
+
+ +#### 📝 Description +
+
+
+ +Replaces the project content policy and creates a new immutable revision. Graphs that already exist keep the revision they bound. An empty policy (no categories and no rules) removes the content policy for new graphs. +
+
+
+
+ #### 🔌 Usage
@@ -3491,10 +3516,7 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.thread.get_context( - thread_uuid="thread_uuid", - template_uuid="template_uuid", -) +client.project.set_content_policy() ```
@@ -3510,7 +3532,10 @@ client.thread.get_context(
-**thread_uuid:** `str` — Thread UUID +**categories:** `typing.Optional[typing.List[ContentPolicyCategoryRequest]]` + +The categories of the policy. Maximum 16. An empty list with no rules +means no content policy.
@@ -3518,7 +3543,7 @@ client.thread.get_context(
-**template_uuid:** `typing.Optional[str]` — Context template UUID +**rules:** `typing.Optional[typing.List[ContentPolicyRuleRequest]]` — The rules of the policy. Maximum 32.
@@ -3538,10 +3563,24 @@ client.thread.get_context(
-
client.thread.list_episodes(...) -> EpisodePage +
client.project.list_content_policy_revisions(...) -> ContentPolicyRevisionPage +
+
+ +#### 📝 Description + +
+
+
+Lists every revision of the project content policy, newest first, including revision 0. +
+
+
+
+ #### 🔌 Usage
@@ -3559,11 +3598,7 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.thread.list_episodes( - thread_uuid="thread_uuid", - limit=1, - cursor="cursor", -) +client.project.list_content_policy_revisions() ```
@@ -3579,14 +3614,6 @@ client.thread.list_episodes(
-**thread_uuid:** `str` — Thread UUID - -
-
- -
-
- **limit:** `typing.Optional[int]` — Page size
@@ -3615,7 +3642,7 @@ client.thread.list_episodes(
-
client.thread.list_messages(...) -> MessagePage +
client.project.get_content_policy_revision(...) -> ContentPolicy
@@ -3636,10 +3663,8 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.thread.list_messages( - thread_uuid="thread_uuid", - limit=1, - cursor="cursor", +client.project.get_content_policy_revision( + revision_uuid="revision_uuid", ) ``` @@ -3656,23 +3681,7 @@ client.thread.list_messages(
-**thread_uuid:** `str` — Thread UUID - -
-
- -
-
- -**limit:** `typing.Optional[int]` — Page size - -
-
- -
-
- -**cursor:** `typing.Optional[str]` — Opaque page cursor +**revision_uuid:** `str` — Revision UUID
@@ -3692,7 +3701,7 @@ client.thread.list_messages(
-
client.thread.add_messages(...) -> AddMessagesResult +
client.project.get_instructions() -> Instructions
@@ -3705,7 +3714,7 @@ client.thread.list_messages(
```python -from zep_cloud import Zep, AddMessage +from zep_cloud import Zep from zep_cloud.environment import ZepEnvironment client = Zep( @@ -3713,12 +3722,7 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.thread.add_messages( - thread_uuid="thread_uuid", - messages=[ - AddMessage() - ], -) +client.project.get_instructions() ```
@@ -3734,34 +3738,1159 @@ client.thread.add_messages(
-**thread_uuid:** `str` — Thread UUID +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+ +
-
-
-**messages:** `typing.List[AddMessage]` — The messages to add to the thread. -
+
+
client.project.set_instructions(...) -> Instructions
-**ignore_roles:** `typing.Optional[typing.List[str]]` - -Message roles to skip during graph extraction; the messages are still -stored. - -
-
+#### 🔌 Usage
-**return_context:** `typing.Optional[bool]` +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.project.set_instructions() + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Instructions` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + + + +
+ +
client.project.get_observation_steering() -> ObservationSteering +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.project.get_observation_steering() + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.project.set_observation_steering(...) -> ObservationSteering +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.project.set_observation_steering() + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `ObservationSteering` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.project.get_ontology() -> Ontology +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.project.get_ontology() + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.project.set_ontology(...) -> Ontology +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Replaces the entity types and the edge types that the project uses. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.project.set_ontology() + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Ontology` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.project.get_user_summary_instructions() -> UserSummaryInstructions +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.project.get_user_summary_instructions() + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.project.set_user_summary_instructions(...) -> UserSummaryInstructions +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.project.set_user_summary_instructions() + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `UserSummaryInstructions` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +## Task +
client.task.list(...) -> TaskPage +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.task.list() + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Page size + +
+
+ +
+
+ +**cursor:** `typing.Optional[str]` — Opaque page cursor + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.task.get(...) -> Task +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.task.get( + task_uuid="task_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**task_uuid:** `str` — Task UUID + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +## Thread +
client.thread.list(...) -> ThreadPage +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.thread.list() + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Page size + +
+
+ +
+
+ +**cursor:** `typing.Optional[str]` — Opaque page cursor + +
+
+ +
+
+ +**order_by:** `typing.Optional[ThreadListRequestOrderBy]` — Sort field + +
+
+ +
+
+ +**order:** `typing.Optional[ThreadListRequestOrder]` — asc or desc + +
+
+ +
+
+ +**user_uuid:** `typing.Optional[str]` — Filter by user UUID + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.thread.create(...) -> Thread +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.thread.create( + user_uuid="user_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**user_uuid:** `str` — The UUID of the user this thread belongs to. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.thread.lookup(...) -> Thread +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.thread.lookup() + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `LookupRequest` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.thread.get(...) -> Thread +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.thread.get( + thread_uuid="thread_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**thread_uuid:** `str` — Thread UUID + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.thread.delete(...) -> ThreadDeleteResult +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.thread.delete( + thread_uuid="thread_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**thread_uuid:** `str` — Thread UUID + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.thread.get_context(...) -> ThreadContextResponse +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.thread.get_context( + thread_uuid="thread_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**thread_uuid:** `str` — Thread UUID + +
+
+ +
+
+ +**template_uuid:** `typing.Optional[str]` — Context template UUID + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.thread.list_episodes(...) -> EpisodePage +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.thread.list_episodes( + thread_uuid="thread_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**thread_uuid:** `str` — Thread UUID + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Page size + +
+
+ +
+
+ +**cursor:** `typing.Optional[str]` — Opaque page cursor + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.thread.list_messages(...) -> MessagePage +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.thread.list_messages( + thread_uuid="thread_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**thread_uuid:** `str` — Thread UUID + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Page size + +
+
+ +
+
+ +**cursor:** `typing.Optional[str]` — Opaque page cursor + +
+
+ +
+
+ +**order_by:** `typing.Optional[typing.Literal]` — Sort field + +
+
+ +
+
+ +**order:** `typing.Optional[ThreadListMessagesRequestOrder]` — Sort direction: asc or desc + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.thread.add_messages(...) -> AddMessagesResult +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep, AddMessage +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.thread.add_messages( + thread_uuid="thread_uuid", + messages=[ + AddMessage() + ], +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**thread_uuid:** `str` — Thread UUID + +
+
+ +
+
+ +**messages:** `typing.List[AddMessage]` — The messages to add to the thread. + +
+
+ +
+
+ +**ignore_roles:** `typing.Optional[typing.List[str]]` + +Message roles to skip during graph extraction; the messages are still +stored. + +
+
+ +
+
+ +**return_context:** `typing.Optional[bool]` When true, returns the context block for the thread's most recent messages. @@ -3772,10 +4901,6922 @@ messages.
-**strict_ontology:** `typing.Optional[bool]` +**strict_ontology:** `typing.Optional[bool]` + +When true, prevents extraction of generic entity nodes that do not match +the configured ontology. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.thread.get_summary(...) -> ThreadSummary +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.thread.get_summary( + thread_uuid="thread_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**thread_uuid:** `str` — Thread UUID + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +## TraceConnection +
client.trace_connection.list(...) -> TraceConnectionPage +
+
+ +#### 📝 Description + +
+
+ +
+
+ +List trace connections in the current Zep project. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.trace_connection.list() + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Page size + +
+
+ +
+
+ +**cursor:** `typing.Optional[str]` — Opaque page cursor + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.trace_connection.create(...) -> TraceConnection +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Verify the provider credential before Zep stores it. Example request: `{"name":"Support traces","provider":"braintrust","credential":"secret","requests_per_minute":10}`. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.trace_connection.create() + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**api_url:** `typing.Optional[str]` — APIURL is an optional custom provider endpoint. + +
+
+ +
+
+ +**credential:** `typing.Optional[str]` — Credential is the write-only provider credential. + +
+
+ +
+
+ +**name:** `typing.Optional[str]` — Name is the connection name. + +
+
+ +
+
+ +**provider:** `typing.Optional[str]` — Provider is the provider name. + +
+
+ +
+
+ +**requests_per_minute:** `typing.Optional[int]` — RequestsPerMinute is the provider request rate limit. + +
+
+ +
+
+ +**retention_days:** `typing.Optional[int]` — RetentionDays is an optional provider retention window. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.trace_connection.get(...) -> TraceConnection +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Read one trace connection. The response includes a credential hint and never includes the credential. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.trace_connection.get( + connection_uuid="connection_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**connection_uuid:** `str` — Trace connection UUID + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.trace_connection.delete(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Delete a trace connection that no active trajectory import uses. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.trace_connection.delete( + connection_uuid="connection_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**connection_uuid:** `str` — Trace connection UUID + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.trace_connection.update(...) -> TraceConnection +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Verify changed provider settings before Zep stores them. Example request: `{"credential":"new-secret","requests_per_minute":20}`. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.trace_connection.update( + connection_uuid="connection_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**connection_uuid:** `str` — Trace connection UUID + +
+
+ +
+
+ +**api_url:** `typing.Optional[str]` — APIURL is the new custom provider endpoint, when supplied. + +
+
+ +
+
+ +**credential:** `typing.Optional[str]` — Credential is the new write-only provider credential, when supplied. + +
+
+ +
+
+ +**name:** `typing.Optional[str]` — Name is the new connection name, when supplied. + +
+
+ +
+
+ +**requests_per_minute:** `typing.Optional[int]` — RequestsPerMinute is the new provider request rate limit, when supplied. + +
+
+ +
+
+ +**retention_days:** `typing.Optional[int]` — RetentionDays is the new provider retention window, when supplied. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.trace_connection.verify(...) -> TraceConnection +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Check the provider credential and update the connection status. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.trace_connection.verify( + connection_uuid="connection_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**connection_uuid:** `str` — Trace connection UUID + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +## UserGroup +
client.user_group.create(...) -> UserGroup +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.user_group.create( + name="name", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**name:** `str` — The name of the user group. + +
+
+ +
+
+ +**description:** `typing.Optional[str]` — A description of the user group. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.user_group.list(...) -> UserGroupPage +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.user_group.list() + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `SearchListRequest` + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Page size + +
+
+ +
+
+ +**cursor:** `typing.Optional[str]` — Opaque page cursor + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.user_group.get(...) -> UserGroup +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.user_group.get( + group_uuid="group_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**group_uuid:** `str` — User group UUID + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.user_group.delete(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.user_group.delete( + group_uuid="group_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**group_uuid:** `str` — User group UUID + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.user_group.update(...) -> UserGroup +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.user_group.update( + group_uuid="group_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**group_uuid:** `str` — User group UUID + +
+
+ +
+
+ +**description:** `typing.Optional[str]` — A description of the user group. + +
+
+ +
+
+ +**expected_version:** `typing.Optional[int]` — The user group's current version, used to detect concurrent updates. + +
+
+ +
+
+ +**name:** `typing.Optional[str]` — The name of the user group. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.user_group.list_member_candidates(...) -> UserPage +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.user_group.list_member_candidates( + group_uuid="group_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**group_uuid:** `str` — User group UUID + +
+
+ +
+
+ +**request:** `SearchListRequest` + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Page size + +
+
+ +
+
+ +**cursor:** `typing.Optional[str]` — Opaque page cursor + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.user_group.add_members(...) -> MembershipMutationResult +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.user_group.add_members( + group_uuid="group_uuid", + user_uuids=[ + "user_uuids" + ], +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**group_uuid:** `str` — User group UUID + +
+
+ +
+
+ +**request:** `MutateMembersRequest` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.user_group.list_members(...) -> UserPage +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.user_group.list_members( + group_uuid="group_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**group_uuid:** `str` — User group UUID + +
+
+ +
+
+ +**request:** `SearchListRequest` + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Page size + +
+
+ +
+
+ +**cursor:** `typing.Optional[str]` — Opaque page cursor + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.user_group.remove_members(...) -> MembershipMutationResult +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.user_group.remove_members( + group_uuid="group_uuid", + user_uuids=[ + "user_uuids" + ], +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**group_uuid:** `str` — User group UUID + +
+
+ +
+
+ +**request:** `MutateMembersRequest` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.user_group.remove_member(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.user_group.remove_member( + group_uuid="group_uuid", + user_uuid="user_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**group_uuid:** `str` — User group UUID + +
+
+ +
+
+ +**user_uuid:** `str` — User UUID + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.user_group.list_for_user(...) -> UserGroupPage +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.user_group.list_for_user( + user_uuid="user_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**user_uuid:** `str` — User UUID + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Page size + +
+
+ +
+
+ +**cursor:** `typing.Optional[str]` — Opaque page cursor + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +## User +
client.user.create(...) -> User +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.user.create() + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**content_policy:** `typing.Optional[GraphContentPolicyRequest]` + +Content policy additions for the user's graph. The graph binds the +current project content policy plus these additions, and the binding +does not change after creation. + +
+
+ +
+
+ +**disable_default_ontology:** `typing.Optional[bool]` — When true, disables the default ontology for the user's graph. + +
+
+ +
+
+ +**email:** `typing.Optional[str]` — The email address of the user. + +
+
+ +
+
+ +**first_name:** `typing.Optional[str]` — The user's first name. + +
+
+ +
+
+ +**last_name:** `typing.Optional[str]` — The user's last name. + +
+
+ +
+
+ +**metadata:** `typing.Optional[typing.Dict[str, typing.Any]]` — Metadata to store on the user. + +
+
+ +
+
+ +**time_zone:** `typing.Optional[str]` — The user's IANA time zone. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.user.list(...) -> UserPage +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.user.list() + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Page size + +
+
+ +
+
+ +**cursor:** `typing.Optional[str]` — Opaque page cursor + +
+
+ +
+
+ +**order_by:** `typing.Optional[UserListRequestOrderBy]` — Sort field + +
+
+ +
+
+ +**order:** `typing.Optional[UserListRequestOrder]` — asc or desc + +
+
+ +
+
+ +**search:** `typing.Optional[str]` — Filters results to users whose user ID, email, or name contains this text. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.user.lookup(...) -> User +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.user.lookup() + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `LookupRequest` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.user.get(...) -> User +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.user.get( + user_uuid="user_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**user_uuid:** `str` — User UUID + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.user.delete(...) -> UserDeleteResult +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.user.delete( + user_uuid="user_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**user_uuid:** `str` — User UUID + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.user.update(...) -> User +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.user.update( + user_uuid="user_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**user_uuid:** `str` — User UUID + +
+
+ +
+
+ +**disable_default_ontology:** `typing.Optional[bool]` — When true, disables the default ontology for the user's graph. + +
+
+ +
+
+ +**email:** `typing.Optional[str]` — The email address of the user. + +
+
+ +
+
+ +**first_name:** `typing.Optional[str]` — The user's first name. + +
+
+ +
+
+ +**last_name:** `typing.Optional[str]` — The user's last name. + +
+
+ +
+
+ +**metadata:** `typing.Optional[typing.Dict[str, typing.Any]]` — Metadata to merge onto the user; a key set to null is removed. + +
+
+ +
+
+ +**time_zone:** `typing.Optional[str]` — The user's IANA time zone. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.user.get_node(...) -> Node +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.user.get_node( + user_uuid="user_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**user_uuid:** `str` — User UUID + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.user.get_summary_instructions(...) -> UserSummaryInstructions +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.user.get_summary_instructions( + user_uuid="user_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**user_uuid:** `str` — User UUID + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.user.set_summary_instructions(...) -> UserSummaryInstructions +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.user.set_summary_instructions( + user_uuid="user_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**user_uuid:** `str` — User UUID + +
+
+ +
+
+ +**request:** `UserSummaryInstructions` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +## Agent Learning +
client.agent.learning.get(...) -> AgentLearningState +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.learning.get( + agent_uuid="agent_uuid", + task_family="task_family", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**task_family:** `str` — Task family + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agent.learning.list_runs(...) -> Pagev4AgentSkillCompilationOutcome +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.learning.list_runs( + agent_uuid="agent_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**task_family:** `typing.Optional[str]` — Task family + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Page size + +
+
+ +
+
+ +**cursor:** `typing.Optional[str]` — Opaque page cursor + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +## Agent LiteralPolicy +
client.agent.literal_policy.get(...) -> AgentLiteralPolicy +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.literal_policy.get( + agent_uuid="agent_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agent.literal_policy.update(...) -> AgentLiteralPolicy +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep, AgentLiteralPolicyClasses, AgentLiteralPolicyValues +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.literal_policy.update( + agent_uuid="agent_uuid", + allowlisted_classes=AgentLiteralPolicyClasses( + environments=[ + "environments" + ], + tools=[ + "tools" + ], + ), + allowlisted_values=AgentLiteralPolicyValues( + environments=[ + "environments" + ], + tools=[ + "tools" + ], + ), + default="parameterize", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**allowlisted_classes:** `AgentLiteralPolicyClasses` — Typed reusable literal classes. + +
+
+ +
+
+ +**allowlisted_values:** `AgentLiteralPolicyValues` — Exact reusable values scoped by tools and environments. + +
+
+ +
+
+ +**default:** `UpdateAgentLiteralPolicyRequestDefault` — The remediation for literals that are not explicitly allowed. + +
+
+ +
+
+ +**expected_revision:** `typing.Optional[int]` — The current literal-policy revision used for optimistic concurrency. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +## Agent Skill +
client.agent.skill.create(...) -> AgentSkill +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep, SkillDefinition +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.skill.create( + agent_uuid="agent_uuid", + definition=SkillDefinition(), +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**definition:** `SkillDefinition` + +
+
+ +
+
+ +**skill_id:** `typing.Optional[str]` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agent.skill.import_package(...) -> Task +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Submit a portable Skill archive. The completed Task returns `{"result":{"skill_uuid":""}}`. Approve that Skill before retrieval. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +client.agent.skill.import_package(...) +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**request:** `typing.Union[bytes, typing.Iterator[bytes], typing.AsyncIterator[bytes]]` — Portable Skill ZIP archive + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agent.skill.list(...) -> Pagev4AgentSkillSearchHit +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.skill.list( + agent_uuid="agent_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Page size (maximum 20) + +
+
+ +
+
+ +**cursor:** `typing.Optional[str]` — Opaque page cursor + +
+
+ +
+
+ +**environments:** `typing.Optional[typing.List[str]]` + +
+
+ +
+
+ +**kind:** `typing.Optional[str]` + +
+
+ +
+
+ +**task_family:** `typing.Optional[str]` + +
+
+ +
+
+ +**tools:** `typing.Optional[typing.List[str]]` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agent.skill.search(...) -> AgentSkillSearchResponse +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.skill.search( + agent_uuid="agent_uuid", + query="query", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**query:** `str` + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Page size (maximum 20) + +
+
+ +
+
+ +**cursor:** `typing.Optional[str]` — Opaque page cursor + +
+
+ +
+
+ +**environments:** `typing.Optional[typing.List[str]]` + +
+
+ +
+
+ +**include_markdown:** `typing.Optional[bool]` + +
+
+ +
+
+ +**kind:** `typing.Optional[str]` + +
+
+ +
+
+ +**markdown_format:** `typing.Optional[AgentSkillSearchRequestMarkdownFormat]` + +MarkdownFormat selects the form of inline `markdown`. `agent` (the +default) returns the Skill text that an Agent needs: no evidence +markers, the description only in the frontmatter, and no empty +sections. `full` returns the stored SKILL.md with its evidence markers. + +
+
+ +
+
+ +**task_family:** `typing.Optional[str]` + +
+
+ +
+
+ +**tools:** `typing.Optional[typing.List[str]]` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agent.skill.get(...) -> AgentSkill +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.skill.get( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**skill_uuid:** `str` — Skill UUID + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agent.skill.approve(...) -> AgentSkillAdmissionDecision +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.skill.approve( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + expected_version=1, +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**skill_uuid:** `str` — Skill UUID + +
+
+ +
+
+ +**expected_version:** `int` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agent.skill.retire(...) -> AgentSkill +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.skill.retire( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + expected_version=1, +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**skill_uuid:** `str` — Skill UUID + +
+
+ +
+
+ +**expected_version:** `int` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agent.skill.create_version(...) -> AgentSkillVersion +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep, SkillDefinition +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.skill.create_version( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + definition=SkillDefinition(), + expected_version=1, +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**skill_uuid:** `str` — Skill UUID + +
+
+ +
+
+ +**definition:** `SkillDefinition` + +
+
+ +
+
+ +**expected_version:** `int` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +## Agent Split +
client.agent.split.plan(...) -> AgentSplitPlan +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep, AgentSplitPlanDestinationRequest, CreateAgentRequest, AgentSplitPlanSkillSelectionRequest +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.split.plan( + agent_uuid="agent_uuid", + destinations=[ + AgentSplitPlanDestinationRequest( + agent=CreateAgentRequest( + agent_id="agent_id", + name="name", + security_domain="security_domain", + ), + skills=[ + AgentSplitPlanSkillSelectionRequest( + skill_uuid="skill_uuid", + skill_version_uuid="skill_version_uuid", + version=1, + ) + ], + ) + ], + expected_revision=1, + rationale="rationale", + review_acknowledged=True, +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Source Agent UUID + +
+
+ +
+
+ +**destinations:** `typing.List[AgentSplitPlanDestinationRequest]` + +
+
+ +
+
+ +**expected_revision:** `int` + +
+
+ +
+
+ +**rationale:** `str` + +
+
+ +
+
+ +**review_acknowledged:** `bool` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +## Agent Trajectory +
client.agent.trajectory.create(...) -> AgentTrajectory +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.trajectory.create( + agent_uuid="agent_uuid", + objective="objective", + task_family="task_family", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**objective:** `str` — The task-instance objective captured for this attempt. + +
+
+ +
+
+ +**task_family:** `str` — The task-family slug. + +
+
+ +
+
+ +**learn_from:** `typing.Optional[bool]` — Whether eligible evidence may participate in learning. Defaults to true. + +
+
+ +
+
+ +**metadata:** `typing.Optional[typing.Dict[str, typing.Any]]` — Developer metadata used to organize and filter Trajectories. + +
+
+ +
+
+ +**parent_trajectory_uuid:** `typing.Optional[str]` — The parent Trajectory UUID when this attempt retries an earlier attempt. + +
+
+ +
+
+ +**trajectory_id:** `typing.Optional[str]` — The optional customer-assigned identifier, unique within the Agent. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agent.trajectory.list(...) -> AgentTrajectoryPage +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.trajectory.list( + agent_uuid="agent_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Page size (maximum 100) + +
+
+ +
+
+ +**cursor:** `typing.Optional[str]` — Opaque page cursor + +
+
+ +
+
+ +**import_uuid:** `typing.Optional[str]` — Filter by owning Trajectory import UUID + +
+
+ +
+
+ +**source_kind:** `typing.Optional[TrajectoryListRequestSourceKind]` — Source kind + +
+
+ +
+
+ +**metadata:** `typing.Optional[typing.Dict[str, typing.Any]]` — Filters to Trajectories whose metadata contains these key-value pairs. + +
+
+ +
+
+ +**outcome:** `typing.Optional[AgentTrajectoryOutcome]` — Filters to one reported outcome. + +
+
+ +
+
+ +**parent_trajectory_uuid:** `typing.Optional[str]` — Filters to direct retries of this parent Trajectory. + +
+
+ +
+
+ +**status:** `typing.Optional[AgentTrajectoryLifecycle]` — Filters to one lifecycle state. + +
+
+ +
+
+ +**task_family:** `typing.Optional[str]` — Filters to an exact task-family slug. + +
+
+ +
+
+ +**verification:** `typing.Optional[AgentTrajectoryVerification]` — Filters to one verification strength. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agent.trajectory.get(...) -> AgentTrajectory +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.trajectory.get( + agent_uuid="agent_uuid", + trajectory_uuid="trajectory_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**trajectory_uuid:** `str` — Trajectory UUID + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agent.trajectory.delete(...) -> AgentTrajectorySourceDeletionResult +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.trajectory.delete( + agent_uuid="agent_uuid", + trajectory_uuid="trajectory_uuid", + expected_revision=1, +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**trajectory_uuid:** `str` — Trajectory UUID + +
+
+ +
+
+ +**request:** `DeleteAgentTrajectoryRequest` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agent.trajectory.update(...) -> AgentTrajectory +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.trajectory.update( + agent_uuid="agent_uuid", + trajectory_uuid="trajectory_uuid", + expected_revision=1, +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**trajectory_uuid:** `str` — Trajectory UUID + +
+
+ +
+
+ +**expected_revision:** `int` — The current Trajectory revision used for optimistic concurrency. + +
+
+ +
+
+ +**task_family:** `typing.Optional[str]` — Replacement task-family slug. Set to null to clear it. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agent.trajectory.abandon(...) -> AgentTrajectoryFinalizationResult +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.trajectory.abandon( + agent_uuid="agent_uuid", + trajectory_uuid="trajectory_uuid", + highest_accepted_sequence=1, +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**trajectory_uuid:** `str` — Trajectory UUID + +
+
+ +
+
+ +**highest_accepted_sequence:** `int` + +
+
+ +
+
+ +**assertion_uuid:** `typing.Optional[str]` + +
+
+ +
+
+ +**expected_revision:** `typing.Optional[int]` + +
+
+ +
+
+ +**missing_sequence_ranges:** `typing.Optional[typing.List[AgentTrajectorySequenceRange]]` + +
+
+ +
+
+ +**reason:** `typing.Optional[str]` + +
+
+ +
+
+ +**verification:** `typing.Optional[AgentTrajectoryVerification]` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agent.trajectory.close(...) -> AgentTrajectoryFinalizationResult +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.trajectory.close( + agent_uuid="agent_uuid", + trajectory_uuid="trajectory_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**trajectory_uuid:** `str` — Trajectory UUID + +
+
+ +
+
+ +**closing_sequence:** `typing.Optional[int]` + +
+
+ +
+
+ +**expected_revision:** `typing.Optional[int]` + +
+
+ +
+
+ +**missing_sequence_ranges:** `typing.Optional[typing.List[AgentTrajectorySequenceRange]]` + +
+
+ +
+
+ +**outcome:** `typing.Optional[AgentTrajectoryOutcome]` + +
+
+ +
+
+ +**reason:** `typing.Optional[str]` + +
+
+ +
+
+ +**verification:** `typing.Optional[AgentTrajectoryVerification]` + +
+
+ +
+
+ +**verifier:** `typing.Optional[AgentTrajectoryCloseVerifier]` + +
+
+ +
+
+ +**verifier_id:** `typing.Optional[str]` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agent.trajectory.correct_task_family(...) -> AgentTrajectoryFinalizationResult +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.trajectory.correct_task_family( + agent_uuid="agent_uuid", + trajectory_uuid="trajectory_uuid", + expected_revision=1, + reason="reason", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**trajectory_uuid:** `str` — Trajectory UUID + +
+
+ +
+
+ +**expected_revision:** `int` — The current Trajectory revision used for optimistic concurrency. + +
+
+ +
+
+ +**reason:** `str` — Why the terminal Trajectory classification is being corrected. + +
+
+ +
+
+ +**task_family:** `typing.Optional[str]` — Replacement task-family slug. Set to null to clear it. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agent.trajectory.list_events(...) -> AgentTrajectoryEventPage +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.trajectory.list_events( + agent_uuid="agent_uuid", + trajectory_uuid="trajectory_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**trajectory_uuid:** `str` — Trajectory UUID + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Page size (maximum 100) + +
+
+ +
+
+ +**cursor:** `typing.Optional[str]` — Opaque page cursor + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agent.trajectory.append_event(...) -> AgentTrajectoryEvent +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.trajectory.append_event( + agent_uuid="agent_uuid", + trajectory_uuid="trajectory_uuid", + event_type="input_reference", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**trajectory_uuid:** `str` — Trajectory UUID + +
+
+ +
+
+ +**event_type:** `AgentTrajectoryEventType` + +
+
+ +
+
+ +**content:** `typing.Optional[str]` + +
+
+ +
+
+ +**context:** `typing.Optional[AgentTrajectoryEventContext]` + +
+
+ +
+
+ +**event_id:** `typing.Optional[str]` + +
+
+ +
+
+ +**metadata:** `typing.Optional[typing.Dict[str, typing.Any]]` + +
+
+ +
+
+ +**occurred_at:** `typing.Optional[str]` + +
+
+ +
+
+ +**sequence:** `typing.Optional[int]` + +
+
+ +
+
+ +**sources:** `typing.Optional[typing.List[AgentTrajectoryEventSource]]` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agent.trajectory.delete_event(...) -> AgentTrajectorySourceDeletionResult +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.trajectory.delete_event( + agent_uuid="agent_uuid", + trajectory_uuid="trajectory_uuid", + event_uuid="event_uuid", + expected_revision=1, +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**trajectory_uuid:** `str` — Trajectory UUID + +
+
+ +
+
+ +**event_uuid:** `str` — Event UUID + +
+
+ +
+
+ +**request:** `DeleteAgentTrajectoryRequest` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agent.trajectory.reopen(...) -> AgentTrajectory +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.trajectory.reopen( + agent_uuid="agent_uuid", + trajectory_uuid="trajectory_uuid", + expected_revision=1, +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**trajectory_uuid:** `str` — Trajectory UUID + +
+
+ +
+
+ +**expected_revision:** `int` — The current Trajectory revision used for optimistic concurrency. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agent.trajectory.get_summary(...) -> AgentTrajectorySummaryVersion +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.trajectory.get_summary( + agent_uuid="agent_uuid", + trajectory_uuid="trajectory_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**trajectory_uuid:** `str` — Trajectory UUID + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agent.trajectory.list_summary_versions(...) -> AgentTrajectorySummaryPage +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.trajectory.list_summary_versions( + agent_uuid="agent_uuid", + trajectory_uuid="trajectory_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**trajectory_uuid:** `str` — Trajectory UUID + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Page size (maximum 100) + +
+
+ +
+
+ +**cursor:** `typing.Optional[str]` — Opaque page cursor + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +## Agent TrajectoryImport +
client.agent.trajectory_import.list(...) -> TrajectoryImportPage +
+
+ +#### 📝 Description + +
+
+ +
+
+ +List trajectory imports that belong to this Agent. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.trajectory_import.list( + agent_uuid="agent_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Page size + +
+
+ +
+
+ +**cursor:** `typing.Optional[str]` — Opaque page cursor + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agent.trajectory_import.create(...) -> TrajectoryImport +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Create a scheduled import or queue a one-time import. Example request: `{"connection_uuid":"8c78a85e-eac2-4f57-b5f5-59a68a1e77a1","provider_project_id":"project-123","name":"Support traces","selection":{"trace_ids":["trace-123"]},"mapping":{"task_family":{"source":"fixed","value":"support"}}}`. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.trajectory_import.create( + agent_uuid="agent_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**connection_uuid:** `typing.Optional[str]` — ConnectionUUID identifies the project trace connection. + +
+
+ +
+
+ +**learn_from:** `typing.Optional[bool]` — LearnFrom controls whether imported evidence can support Skills. + +
+
+ +
+
+ +**mapping:** `typing.Optional[TrajectoryMapping]` — Mapping defines how source traces become Trajectories. Example: {"task_family":{"source":"fixed","value":"support"}}. + +
+
+ +
+
+ +**name:** `typing.Optional[str]` — Name is the import display name. + +
+
+ +
+
+ +**on_source_change:** `typing.Optional[str]` — OnSourceChange defines how changed source traces are handled. + +
+
+ +
+
+ +**provider_project_id:** `typing.Optional[str]` — ProviderProjectID is the source provider project identifier. + +
+
+ +
+
+ +**require_review:** `typing.Optional[bool]` — RequireReview requires review for candidates backed by this import. + +
+
+ +
+
+ +**schedule:** `typing.Optional[TrajectoryImportSchedule]` — Schedule enables recurring imports when supplied. Example: {"interval_hours":4,"start_from":"24h","settle_minutes":5,"max_open_hours":24}. + +
+
+ +
+
+ +**selection:** `typing.Optional[TrajectoryImportSelection]` — Selection defines the traces to import. Example: {"trace_ids":["trace_123"]}. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agent.trajectory_import.get(...) -> TrajectoryImport +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Read one trajectory import. The response does not include its source cursor. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.trajectory_import.get( + agent_uuid="agent_uuid", + import_uuid="import_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**import_uuid:** `str` — Trajectory import UUID + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agent.trajectory_import.delete(...) -> typing.Optional[Task] +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Set `trajectories=delete` to queue asynchronous Trajectory deletion. The default keeps Trajectories. Example query: `?trajectories=delete`. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.trajectory_import.delete( + agent_uuid="agent_uuid", + import_uuid="import_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**import_uuid:** `str` — Trajectory import UUID + +
+
+ +
+
+ +**trajectories:** `typing.Optional[TrajectoryImportDeleteRequestTrajectories]` — Whether to delete imported Trajectories + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agent.trajectory_import.update(...) -> TrajectoryImport +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Use `expected_revision` to reject a stale update. Example request: `{"expected_revision":1,"name":"Updated support traces"}`. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.trajectory_import.update( + agent_uuid="agent_uuid", + import_uuid="import_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**import_uuid:** `str` — Trajectory import UUID + +
+
+ +
+
+ +**expected_revision:** `typing.Optional[int]` — ExpectedRevision is the current import revision. + +
+
+ +
+
+ +**learn_from:** `typing.Optional[bool]` — LearnFrom is the new learning setting, when supplied. + +
+
+ +
+
+ +**mapping:** `typing.Optional[TrajectoryMapping]` — Mapping is the new mapping, when supplied. Example: {"task_family":{"source":"fixed","value":"support"}}. + +
+
+ +
+
+ +**name:** `typing.Optional[str]` — Name is the new import name, when supplied. + +
+
+ +
+
+ +**on_source_change:** `typing.Optional[str]` — OnSourceChange is the new change policy, when supplied. + +
+
+ +
+
+ +**require_review:** `typing.Optional[bool]` — RequireReview is the new review setting, when supplied. + +
+
+ +
+
+ +**schedule:** `typing.Optional[TrajectoryImportSchedule]` — Schedule is the new schedule, when supplied. Example: {"interval_hours":4,"start_from":"24h","settle_minutes":5,"max_open_hours":24}. + +
+
+ +
+
+ +**selection:** `typing.Optional[TrajectoryImportSelection]` — Selection is the new selection, when supplied. Example: {"trace_ids":["trace_123"]}. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agent.trajectory_import.pause(...) -> TrajectoryImport +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Pause a scheduled trajectory import. One-time imports cannot be paused. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.trajectory_import.pause( + agent_uuid="agent_uuid", + import_uuid="import_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**import_uuid:** `str` — Trajectory import UUID + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agent.trajectory_import.resume(...) -> TrajectoryImport +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Resume a scheduled trajectory import. Zep verifies credentials first when they caused the pause. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.trajectory_import.resume( + agent_uuid="agent_uuid", + import_uuid="import_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**import_uuid:** `str` — Trajectory import UUID + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +## Agent Verifier +
client.agent.verifier.list(...) -> Pagev4AgentVerifier +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.verifier.list( + agent_uuid="agent_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Page size + +
+
+ +
+
+ +**cursor:** `typing.Optional[str]` — Page cursor + +
+
+ +
+
+ +**class:** `typing.Optional[str]` — Filters to an exact immutable verifier class. + +
+
+ +
+
+ +**principal_id:** `typing.Optional[str]` — Filters to registrations bound to this exact principal identifier. + +
+
+ +
+
+ +**principal_type:** `typing.Optional[str]` — Filters to registrations bound to this principal type. + +
+
+ +
+
+ +**status:** `typing.Optional[AgentVerifierStatus]` — Filters to active or revoked registrations. Omit to include both. + +
+
+ +
+
+ +**verifier_id:** `typing.Optional[str]` — Filters to an exact developer-assigned verifier identifier. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agent.verifier.get(...) -> AgentVerifier +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.verifier.get( + agent_uuid="agent_uuid", + verifier_uuid="verifier_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**verifier_uuid:** `str` — Verifier UUID + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agent.verifier.update(...) -> AgentVerifier +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.verifier.update( + agent_uuid="agent_uuid", + verifier_uuid="verifier_uuid", + expected_revision=1, +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**verifier_uuid:** `str` — Verifier UUID + +
+
+ +
+
+ +**expected_revision:** `int` — The current verifier revision used for optimistic concurrency. + +
+
+ +
+
+ +**capabilities:** `typing.Optional[typing.Dict[str, typing.Any]]` — Replacement capabilities. Set to null to clear them. + +
+
+ +
+
+ +**metadata:** `typing.Optional[typing.Dict[str, typing.Any]]` — Replacement metadata. Set to null to clear it. + +
+
+ +
+
+ +**permitted_strengths:** `typing.Optional[typing.List[AgentVerificationStrength]]` — Replacement permitted strengths. The list cannot be empty or null. + +
+
+ +
+
+ +**principal_bindings:** `typing.Optional[typing.List[AgentVerifierPrincipalBindingInput]]` — Replacement exact principal bindings. The list cannot be empty or null. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agent.verifier.invalidate_evidence(...) -> AgentVerifierEvidenceInvalidationResult +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.verifier.invalidate_evidence( + agent_uuid="agent_uuid", + verifier_uuid="verifier_uuid", + reason="reason", + verifier_revisions=[ + 1 + ], +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**verifier_uuid:** `str` — Verifier UUID + +
+
+ +
+
+ +**reason:** `str` — Why evidence from these verifier revisions is invalid. + +
+
+ +
+
+ +**verifier_revisions:** `typing.List[int]` — Verifier revisions whose accepted evidence is no longer valid. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agent.verifier.revoke(...) -> AgentVerifier +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.verifier.revoke( + agent_uuid="agent_uuid", + verifier_uuid="verifier_uuid", + expected_revision=1, +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**verifier_uuid:** `str` — Verifier UUID + +
+
+ +
+
+ +**expected_revision:** `int` — The current verifier revision used for optimistic concurrency. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +## Agent Skill Candidate +
client.agent.skill.candidate.list(...) -> Pagev4AgentSkillCandidateReviewSummary +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.skill.candidate.list( + agent_uuid="agent_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Page size (maximum 100) + +
+
+ +
+
+ +**cursor:** `typing.Optional[str]` — Opaque page cursor + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agent.skill.candidate.get(...) -> AgentSkillCandidateReview +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.skill.candidate.get( + agent_uuid="agent_uuid", + review_uuid="review_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**review_uuid:** `str` — Candidate review UUID + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +## Agent Skill Evaluation +
client.agent.skill.evaluation.create_for_candidate(...) -> AgentSkillCandidateEvaluation +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.skill.evaluation.create_for_candidate( + agent_uuid="agent_uuid", + review_uuid="review_uuid", + candidate_uuid="candidate_uuid", + evaluated_by="customer", + evaluator_version="evaluator_version", + expected_revision=1, + verdict="succeeded", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**review_uuid:** `str` — Candidate review UUID + +
+
+ +
+
+ +**candidate_uuid:** `str` — Candidate UUID + +
+
+ +
+
+ +**evaluated_by:** `CreateAgentSkillCandidateEvaluationRequestEvaluatedBy` + +
+
+ +
+
+ +**evaluator_version:** `str` + +
+
+ +
+
+ +**expected_revision:** `int` + +
+
+ +
+
+ +**verdict:** `CreateAgentSkillCandidateEvaluationRequestVerdict` + +
+
+ +
+
+ +**controlled_test:** `typing.Optional[bool]` + +
+
+ +
+
+ +**environment:** `typing.Optional[str]` + +
+
+ +
+
+ +**evidence_reference:** `typing.Optional[str]` + +
+
+ +
+
+ +**metrics:** `typing.Optional[typing.Dict[str, float]]` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agent.skill.evaluation.create(...) -> AgentSkillEvaluation +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.skill.evaluation.create( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + evaluated_by="customer", + evaluator_version="evaluator_version", + skill_version=1, + verdict="succeeded", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**skill_uuid:** `str` — Skill UUID + +
+
+ +
+
+ +**evaluated_by:** `CreateAgentSkillEvaluationRequestEvaluatedBy` + +
+
+ +
+
+ +**evaluator_version:** `str` + +
+
+ +
+
+ +**skill_version:** `int` + +
+
+ +
+
+ +**verdict:** `CreateAgentSkillEvaluationRequestVerdict` + +
+
+ +
+
+ +**controlled_test:** `typing.Optional[bool]` + +
+
+ +
+
+ +**environment:** `typing.Optional[str]` + +
+
+ +
+
+ +**evidence_reference:** `typing.Optional[str]` + +
+
+ +
+
+ +**metrics:** `typing.Optional[typing.Dict[str, float]]` + +
+
+ +
+
+ +**use_uuid:** `typing.Optional[str]` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +## Agent Skill Publication +
client.agent.skill.publication.lookup(...) -> AgentSkillPublicationLineage +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Find a destination Skill by its source Agent, Skill, and version. The endpoint returns 404 until an automatic publication is ready or after it is invalidated. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.skill.publication.lookup( + agent_uuid="agent_uuid", + source_agent_uuid="source_agent_uuid", + source_skill_uuid="source_skill_uuid", + source_version=1, +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Destination Agent UUID + +
+
+ +
+
+ +**source_agent_uuid:** `str` — Source Agent UUID + +
+
+ +
+
+ +**source_skill_uuid:** `str` — Source Skill UUID + +
+
+ +
+
+ +**source_version:** `int` — Source version number + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agent.skill.publication.get(...) -> AgentSkillPublicationLineage +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Get the publication that created a destination Skill. Use its source version and policy identity to verify a copied Skill. The endpoint returns 404 for unpublished and invalidated Skills. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.skill.publication.get( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Destination Agent UUID + +
+
+ +
+
+ +**skill_uuid:** `str` — Destination Skill UUID + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +## Agent Skill Evidence +
client.agent.skill.evidence.list(...) -> Pagev4AgentSkillEvidence +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.skill.evidence.list( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**skill_uuid:** `str` — Skill UUID + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Page size (maximum 100) + +
+
+ +
+
+ +**cursor:** `typing.Optional[str]` — Opaque page cursor + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +## Agent Skill Relation +
client.agent.skill.relation.list(...) -> Pagev4AgentSkillRelationship +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.skill.relation.list( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**skill_uuid:** `str` — Skill UUID + +
+
+ +
+
+ +**kind:** `typing.Optional[typing.Union[RelationListRequestKindItem, typing.Sequence[RelationListRequestKindItem]]]` — Relationship kinds + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Page size (maximum 100) + +
+
+ +
+
+ +**cursor:** `typing.Optional[str]` — Opaque page cursor + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +## Agent Skill Version +
client.agent.skill.version.restore_version(...) -> AgentSkillVersion +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.skill.version.restore_version( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + expected_version=1, + version=1, +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**skill_uuid:** `str` — Skill UUID + +
+
+ +
+
+ +**expected_version:** `int` + +
+
+ +
+
+ +**version:** `int` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agent.skill.version.list(...) -> Pagev4AgentSkillVersion +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.skill.version.list( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**skill_uuid:** `str` — Skill UUID + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Page size (maximum 100) + +
+
+ +
+
+ +**cursor:** `typing.Optional[str]` — Opaque page cursor + +
+
+ +
+
+ +**markdown_format:** `typing.Optional[VersionListRequestMarkdownFormat]` — Markdown form: agent (default) or full + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
-When true, prevents extraction of generic entity nodes that do not match -the configured ontology. + +
+
+
+ +
client.agent.skill.version.compare(...) -> AgentSkillVersionComparison +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.skill.version.compare( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + from_version=1, + to_version=1, +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**skill_uuid:** `str` — Skill UUID + +
+
+ +
+
+ +**from_version:** `int` + +
+
+ +
+
+ +**to_version:** `int`
@@ -3795,7 +11836,7 @@ the configured ontology.
-
client.thread.get_summary(...) -> ThreadSummary +
client.agent.skill.version.get(...) -> AgentSkillVersion
@@ -3816,8 +11857,10 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.thread.get_summary( - thread_uuid="thread_uuid", +client.agent.skill.version.get( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + version=1, ) ``` @@ -3834,7 +11877,31 @@ client.thread.get_summary(
-**thread_uuid:** `str` — Thread UUID +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**skill_uuid:** `str` — Skill UUID + +
+
+ +
+
+ +**version:** `int` — Skill version + +
+
+ +
+
+ +**markdown_format:** `typing.Optional[VersionGetRequestMarkdownFormat]` — Markdown form: agent (default) or full
@@ -3854,12 +11921,12 @@ client.thread.get_summary(
-## UserGroup -
client.user_group.create(...) -> UserGroup +## Agent Skill Use +
client.agent.skill.use.create(...) -> AgentSkillUse
-#### 📝 Description +#### 🔌 Usage
@@ -3867,12 +11934,196 @@ client.thread.get_summary(
-Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.skill.use.create( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + search_id="search_id", + trajectory_uuid="trajectory_uuid", + usage="selected", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**skill_uuid:** `str` — Skill UUID + +
+
+ +
+
+ +**search_id:** `str` + +
+
+ +
+
+ +**trajectory_uuid:** `str` + +
+
+ +
+
+ +**usage:** `CreateAgentSkillUseRequestUsage` + +
+
+ +
+
+ +**outcome:** `typing.Optional[AddAgentSkillUseOutcomeRequest]` + +
+
+ +
+
+ +**reason_code:** `typing.Optional[str]` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agent.skill.use.add_outcome(...) -> AgentSkillUseOutcome +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.agent.skill.use.add_outcome( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + use_uuid="use_uuid", + outcome="succeeded", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**skill_uuid:** `str` — Skill UUID + +
+
+ +
+
+ +**use_uuid:** `str` — Skill use UUID + +
+
+ +
+
+ +**request:** `AddAgentSkillUseOutcomeRequest` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +
+ +
+
+
+ +## Agent Skill Export +
client.agent.skill.export.create(...) -> Task +
+
+ #### 🔌 Usage
@@ -3890,8 +12141,10 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.user_group.create( - name="name", +client.agent.skill.export.create( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + version=1, ) ``` @@ -3908,7 +12161,7 @@ client.user_group.create(
-**name:** `str` — The name of the user group. +**agent_uuid:** `str` — Agent UUID
@@ -3916,7 +12169,15 @@ client.user_group.create(
-**description:** `typing.Optional[str]` — A description of the user group. +**skill_uuid:** `str` — Skill UUID + +
+
+ +
+
+ +**version:** `int` — Skill version
@@ -3936,24 +12197,10 @@ client.user_group.create(
-
client.user_group.list(...) -> UserGroupPage -
-
- -#### 📝 Description - -
-
- +
client.agent.skill.export.get(...) -> typing.Iterator[bytes]
-Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. -
-
-
-
- #### 🔌 Usage
@@ -3971,9 +12218,11 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.user_group.list( - limit=1, - cursor="cursor", +client.agent.skill.export.get( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + version=1, + task_uuid="task_uuid", ) ``` @@ -3990,7 +12239,7 @@ client.user_group.list(
-**request:** `SearchListRequest` +**agent_uuid:** `str` — Agent UUID
@@ -3998,7 +12247,7 @@ client.user_group.list(
-**limit:** `typing.Optional[int]` — Page size +**skill_uuid:** `str` — Skill UUID
@@ -4006,7 +12255,15 @@ client.user_group.list(
-**cursor:** `typing.Optional[str]` — Opaque page cursor +**version:** `int` — Skill version + +
+
+ +
+
+ +**task_uuid:** `str` — Export Task UUID
@@ -4026,7 +12283,8 @@ client.user_group.list(
-
client.user_group.get(...) -> UserGroup +## Agent TrajectoryImport Run +
client.agent.trajectory_import.run.list(...) -> TrajectoryImportRunPage
@@ -4038,7 +12296,7 @@ client.user_group.list(
-Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. +List runs that belong to this trajectory import.
@@ -4061,8 +12319,9 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.user_group.get( - group_uuid="group_uuid", +client.agent.trajectory_import.run.list( + agent_uuid="agent_uuid", + import_uuid="import_uuid", ) ``` @@ -4079,7 +12338,31 @@ client.user_group.get(
-**group_uuid:** `str` — User group UUID +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**import_uuid:** `str` — Trajectory import UUID + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Page size + +
+
+ +
+
+ +**cursor:** `typing.Optional[str]` — Opaque page cursor
@@ -4099,7 +12382,7 @@ client.user_group.get(
-
client.user_group.delete(...) +
client.agent.trajectory_import.run.create(...) -> Task
@@ -4111,7 +12394,7 @@ client.user_group.get(
-Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. +Create a pending run and its Task. This operation does not start the run.
@@ -4134,8 +12417,9 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.user_group.delete( - group_uuid="group_uuid", +client.agent.trajectory_import.run.create( + agent_uuid="agent_uuid", + import_uuid="import_uuid", ) ``` @@ -4152,7 +12436,15 @@ client.user_group.delete(
-**group_uuid:** `str` — User group UUID +**agent_uuid:** `str` — Agent UUID + +
+
+ +
+
+ +**import_uuid:** `str` — Trajectory import UUID
@@ -4172,7 +12464,7 @@ client.user_group.delete(
-
client.user_group.update(...) -> UserGroup +
client.agent.trajectory_import.run.get(...) -> TrajectoryImportRun
@@ -4184,7 +12476,7 @@ client.user_group.delete(
-Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. +Read one run that belongs to this trajectory import.
@@ -4207,8 +12499,10 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.user_group.update( - group_uuid="group_uuid", +client.agent.trajectory_import.run.get( + agent_uuid="agent_uuid", + import_uuid="import_uuid", + run_uuid="run_uuid", ) ``` @@ -4225,15 +12519,7 @@ client.user_group.update(
-**group_uuid:** `str` — User group UUID - -
-
- -
-
- -**description:** `typing.Optional[str]` — A description of the user group. +**agent_uuid:** `str` — Agent UUID
@@ -4241,7 +12527,7 @@ client.user_group.update(
-**expected_version:** `typing.Optional[int]` — The user group's current version, used to detect concurrent updates. +**import_uuid:** `str` — Trajectory import UUID
@@ -4249,7 +12535,7 @@ client.user_group.update(
-**name:** `typing.Optional[str]` — The name of the user group. +**run_uuid:** `str` — Run UUID
@@ -4269,7 +12555,8 @@ client.user_group.update(
-
client.user_group.list_member_candidates(...) -> UserPage +## Agent TrajectoryImport Run Item +
client.agent.trajectory_import.run.item.list(...) -> TrajectoryImportRunItemPage
@@ -4281,7 +12568,7 @@ client.user_group.update(
-Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. +List trace results for this run. Run items do not include source payload.
@@ -4304,10 +12591,10 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.user_group.list_member_candidates( - group_uuid="group_uuid", - limit=1, - cursor="cursor", +client.agent.trajectory_import.run.item.list( + agent_uuid="agent_uuid", + import_uuid="import_uuid", + run_uuid="run_uuid", ) ``` @@ -4324,7 +12611,7 @@ client.user_group.list_member_candidates(
-**group_uuid:** `str` — User group UUID +**agent_uuid:** `str` — Agent UUID
@@ -4332,7 +12619,15 @@ client.user_group.list_member_candidates(
-**request:** `SearchListRequest` +**import_uuid:** `str` — Trajectory import UUID + +
+
+ +
+
+ +**run_uuid:** `str` — Run UUID
@@ -4368,24 +12663,11 @@ client.user_group.list_member_candidates(
-
client.user_group.add_members(...) -> MembershipMutationResult -
-
- -#### 📝 Description - -
-
- +## Graph DocumentSummary +
client.graph.document_summary.list(...) -> DocumentSummaryPage
-Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. -
-
-
-
- #### 🔌 Usage
@@ -4403,11 +12685,8 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.user_group.add_members( - group_uuid="group_uuid", - user_uuids=[ - "user_uuids" - ], +client.graph.document_summary.list( + graph_uuid="graph_uuid", ) ``` @@ -4424,7 +12703,7 @@ client.user_group.add_members(
-**group_uuid:** `str` — User group UUID +**graph_uuid:** `str` — Graph UUID
@@ -4432,7 +12711,7 @@ client.user_group.add_members(
-**request:** `MutateMembersRequest` +**request:** `ArtifactListRequest`
@@ -4440,35 +12719,38 @@ client.user_group.add_members(
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**limit:** `typing.Optional[int]` — Page size
-
-
- - - - -
-
client.user_group.list_members(...) -> UserPage
-#### 📝 Description - -
-
+**cursor:** `typing.Optional[str]` — Opaque page cursor + +
+
-Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+ + +
+ +## Graph Episode +
client.graph.episode.list_for_document(...) -> EpisodePage +
+
#### 🔌 Usage @@ -4487,10 +12769,9 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.user_group.list_members( - group_uuid="group_uuid", - limit=1, - cursor="cursor", +client.graph.episode.list_for_document( + graph_uuid="graph_uuid", + document_id="document_id", ) ``` @@ -4507,7 +12788,7 @@ client.user_group.list_members(
-**group_uuid:** `str` — User group UUID +**graph_uuid:** `str` — Graph UUID
@@ -4515,7 +12796,7 @@ client.user_group.list_members(
-**request:** `SearchListRequest` +**document_id:** `str` — Document ID
@@ -4551,11 +12832,11 @@ client.user_group.list_members(
-
client.user_group.remove_members(...) -> MembershipMutationResult +
client.graph.episode.add(...) -> AddEpisodeResult
-#### 📝 Description +#### 🔌 Usage
@@ -4563,13 +12844,27 @@ client.user_group.list_members(
-Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. +```python +from zep_cloud import Zep +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.graph.episode.add( + graph_uuid="graph_uuid", + data="data", +) + +```
-#### 🔌 Usage +#### ⚙️ Parameters
@@ -4577,37 +12872,61 @@ Requires a project API key, or an account-admin bearer token with the X-Zep-Proj
-```python -from zep_cloud import Zep -from zep_cloud.environment import ZepEnvironment +**graph_uuid:** `str` — Graph UUID + +
+
-client = Zep( - api_key="", - environment=ZepEnvironment.DEFAULT, -) +
+
-client.user_group.remove_members( - group_uuid="group_uuid", - user_uuids=[ - "user_uuids" - ], -) +**data:** `str` — The episode content to add to the graph. + +
+
-``` +
+
+ +**created_at:** `typing.Optional[str]` + +The episode's reference time, used for temporal reasoning rather than +ingestion time. +
+ +
+
+ +**document_id:** `typing.Optional[str]` — Groups this episode as a chunk of a document on the graph. +
-#### ⚙️ Parameters +
+
+ +**metadata:** `typing.Optional[typing.Dict[str, typing.Any]]` — Metadata to store on the episode. Max 10 keys. Values must be strings, numbers, booleans, or arrays of scalars. + +
+
+**source_description:** `typing.Optional[str]` — A description of the source of this episode. + +
+
+
-**group_uuid:** `str` — User group UUID +**strict_ontology:** `typing.Optional[bool]` + +When true, prevents extraction of generic entity nodes that do not match +the configured ontology.
@@ -4615,7 +12934,7 @@ client.user_group.remove_members(
-**request:** `MutateMembersRequest` +**type:** `typing.Optional[AddEpisodeRequestType]` — The data format of the episode: text, json, or message. Defaults to text.
@@ -4635,7 +12954,7 @@ client.user_group.remove_members(
-
client.user_group.remove_member(...) +
client.graph.episode.list(...) -> EpisodePage
@@ -4647,7 +12966,12 @@ client.user_group.remove_members(
-Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. +Lists the episodes of a graph. `filters.mentioned_node_uuids` restricts +the results to episodes that mention any of the listed node UUIDs. The +list can also contain episode UUIDs: an episode UUID matches that episode, +so one request can return a known set of episodes. At most 256 entries. +`filters.metadata_filters` restricts the results to episodes whose stored +metadata matches the predicate.
@@ -4670,9 +12994,8 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.user_group.remove_member( - group_uuid="group_uuid", - user_uuid="user_uuid", +client.graph.episode.list( + graph_uuid="graph_uuid", ) ``` @@ -4689,7 +13012,7 @@ client.user_group.remove_member(
-**group_uuid:** `str` — User group UUID +**graph_uuid:** `str` — Graph UUID
@@ -4697,7 +13020,7 @@ client.user_group.remove_member(
-**user_uuid:** `str` — User UUID +**request:** `ArtifactListRequest`
@@ -4705,36 +13028,54 @@ client.user_group.remove_member(
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**limit:** `typing.Optional[int]` — Page size
- -
+
+
+**cursor:** `typing.Optional[str]` — Opaque page cursor +
-
-
client.user_group.list_for_user(...) -> UserGroupPage
-#### 📝 Description +**order_by:** `typing.Optional[EpisodeListRequestOrderBy]` — Sort field + +
+
+**order:** `typing.Optional[EpisodeListRequestOrder]` — Sort direction: asc or desc + +
+
+
-Requires a project API key, or an account-admin bearer token with the X-Zep-Project header. The account must be entitled to attribute-based access control. +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +
+ + + +
+ +
client.graph.episode.get(...) -> Episode +
+
+ #### 🔌 Usage
@@ -4752,10 +13093,9 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.user_group.list_for_user( - user_uuid="user_uuid", - limit=1, - cursor="cursor", +client.graph.episode.get( + graph_uuid="graph_uuid", + episode_uuid="episode_uuid", ) ``` @@ -4772,15 +13112,7 @@ client.user_group.list_for_user(
-**user_uuid:** `str` — User UUID - -
-
- -
-
- -**limit:** `typing.Optional[int]` — Page size +**graph_uuid:** `str` — Graph UUID
@@ -4788,7 +13120,7 @@ client.user_group.list_for_user(
-**cursor:** `typing.Optional[str]` — Opaque page cursor +**episode_uuid:** `str` — Episode UUID
@@ -4808,8 +13140,7 @@ client.user_group.list_for_user(
-## User -
client.user.create(...) -> User +
client.graph.episode.delete(...) -> AsyncResult
@@ -4830,7 +13161,10 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.user.create() +client.graph.episode.delete( + graph_uuid="graph_uuid", + episode_uuid="episode_uuid", +) ```
@@ -4846,47 +13180,7 @@ client.user.create()
-**disable_default_ontology:** `typing.Optional[bool]` — When true, disables the default ontology for the user's graph. - -
-
- -
-
- -**email:** `typing.Optional[str]` — The email address of the user. - -
-
- -
-
- -**first_name:** `typing.Optional[str]` — The user's first name. - -
-
- -
-
- -**last_name:** `typing.Optional[str]` — The user's last name. - -
-
- -
-
- -**metadata:** `typing.Optional[typing.Dict[str, typing.Any]]` — Metadata to store on the user. - -
-
- -
-
- -**time_zone:** `typing.Optional[str]` — The user's IANA time zone. +**graph_uuid:** `str` — Graph UUID
@@ -4894,7 +13188,7 @@ client.user.create()
-**user_id:** `typing.Optional[str]` — An optional developer-assigned identifier for the user. +**episode_uuid:** `str` — Episode UUID
@@ -4914,7 +13208,7 @@ client.user.create()
-
client.user.list(...) -> UserPage +
client.graph.episode.update(...) -> Episode
@@ -4935,11 +13229,9 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.user.list( - limit=1, - cursor="cursor", - order_by="order_by", - order="order", +client.graph.episode.update( + graph_uuid="graph_uuid", + episode_uuid="episode_uuid", ) ``` @@ -4956,7 +13248,7 @@ client.user.list(
-**limit:** `typing.Optional[int]` — Page size +**graph_uuid:** `str` — Graph UUID
@@ -4964,7 +13256,7 @@ client.user.list(
-**cursor:** `typing.Optional[str]` — Opaque page cursor +**episode_uuid:** `str` — Episode UUID
@@ -4972,7 +13264,7 @@ client.user.list(
-**order_by:** `typing.Optional[str]` — Sort field +**metadata:** `typing.Optional[typing.Dict[str, typing.Any]]` — Metadata to merge onto the episode; a key set to null is removed. Max 10 keys after the merge. Values must be strings, numbers, booleans, or arrays of scalars.
@@ -4980,38 +13272,36 @@ client.user.list(
-**order:** `typing.Optional[str]` — asc or desc +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
-
-
-**search:** `typing.Optional[str]` — Filters results to users whose user ID, email, or name contains this text. -
+
+
client.graph.episode.get_debug_logs(...) -> EpisodeDebugLog
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. - -
-
- - - +#### 📝 Description - - -
+
+
-
client.user.lookup(...) -> User
+Returns the ingestion workflow log of an episode. The log exists only when debug logging was enabled for the project when the episode was ingested (see `debug_log.enable`). The log holds episode content, so an API key with an ABAC policy needs an explicit grant of this action; the `readonly` macro does not grant it. +
+
+
+
+ #### 🔌 Usage
@@ -5029,7 +13319,10 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.user.lookup() +client.graph.episode.get_debug_logs( + graph_uuid="graph_uuid", + episode_uuid="episode_uuid", +) ``` @@ -5045,7 +13338,15 @@ client.user.lookup()
-**request:** `LookupRequest` +**graph_uuid:** `str` — Graph UUID + +
+
+ +
+
+ +**episode_uuid:** `str` — Episode UUID
@@ -5065,10 +13366,24 @@ client.user.lookup()
-
client.user.get(...) -> User +
client.graph.episode.list_ingestion_traces(...) -> IngestionTracePage +
+
+ +#### 📝 Description + +
+
+
+Returns the ingestion traces of an episode, oldest first. Each trace records the input and the output of one ingestion step, with an explanation on each output entry that has one. Traces exist only when ingestion tracing was enabled for the project when the episode was ingested (see `debug_log.enable`). An episode with no traces returns a page with an empty `items` array. Traces hold episode content, prompt input, and model output, so an API key with an ABAC policy needs an explicit grant of this action; the `readonly` macro does not grant it. +
+
+
+
+ #### 🔌 Usage
@@ -5086,8 +13401,9 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.user.get( - user_uuid="user_uuid", +client.graph.episode.list_ingestion_traces( + graph_uuid="graph_uuid", + episode_uuid="episode_uuid", ) ``` @@ -5104,7 +13420,7 @@ client.user.get(
-**user_uuid:** `str` — User UUID +**graph_uuid:** `str` — Graph UUID
@@ -5112,58 +13428,23 @@ client.user.get(
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**episode_uuid:** `str` — Episode UUID
-
-
- - - - -
- -
client.user.delete(...) -> UserDeleteResult -
-
- -#### 🔌 Usage - -
-
-```python -from zep_cloud import Zep -from zep_cloud.environment import ZepEnvironment - -client = Zep( - api_key="", - environment=ZepEnvironment.DEFAULT, -) - -client.user.delete( - user_uuid="user_uuid", -) - -``` -
-
+**limit:** `typing.Optional[int]` — Page size +
-#### ⚙️ Parameters - -
-
-
-**user_uuid:** `str` — User UUID +**cursor:** `typing.Optional[str]` — Opaque page cursor
@@ -5183,11 +13464,12 @@ client.user.delete(
-
client.user.update(...) -> User +## Graph Edge +
client.graph.edge.add(...) -> AddEdgesResult
-#### 🔌 Usage +#### 📝 Description
@@ -5195,26 +13477,14 @@ client.user.delete(
-```python -from zep_cloud import Zep -from zep_cloud.environment import ZepEnvironment - -client = Zep( - api_key="", - environment=ZepEnvironment.DEFAULT, -) - -client.user.update( - user_uuid="user_uuid", -) - -``` +Adds 1 to 100 edges. A name creates a node when deduplicate is false. When deduplicate is true, Zep matches a node by name first. +Example: {"edges":[{"fact":"Ada works at Acme Corp","fact_name":"WORKS_AT","source_node":{"uuid":"f47ac10b-58cc-4372-a567-0e02b2c3d479"},"target_node":{"uuid":"f47ac10b-58cc-4372-a567-0e02b2c3d480"}},{"fact":"Ada leads a team","fact_name":"LEADS","source_node":{"name":"Ada Lovelace","labels":["Person"]},"target_node":{"name":"Engineering","labels":["Department"]}}],"deduplicate":false}
-#### ⚙️ Parameters +#### 🔌 Usage
@@ -5222,39 +13492,42 @@ client.user.update(
-**user_uuid:** `str` — User UUID - -
-
+```python +from zep_cloud import Zep, EdgeInput, EdgeNodeRef +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) -
-
+client.graph.edge.add( + graph_uuid="graph_uuid", + edges=[ + EdgeInput( + fact="Ada works at Acme Corp", + fact_name="WORKS_AT", + source_node=EdgeNodeRef(), + target_node=EdgeNodeRef(), + ) + ], +) -**disable_default_ontology:** `typing.Optional[bool]` — When true, disables the default ontology for the user's graph. - +```
- -
-
- -**email:** `typing.Optional[str]` — The email address of the user. -
+#### ⚙️ Parameters +
-**first_name:** `typing.Optional[str]` — The user's first name. - -
-
-
-**last_name:** `typing.Optional[str]` — The user's last name. +**graph_uuid:** `str` — Graph UUID
@@ -5262,7 +13535,7 @@ client.user.update(
-**metadata:** `typing.Optional[typing.Dict[str, typing.Any]]` — Metadata to merge onto the user; a key set to null is removed. +**edges:** `typing.List[EdgeInput]` — The edges to add to the graph. The request accepts 1 to 100 edges.
@@ -5270,7 +13543,11 @@ client.user.update(
-**time_zone:** `typing.Optional[str]` — The user's IANA time zone. +**deduplicate:** `typing.Optional[bool]` + +When true, Zep compares each edge with graph edges and can merge a +duplicate or invalidate a contradicted edge. This adds an LLM call per +edge. The default is false.
@@ -5290,7 +13567,7 @@ client.user.update(
-
client.user.get_node(...) -> Node +
client.graph.edge.list(...) -> EdgePage
@@ -5311,8 +13588,8 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.user.get_node( - user_uuid="user_uuid", +client.graph.edge.list( + graph_uuid="graph_uuid", ) ``` @@ -5329,7 +13606,31 @@ client.user.get_node(
-**user_uuid:** `str` — User UUID +**graph_uuid:** `str` — Graph UUID + +
+
+ +
+
+ +**request:** `ArtifactListRequest` + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Page size + +
+
+ +
+
+ +**cursor:** `typing.Optional[str]` — Opaque page cursor
@@ -5349,7 +13650,7 @@ client.user.get_node(
-
client.user.get_summary_instructions(...) -> UserSummaryInstructions +
client.graph.edge.get(...) -> Edge
@@ -5370,8 +13671,9 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.user.get_summary_instructions( - user_uuid="user_uuid", +client.graph.edge.get( + graph_uuid="graph_uuid", + edge_uuid="edge_uuid", ) ``` @@ -5388,7 +13690,15 @@ client.user.get_summary_instructions(
-**user_uuid:** `str` — User UUID +**graph_uuid:** `str` — Graph UUID + +
+
+ +
+
+ +**edge_uuid:** `str` — Edge UUID
@@ -5408,7 +13718,7 @@ client.user.get_summary_instructions(
-
client.user.set_summary_instructions(...) -> UserSummaryInstructions +
client.graph.edge.delete(...) -> AsyncResult
@@ -5429,8 +13739,9 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.user.set_summary_instructions( - user_uuid="user_uuid", +client.graph.edge.delete( + graph_uuid="graph_uuid", + edge_uuid="edge_uuid", ) ``` @@ -5447,7 +13758,7 @@ client.user.set_summary_instructions(
-**user_uuid:** `str` — User UUID +**graph_uuid:** `str` — Graph UUID
@@ -5455,7 +13766,7 @@ client.user.set_summary_instructions(
-**request:** `UserSummaryInstructions` +**edge_uuid:** `str` — Edge UUID
@@ -5475,11 +13786,27 @@ client.user.set_summary_instructions(
-## Graph DocumentSummary -
client.graph.document_summary.list(...) -> DocumentSummaryPage +
client.graph.edge.update(...) -> Edge +
+
+ +#### 📝 Description + +
+
+
+Updates one edge. When the edge belongs to a hyperedge, changing fact +rewrites it on every member of that hyperedge in one all-or-nothing +write, because the members share it. Attribute-only edits touch this +edge alone. +
+
+
+
+ #### 🔌 Usage
@@ -5497,10 +13824,9 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.document_summary.list( +client.graph.edge.update( graph_uuid="graph_uuid", - limit=1, - cursor="cursor", + edge_uuid="edge_uuid", ) ``` @@ -5525,7 +13851,7 @@ client.graph.document_summary.list(
-**request:** `ArtifactListRequest` +**edge_uuid:** `str` — Edge UUID
@@ -5533,7 +13859,10 @@ client.graph.document_summary.list(
-**limit:** `typing.Optional[int]` — Page size +**attributes:** `typing.Optional[typing.Dict[str, typing.Any]]` + +Additional attributes to merge onto the edge; a key set to null is +removed.
@@ -5541,7 +13870,10 @@ client.graph.document_summary.list(
-**cursor:** `typing.Optional[str]` — Opaque page cursor +**fact:** `typing.Optional[str]` + +The fact text describing the relationship between the source and target +nodes.
@@ -5561,11 +13893,30 @@ client.graph.document_summary.list(
-## Graph Episode -
client.graph.episode.list_for_document(...) -> EpisodePage +## Graph Hyperedge +
client.graph.hyperedge.add(...) -> AddHyperedgeResult +
+
+ +#### 📝 Description + +
+
+
+Creates one hyperedge: a fact that relates more than two nodes, written +onto one member edge per node pair. The member edges must span at least +three distinct nodes, since two nodes are a pair of edges rather than a +hyperedge; a single pair uses graph.edge.add. Zep assigns the hyperedge +identifier and every member edge identifier at accept time, and the +members become readable when the task completes. +
+
+
+
+ #### 🔌 Usage
@@ -5575,7 +13926,7 @@ client.graph.document_summary.list(
```python -from zep_cloud import Zep +from zep_cloud import Zep, HyperedgeInput, EdgeNodeRef from zep_cloud.environment import ZepEnvironment client = Zep( @@ -5583,11 +13934,16 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.episode.list_for_document( +client.graph.hyperedge.add( graph_uuid="graph_uuid", - document_id="document_id", - limit=1, - cursor="cursor", + edges=[ + HyperedgeInput( + name="name", + source_node=EdgeNodeRef(), + target_node=EdgeNodeRef(), + ) + ], + fact="fact", ) ``` @@ -5612,7 +13968,10 @@ client.graph.episode.list_for_document(
-**document_id:** `str` — Document ID +**edges:** `typing.List[HyperedgeInput]` + +The member edges to create. Each pair becomes one edge carrying the +shared fact.
@@ -5620,7 +13979,7 @@ client.graph.episode.list_for_document(
-**limit:** `typing.Optional[int]` — Page size +**fact:** `str` — The natural-language fact, written onto every member edge.
@@ -5628,7 +13987,39 @@ client.graph.episode.list_for_document(
-**cursor:** `typing.Optional[str]` — Opaque page cursor +**attributes:** `typing.Optional[typing.Dict[str, typing.Any]]` — Additional attributes to store on every member edge. + +
+
+ +
+
+ +**expired_at:** `typing.Optional[str]` — The time at which the fact was superseded or invalidated. + +
+
+ +
+
+ +**invalid_at:** `typing.Optional[str]` — The time at which the fact stopped being true. + +
+
+ +
+
+ +**metadata:** `typing.Optional[typing.Dict[str, typing.Any]]` — Metadata attached to the episode created for this hyperedge. + +
+
+ +
+
+ +**valid_at:** `typing.Optional[str]` — The time at which the fact became true.
@@ -5648,10 +14039,27 @@ client.graph.episode.list_for_document(
-
client.graph.episode.add(...) -> AddEpisodeResult +
client.graph.hyperedge.list(...) -> HyperedgePage +
+
+ +#### 📝 Description + +
+
+
+Returns the graph's hyperedges. A hyperedge is listed while it has at +least one member edge. Supported filters are node_uuids, edge_uuids and +episode_uuids: a hyperedge matches a list when any of its members does, +and must match every list supplied. +
+
+
+
+ #### 🔌 Usage
@@ -5669,9 +14077,8 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.episode.add( +client.graph.hyperedge.list( graph_uuid="graph_uuid", - data="data", ) ``` @@ -5696,7 +14103,7 @@ client.graph.episode.add(
-**data:** `str` — The episode content to add to the graph. +**request:** `ArtifactListRequest`
@@ -5704,10 +14111,7 @@ client.graph.episode.add(
-**created_at:** `typing.Optional[str]` - -The episode's reference time, used for temporal reasoning rather than -ingestion time. +**limit:** `typing.Optional[int]` — Page size
@@ -5715,7 +14119,7 @@ ingestion time.
-**document_id:** `typing.Optional[str]` — Groups this episode as a chunk of a document on the graph. +**cursor:** `typing.Optional[str]` — Opaque page cursor
@@ -5723,7 +14127,7 @@ ingestion time.
-**metadata:** `typing.Optional[typing.Dict[str, typing.Any]]` — Metadata to store on the episode. +**order_by:** `typing.Optional[HyperedgeListRequestOrderBy]` — Sort key: uuid or created_at
@@ -5731,7 +14135,7 @@ ingestion time.
-**source_description:** `typing.Optional[str]` — A description of the source of this episode. +**order:** `typing.Optional[HyperedgeListRequestOrder]` — Sort direction: asc or desc
@@ -5739,41 +14143,38 @@ ingestion time.
-**strict_ontology:** `typing.Optional[bool]` - -When true, prevents extraction of generic entity nodes that do not match -the configured ontology. +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
-
-
-**type:** `typing.Optional[V4AddEpisodeRequestType]` — The data format of the episode: text, json, or message. Defaults to text. -
+
+
client.graph.hyperedge.get(...) -> Hyperedge
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. - -
-
- - - +#### 📝 Description - - -
+
+
-
client.graph.episode.list(...) -> EpisodePage
+Returns one hyperedge assembled from its member edges. The fact and the +validity timestamps are shared by every member and are reported on the +hyperedge; each member reports only its own name and endpoints. +
+
+
+
+ #### 🔌 Usage
@@ -5791,10 +14192,9 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.episode.list( +client.graph.hyperedge.get( graph_uuid="graph_uuid", - limit=1, - cursor="cursor", + hyperedge_uuid="hyperedge_uuid", ) ``` @@ -5819,7 +14219,7 @@ client.graph.episode.list(
-**request:** `ArtifactListRequest` +**hyperedge_uuid:** `str` — Hyperedge UUID
@@ -5827,37 +14227,36 @@ client.graph.episode.list(
-**limit:** `typing.Optional[int]` — Page size +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+ +
-
-
-**cursor:** `typing.Optional[str]` — Opaque page cursor -
+
+
client.graph.hyperedge.delete(...) -> AsyncResult
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. - -
-
+#### 📝 Description + +
+
+ +
+
+ +Deletes every member edge of the hyperedge. After the task completes the +hyperedge and each of its members are gone.
- -
-
- -
client.graph.episode.get(...) -> Episode -
-
#### 🔌 Usage @@ -5876,9 +14275,9 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.episode.get( +client.graph.hyperedge.delete( graph_uuid="graph_uuid", - episode_uuid="episode_uuid", + hyperedge_uuid="hyperedge_uuid", ) ``` @@ -5903,7 +14302,7 @@ client.graph.episode.get(
-**episode_uuid:** `str` — Episode UUID +**hyperedge_uuid:** `str` — Hyperedge UUID
@@ -5923,10 +14322,29 @@ client.graph.episode.get(
-
client.graph.episode.delete(...) -> AsyncResult +
client.graph.hyperedge.update(...) -> Hyperedge +
+
+ +#### 📝 Description +
+
+
+ +Updates the shared fact and writes it onto every member edge in one +all-or-nothing write: either every member carries the new fact or none +does. Only fact is accepted, because it is the only field the members +share. name belongs to each member edge, and membership changes use +create_edge and delete_edge. Updating fact on one member through +graph.edge.update cascades the same way. +
+
+
+
+ #### 🔌 Usage
@@ -5944,9 +14362,9 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.episode.delete( +client.graph.hyperedge.update( graph_uuid="graph_uuid", - episode_uuid="episode_uuid", + hyperedge_uuid="hyperedge_uuid", ) ``` @@ -5971,7 +14389,15 @@ client.graph.episode.delete(
-**episode_uuid:** `str` — Episode UUID +**hyperedge_uuid:** `str` — Hyperedge UUID + +
+
+ +
+
+ +**fact:** `typing.Optional[str]` — The natural-language fact, rewritten onto every member edge.
@@ -5991,10 +14417,26 @@ client.graph.episode.delete(
-
client.graph.episode.update(...) -> Episode +
client.graph.hyperedge.create_edge(...) -> AddHyperedgeEdgeResult +
+
+ +#### 📝 Description +
+
+
+ +Adds one member edge to an existing hyperedge. The new member inherits the +hyperedge's fact and timestamps and joins its episodes, so only its own +name and node pair are supplied. +
+
+
+
+ #### 🔌 Usage
@@ -6004,7 +14446,7 @@ client.graph.episode.delete(
```python -from zep_cloud import Zep +from zep_cloud import Zep, EdgeNodeRef from zep_cloud.environment import ZepEnvironment client = Zep( @@ -6012,9 +14454,12 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.episode.update( +client.graph.hyperedge.create_edge( graph_uuid="graph_uuid", - episode_uuid="episode_uuid", + hyperedge_uuid="hyperedge_uuid", + name="name", + source_node=EdgeNodeRef(), + target_node=EdgeNodeRef(), ) ``` @@ -6039,7 +14484,23 @@ client.graph.episode.update(
-**episode_uuid:** `str` — Episode UUID +**hyperedge_uuid:** `str` — Hyperedge UUID + +
+
+ +
+
+ +**name:** `str` — The name of the new member edge, in upper snake case. + +
+
+ +
+
+ +**source_node:** `EdgeNodeRef` — The source node of the new member.
@@ -6047,7 +14508,7 @@ client.graph.episode.update(
-**metadata:** `typing.Optional[typing.Dict[str, typing.Any]]` — Metadata to merge onto the episode; a key set to null is removed. +**target_node:** `EdgeNodeRef` — The target node of the new member.
@@ -6067,11 +14528,25 @@ client.graph.episode.update(
-## Graph Edge -
client.graph.edge.add(...) -> AddEdgeResult +
client.graph.hyperedge.delete_edge(...) -> AsyncResult +
+
+ +#### 📝 Description +
+
+
+ +Removes one member edge from the hyperedge. The remaining members stay in +the hyperedge, and deleting the last member removes the hyperedge itself. +
+
+
+
+ #### 🔌 Usage
@@ -6081,7 +14556,7 @@ client.graph.episode.update(
```python -from zep_cloud import Zep, EdgeNodeRef +from zep_cloud import Zep from zep_cloud.environment import ZepEnvironment client = Zep( @@ -6089,12 +14564,10 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.edge.add( +client.graph.hyperedge.delete_edge( graph_uuid="graph_uuid", - fact="fact", - fact_name="fact_name", - source_node=EdgeNodeRef(), - target_node=EdgeNodeRef(), + hyperedge_uuid="hyperedge_uuid", + edge_uuid="edge_uuid", ) ``` @@ -6119,10 +14592,7 @@ client.graph.edge.add(
-**fact:** `str` - -The fact text describing the relationship between the source and target -nodes. +**hyperedge_uuid:** `str` — Hyperedge UUID
@@ -6130,7 +14600,7 @@ nodes.
-**fact_name:** `str` — The name of the edge, in upper snake case, for example RELATES_TO. +**edge_uuid:** `str` — Edge UUID
@@ -6138,53 +14608,64 @@ nodes.
-**source_node:** `EdgeNodeRef` - -The source node of the edge, referenced by uuid or created or matched by -name. +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
-
-
- -**target_node:** `EdgeNodeRef` -The target node of the edge, referenced by uuid or created or matched by -name. -
+
+## Graph Node +
client.graph.node.add(...) -> AddNodesResult
-**attributes:** `typing.Optional[typing.Dict[str, typing.Any]]` — Additional attributes to store on the edge. - -
-
+#### 🔌 Usage
-**expired_at:** `typing.Optional[str]` — The time at which the fact was superseded or invalidated. - -
-
-
-**invalid_at:** `typing.Optional[str]` — The time at which the fact stopped being true. - +```python +from zep_cloud import Zep, NodeInput +from zep_cloud.environment import ZepEnvironment + +client = Zep( + api_key="", + environment=ZepEnvironment.DEFAULT, +) + +client.graph.node.add( + graph_uuid="graph_uuid", + nodes=[ + NodeInput( + name="name", + ) + ], +) + +```
+ + + +#### ⚙️ Parameters
-**metadata:** `typing.Optional[typing.Dict[str, typing.Any]]` — Metadata attached to the episode created for this edge. +
+
+ +**graph_uuid:** `str` — Graph UUID
@@ -6192,7 +14673,7 @@ name.
-**valid_at:** `typing.Optional[str]` — The time at which the fact became true. +**nodes:** `typing.List[NodeInput]` — The nodes to add to the graph.
@@ -6212,7 +14693,7 @@ name.
-
client.graph.edge.list(...) -> EdgePage +
client.graph.node.list(...) -> NodePage
@@ -6233,10 +14714,8 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.edge.list( +client.graph.node.list( graph_uuid="graph_uuid", - limit=1, - cursor="cursor", ) ``` @@ -6285,6 +14764,22 @@ client.graph.edge.list(
+**order_by:** `typing.Optional[NodeListRequestOrderBy]` — Sort key: uuid (default) or degree + +
+
+ +
+
+ +**order:** `typing.Optional[NodeListRequestOrder]` — Sort direction: asc or desc (default desc) + +
+
+ +
+
+ **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -6297,7 +14792,7 @@ client.graph.edge.list(
-
client.graph.edge.get(...) -> Edge +
client.graph.node.get(...) -> Node
@@ -6318,9 +14813,9 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.edge.get( +client.graph.node.get( graph_uuid="graph_uuid", - edge_uuid="edge_uuid", + node_uuid="node_uuid", ) ``` @@ -6345,7 +14840,7 @@ client.graph.edge.get(
-**edge_uuid:** `str` — Edge UUID +**node_uuid:** `str` — Node UUID
@@ -6365,7 +14860,7 @@ client.graph.edge.get(
-
client.graph.edge.delete(...) -> AsyncResult +
client.graph.node.delete(...) -> AsyncResult
@@ -6386,9 +14881,9 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.edge.delete( +client.graph.node.delete( graph_uuid="graph_uuid", - edge_uuid="edge_uuid", + node_uuid="node_uuid", ) ``` @@ -6413,7 +14908,7 @@ client.graph.edge.delete(
-**edge_uuid:** `str` — Edge UUID +**node_uuid:** `str` — Node UUID
@@ -6433,7 +14928,7 @@ client.graph.edge.delete(
-
client.graph.edge.update(...) -> Edge +
client.graph.node.update(...) -> Node
@@ -6454,9 +14949,9 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.edge.update( +client.graph.node.update( graph_uuid="graph_uuid", - edge_uuid="edge_uuid", + node_uuid="node_uuid", ) ``` @@ -6481,7 +14976,7 @@ client.graph.edge.update(
-**edge_uuid:** `str` — Edge UUID +**node_uuid:** `str` — Node UUID
@@ -6491,7 +14986,7 @@ client.graph.edge.update( **attributes:** `typing.Optional[typing.Dict[str, typing.Any]]` -Additional attributes to merge onto the edge; a key set to null is +Additional attributes to merge onto the node; a key set to null is removed.
@@ -6500,10 +14995,15 @@ removed.
-**fact:** `typing.Optional[str]` +**name:** `typing.Optional[str]` — The node's name. + +
+
-The fact text describing the relationship between the source and target -nodes. +
+
+ +**summary:** `typing.Optional[str]` — A summary of the node.
@@ -6523,8 +15023,7 @@ nodes.
-## Graph Node -
client.graph.node.add(...) -> AddNodesResult +
client.graph.node.list_neighbors(...) -> NeighborPage
@@ -6537,7 +15036,7 @@ nodes.
```python -from zep_cloud import Zep, NodeInput +from zep_cloud import Zep from zep_cloud.environment import ZepEnvironment client = Zep( @@ -6545,13 +15044,9 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.node.add( +client.graph.node.list_neighbors( graph_uuid="graph_uuid", - nodes=[ - NodeInput( - name="name", - ) - ], + node_uuid="node_uuid", ) ``` @@ -6576,68 +15071,31 @@ client.graph.node.add(
-**nodes:** `typing.List[NodeInput]` — The nodes to add to the graph. - -
-
- -
-
- -**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**node_uuid:** `str` — Node UUID
-
-
- - - - -
- -
client.graph.node.list(...) -> NodePage -
-
- -#### 🔌 Usage - -
-
-```python -from zep_cloud import Zep -from zep_cloud.environment import ZepEnvironment - -client = Zep( - api_key="", - environment=ZepEnvironment.DEFAULT, -) - -client.graph.node.list( - graph_uuid="graph_uuid", - limit=1, - cursor="cursor", -) - -``` -
-
+**limit:** `typing.Optional[int]` — Page size +
-#### ⚙️ Parameters -
+**cursor:** `typing.Optional[str]` — Opaque page cursor + +
+
+
-**graph_uuid:** `str` — Graph UUID +**order_by:** `typing.Optional[NodeListNeighborsRequestOrderBy]` — Sort field
@@ -6645,7 +15103,7 @@ client.graph.node.list(
-**request:** `ArtifactListRequest` +**order:** `typing.Optional[NodeListNeighborsRequestOrder]` — Sort direction: asc or desc
@@ -6653,7 +15111,7 @@ client.graph.node.list(
-**limit:** `typing.Optional[int]` — Page size +**direction:** `typing.Optional[NeighborsRequestDirection]` — The edge orientation to follow from the node: in, out, or both.
@@ -6661,7 +15119,7 @@ client.graph.node.list(
-**cursor:** `typing.Optional[str]` — Opaque page cursor +**filters:** `typing.Optional[SearchFilters]` — Filters constraining the connecting edges and the neighbor nodes.
@@ -6681,7 +15139,8 @@ client.graph.node.list(
-
client.graph.node.get(...) -> Node +## Graph Observation +
client.graph.observation.list(...) -> ObservationPage
@@ -6702,9 +15161,8 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.node.get( +client.graph.observation.list( graph_uuid="graph_uuid", - node_uuid="node_uuid", ) ``` @@ -6729,7 +15187,23 @@ client.graph.node.get(
-**node_uuid:** `str` — Node UUID +**request:** `ArtifactListRequest` + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Page size + +
+
+ +
+
+ +**cursor:** `typing.Optional[str]` — Opaque page cursor
@@ -6749,7 +15223,7 @@ client.graph.node.get(
-
client.graph.node.delete(...) -> AsyncResult +
client.graph.observation.get(...) -> Observation
@@ -6770,9 +15244,9 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.node.delete( +client.graph.observation.get( graph_uuid="graph_uuid", - node_uuid="node_uuid", + observation_uuid="observation_uuid", ) ``` @@ -6797,7 +15271,7 @@ client.graph.node.delete(
-**node_uuid:** `str` — Node UUID +**observation_uuid:** `str` — Observation UUID
@@ -6817,7 +15291,8 @@ client.graph.node.delete(
-
client.graph.node.update(...) -> Node +## Graph ThreadSummary +
client.graph.thread_summary.list(...) -> ThreadSummaryPage
@@ -6838,9 +15313,8 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.node.update( +client.graph.thread_summary.list( graph_uuid="graph_uuid", - node_uuid="node_uuid", ) ``` @@ -6865,18 +15339,7 @@ client.graph.node.update(
-**node_uuid:** `str` — Node UUID - -
-
- -
-
- -**attributes:** `typing.Optional[typing.Dict[str, typing.Any]]` - -Additional attributes to merge onto the node; a key set to null is -removed. +**request:** `ArtifactListRequest`
@@ -6884,7 +15347,7 @@ removed.
-**name:** `typing.Optional[str]` — The node's name. +**limit:** `typing.Optional[int]` — Page size
@@ -6892,7 +15355,7 @@ removed.
-**summary:** `typing.Optional[str]` — A summary of the node. +**cursor:** `typing.Optional[str]` — Opaque page cursor
@@ -6912,7 +15375,8 @@ removed.
-
client.graph.node.list_neighbors(...) -> NeighborPage +## Thread Message +
client.thread.message.get(...) -> Message
@@ -6933,11 +15397,9 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.node.list_neighbors( - graph_uuid="graph_uuid", - node_uuid="node_uuid", - limit=1, - cursor="cursor", +client.thread.message.get( + thread_uuid="thread_uuid", + message_uuid="message_uuid", ) ``` @@ -6954,39 +15416,7 @@ client.graph.node.list_neighbors(
-**graph_uuid:** `str` — Graph UUID - -
-
- -
-
- -**node_uuid:** `str` — Node UUID - -
-
- -
-
- -**limit:** `typing.Optional[int]` — Page size - -
-
- -
-
- -**cursor:** `typing.Optional[str]` — Opaque page cursor - -
-
- -
-
- -**direction:** `typing.Optional[V4NeighborsRequestDirection]` — The edge orientation to follow from the node: in, out, or both. +**thread_uuid:** `str` — Thread UUID
@@ -6994,7 +15424,7 @@ client.graph.node.list_neighbors(
-**filters:** `typing.Optional[SearchFilters]` — Filters constraining the connecting edges and the neighbor nodes. +**message_uuid:** `str` — Message UUID
@@ -7014,8 +15444,7 @@ client.graph.node.list_neighbors(
-## Graph Observation -
client.graph.observation.list(...) -> ObservationPage +
client.thread.message.update(...) -> Message
@@ -7036,10 +15465,9 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.observation.list( - graph_uuid="graph_uuid", - limit=1, - cursor="cursor", +client.thread.message.update( + thread_uuid="thread_uuid", + message_uuid="message_uuid", ) ``` @@ -7056,15 +15484,7 @@ client.graph.observation.list(
-**graph_uuid:** `str` — Graph UUID - -
-
- -
-
- -**request:** `ArtifactListRequest` +**thread_uuid:** `str` — Thread UUID
@@ -7072,7 +15492,7 @@ client.graph.observation.list(
-**limit:** `typing.Optional[int]` — Page size +**message_uuid:** `str` — Message UUID
@@ -7080,7 +15500,7 @@ client.graph.observation.list(
-**cursor:** `typing.Optional[str]` — Opaque page cursor +**metadata:** `typing.Optional[typing.Dict[str, typing.Any]]` — Metadata to merge onto the message; a key set to null is removed. Max 10 keys after the merge. Values must be strings, numbers, booleans, or arrays of scalars.
@@ -7100,10 +15520,25 @@ client.graph.observation.list(
-
client.graph.observation.get(...) -> Observation +## TraceConnection Project +
client.trace_connection.project.list(...) -> TraceProviderProjectPage +
+
+ +#### 📝 Description +
+
+
+ +List provider projects with the `limit` and `cursor` query parameters. +
+
+
+
+ #### 🔌 Usage
@@ -7121,9 +15556,8 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.observation.get( - graph_uuid="graph_uuid", - observation_uuid="observation_uuid", +client.trace_connection.project.list( + connection_uuid="connection_uuid", ) ``` @@ -7140,7 +15574,7 @@ client.graph.observation.get(
-**graph_uuid:** `str` — Graph UUID +**connection_uuid:** `str` — Trace connection UUID
@@ -7148,7 +15582,15 @@ client.graph.observation.get(
-**observation_uuid:** `str` — Observation UUID +**limit:** `typing.Optional[int]` — Page size from 1 to 100; default 50 + +
+
+ +
+
+ +**cursor:** `typing.Optional[str]` — Provider page cursor
@@ -7168,11 +15610,25 @@ client.graph.observation.get(
-## Graph ThreadSummary -
client.graph.thread_summary.list(...) -> ThreadSummaryPage +## TraceConnection Trace +
client.trace_connection.trace.get(...) -> SourceTraceResponse +
+
+ +#### 📝 Description + +
+
+
+Read one trace and optionally preview a mapping. Example body: `{"provider_project_id":"project_123","trace_id":"trace-123","mapping":{"task_family":{"source":"fixed","value":"support"}}}`. +
+
+
+
+ #### 🔌 Usage
@@ -7190,10 +15646,10 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.graph.thread_summary.list( - graph_uuid="graph_uuid", - limit=1, - cursor="cursor", +client.trace_connection.trace.get( + connection_uuid="connection_uuid", + provider_project_id="project_123", + trace_id="trace_123", ) ``` @@ -7210,7 +15666,7 @@ client.graph.thread_summary.list(
-**graph_uuid:** `str` — Graph UUID +**connection_uuid:** `str` — Trace connection UUID
@@ -7218,7 +15674,7 @@ client.graph.thread_summary.list(
-**request:** `ArtifactListRequest` +**provider_project_id:** `str` — ProviderProjectID is the provider project identifier.
@@ -7226,7 +15682,7 @@ client.graph.thread_summary.list(
-**limit:** `typing.Optional[int]` — Page size +**trace_id:** `str` — TraceID is the provider trace identifier.
@@ -7234,7 +15690,7 @@ client.graph.thread_summary.list(
-**cursor:** `typing.Optional[str]` — Opaque page cursor +**mapping:** `typing.Optional[TrajectoryMapping]` — Mapping is an optional mapping preview configuration. Example: {"task_family":{"source":"fixed","value":"support"}}.
@@ -7254,11 +15710,24 @@ client.graph.thread_summary.list(
-## Thread Message -
client.thread.message.get(...) -> Message +
client.trace_connection.trace.list(...) -> SourceTracePage +
+
+ +#### 📝 Description +
+
+
+ +Filter provider traces. Example body: `{"provider_project_id":"project_123","filter":{"started_after":"2026-01-01T00:00:00Z"}}`. +
+
+
+
+ #### 🔌 Usage
@@ -7276,9 +15745,9 @@ client = Zep( environment=ZepEnvironment.DEFAULT, ) -client.thread.message.get( - thread_uuid="thread_uuid", - message_uuid="message_uuid", +client.trace_connection.trace.list( + connection_uuid="connection_uuid", + provider_project_id="project_123", ) ``` @@ -7295,15 +15764,7 @@ client.thread.message.get(
-**thread_uuid:** `str` — Thread UUID - -
-
- -
-
- -**message_uuid:** `str` — Message UUID +**connection_uuid:** `str` — Trace connection UUID
@@ -7311,59 +15772,15 @@ client.thread.message.get(
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**provider_project_id:** `str` — ProviderProjectID is the provider project identifier. -
-
-
-
- - - - -
- -
client.thread.message.update(...) -> Message -
-
- -#### 🔌 Usage - -
-
- -
-
- -```python -from zep_cloud import Zep -from zep_cloud.environment import ZepEnvironment - -client = Zep( - api_key="", - environment=ZepEnvironment.DEFAULT, -) - -client.thread.message.update( - thread_uuid="thread_uuid", - message_uuid="message_uuid", -) - -``` -
-
-#### ⚙️ Parameters - -
-
-
-**thread_uuid:** `str` — Thread UUID +**limit:** `typing.Optional[int]` — Page size from 1 to 100; default 25
@@ -7371,7 +15788,7 @@ client.thread.message.update(
-**message_uuid:** `str` — Message UUID +**cursor:** `typing.Optional[str]` — Opaque page cursor
@@ -7379,7 +15796,7 @@ client.thread.message.update(
-**metadata:** `typing.Optional[typing.Dict[str, typing.Any]]` — Metadata to merge onto the message; a key set to null is removed. +**filter:** `typing.Optional[TraceFilter]` — Filter contains provider trace filters. Example: {"started_after":"2026-01-01T00:00:00Z"}.
diff --git a/requirements.txt b/requirements.txt index e80f640a..443b1af4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ httpx>=0.21.2 pydantic>= 1.9.2 -pydantic-core>=2.18.2 +pydantic-core>=2.18.2,<3.0.0 typing_extensions>= 4.0.0 diff --git a/src/zep_cloud/__init__.py b/src/zep_cloud/__init__.py index 14601278..94506b06 100644 --- a/src/zep_cloud/__init__.py +++ b/src/zep_cloud/__init__.py @@ -7,26 +7,127 @@ if typing.TYPE_CHECKING: from .types import ( - AddEdgeResult, + AddAgentSkillUseOutcomeRequest, + AddAgentSkillUseOutcomeRequestOutcome, + AddEdgesResult, AddEpisodeResult, + AddHyperedgeEdgeResult, + AddHyperedgeResult, AddMessage, AddMessagesResult, AddNodesResult, AddedEdge, + AddedHyperedge, + AddedHyperedgeEdge, AddedNode, + Agent, + AgentBreakingChange, + AgentContext, + AgentContextEvidenceCounts, + AgentContextPartialSource, + AgentContextResource, + AgentContextSkillSnapshot, + AgentContextSkippedSkill, + AgentDeleteResult, + AgentLearningState, + AgentLiteralPolicy, + AgentLiteralPolicyClasses, + AgentLiteralPolicyValues, + AgentMemoryEvaluationPolicy, + AgentMemoryEvaluationRequirement, + AgentMemorySettings, + AgentMemorySettingsApproval, + AgentMemorySettingsCompilationMode, + AgentPage, + AgentSkill, + AgentSkillAdmissionDecision, + AgentSkillCandidate, + AgentSkillCandidateBaseVersion, + AgentSkillCandidateEvaluation, + AgentSkillCandidateEvidence, + AgentSkillCandidateReview, + AgentSkillCandidateReviewResult, + AgentSkillCandidateReviewSummary, + AgentSkillCompilationOutcome, + AgentSkillCompilationOutcomeRejectionClass, + AgentSkillEvaluation, + AgentSkillEvidence, + AgentSkillPublicationLineage, + AgentSkillRelationship, + AgentSkillSearchHit, + AgentSkillSearchHitMaturity, + AgentSkillSearchResponse, + AgentSkillUse, + AgentSkillUseOutcome, + AgentSkillVersion, + AgentSkillVersionComparison, + AgentSplitPlan, + AgentSplitPlanDestination, + AgentSplitPlanDestinationRequest, + AgentSplitPlanSkillReference, + AgentSplitPlanSkillSelectionRequest, + AgentSplitPlanSource, + AgentStatus, + AgentTrajectory, + AgentTrajectoryCloseVerifier, + AgentTrajectoryEvent, + AgentTrajectoryEventContext, + AgentTrajectoryEventPage, + AgentTrajectoryEventProcessingState, + AgentTrajectoryEventSource, + AgentTrajectoryEventSourceCopyMode, + AgentTrajectoryEventSourceRetentionMode, + AgentTrajectoryEventType, + AgentTrajectoryFinalizationResult, + AgentTrajectoryInternal, + AgentTrajectoryLifecycle, + AgentTrajectoryOutcome, + AgentTrajectoryPage, + AgentTrajectoryProcessingState, + AgentTrajectoryResourceRef, + AgentTrajectorySequenceRange, + AgentTrajectorySource, + AgentTrajectorySourceDeletionResult, + AgentTrajectorySummaryCreationReason, + AgentTrajectorySummaryOmissionReason, + AgentTrajectorySummaryOmittedRange, + AgentTrajectorySummaryPage, + AgentTrajectorySummaryVersion, + AgentTrajectoryVerification, + AgentVerificationStrength, + AgentVerifier, + AgentVerifierAssertionOutcome, + AgentVerifierEvidenceInvalidationResult, + AgentVerifierPrincipal, + AgentVerifierPrincipalBinding, + AgentVerifierPrincipalBindingInput, + AgentVerifierStatus, ApiError, ArtifactListRequest, AsyncResult, Batch, BatchItem, BatchItemInput, + BatchItemInputDataType, + BatchItemInputRole, + BatchItemInputType, BatchItemKind, BatchItemPage, BatchItemStatus, BatchItemsResponse, BatchPage, + CloneGraphRequest, CloneGraphResult, - ComparisonOperator, + ContentPolicy, + ContentPolicyCategory, + ContentPolicyCategoryRequest, + ContentPolicyEvent, + ContentPolicyEventArtifactKind, + ContentPolicyEventDropReason, + ContentPolicyEventPage, + ContentPolicyRevisionPage, + ContentPolicyRule, + ContentPolicyRuleRequest, ContextEdge, ContextEpisode, ContextNode, @@ -35,12 +136,23 @@ ContextTemplate, ContextTemplatePage, ContextThreadSummary, + CreateAgentRequest, CreateContextTemplateRequest, CustomInstruction, DateFilter, + DateFilterField, + DateFilterGroup, + DateFilterOperator, + DateFilters, + DebugLogEntry, + DebugLogLevel, + DebugLogStatus, + DebugLoggingEnablement, + DeleteAgentTrajectoryRequest, DocumentSummary, DocumentSummaryPage, Edge, + EdgeInput, EdgeNodeRef, EdgePage, EdgeSourceTarget, @@ -49,15 +161,37 @@ EntityPropertyType, EntityType, Episode, - EpisodeMetadataFilter, + EpisodeContentPolicy, + EpisodeContentPolicyStatus, + EpisodeDebugLog, EpisodePage, ErrorBody, Graph, + GraphContentPolicy, + GraphContentPolicyRequest, GraphContextResponse, GraphDataType, GraphDeleteResult, GraphPage, - GraphitiMetadataFilterGroupType, + Hyperedge, + HyperedgeEdge, + HyperedgeInput, + HyperedgePage, + ImportedTrajectoryReference, + IngestionTrace, + IngestionTraceEdge, + IngestionTraceEdgeInvalidation, + IngestionTraceEdgeReference, + IngestionTraceEntityType, + IngestionTraceEpisode, + IngestionTraceInput, + IngestionTraceNode, + IngestionTraceNodeDuplicate, + IngestionTraceNodeResolution, + IngestionTraceOutput, + IngestionTracePage, + IngestionTraceStatus, + IngestionTraceStep, Instructions, LookupBatchResponse, LookupItem, @@ -65,27 +199,60 @@ MembershipMutationResult, Message, MessagePage, + MetadataFilter, MetadataFilterGroup, + MetadataFilterGroupType, + MetadataFilterOperator, + MetadataFilterValue, + MetadataFilterValueThreeItem, MutateMembersRequest, NeighborEntry, NeighborPage, Node, NodeInput, NodePage, + ObjectiveMappingRule, + ObjectiveMappingRuleSource, Observation, ObservationPage, ObservationSteering, ObservationType, Ontology, + OutcomeMappingRule, + OutcomeMappingRuleRule, + Pagev4AgentSkillCandidateReviewSummary, + Pagev4AgentSkillCompilationOutcome, + Pagev4AgentSkillEvidence, + Pagev4AgentSkillRelationship, + Pagev4AgentSkillSearchHit, + Pagev4AgentSkillVersion, + Pagev4AgentVerifier, ProcessBatchResult, Project, PropertyFilter, + PropertyFilterOperator, + PropertyFilterValue, + PropertyFilterValueThreeItem, RoleType, SearchFilters, SearchListRequest, SearchRequest, + SearchRequestReranker, + SkillDefinition, + SkillDefinitionSection, + SkillFailure, + SkillProcedureStep, + SkillRelation, + SkillResource, + SourceSpan, + SourceTrace, + SourceTracePage, + SourceTraceResponse, + SourceTraceSummary, SubgraphResponse, Task, + TaskFamilyMappingRule, + TaskFamilyMappingRuleSource, TaskPage, TaskProgress, Thread, @@ -94,6 +261,32 @@ ThreadPage, ThreadSummary, ThreadSummaryPage, + TraceConnection, + TraceConnectionPage, + TraceConnectionSettings, + TraceFilter, + TracePreview, + TraceProviderProject, + TraceProviderProjectPage, + TraceScoreRange, + TrajectoryContentMapping, + TrajectoryImport, + TrajectoryImportPage, + TrajectoryImportPauseReason, + TrajectoryImportRun, + TrajectoryImportRunItem, + TrajectoryImportRunItemPage, + TrajectoryImportRunPage, + TrajectoryImportRunReference, + TrajectoryImportRunReferenceStatus, + TrajectoryImportRunReferenceTrigger, + TrajectoryImportSchedule, + TrajectoryImportSelection, + TrajectoryMapping, + TrajectoryMappingIncludeOutcomesItem, + TrajectoryMappingResult, + TrajectoryMappingResultOutcome, + TrajectoryMappingResultOutcomeRule, User, UserDeleteResult, UserGroup, @@ -101,41 +294,173 @@ UserInstruction, UserPage, UserSummaryInstructions, - V4BatchItemInputDataType, - V4BatchItemInputRole, - V4BatchItemInputType, - V4SearchRequestReranker, ) - from .errors import BadRequestError, ConflictError, ForbiddenError, NotFoundError, UnauthorizedError - from . import batch, context, graph, lookup, project, task, thread, user, user_group + from .errors import ( + BadGatewayError, + BadRequestError, + ConflictError, + ContentTooLargeError, + ForbiddenError, + NotFoundError, + ServiceUnavailableError, + UnauthorizedError, + UnprocessableEntityError, + ) + from . import ( + agent, + batch, + context, + debug_log, + graph, + lookup, + project, + task, + thread, + trace_connection, + user, + user_group, + ) + from ._default_clients import DefaultAioHttpClient, DefaultAsyncHttpxClient + from .batch import BatchListRequestStatus from .client import AsyncZep, Zep from .environment import ZepEnvironment - from .graph import V4GraphContextRequestRecencyBias, V4SubgraphRequestDirection + from .graph import ( + GraphContextRequestRecencyBias, + GraphListRequestOrder, + GraphListRequestOrderBy, + SubgraphRequestDirection, + ) + from .thread import ThreadListMessagesRequestOrder, ThreadListRequestOrder, ThreadListRequestOrderBy + from .user import UserListRequestOrder, UserListRequestOrderBy from .version import __version__ _dynamic_imports: typing.Dict[str, str] = { - "AddEdgeResult": ".types", + "AddAgentSkillUseOutcomeRequest": ".types", + "AddAgentSkillUseOutcomeRequestOutcome": ".types", + "AddEdgesResult": ".types", "AddEpisodeResult": ".types", + "AddHyperedgeEdgeResult": ".types", + "AddHyperedgeResult": ".types", "AddMessage": ".types", "AddMessagesResult": ".types", "AddNodesResult": ".types", "AddedEdge": ".types", + "AddedHyperedge": ".types", + "AddedHyperedgeEdge": ".types", "AddedNode": ".types", + "Agent": ".types", + "AgentBreakingChange": ".types", + "AgentContext": ".types", + "AgentContextEvidenceCounts": ".types", + "AgentContextPartialSource": ".types", + "AgentContextResource": ".types", + "AgentContextSkillSnapshot": ".types", + "AgentContextSkippedSkill": ".types", + "AgentDeleteResult": ".types", + "AgentLearningState": ".types", + "AgentLiteralPolicy": ".types", + "AgentLiteralPolicyClasses": ".types", + "AgentLiteralPolicyValues": ".types", + "AgentMemoryEvaluationPolicy": ".types", + "AgentMemoryEvaluationRequirement": ".types", + "AgentMemorySettings": ".types", + "AgentMemorySettingsApproval": ".types", + "AgentMemorySettingsCompilationMode": ".types", + "AgentPage": ".types", + "AgentSkill": ".types", + "AgentSkillAdmissionDecision": ".types", + "AgentSkillCandidate": ".types", + "AgentSkillCandidateBaseVersion": ".types", + "AgentSkillCandidateEvaluation": ".types", + "AgentSkillCandidateEvidence": ".types", + "AgentSkillCandidateReview": ".types", + "AgentSkillCandidateReviewResult": ".types", + "AgentSkillCandidateReviewSummary": ".types", + "AgentSkillCompilationOutcome": ".types", + "AgentSkillCompilationOutcomeRejectionClass": ".types", + "AgentSkillEvaluation": ".types", + "AgentSkillEvidence": ".types", + "AgentSkillPublicationLineage": ".types", + "AgentSkillRelationship": ".types", + "AgentSkillSearchHit": ".types", + "AgentSkillSearchHitMaturity": ".types", + "AgentSkillSearchResponse": ".types", + "AgentSkillUse": ".types", + "AgentSkillUseOutcome": ".types", + "AgentSkillVersion": ".types", + "AgentSkillVersionComparison": ".types", + "AgentSplitPlan": ".types", + "AgentSplitPlanDestination": ".types", + "AgentSplitPlanDestinationRequest": ".types", + "AgentSplitPlanSkillReference": ".types", + "AgentSplitPlanSkillSelectionRequest": ".types", + "AgentSplitPlanSource": ".types", + "AgentStatus": ".types", + "AgentTrajectory": ".types", + "AgentTrajectoryCloseVerifier": ".types", + "AgentTrajectoryEvent": ".types", + "AgentTrajectoryEventContext": ".types", + "AgentTrajectoryEventPage": ".types", + "AgentTrajectoryEventProcessingState": ".types", + "AgentTrajectoryEventSource": ".types", + "AgentTrajectoryEventSourceCopyMode": ".types", + "AgentTrajectoryEventSourceRetentionMode": ".types", + "AgentTrajectoryEventType": ".types", + "AgentTrajectoryFinalizationResult": ".types", + "AgentTrajectoryInternal": ".types", + "AgentTrajectoryLifecycle": ".types", + "AgentTrajectoryOutcome": ".types", + "AgentTrajectoryPage": ".types", + "AgentTrajectoryProcessingState": ".types", + "AgentTrajectoryResourceRef": ".types", + "AgentTrajectorySequenceRange": ".types", + "AgentTrajectorySource": ".types", + "AgentTrajectorySourceDeletionResult": ".types", + "AgentTrajectorySummaryCreationReason": ".types", + "AgentTrajectorySummaryOmissionReason": ".types", + "AgentTrajectorySummaryOmittedRange": ".types", + "AgentTrajectorySummaryPage": ".types", + "AgentTrajectorySummaryVersion": ".types", + "AgentTrajectoryVerification": ".types", + "AgentVerificationStrength": ".types", + "AgentVerifier": ".types", + "AgentVerifierAssertionOutcome": ".types", + "AgentVerifierEvidenceInvalidationResult": ".types", + "AgentVerifierPrincipal": ".types", + "AgentVerifierPrincipalBinding": ".types", + "AgentVerifierPrincipalBindingInput": ".types", + "AgentVerifierStatus": ".types", "ApiError": ".types", "ArtifactListRequest": ".types", "AsyncResult": ".types", "AsyncZep": ".client", + "BadGatewayError": ".errors", "BadRequestError": ".errors", "Batch": ".types", "BatchItem": ".types", "BatchItemInput": ".types", + "BatchItemInputDataType": ".types", + "BatchItemInputRole": ".types", + "BatchItemInputType": ".types", "BatchItemKind": ".types", "BatchItemPage": ".types", "BatchItemStatus": ".types", "BatchItemsResponse": ".types", + "BatchListRequestStatus": ".batch", "BatchPage": ".types", + "CloneGraphRequest": ".types", "CloneGraphResult": ".types", - "ComparisonOperator": ".types", "ConflictError": ".errors", + "ContentPolicy": ".types", + "ContentPolicyCategory": ".types", + "ContentPolicyCategoryRequest": ".types", + "ContentPolicyEvent": ".types", + "ContentPolicyEventArtifactKind": ".types", + "ContentPolicyEventDropReason": ".types", + "ContentPolicyEventPage": ".types", + "ContentPolicyRevisionPage": ".types", + "ContentPolicyRule": ".types", + "ContentPolicyRuleRequest": ".types", + "ContentTooLargeError": ".errors", "ContextEdge": ".types", "ContextEpisode": ".types", "ContextNode": ".types", @@ -144,12 +469,25 @@ "ContextTemplate": ".types", "ContextTemplatePage": ".types", "ContextThreadSummary": ".types", + "CreateAgentRequest": ".types", "CreateContextTemplateRequest": ".types", "CustomInstruction": ".types", "DateFilter": ".types", + "DateFilterField": ".types", + "DateFilterGroup": ".types", + "DateFilterOperator": ".types", + "DateFilters": ".types", + "DebugLogEntry": ".types", + "DebugLogLevel": ".types", + "DebugLogStatus": ".types", + "DebugLoggingEnablement": ".types", + "DefaultAioHttpClient": "._default_clients", + "DefaultAsyncHttpxClient": "._default_clients", + "DeleteAgentTrajectoryRequest": ".types", "DocumentSummary": ".types", "DocumentSummaryPage": ".types", "Edge": ".types", + "EdgeInput": ".types", "EdgeNodeRef": ".types", "EdgePage": ".types", "EdgeSourceTarget": ".types", @@ -158,16 +496,41 @@ "EntityPropertyType": ".types", "EntityType": ".types", "Episode": ".types", - "EpisodeMetadataFilter": ".types", + "EpisodeContentPolicy": ".types", + "EpisodeContentPolicyStatus": ".types", + "EpisodeDebugLog": ".types", "EpisodePage": ".types", "ErrorBody": ".types", "ForbiddenError": ".errors", "Graph": ".types", + "GraphContentPolicy": ".types", + "GraphContentPolicyRequest": ".types", + "GraphContextRequestRecencyBias": ".graph", "GraphContextResponse": ".types", "GraphDataType": ".types", "GraphDeleteResult": ".types", + "GraphListRequestOrder": ".graph", + "GraphListRequestOrderBy": ".graph", "GraphPage": ".types", - "GraphitiMetadataFilterGroupType": ".types", + "Hyperedge": ".types", + "HyperedgeEdge": ".types", + "HyperedgeInput": ".types", + "HyperedgePage": ".types", + "ImportedTrajectoryReference": ".types", + "IngestionTrace": ".types", + "IngestionTraceEdge": ".types", + "IngestionTraceEdgeInvalidation": ".types", + "IngestionTraceEdgeReference": ".types", + "IngestionTraceEntityType": ".types", + "IngestionTraceEpisode": ".types", + "IngestionTraceInput": ".types", + "IngestionTraceNode": ".types", + "IngestionTraceNodeDuplicate": ".types", + "IngestionTraceNodeResolution": ".types", + "IngestionTraceOutput": ".types", + "IngestionTracePage": ".types", + "IngestionTraceStatus": ".types", + "IngestionTraceStep": ".types", "Instructions": ".types", "LookupBatchResponse": ".types", "LookupItem": ".types", @@ -175,7 +538,12 @@ "MembershipMutationResult": ".types", "Message": ".types", "MessagePage": ".types", + "MetadataFilter": ".types", "MetadataFilterGroup": ".types", + "MetadataFilterGroupType": ".types", + "MetadataFilterOperator": ".types", + "MetadataFilterValue": ".types", + "MetadataFilterValueThreeItem": ".types", "MutateMembersRequest": ".types", "NeighborEntry": ".types", "NeighborPage": ".types", @@ -183,52 +551,111 @@ "NodeInput": ".types", "NodePage": ".types", "NotFoundError": ".errors", + "ObjectiveMappingRule": ".types", + "ObjectiveMappingRuleSource": ".types", "Observation": ".types", "ObservationPage": ".types", "ObservationSteering": ".types", "ObservationType": ".types", "Ontology": ".types", + "OutcomeMappingRule": ".types", + "OutcomeMappingRuleRule": ".types", + "Pagev4AgentSkillCandidateReviewSummary": ".types", + "Pagev4AgentSkillCompilationOutcome": ".types", + "Pagev4AgentSkillEvidence": ".types", + "Pagev4AgentSkillRelationship": ".types", + "Pagev4AgentSkillSearchHit": ".types", + "Pagev4AgentSkillVersion": ".types", + "Pagev4AgentVerifier": ".types", "ProcessBatchResult": ".types", "Project": ".types", "PropertyFilter": ".types", + "PropertyFilterOperator": ".types", + "PropertyFilterValue": ".types", + "PropertyFilterValueThreeItem": ".types", "RoleType": ".types", "SearchFilters": ".types", "SearchListRequest": ".types", "SearchRequest": ".types", + "SearchRequestReranker": ".types", + "ServiceUnavailableError": ".errors", + "SkillDefinition": ".types", + "SkillDefinitionSection": ".types", + "SkillFailure": ".types", + "SkillProcedureStep": ".types", + "SkillRelation": ".types", + "SkillResource": ".types", + "SourceSpan": ".types", + "SourceTrace": ".types", + "SourceTracePage": ".types", + "SourceTraceResponse": ".types", + "SourceTraceSummary": ".types", + "SubgraphRequestDirection": ".graph", "SubgraphResponse": ".types", "Task": ".types", + "TaskFamilyMappingRule": ".types", + "TaskFamilyMappingRuleSource": ".types", "TaskPage": ".types", "TaskProgress": ".types", "Thread": ".types", "ThreadContextResponse": ".types", "ThreadDeleteResult": ".types", + "ThreadListMessagesRequestOrder": ".thread", + "ThreadListRequestOrder": ".thread", + "ThreadListRequestOrderBy": ".thread", "ThreadPage": ".types", "ThreadSummary": ".types", "ThreadSummaryPage": ".types", + "TraceConnection": ".types", + "TraceConnectionPage": ".types", + "TraceConnectionSettings": ".types", + "TraceFilter": ".types", + "TracePreview": ".types", + "TraceProviderProject": ".types", + "TraceProviderProjectPage": ".types", + "TraceScoreRange": ".types", + "TrajectoryContentMapping": ".types", + "TrajectoryImport": ".types", + "TrajectoryImportPage": ".types", + "TrajectoryImportPauseReason": ".types", + "TrajectoryImportRun": ".types", + "TrajectoryImportRunItem": ".types", + "TrajectoryImportRunItemPage": ".types", + "TrajectoryImportRunPage": ".types", + "TrajectoryImportRunReference": ".types", + "TrajectoryImportRunReferenceStatus": ".types", + "TrajectoryImportRunReferenceTrigger": ".types", + "TrajectoryImportSchedule": ".types", + "TrajectoryImportSelection": ".types", + "TrajectoryMapping": ".types", + "TrajectoryMappingIncludeOutcomesItem": ".types", + "TrajectoryMappingResult": ".types", + "TrajectoryMappingResultOutcome": ".types", + "TrajectoryMappingResultOutcomeRule": ".types", "UnauthorizedError": ".errors", + "UnprocessableEntityError": ".errors", "User": ".types", "UserDeleteResult": ".types", "UserGroup": ".types", "UserGroupPage": ".types", "UserInstruction": ".types", + "UserListRequestOrder": ".user", + "UserListRequestOrderBy": ".user", "UserPage": ".types", "UserSummaryInstructions": ".types", - "V4BatchItemInputDataType": ".types", - "V4BatchItemInputRole": ".types", - "V4BatchItemInputType": ".types", - "V4GraphContextRequestRecencyBias": ".graph", - "V4SearchRequestReranker": ".types", - "V4SubgraphRequestDirection": ".graph", "Zep": ".client", "ZepEnvironment": ".environment", "__version__": ".version", + "agent": ".agent", "batch": ".batch", "context": ".context", + "debug_log": ".debug_log", "graph": ".graph", "lookup": ".lookup", "project": ".project", "task": ".task", "thread": ".thread", + "trace_connection": ".trace_connection", "user": ".user", "user_group": ".user_group", } @@ -256,29 +683,133 @@ def __dir__(): __all__ = [ - "AddEdgeResult", + "AddAgentSkillUseOutcomeRequest", + "AddAgentSkillUseOutcomeRequestOutcome", + "AddEdgesResult", "AddEpisodeResult", + "AddHyperedgeEdgeResult", + "AddHyperedgeResult", "AddMessage", "AddMessagesResult", "AddNodesResult", "AddedEdge", + "AddedHyperedge", + "AddedHyperedgeEdge", "AddedNode", + "Agent", + "AgentBreakingChange", + "AgentContext", + "AgentContextEvidenceCounts", + "AgentContextPartialSource", + "AgentContextResource", + "AgentContextSkillSnapshot", + "AgentContextSkippedSkill", + "AgentDeleteResult", + "AgentLearningState", + "AgentLiteralPolicy", + "AgentLiteralPolicyClasses", + "AgentLiteralPolicyValues", + "AgentMemoryEvaluationPolicy", + "AgentMemoryEvaluationRequirement", + "AgentMemorySettings", + "AgentMemorySettingsApproval", + "AgentMemorySettingsCompilationMode", + "AgentPage", + "AgentSkill", + "AgentSkillAdmissionDecision", + "AgentSkillCandidate", + "AgentSkillCandidateBaseVersion", + "AgentSkillCandidateEvaluation", + "AgentSkillCandidateEvidence", + "AgentSkillCandidateReview", + "AgentSkillCandidateReviewResult", + "AgentSkillCandidateReviewSummary", + "AgentSkillCompilationOutcome", + "AgentSkillCompilationOutcomeRejectionClass", + "AgentSkillEvaluation", + "AgentSkillEvidence", + "AgentSkillPublicationLineage", + "AgentSkillRelationship", + "AgentSkillSearchHit", + "AgentSkillSearchHitMaturity", + "AgentSkillSearchResponse", + "AgentSkillUse", + "AgentSkillUseOutcome", + "AgentSkillVersion", + "AgentSkillVersionComparison", + "AgentSplitPlan", + "AgentSplitPlanDestination", + "AgentSplitPlanDestinationRequest", + "AgentSplitPlanSkillReference", + "AgentSplitPlanSkillSelectionRequest", + "AgentSplitPlanSource", + "AgentStatus", + "AgentTrajectory", + "AgentTrajectoryCloseVerifier", + "AgentTrajectoryEvent", + "AgentTrajectoryEventContext", + "AgentTrajectoryEventPage", + "AgentTrajectoryEventProcessingState", + "AgentTrajectoryEventSource", + "AgentTrajectoryEventSourceCopyMode", + "AgentTrajectoryEventSourceRetentionMode", + "AgentTrajectoryEventType", + "AgentTrajectoryFinalizationResult", + "AgentTrajectoryInternal", + "AgentTrajectoryLifecycle", + "AgentTrajectoryOutcome", + "AgentTrajectoryPage", + "AgentTrajectoryProcessingState", + "AgentTrajectoryResourceRef", + "AgentTrajectorySequenceRange", + "AgentTrajectorySource", + "AgentTrajectorySourceDeletionResult", + "AgentTrajectorySummaryCreationReason", + "AgentTrajectorySummaryOmissionReason", + "AgentTrajectorySummaryOmittedRange", + "AgentTrajectorySummaryPage", + "AgentTrajectorySummaryVersion", + "AgentTrajectoryVerification", + "AgentVerificationStrength", + "AgentVerifier", + "AgentVerifierAssertionOutcome", + "AgentVerifierEvidenceInvalidationResult", + "AgentVerifierPrincipal", + "AgentVerifierPrincipalBinding", + "AgentVerifierPrincipalBindingInput", + "AgentVerifierStatus", "ApiError", "ArtifactListRequest", "AsyncResult", "AsyncZep", + "BadGatewayError", "BadRequestError", "Batch", "BatchItem", "BatchItemInput", + "BatchItemInputDataType", + "BatchItemInputRole", + "BatchItemInputType", "BatchItemKind", "BatchItemPage", "BatchItemStatus", "BatchItemsResponse", + "BatchListRequestStatus", "BatchPage", + "CloneGraphRequest", "CloneGraphResult", - "ComparisonOperator", "ConflictError", + "ContentPolicy", + "ContentPolicyCategory", + "ContentPolicyCategoryRequest", + "ContentPolicyEvent", + "ContentPolicyEventArtifactKind", + "ContentPolicyEventDropReason", + "ContentPolicyEventPage", + "ContentPolicyRevisionPage", + "ContentPolicyRule", + "ContentPolicyRuleRequest", + "ContentTooLargeError", "ContextEdge", "ContextEpisode", "ContextNode", @@ -287,12 +818,25 @@ def __dir__(): "ContextTemplate", "ContextTemplatePage", "ContextThreadSummary", + "CreateAgentRequest", "CreateContextTemplateRequest", "CustomInstruction", "DateFilter", + "DateFilterField", + "DateFilterGroup", + "DateFilterOperator", + "DateFilters", + "DebugLogEntry", + "DebugLogLevel", + "DebugLogStatus", + "DebugLoggingEnablement", + "DefaultAioHttpClient", + "DefaultAsyncHttpxClient", + "DeleteAgentTrajectoryRequest", "DocumentSummary", "DocumentSummaryPage", "Edge", + "EdgeInput", "EdgeNodeRef", "EdgePage", "EdgeSourceTarget", @@ -301,16 +845,41 @@ def __dir__(): "EntityPropertyType", "EntityType", "Episode", - "EpisodeMetadataFilter", + "EpisodeContentPolicy", + "EpisodeContentPolicyStatus", + "EpisodeDebugLog", "EpisodePage", "ErrorBody", "ForbiddenError", "Graph", + "GraphContentPolicy", + "GraphContentPolicyRequest", + "GraphContextRequestRecencyBias", "GraphContextResponse", "GraphDataType", "GraphDeleteResult", + "GraphListRequestOrder", + "GraphListRequestOrderBy", "GraphPage", - "GraphitiMetadataFilterGroupType", + "Hyperedge", + "HyperedgeEdge", + "HyperedgeInput", + "HyperedgePage", + "ImportedTrajectoryReference", + "IngestionTrace", + "IngestionTraceEdge", + "IngestionTraceEdgeInvalidation", + "IngestionTraceEdgeReference", + "IngestionTraceEntityType", + "IngestionTraceEpisode", + "IngestionTraceInput", + "IngestionTraceNode", + "IngestionTraceNodeDuplicate", + "IngestionTraceNodeResolution", + "IngestionTraceOutput", + "IngestionTracePage", + "IngestionTraceStatus", + "IngestionTraceStep", "Instructions", "LookupBatchResponse", "LookupItem", @@ -318,7 +887,12 @@ def __dir__(): "MembershipMutationResult", "Message", "MessagePage", + "MetadataFilter", "MetadataFilterGroup", + "MetadataFilterGroupType", + "MetadataFilterOperator", + "MetadataFilterValue", + "MetadataFilterValueThreeItem", "MutateMembersRequest", "NeighborEntry", "NeighborPage", @@ -326,52 +900,111 @@ def __dir__(): "NodeInput", "NodePage", "NotFoundError", + "ObjectiveMappingRule", + "ObjectiveMappingRuleSource", "Observation", "ObservationPage", "ObservationSteering", "ObservationType", "Ontology", + "OutcomeMappingRule", + "OutcomeMappingRuleRule", + "Pagev4AgentSkillCandidateReviewSummary", + "Pagev4AgentSkillCompilationOutcome", + "Pagev4AgentSkillEvidence", + "Pagev4AgentSkillRelationship", + "Pagev4AgentSkillSearchHit", + "Pagev4AgentSkillVersion", + "Pagev4AgentVerifier", "ProcessBatchResult", "Project", "PropertyFilter", + "PropertyFilterOperator", + "PropertyFilterValue", + "PropertyFilterValueThreeItem", "RoleType", "SearchFilters", "SearchListRequest", "SearchRequest", + "SearchRequestReranker", + "ServiceUnavailableError", + "SkillDefinition", + "SkillDefinitionSection", + "SkillFailure", + "SkillProcedureStep", + "SkillRelation", + "SkillResource", + "SourceSpan", + "SourceTrace", + "SourceTracePage", + "SourceTraceResponse", + "SourceTraceSummary", + "SubgraphRequestDirection", "SubgraphResponse", "Task", + "TaskFamilyMappingRule", + "TaskFamilyMappingRuleSource", "TaskPage", "TaskProgress", "Thread", "ThreadContextResponse", "ThreadDeleteResult", + "ThreadListMessagesRequestOrder", + "ThreadListRequestOrder", + "ThreadListRequestOrderBy", "ThreadPage", "ThreadSummary", "ThreadSummaryPage", + "TraceConnection", + "TraceConnectionPage", + "TraceConnectionSettings", + "TraceFilter", + "TracePreview", + "TraceProviderProject", + "TraceProviderProjectPage", + "TraceScoreRange", + "TrajectoryContentMapping", + "TrajectoryImport", + "TrajectoryImportPage", + "TrajectoryImportPauseReason", + "TrajectoryImportRun", + "TrajectoryImportRunItem", + "TrajectoryImportRunItemPage", + "TrajectoryImportRunPage", + "TrajectoryImportRunReference", + "TrajectoryImportRunReferenceStatus", + "TrajectoryImportRunReferenceTrigger", + "TrajectoryImportSchedule", + "TrajectoryImportSelection", + "TrajectoryMapping", + "TrajectoryMappingIncludeOutcomesItem", + "TrajectoryMappingResult", + "TrajectoryMappingResultOutcome", + "TrajectoryMappingResultOutcomeRule", "UnauthorizedError", + "UnprocessableEntityError", "User", "UserDeleteResult", "UserGroup", "UserGroupPage", "UserInstruction", + "UserListRequestOrder", + "UserListRequestOrderBy", "UserPage", "UserSummaryInstructions", - "V4BatchItemInputDataType", - "V4BatchItemInputRole", - "V4BatchItemInputType", - "V4GraphContextRequestRecencyBias", - "V4SearchRequestReranker", - "V4SubgraphRequestDirection", "Zep", "ZepEnvironment", "__version__", + "agent", "batch", "context", + "debug_log", "graph", "lookup", "project", "task", "thread", + "trace_connection", "user", "user_group", ] diff --git a/src/zep_cloud/_default_clients.py b/src/zep_cloud/_default_clients.py new file mode 100644 index 00000000..f4e918c2 --- /dev/null +++ b/src/zep_cloud/_default_clients.py @@ -0,0 +1,30 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import httpx + +SDK_DEFAULT_TIMEOUT = 60 + +try: + import httpx_aiohttp # type: ignore[import-not-found] +except ImportError: + + class DefaultAioHttpClient(httpx.AsyncClient): # type: ignore + def __init__(self, **kwargs: typing.Any) -> None: + raise RuntimeError("To use the aiohttp client, install the aiohttp extra: pip install zep-cloud[aiohttp]") + +else: + + class DefaultAioHttpClient(httpx_aiohttp.HttpxAiohttpClient): # type: ignore + def __init__(self, **kwargs: typing.Any) -> None: + kwargs.setdefault("timeout", SDK_DEFAULT_TIMEOUT) + kwargs.setdefault("follow_redirects", True) + super().__init__(**kwargs) + + +class DefaultAsyncHttpxClient(httpx.AsyncClient): + def __init__(self, **kwargs: typing.Any) -> None: + kwargs.setdefault("timeout", SDK_DEFAULT_TIMEOUT) + kwargs.setdefault("follow_redirects", True) + super().__init__(**kwargs) diff --git a/src/zep_cloud/agent/__init__.py b/src/zep_cloud/agent/__init__.py new file mode 100644 index 00000000..12344901 --- /dev/null +++ b/src/zep_cloud/agent/__init__.py @@ -0,0 +1,62 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from . import learning, literal_policy, skill, split, trajectory, trajectory_import, verifier + from .literal_policy import UpdateAgentLiteralPolicyRequestDefault + from .skill import AgentSkillSearchRequestMarkdownFormat + from .trajectory import TrajectoryListRequestSourceKind + from .trajectory_import import TrajectoryImportDeleteRequestTrajectories +_dynamic_imports: typing.Dict[str, str] = { + "AgentSkillSearchRequestMarkdownFormat": ".skill", + "TrajectoryImportDeleteRequestTrajectories": ".trajectory_import", + "TrajectoryListRequestSourceKind": ".trajectory", + "UpdateAgentLiteralPolicyRequestDefault": ".literal_policy", + "learning": ".learning", + "literal_policy": ".literal_policy", + "skill": ".skill", + "split": ".split", + "trajectory": ".trajectory", + "trajectory_import": ".trajectory_import", + "verifier": ".verifier", +} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = [ + "AgentSkillSearchRequestMarkdownFormat", + "TrajectoryImportDeleteRequestTrajectories", + "TrajectoryListRequestSourceKind", + "UpdateAgentLiteralPolicyRequestDefault", + "learning", + "literal_policy", + "skill", + "split", + "trajectory", + "trajectory_import", + "verifier", +] diff --git a/src/zep_cloud/agent/client.py b/src/zep_cloud/agent/client.py new file mode 100644 index 00000000..cd545428 --- /dev/null +++ b/src/zep_cloud/agent/client.py @@ -0,0 +1,1086 @@ +# This file was auto-generated by Fern from our API Definition. + +from __future__ import annotations + +import typing + +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.pagination import AsyncPager, SyncPager +from ..core.request_options import RequestOptions +from ..types.agent import Agent +from ..types.agent_breaking_change import AgentBreakingChange +from ..types.agent_context import AgentContext +from ..types.agent_context_resource import AgentContextResource +from ..types.agent_delete_result import AgentDeleteResult +from ..types.agent_memory_settings import AgentMemorySettings +from ..types.agent_page import AgentPage +from ..types.agent_status import AgentStatus +from .raw_client import AsyncRawAgentClient, RawAgentClient + +if typing.TYPE_CHECKING: + from .learning.client import AsyncLearningClient, LearningClient + from .literal_policy.client import AsyncLiteralPolicyClient, LiteralPolicyClient + from .skill.client import AsyncSkillClient, SkillClient + from .split.client import AsyncSplitClient, SplitClient + from .trajectory.client import AsyncTrajectoryClient, TrajectoryClient + from .trajectory_import.client import AsyncTrajectoryImportClient, TrajectoryImportClient + from .verifier.client import AsyncVerifierClient, VerifierClient +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class AgentClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawAgentClient(client_wrapper=client_wrapper) + self._client_wrapper = client_wrapper + self._learning: typing.Optional[LearningClient] = None + self._literal_policy: typing.Optional[LiteralPolicyClient] = None + self._skill: typing.Optional[SkillClient] = None + self._split: typing.Optional[SplitClient] = None + self._trajectory: typing.Optional[TrajectoryClient] = None + self._trajectory_import: typing.Optional[TrajectoryImportClient] = None + self._verifier: typing.Optional[VerifierClient] = None + + @property + def with_raw_response(self) -> RawAgentClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawAgentClient + """ + return self._raw_client + + def create( + self, + *, + agent_id: str, + name: str, + security_domain: str, + deployment_id: typing.Optional[str] = OMIT, + description: typing.Optional[str] = OMIT, + memory_settings: typing.Optional[AgentMemorySettings] = OMIT, + metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + version: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> Agent: + """ + Parameters + ---------- + agent_id : str + The developer-assigned Agent identifier, unique within the project. + + name : str + The Agent's display name. + + security_domain : str + The immutable boundary within which Skills may be synthesized. 1 to 200 characters of lowercase letters, digits, and the characters : . - _ + + deployment_id : typing.Optional[str] + The customer deployment this Agent represents. + + description : typing.Optional[str] + A human-readable description of the Agent. + + memory_settings : typing.Optional[AgentMemorySettings] + Agent Memory capture, compilation, and promotion settings. + + metadata : typing.Optional[typing.Dict[str, typing.Any]] + Developer metadata used to organize and filter Agents. + + version : typing.Optional[str] + The customer deployment version this Agent represents. If you omit it, the version is "default". + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Agent + Created + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.create( + agent_id="agent_id", + name="name", + security_domain="security_domain", + ) + """ + _response = self._raw_client.create( + agent_id=agent_id, + name=name, + security_domain=security_domain, + deployment_id=deployment_id, + description=description, + memory_settings=memory_settings, + metadata=metadata, + version=version, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + def list( + self, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + agent_id: typing.Optional[str] = OMIT, + deployment_id: typing.Optional[str] = OMIT, + metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + status: typing.Optional[AgentStatus] = OMIT, + version: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[Agent, AgentPage]: + """ + Parameters + ---------- + limit : typing.Optional[int] + Page size (maximum 100) + + cursor : typing.Optional[str] + Opaque page cursor + + agent_id : typing.Optional[str] + Filters to the exact developer-assigned Agent identifier. + + deployment_id : typing.Optional[str] + Filters to the exact deployment identifier. + + metadata : typing.Optional[typing.Dict[str, typing.Any]] + Filters to Agents whose metadata contains these key-value pairs. + + status : typing.Optional[AgentStatus] + Filters to lifecycle status. Omit to include every status. + + version : typing.Optional[str] + Filters to the exact deployment version. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[Agent, AgentPage] + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + response = client.agent.list() + for item in response: + yield item + # alternatively, you can paginate page-by-page + for page in response.iter_pages(): + yield page + """ + return self._raw_client.list( + limit=limit, + cursor=cursor, + agent_id=agent_id, + deployment_id=deployment_id, + metadata=metadata, + status=status, + version=version, + request_options=request_options, + ) + + def get(self, agent_uuid: str, *, request_options: typing.Optional[RequestOptions] = None) -> Agent: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Agent + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.get( + agent_uuid="agent_uuid", + ) + """ + _response = self._raw_client.get(agent_uuid, request_options=request_options) + return _response.data + + def delete( + self, + agent_uuid: str, + *, + expected_revision: int, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentDeleteResult: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + expected_revision : int + The current Agent revision used for optimistic concurrency. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentDeleteResult + Accepted + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.delete( + agent_uuid="agent_uuid", + expected_revision=1, + ) + """ + _response = self._raw_client.delete( + agent_uuid, + expected_revision=expected_revision, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + def update( + self, + agent_uuid: str, + *, + expected_revision: int, + deployment_id: typing.Optional[str] = OMIT, + description: typing.Optional[str] = OMIT, + memory_settings: typing.Optional[AgentMemorySettings] = OMIT, + metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + name: typing.Optional[str] = OMIT, + version: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> Agent: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + expected_revision : int + The current Agent revision used for optimistic concurrency. + + deployment_id : typing.Optional[str] + The customer deployment this Agent represents. Set to null to clear it. + + description : typing.Optional[str] + A human-readable description of the Agent. Set to null to clear it. + + memory_settings : typing.Optional[AgentMemorySettings] + Replacement Agent Memory settings. Set to null to restore defaults. + + metadata : typing.Optional[typing.Dict[str, typing.Any]] + Replacement developer metadata. Set to null to clear it. + + name : typing.Optional[str] + The Agent's display name. + + version : typing.Optional[str] + The customer deployment version this Agent represents. Set to null to clear it. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Agent + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.update( + agent_uuid="agent_uuid", + expected_revision=1, + ) + """ + _response = self._raw_client.update( + agent_uuid, + expected_revision=expected_revision, + deployment_id=deployment_id, + description=description, + memory_settings=memory_settings, + metadata=metadata, + name=name, + version=version, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + def declare_breaking_change( + self, + agent_uuid: str, + *, + expected_revision: int, + version: str, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentBreakingChange: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + expected_revision : int + + version : str + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentBreakingChange + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.declare_breaking_change( + agent_uuid="agent_uuid", + expected_revision=1, + version="version", + ) + """ + _response = self._raw_client.declare_breaking_change( + agent_uuid, + expected_revision=expected_revision, + version=version, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + def get_context( + self, + agent_uuid: str, + *, + environments: typing.Optional[typing.Sequence[AgentContextResource]] = OMIT, + kind: typing.Optional[str] = OMIT, + max_characters: typing.Optional[int] = OMIT, + models: typing.Optional[typing.Sequence[AgentContextResource]] = OMIT, + objective: typing.Optional[str] = OMIT, + task_family: typing.Optional[str] = OMIT, + tools: typing.Optional[typing.Sequence[AgentContextResource]] = OMIT, + trajectory_uuid: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentContext: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + environments : typing.Optional[typing.Sequence[AgentContextResource]] + + kind : typing.Optional[str] + + max_characters : typing.Optional[int] + + models : typing.Optional[typing.Sequence[AgentContextResource]] + + objective : typing.Optional[str] + + task_family : typing.Optional[str] + + tools : typing.Optional[typing.Sequence[AgentContextResource]] + + trajectory_uuid : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentContext + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.get_context( + agent_uuid="agent_uuid", + ) + """ + _response = self._raw_client.get_context( + agent_uuid, + environments=environments, + kind=kind, + max_characters=max_characters, + models=models, + objective=objective, + task_family=task_family, + tools=tools, + trajectory_uuid=trajectory_uuid, + request_options=request_options, + ) + return _response.data + + @property + def learning(self): + if self._learning is None: + from .learning.client import LearningClient # noqa: E402 + + self._learning = LearningClient(client_wrapper=self._client_wrapper) + return self._learning + + @property + def literal_policy(self): + if self._literal_policy is None: + from .literal_policy.client import LiteralPolicyClient # noqa: E402 + + self._literal_policy = LiteralPolicyClient(client_wrapper=self._client_wrapper) + return self._literal_policy + + @property + def skill(self): + if self._skill is None: + from .skill.client import SkillClient # noqa: E402 + + self._skill = SkillClient(client_wrapper=self._client_wrapper) + return self._skill + + @property + def split(self): + if self._split is None: + from .split.client import SplitClient # noqa: E402 + + self._split = SplitClient(client_wrapper=self._client_wrapper) + return self._split + + @property + def trajectory(self): + if self._trajectory is None: + from .trajectory.client import TrajectoryClient # noqa: E402 + + self._trajectory = TrajectoryClient(client_wrapper=self._client_wrapper) + return self._trajectory + + @property + def trajectory_import(self): + if self._trajectory_import is None: + from .trajectory_import.client import TrajectoryImportClient # noqa: E402 + + self._trajectory_import = TrajectoryImportClient(client_wrapper=self._client_wrapper) + return self._trajectory_import + + @property + def verifier(self): + if self._verifier is None: + from .verifier.client import VerifierClient # noqa: E402 + + self._verifier = VerifierClient(client_wrapper=self._client_wrapper) + return self._verifier + + +class AsyncAgentClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawAgentClient(client_wrapper=client_wrapper) + self._client_wrapper = client_wrapper + self._learning: typing.Optional[AsyncLearningClient] = None + self._literal_policy: typing.Optional[AsyncLiteralPolicyClient] = None + self._skill: typing.Optional[AsyncSkillClient] = None + self._split: typing.Optional[AsyncSplitClient] = None + self._trajectory: typing.Optional[AsyncTrajectoryClient] = None + self._trajectory_import: typing.Optional[AsyncTrajectoryImportClient] = None + self._verifier: typing.Optional[AsyncVerifierClient] = None + + @property + def with_raw_response(self) -> AsyncRawAgentClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawAgentClient + """ + return self._raw_client + + async def create( + self, + *, + agent_id: str, + name: str, + security_domain: str, + deployment_id: typing.Optional[str] = OMIT, + description: typing.Optional[str] = OMIT, + memory_settings: typing.Optional[AgentMemorySettings] = OMIT, + metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + version: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> Agent: + """ + Parameters + ---------- + agent_id : str + The developer-assigned Agent identifier, unique within the project. + + name : str + The Agent's display name. + + security_domain : str + The immutable boundary within which Skills may be synthesized. 1 to 200 characters of lowercase letters, digits, and the characters : . - _ + + deployment_id : typing.Optional[str] + The customer deployment this Agent represents. + + description : typing.Optional[str] + A human-readable description of the Agent. + + memory_settings : typing.Optional[AgentMemorySettings] + Agent Memory capture, compilation, and promotion settings. + + metadata : typing.Optional[typing.Dict[str, typing.Any]] + Developer metadata used to organize and filter Agents. + + version : typing.Optional[str] + The customer deployment version this Agent represents. If you omit it, the version is "default". + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Agent + Created + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.create( + agent_id="agent_id", + name="name", + security_domain="security_domain", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.create( + agent_id=agent_id, + name=name, + security_domain=security_domain, + deployment_id=deployment_id, + description=description, + memory_settings=memory_settings, + metadata=metadata, + version=version, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + async def list( + self, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + agent_id: typing.Optional[str] = OMIT, + deployment_id: typing.Optional[str] = OMIT, + metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + status: typing.Optional[AgentStatus] = OMIT, + version: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[Agent, AgentPage]: + """ + Parameters + ---------- + limit : typing.Optional[int] + Page size (maximum 100) + + cursor : typing.Optional[str] + Opaque page cursor + + agent_id : typing.Optional[str] + Filters to the exact developer-assigned Agent identifier. + + deployment_id : typing.Optional[str] + Filters to the exact deployment identifier. + + metadata : typing.Optional[typing.Dict[str, typing.Any]] + Filters to Agents whose metadata contains these key-value pairs. + + status : typing.Optional[AgentStatus] + Filters to lifecycle status. Omit to include every status. + + version : typing.Optional[str] + Filters to the exact deployment version. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[Agent, AgentPage] + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + response = await client.agent.list() + async for item in response: + yield item + + # alternatively, you can paginate page-by-page + async for page in response.iter_pages(): + yield page + + + asyncio.run(main()) + """ + return await self._raw_client.list( + limit=limit, + cursor=cursor, + agent_id=agent_id, + deployment_id=deployment_id, + metadata=metadata, + status=status, + version=version, + request_options=request_options, + ) + + async def get(self, agent_uuid: str, *, request_options: typing.Optional[RequestOptions] = None) -> Agent: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Agent + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.get( + agent_uuid="agent_uuid", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get(agent_uuid, request_options=request_options) + return _response.data + + async def delete( + self, + agent_uuid: str, + *, + expected_revision: int, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentDeleteResult: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + expected_revision : int + The current Agent revision used for optimistic concurrency. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentDeleteResult + Accepted + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.delete( + agent_uuid="agent_uuid", + expected_revision=1, + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.delete( + agent_uuid, + expected_revision=expected_revision, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + async def update( + self, + agent_uuid: str, + *, + expected_revision: int, + deployment_id: typing.Optional[str] = OMIT, + description: typing.Optional[str] = OMIT, + memory_settings: typing.Optional[AgentMemorySettings] = OMIT, + metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + name: typing.Optional[str] = OMIT, + version: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> Agent: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + expected_revision : int + The current Agent revision used for optimistic concurrency. + + deployment_id : typing.Optional[str] + The customer deployment this Agent represents. Set to null to clear it. + + description : typing.Optional[str] + A human-readable description of the Agent. Set to null to clear it. + + memory_settings : typing.Optional[AgentMemorySettings] + Replacement Agent Memory settings. Set to null to restore defaults. + + metadata : typing.Optional[typing.Dict[str, typing.Any]] + Replacement developer metadata. Set to null to clear it. + + name : typing.Optional[str] + The Agent's display name. + + version : typing.Optional[str] + The customer deployment version this Agent represents. Set to null to clear it. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Agent + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.update( + agent_uuid="agent_uuid", + expected_revision=1, + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.update( + agent_uuid, + expected_revision=expected_revision, + deployment_id=deployment_id, + description=description, + memory_settings=memory_settings, + metadata=metadata, + name=name, + version=version, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + async def declare_breaking_change( + self, + agent_uuid: str, + *, + expected_revision: int, + version: str, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentBreakingChange: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + expected_revision : int + + version : str + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentBreakingChange + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.declare_breaking_change( + agent_uuid="agent_uuid", + expected_revision=1, + version="version", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.declare_breaking_change( + agent_uuid, + expected_revision=expected_revision, + version=version, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + async def get_context( + self, + agent_uuid: str, + *, + environments: typing.Optional[typing.Sequence[AgentContextResource]] = OMIT, + kind: typing.Optional[str] = OMIT, + max_characters: typing.Optional[int] = OMIT, + models: typing.Optional[typing.Sequence[AgentContextResource]] = OMIT, + objective: typing.Optional[str] = OMIT, + task_family: typing.Optional[str] = OMIT, + tools: typing.Optional[typing.Sequence[AgentContextResource]] = OMIT, + trajectory_uuid: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentContext: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + environments : typing.Optional[typing.Sequence[AgentContextResource]] + + kind : typing.Optional[str] + + max_characters : typing.Optional[int] + + models : typing.Optional[typing.Sequence[AgentContextResource]] + + objective : typing.Optional[str] + + task_family : typing.Optional[str] + + tools : typing.Optional[typing.Sequence[AgentContextResource]] + + trajectory_uuid : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentContext + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.get_context( + agent_uuid="agent_uuid", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get_context( + agent_uuid, + environments=environments, + kind=kind, + max_characters=max_characters, + models=models, + objective=objective, + task_family=task_family, + tools=tools, + trajectory_uuid=trajectory_uuid, + request_options=request_options, + ) + return _response.data + + @property + def learning(self): + if self._learning is None: + from .learning.client import AsyncLearningClient # noqa: E402 + + self._learning = AsyncLearningClient(client_wrapper=self._client_wrapper) + return self._learning + + @property + def literal_policy(self): + if self._literal_policy is None: + from .literal_policy.client import AsyncLiteralPolicyClient # noqa: E402 + + self._literal_policy = AsyncLiteralPolicyClient(client_wrapper=self._client_wrapper) + return self._literal_policy + + @property + def skill(self): + if self._skill is None: + from .skill.client import AsyncSkillClient # noqa: E402 + + self._skill = AsyncSkillClient(client_wrapper=self._client_wrapper) + return self._skill + + @property + def split(self): + if self._split is None: + from .split.client import AsyncSplitClient # noqa: E402 + + self._split = AsyncSplitClient(client_wrapper=self._client_wrapper) + return self._split + + @property + def trajectory(self): + if self._trajectory is None: + from .trajectory.client import AsyncTrajectoryClient # noqa: E402 + + self._trajectory = AsyncTrajectoryClient(client_wrapper=self._client_wrapper) + return self._trajectory + + @property + def trajectory_import(self): + if self._trajectory_import is None: + from .trajectory_import.client import AsyncTrajectoryImportClient # noqa: E402 + + self._trajectory_import = AsyncTrajectoryImportClient(client_wrapper=self._client_wrapper) + return self._trajectory_import + + @property + def verifier(self): + if self._verifier is None: + from .verifier.client import AsyncVerifierClient # noqa: E402 + + self._verifier = AsyncVerifierClient(client_wrapper=self._client_wrapper) + return self._verifier diff --git a/src/zep_cloud/agent/learning/__init__.py b/src/zep_cloud/agent/learning/__init__.py new file mode 100644 index 00000000..5cde0202 --- /dev/null +++ b/src/zep_cloud/agent/learning/__init__.py @@ -0,0 +1,4 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + diff --git a/src/zep_cloud/agent/learning/client.py b/src/zep_cloud/agent/learning/client.py new file mode 100644 index 00000000..96a4a58f --- /dev/null +++ b/src/zep_cloud/agent/learning/client.py @@ -0,0 +1,234 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ...core.pagination import AsyncPager, SyncPager +from ...core.request_options import RequestOptions +from ...types.agent_learning_state import AgentLearningState +from ...types.agent_skill_compilation_outcome import AgentSkillCompilationOutcome +from ...types.pagev4agent_skill_compilation_outcome import Pagev4AgentSkillCompilationOutcome +from .raw_client import AsyncRawLearningClient, RawLearningClient + + +class LearningClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawLearningClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawLearningClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawLearningClient + """ + return self._raw_client + + def get( + self, agent_uuid: str, *, task_family: str, request_options: typing.Optional[RequestOptions] = None + ) -> AgentLearningState: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + task_family : str + Task family + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentLearningState + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.learning.get( + agent_uuid="agent_uuid", + task_family="task_family", + ) + """ + _response = self._raw_client.get(agent_uuid, task_family=task_family, request_options=request_options) + return _response.data + + def list_runs( + self, + agent_uuid: str, + *, + task_family: typing.Optional[str] = None, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[AgentSkillCompilationOutcome, Pagev4AgentSkillCompilationOutcome]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + task_family : typing.Optional[str] + Task family + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[AgentSkillCompilationOutcome, Pagev4AgentSkillCompilationOutcome] + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + response = client.agent.learning.list_runs( + agent_uuid="agent_uuid", + ) + for item in response: + yield item + # alternatively, you can paginate page-by-page + for page in response.iter_pages(): + yield page + """ + return self._raw_client.list_runs( + agent_uuid, task_family=task_family, limit=limit, cursor=cursor, request_options=request_options + ) + + +class AsyncLearningClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawLearningClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawLearningClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawLearningClient + """ + return self._raw_client + + async def get( + self, agent_uuid: str, *, task_family: str, request_options: typing.Optional[RequestOptions] = None + ) -> AgentLearningState: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + task_family : str + Task family + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentLearningState + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.learning.get( + agent_uuid="agent_uuid", + task_family="task_family", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get(agent_uuid, task_family=task_family, request_options=request_options) + return _response.data + + async def list_runs( + self, + agent_uuid: str, + *, + task_family: typing.Optional[str] = None, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[AgentSkillCompilationOutcome, Pagev4AgentSkillCompilationOutcome]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + task_family : typing.Optional[str] + Task family + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[AgentSkillCompilationOutcome, Pagev4AgentSkillCompilationOutcome] + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + response = await client.agent.learning.list_runs( + agent_uuid="agent_uuid", + ) + async for item in response: + yield item + + # alternatively, you can paginate page-by-page + async for page in response.iter_pages(): + yield page + + + asyncio.run(main()) + """ + return await self._raw_client.list_runs( + agent_uuid, task_family=task_family, limit=limit, cursor=cursor, request_options=request_options + ) diff --git a/src/zep_cloud/agent/learning/raw_client.py b/src/zep_cloud/agent/learning/raw_client.py new file mode 100644 index 00000000..09b9d873 --- /dev/null +++ b/src/zep_cloud/agent/learning/raw_client.py @@ -0,0 +1,419 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ...core.api_error import ApiError as core_api_error_ApiError +from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ...core.http_response import AsyncHttpResponse, HttpResponse +from ...core.jsonable_encoder import encode_path_param +from ...core.pagination import AsyncPager, SyncPager +from ...core.parse_error import ParsingError +from ...core.pydantic_utilities import parse_obj_as +from ...core.request_options import RequestOptions +from ...errors.bad_request_error import BadRequestError +from ...errors.forbidden_error import ForbiddenError +from ...errors.not_found_error import NotFoundError +from ...errors.unauthorized_error import UnauthorizedError +from ...types.agent_learning_state import AgentLearningState +from ...types.agent_skill_compilation_outcome import AgentSkillCompilationOutcome +from ...types.api_error import ApiError as types_api_error_ApiError +from ...types.pagev4agent_skill_compilation_outcome import Pagev4AgentSkillCompilationOutcome +from pydantic import ValidationError + + +class RawLearningClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def get( + self, agent_uuid: str, *, task_family: str, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[AgentLearningState]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + task_family : str + Task family + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AgentLearningState] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/learning", + method="GET", + params={ + "task_family": task_family, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentLearningState, + parse_obj_as( + type_=AgentLearningState, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def list_runs( + self, + agent_uuid: str, + *, + task_family: typing.Optional[str] = None, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[AgentSkillCompilationOutcome, Pagev4AgentSkillCompilationOutcome]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + task_family : typing.Optional[str] + Task family + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[AgentSkillCompilationOutcome, Pagev4AgentSkillCompilationOutcome] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/learning-runs", + method="GET", + params={ + "task_family": task_family, + "limit": limit, + "cursor": cursor, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + Pagev4AgentSkillCompilationOutcome, + parse_obj_as( + type_=Pagev4AgentSkillCompilationOutcome, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + _get_next = lambda: self.list_runs( + agent_uuid, + task_family=task_family, + limit=limit, + cursor=_parsed_next, + request_options=request_options, + ) + return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + +class AsyncRawLearningClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def get( + self, agent_uuid: str, *, task_family: str, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[AgentLearningState]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + task_family : str + Task family + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AgentLearningState] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/learning", + method="GET", + params={ + "task_family": task_family, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentLearningState, + parse_obj_as( + type_=AgentLearningState, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def list_runs( + self, + agent_uuid: str, + *, + task_family: typing.Optional[str] = None, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[AgentSkillCompilationOutcome, Pagev4AgentSkillCompilationOutcome]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + task_family : typing.Optional[str] + Task family + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[AgentSkillCompilationOutcome, Pagev4AgentSkillCompilationOutcome] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/learning-runs", + method="GET", + params={ + "task_family": task_family, + "limit": limit, + "cursor": cursor, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + Pagev4AgentSkillCompilationOutcome, + parse_obj_as( + type_=Pagev4AgentSkillCompilationOutcome, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + + async def _get_next(): + return await self.list_runs( + agent_uuid, + task_family=task_family, + limit=limit, + cursor=_parsed_next, + request_options=request_options, + ) + + return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) diff --git a/src/zep_cloud/agent/literal_policy/__init__.py b/src/zep_cloud/agent/literal_policy/__init__.py new file mode 100644 index 00000000..cd92c41a --- /dev/null +++ b/src/zep_cloud/agent/literal_policy/__init__.py @@ -0,0 +1,34 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .types import UpdateAgentLiteralPolicyRequestDefault +_dynamic_imports: typing.Dict[str, str] = {"UpdateAgentLiteralPolicyRequestDefault": ".types"} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = ["UpdateAgentLiteralPolicyRequestDefault"] diff --git a/src/zep_cloud/agent/literal_policy/client.py b/src/zep_cloud/agent/literal_policy/client.py new file mode 100644 index 00000000..dd9b2e3b --- /dev/null +++ b/src/zep_cloud/agent/literal_policy/client.py @@ -0,0 +1,266 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ...core.request_options import RequestOptions +from ...types.agent_literal_policy import AgentLiteralPolicy +from ...types.agent_literal_policy_classes import AgentLiteralPolicyClasses +from ...types.agent_literal_policy_values import AgentLiteralPolicyValues +from .raw_client import AsyncRawLiteralPolicyClient, RawLiteralPolicyClient +from .types.update_agent_literal_policy_request_default import UpdateAgentLiteralPolicyRequestDefault + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class LiteralPolicyClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawLiteralPolicyClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawLiteralPolicyClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawLiteralPolicyClient + """ + return self._raw_client + + def get(self, agent_uuid: str, *, request_options: typing.Optional[RequestOptions] = None) -> AgentLiteralPolicy: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentLiteralPolicy + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.literal_policy.get( + agent_uuid="agent_uuid", + ) + """ + _response = self._raw_client.get(agent_uuid, request_options=request_options) + return _response.data + + def update( + self, + agent_uuid: str, + *, + allowlisted_classes: AgentLiteralPolicyClasses, + allowlisted_values: AgentLiteralPolicyValues, + default: UpdateAgentLiteralPolicyRequestDefault, + expected_revision: typing.Optional[int] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentLiteralPolicy: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + allowlisted_classes : AgentLiteralPolicyClasses + Typed reusable literal classes. + + allowlisted_values : AgentLiteralPolicyValues + Exact reusable values scoped by tools and environments. + + default : UpdateAgentLiteralPolicyRequestDefault + The remediation for literals that are not explicitly allowed. + + expected_revision : typing.Optional[int] + The current literal-policy revision used for optimistic concurrency. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentLiteralPolicy + OK + + Examples + -------- + from zep_cloud import AgentLiteralPolicyClasses, AgentLiteralPolicyValues, Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.literal_policy.update( + agent_uuid="agent_uuid", + allowlisted_classes=AgentLiteralPolicyClasses( + environments=["environments"], + tools=["tools"], + ), + allowlisted_values=AgentLiteralPolicyValues( + environments=["environments"], + tools=["tools"], + ), + default="parameterize", + ) + """ + _response = self._raw_client.update( + agent_uuid, + allowlisted_classes=allowlisted_classes, + allowlisted_values=allowlisted_values, + default=default, + expected_revision=expected_revision, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + +class AsyncLiteralPolicyClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawLiteralPolicyClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawLiteralPolicyClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawLiteralPolicyClient + """ + return self._raw_client + + async def get( + self, agent_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AgentLiteralPolicy: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentLiteralPolicy + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.literal_policy.get( + agent_uuid="agent_uuid", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get(agent_uuid, request_options=request_options) + return _response.data + + async def update( + self, + agent_uuid: str, + *, + allowlisted_classes: AgentLiteralPolicyClasses, + allowlisted_values: AgentLiteralPolicyValues, + default: UpdateAgentLiteralPolicyRequestDefault, + expected_revision: typing.Optional[int] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentLiteralPolicy: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + allowlisted_classes : AgentLiteralPolicyClasses + Typed reusable literal classes. + + allowlisted_values : AgentLiteralPolicyValues + Exact reusable values scoped by tools and environments. + + default : UpdateAgentLiteralPolicyRequestDefault + The remediation for literals that are not explicitly allowed. + + expected_revision : typing.Optional[int] + The current literal-policy revision used for optimistic concurrency. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentLiteralPolicy + OK + + Examples + -------- + import asyncio + + from zep_cloud import ( + AgentLiteralPolicyClasses, + AgentLiteralPolicyValues, + AsyncZep, + ) + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.literal_policy.update( + agent_uuid="agent_uuid", + allowlisted_classes=AgentLiteralPolicyClasses( + environments=["environments"], + tools=["tools"], + ), + allowlisted_values=AgentLiteralPolicyValues( + environments=["environments"], + tools=["tools"], + ), + default="parameterize", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.update( + agent_uuid, + allowlisted_classes=allowlisted_classes, + allowlisted_values=allowlisted_values, + default=default, + expected_revision=expected_revision, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data diff --git a/src/zep_cloud/agent/literal_policy/raw_client.py b/src/zep_cloud/agent/literal_policy/raw_client.py new file mode 100644 index 00000000..f117cfa8 --- /dev/null +++ b/src/zep_cloud/agent/literal_policy/raw_client.py @@ -0,0 +1,490 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ...core.api_error import ApiError as core_api_error_ApiError +from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ...core.http_response import AsyncHttpResponse, HttpResponse +from ...core.idempotency import generate_idempotency_key +from ...core.jsonable_encoder import encode_path_param +from ...core.parse_error import ParsingError +from ...core.pydantic_utilities import parse_obj_as +from ...core.request_options import RequestOptions +from ...core.serialization import convert_and_respect_annotation_metadata +from ...errors.bad_request_error import BadRequestError +from ...errors.conflict_error import ConflictError +from ...errors.forbidden_error import ForbiddenError +from ...errors.not_found_error import NotFoundError +from ...errors.unauthorized_error import UnauthorizedError +from ...types.agent_literal_policy import AgentLiteralPolicy +from ...types.agent_literal_policy_classes import AgentLiteralPolicyClasses +from ...types.agent_literal_policy_values import AgentLiteralPolicyValues +from ...types.api_error import ApiError as types_api_error_ApiError +from .types.update_agent_literal_policy_request_default import UpdateAgentLiteralPolicyRequestDefault +from pydantic import ValidationError + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class RawLiteralPolicyClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def get( + self, agent_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[AgentLiteralPolicy]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AgentLiteralPolicy] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/literal-policy", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentLiteralPolicy, + parse_obj_as( + type_=AgentLiteralPolicy, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def update( + self, + agent_uuid: str, + *, + allowlisted_classes: AgentLiteralPolicyClasses, + allowlisted_values: AgentLiteralPolicyValues, + default: UpdateAgentLiteralPolicyRequestDefault, + expected_revision: typing.Optional[int] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[AgentLiteralPolicy]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + allowlisted_classes : AgentLiteralPolicyClasses + Typed reusable literal classes. + + allowlisted_values : AgentLiteralPolicyValues + Exact reusable values scoped by tools and environments. + + default : UpdateAgentLiteralPolicyRequestDefault + The remediation for literals that are not explicitly allowed. + + expected_revision : typing.Optional[int] + The current literal-policy revision used for optimistic concurrency. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AgentLiteralPolicy] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/literal-policy", + method="PUT", + json={ + "allowlisted_classes": convert_and_respect_annotation_metadata( + object_=allowlisted_classes, annotation=AgentLiteralPolicyClasses, direction="write" + ), + "allowlisted_values": convert_and_respect_annotation_metadata( + object_=allowlisted_values, annotation=AgentLiteralPolicyValues, direction="write" + ), + "default": default, + "expected_revision": expected_revision, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentLiteralPolicy, + parse_obj_as( + type_=AgentLiteralPolicy, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + +class AsyncRawLiteralPolicyClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def get( + self, agent_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[AgentLiteralPolicy]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AgentLiteralPolicy] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/literal-policy", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentLiteralPolicy, + parse_obj_as( + type_=AgentLiteralPolicy, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def update( + self, + agent_uuid: str, + *, + allowlisted_classes: AgentLiteralPolicyClasses, + allowlisted_values: AgentLiteralPolicyValues, + default: UpdateAgentLiteralPolicyRequestDefault, + expected_revision: typing.Optional[int] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[AgentLiteralPolicy]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + allowlisted_classes : AgentLiteralPolicyClasses + Typed reusable literal classes. + + allowlisted_values : AgentLiteralPolicyValues + Exact reusable values scoped by tools and environments. + + default : UpdateAgentLiteralPolicyRequestDefault + The remediation for literals that are not explicitly allowed. + + expected_revision : typing.Optional[int] + The current literal-policy revision used for optimistic concurrency. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AgentLiteralPolicy] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/literal-policy", + method="PUT", + json={ + "allowlisted_classes": convert_and_respect_annotation_metadata( + object_=allowlisted_classes, annotation=AgentLiteralPolicyClasses, direction="write" + ), + "allowlisted_values": convert_and_respect_annotation_metadata( + object_=allowlisted_values, annotation=AgentLiteralPolicyValues, direction="write" + ), + "default": default, + "expected_revision": expected_revision, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentLiteralPolicy, + parse_obj_as( + type_=AgentLiteralPolicy, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) diff --git a/src/zep_cloud/agent/literal_policy/types/__init__.py b/src/zep_cloud/agent/literal_policy/types/__init__.py new file mode 100644 index 00000000..8f9c037f --- /dev/null +++ b/src/zep_cloud/agent/literal_policy/types/__init__.py @@ -0,0 +1,36 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .update_agent_literal_policy_request_default import UpdateAgentLiteralPolicyRequestDefault +_dynamic_imports: typing.Dict[str, str] = { + "UpdateAgentLiteralPolicyRequestDefault": ".update_agent_literal_policy_request_default" +} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = ["UpdateAgentLiteralPolicyRequestDefault"] diff --git a/src/zep_cloud/agent/literal_policy/types/update_agent_literal_policy_request_default.py b/src/zep_cloud/agent/literal_policy/types/update_agent_literal_policy_request_default.py new file mode 100644 index 00000000..c8c1f1de --- /dev/null +++ b/src/zep_cloud/agent/literal_policy/types/update_agent_literal_policy_request_default.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +UpdateAgentLiteralPolicyRequestDefault = typing.Union[typing.Literal["parameterize", "remove", "reject"], typing.Any] diff --git a/src/zep_cloud/agent/raw_client.py b/src/zep_cloud/agent/raw_client.py new file mode 100644 index 00000000..6bfb8649 --- /dev/null +++ b/src/zep_cloud/agent/raw_client.py @@ -0,0 +1,1889 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ..core.api_error import ApiError as core_api_error_ApiError +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.http_response import AsyncHttpResponse, HttpResponse +from ..core.idempotency import generate_idempotency_key +from ..core.jsonable_encoder import encode_path_param +from ..core.pagination import AsyncPager, SyncPager +from ..core.parse_error import ParsingError +from ..core.pydantic_utilities import parse_obj_as +from ..core.request_options import RequestOptions +from ..core.serialization import convert_and_respect_annotation_metadata +from ..errors.bad_request_error import BadRequestError +from ..errors.conflict_error import ConflictError +from ..errors.forbidden_error import ForbiddenError +from ..errors.not_found_error import NotFoundError +from ..errors.service_unavailable_error import ServiceUnavailableError +from ..errors.unauthorized_error import UnauthorizedError +from ..types.agent import Agent +from ..types.agent_breaking_change import AgentBreakingChange +from ..types.agent_context import AgentContext +from ..types.agent_context_resource import AgentContextResource +from ..types.agent_delete_result import AgentDeleteResult +from ..types.agent_memory_settings import AgentMemorySettings +from ..types.agent_page import AgentPage +from ..types.agent_status import AgentStatus +from ..types.api_error import ApiError as types_api_error_ApiError +from pydantic import ValidationError + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class RawAgentClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def create( + self, + *, + agent_id: str, + name: str, + security_domain: str, + deployment_id: typing.Optional[str] = OMIT, + description: typing.Optional[str] = OMIT, + memory_settings: typing.Optional[AgentMemorySettings] = OMIT, + metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + version: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[Agent]: + """ + Parameters + ---------- + agent_id : str + The developer-assigned Agent identifier, unique within the project. + + name : str + The Agent's display name. + + security_domain : str + The immutable boundary within which Skills may be synthesized. 1 to 200 characters of lowercase letters, digits, and the characters : . - _ + + deployment_id : typing.Optional[str] + The customer deployment this Agent represents. + + description : typing.Optional[str] + A human-readable description of the Agent. + + memory_settings : typing.Optional[AgentMemorySettings] + Agent Memory capture, compilation, and promotion settings. + + metadata : typing.Optional[typing.Dict[str, typing.Any]] + Developer metadata used to organize and filter Agents. + + version : typing.Optional[str] + The customer deployment version this Agent represents. If you omit it, the version is "default". + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[Agent] + Created + """ + _response = self._client_wrapper.httpx_client.request( + "agents", + method="POST", + json={ + "agent_id": agent_id, + "deployment_id": deployment_id, + "description": description, + "memory_settings": convert_and_respect_annotation_metadata( + object_=memory_settings, annotation=AgentMemorySettings, direction="write" + ), + "metadata": metadata, + "name": name, + "security_domain": security_domain, + "version": version, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + Agent, + parse_obj_as( + type_=Agent, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def list( + self, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + agent_id: typing.Optional[str] = OMIT, + deployment_id: typing.Optional[str] = OMIT, + metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + status: typing.Optional[AgentStatus] = OMIT, + version: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[Agent, AgentPage]: + """ + Parameters + ---------- + limit : typing.Optional[int] + Page size (maximum 100) + + cursor : typing.Optional[str] + Opaque page cursor + + agent_id : typing.Optional[str] + Filters to the exact developer-assigned Agent identifier. + + deployment_id : typing.Optional[str] + Filters to the exact deployment identifier. + + metadata : typing.Optional[typing.Dict[str, typing.Any]] + Filters to Agents whose metadata contains these key-value pairs. + + status : typing.Optional[AgentStatus] + Filters to lifecycle status. Omit to include every status. + + version : typing.Optional[str] + Filters to the exact deployment version. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[Agent, AgentPage] + OK + """ + _response = self._client_wrapper.httpx_client.request( + "agents/list", + method="POST", + params={ + "limit": limit, + "cursor": cursor, + }, + json={ + "agent_id": agent_id, + "deployment_id": deployment_id, + "metadata": metadata, + "status": status, + "version": version, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + AgentPage, + parse_obj_as( + type_=AgentPage, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + _get_next = lambda: self.list( + limit=limit, + cursor=_parsed_next, + agent_id=agent_id, + deployment_id=deployment_id, + metadata=metadata, + status=status, + version=version, + request_options=request_options, + ) + return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def get(self, agent_uuid: str, *, request_options: typing.Optional[RequestOptions] = None) -> HttpResponse[Agent]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[Agent] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + Agent, + parse_obj_as( + type_=Agent, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def delete( + self, + agent_uuid: str, + *, + expected_revision: int, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[AgentDeleteResult]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + expected_revision : int + The current Agent revision used for optimistic concurrency. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AgentDeleteResult] + Accepted + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}", + method="DELETE", + json={ + "expected_revision": expected_revision, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentDeleteResult, + parse_obj_as( + type_=AgentDeleteResult, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def update( + self, + agent_uuid: str, + *, + expected_revision: int, + deployment_id: typing.Optional[str] = OMIT, + description: typing.Optional[str] = OMIT, + memory_settings: typing.Optional[AgentMemorySettings] = OMIT, + metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + name: typing.Optional[str] = OMIT, + version: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[Agent]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + expected_revision : int + The current Agent revision used for optimistic concurrency. + + deployment_id : typing.Optional[str] + The customer deployment this Agent represents. Set to null to clear it. + + description : typing.Optional[str] + A human-readable description of the Agent. Set to null to clear it. + + memory_settings : typing.Optional[AgentMemorySettings] + Replacement Agent Memory settings. Set to null to restore defaults. + + metadata : typing.Optional[typing.Dict[str, typing.Any]] + Replacement developer metadata. Set to null to clear it. + + name : typing.Optional[str] + The Agent's display name. + + version : typing.Optional[str] + The customer deployment version this Agent represents. Set to null to clear it. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[Agent] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}", + method="PATCH", + json={ + "deployment_id": deployment_id, + "description": description, + "expected_revision": expected_revision, + "memory_settings": convert_and_respect_annotation_metadata( + object_=memory_settings, annotation=AgentMemorySettings, direction="write" + ), + "metadata": metadata, + "name": name, + "version": version, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + Agent, + parse_obj_as( + type_=Agent, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def declare_breaking_change( + self, + agent_uuid: str, + *, + expected_revision: int, + version: str, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[AgentBreakingChange]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + expected_revision : int + + version : str + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AgentBreakingChange] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/breaking-changes", + method="POST", + json={ + "expected_revision": expected_revision, + "version": version, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentBreakingChange, + parse_obj_as( + type_=AgentBreakingChange, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def get_context( + self, + agent_uuid: str, + *, + environments: typing.Optional[typing.Sequence[AgentContextResource]] = OMIT, + kind: typing.Optional[str] = OMIT, + max_characters: typing.Optional[int] = OMIT, + models: typing.Optional[typing.Sequence[AgentContextResource]] = OMIT, + objective: typing.Optional[str] = OMIT, + task_family: typing.Optional[str] = OMIT, + tools: typing.Optional[typing.Sequence[AgentContextResource]] = OMIT, + trajectory_uuid: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[AgentContext]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + environments : typing.Optional[typing.Sequence[AgentContextResource]] + + kind : typing.Optional[str] + + max_characters : typing.Optional[int] + + models : typing.Optional[typing.Sequence[AgentContextResource]] + + objective : typing.Optional[str] + + task_family : typing.Optional[str] + + tools : typing.Optional[typing.Sequence[AgentContextResource]] + + trajectory_uuid : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AgentContext] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/context", + method="POST", + json={ + "environments": convert_and_respect_annotation_metadata( + object_=environments, annotation=typing.Sequence[AgentContextResource], direction="write" + ), + "kind": kind, + "max_characters": max_characters, + "models": convert_and_respect_annotation_metadata( + object_=models, annotation=typing.Sequence[AgentContextResource], direction="write" + ), + "objective": objective, + "task_family": task_family, + "tools": convert_and_respect_annotation_metadata( + object_=tools, annotation=typing.Sequence[AgentContextResource], direction="write" + ), + "trajectory_uuid": trajectory_uuid, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentContext, + parse_obj_as( + type_=AgentContext, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + +class AsyncRawAgentClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def create( + self, + *, + agent_id: str, + name: str, + security_domain: str, + deployment_id: typing.Optional[str] = OMIT, + description: typing.Optional[str] = OMIT, + memory_settings: typing.Optional[AgentMemorySettings] = OMIT, + metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + version: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[Agent]: + """ + Parameters + ---------- + agent_id : str + The developer-assigned Agent identifier, unique within the project. + + name : str + The Agent's display name. + + security_domain : str + The immutable boundary within which Skills may be synthesized. 1 to 200 characters of lowercase letters, digits, and the characters : . - _ + + deployment_id : typing.Optional[str] + The customer deployment this Agent represents. + + description : typing.Optional[str] + A human-readable description of the Agent. + + memory_settings : typing.Optional[AgentMemorySettings] + Agent Memory capture, compilation, and promotion settings. + + metadata : typing.Optional[typing.Dict[str, typing.Any]] + Developer metadata used to organize and filter Agents. + + version : typing.Optional[str] + The customer deployment version this Agent represents. If you omit it, the version is "default". + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[Agent] + Created + """ + _response = await self._client_wrapper.httpx_client.request( + "agents", + method="POST", + json={ + "agent_id": agent_id, + "deployment_id": deployment_id, + "description": description, + "memory_settings": convert_and_respect_annotation_metadata( + object_=memory_settings, annotation=AgentMemorySettings, direction="write" + ), + "metadata": metadata, + "name": name, + "security_domain": security_domain, + "version": version, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + Agent, + parse_obj_as( + type_=Agent, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def list( + self, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + agent_id: typing.Optional[str] = OMIT, + deployment_id: typing.Optional[str] = OMIT, + metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + status: typing.Optional[AgentStatus] = OMIT, + version: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[Agent, AgentPage]: + """ + Parameters + ---------- + limit : typing.Optional[int] + Page size (maximum 100) + + cursor : typing.Optional[str] + Opaque page cursor + + agent_id : typing.Optional[str] + Filters to the exact developer-assigned Agent identifier. + + deployment_id : typing.Optional[str] + Filters to the exact deployment identifier. + + metadata : typing.Optional[typing.Dict[str, typing.Any]] + Filters to Agents whose metadata contains these key-value pairs. + + status : typing.Optional[AgentStatus] + Filters to lifecycle status. Omit to include every status. + + version : typing.Optional[str] + Filters to the exact deployment version. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[Agent, AgentPage] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + "agents/list", + method="POST", + params={ + "limit": limit, + "cursor": cursor, + }, + json={ + "agent_id": agent_id, + "deployment_id": deployment_id, + "metadata": metadata, + "status": status, + "version": version, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + AgentPage, + parse_obj_as( + type_=AgentPage, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + + async def _get_next(): + return await self.list( + limit=limit, + cursor=_parsed_next, + agent_id=agent_id, + deployment_id=deployment_id, + metadata=metadata, + status=status, + version=version, + request_options=request_options, + ) + + return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def get( + self, agent_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[Agent]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[Agent] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + Agent, + parse_obj_as( + type_=Agent, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def delete( + self, + agent_uuid: str, + *, + expected_revision: int, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[AgentDeleteResult]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + expected_revision : int + The current Agent revision used for optimistic concurrency. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AgentDeleteResult] + Accepted + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}", + method="DELETE", + json={ + "expected_revision": expected_revision, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentDeleteResult, + parse_obj_as( + type_=AgentDeleteResult, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def update( + self, + agent_uuid: str, + *, + expected_revision: int, + deployment_id: typing.Optional[str] = OMIT, + description: typing.Optional[str] = OMIT, + memory_settings: typing.Optional[AgentMemorySettings] = OMIT, + metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + name: typing.Optional[str] = OMIT, + version: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[Agent]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + expected_revision : int + The current Agent revision used for optimistic concurrency. + + deployment_id : typing.Optional[str] + The customer deployment this Agent represents. Set to null to clear it. + + description : typing.Optional[str] + A human-readable description of the Agent. Set to null to clear it. + + memory_settings : typing.Optional[AgentMemorySettings] + Replacement Agent Memory settings. Set to null to restore defaults. + + metadata : typing.Optional[typing.Dict[str, typing.Any]] + Replacement developer metadata. Set to null to clear it. + + name : typing.Optional[str] + The Agent's display name. + + version : typing.Optional[str] + The customer deployment version this Agent represents. Set to null to clear it. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[Agent] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}", + method="PATCH", + json={ + "deployment_id": deployment_id, + "description": description, + "expected_revision": expected_revision, + "memory_settings": convert_and_respect_annotation_metadata( + object_=memory_settings, annotation=AgentMemorySettings, direction="write" + ), + "metadata": metadata, + "name": name, + "version": version, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + Agent, + parse_obj_as( + type_=Agent, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def declare_breaking_change( + self, + agent_uuid: str, + *, + expected_revision: int, + version: str, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[AgentBreakingChange]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + expected_revision : int + + version : str + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AgentBreakingChange] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/breaking-changes", + method="POST", + json={ + "expected_revision": expected_revision, + "version": version, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentBreakingChange, + parse_obj_as( + type_=AgentBreakingChange, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def get_context( + self, + agent_uuid: str, + *, + environments: typing.Optional[typing.Sequence[AgentContextResource]] = OMIT, + kind: typing.Optional[str] = OMIT, + max_characters: typing.Optional[int] = OMIT, + models: typing.Optional[typing.Sequence[AgentContextResource]] = OMIT, + objective: typing.Optional[str] = OMIT, + task_family: typing.Optional[str] = OMIT, + tools: typing.Optional[typing.Sequence[AgentContextResource]] = OMIT, + trajectory_uuid: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[AgentContext]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + environments : typing.Optional[typing.Sequence[AgentContextResource]] + + kind : typing.Optional[str] + + max_characters : typing.Optional[int] + + models : typing.Optional[typing.Sequence[AgentContextResource]] + + objective : typing.Optional[str] + + task_family : typing.Optional[str] + + tools : typing.Optional[typing.Sequence[AgentContextResource]] + + trajectory_uuid : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AgentContext] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/context", + method="POST", + json={ + "environments": convert_and_respect_annotation_metadata( + object_=environments, annotation=typing.Sequence[AgentContextResource], direction="write" + ), + "kind": kind, + "max_characters": max_characters, + "models": convert_and_respect_annotation_metadata( + object_=models, annotation=typing.Sequence[AgentContextResource], direction="write" + ), + "objective": objective, + "task_family": task_family, + "tools": convert_and_respect_annotation_metadata( + object_=tools, annotation=typing.Sequence[AgentContextResource], direction="write" + ), + "trajectory_uuid": trajectory_uuid, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentContext, + parse_obj_as( + type_=AgentContext, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) diff --git a/src/zep_cloud/agent/skill/__init__.py b/src/zep_cloud/agent/skill/__init__.py new file mode 100644 index 00000000..00db97c1 --- /dev/null +++ b/src/zep_cloud/agent/skill/__init__.py @@ -0,0 +1,80 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .types import AgentSkillSearchRequestMarkdownFormat + from . import candidate, evaluation, evidence, export, publication, relation, use, version + from .evaluation import ( + CreateAgentSkillCandidateEvaluationRequestEvaluatedBy, + CreateAgentSkillCandidateEvaluationRequestVerdict, + CreateAgentSkillEvaluationRequestEvaluatedBy, + CreateAgentSkillEvaluationRequestVerdict, + ) + from .relation import RelationListRequestKindItem + from .use import CreateAgentSkillUseRequestUsage + from .version import VersionGetRequestMarkdownFormat, VersionListRequestMarkdownFormat +_dynamic_imports: typing.Dict[str, str] = { + "AgentSkillSearchRequestMarkdownFormat": ".types", + "CreateAgentSkillCandidateEvaluationRequestEvaluatedBy": ".evaluation", + "CreateAgentSkillCandidateEvaluationRequestVerdict": ".evaluation", + "CreateAgentSkillEvaluationRequestEvaluatedBy": ".evaluation", + "CreateAgentSkillEvaluationRequestVerdict": ".evaluation", + "CreateAgentSkillUseRequestUsage": ".use", + "RelationListRequestKindItem": ".relation", + "VersionGetRequestMarkdownFormat": ".version", + "VersionListRequestMarkdownFormat": ".version", + "candidate": ".candidate", + "evaluation": ".evaluation", + "evidence": ".evidence", + "export": ".export", + "publication": ".publication", + "relation": ".relation", + "use": ".use", + "version": ".version", +} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = [ + "AgentSkillSearchRequestMarkdownFormat", + "CreateAgentSkillCandidateEvaluationRequestEvaluatedBy", + "CreateAgentSkillCandidateEvaluationRequestVerdict", + "CreateAgentSkillEvaluationRequestEvaluatedBy", + "CreateAgentSkillEvaluationRequestVerdict", + "CreateAgentSkillUseRequestUsage", + "RelationListRequestKindItem", + "VersionGetRequestMarkdownFormat", + "VersionListRequestMarkdownFormat", + "candidate", + "evaluation", + "evidence", + "export", + "publication", + "relation", + "use", + "version", +] diff --git a/src/zep_cloud/agent/skill/candidate/__init__.py b/src/zep_cloud/agent/skill/candidate/__init__.py new file mode 100644 index 00000000..5cde0202 --- /dev/null +++ b/src/zep_cloud/agent/skill/candidate/__init__.py @@ -0,0 +1,4 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + diff --git a/src/zep_cloud/agent/skill/candidate/client.py b/src/zep_cloud/agent/skill/candidate/client.py new file mode 100644 index 00000000..55acf471 --- /dev/null +++ b/src/zep_cloud/agent/skill/candidate/client.py @@ -0,0 +1,222 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ....core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ....core.pagination import AsyncPager, SyncPager +from ....core.request_options import RequestOptions +from ....types.agent_skill_candidate_review import AgentSkillCandidateReview +from ....types.agent_skill_candidate_review_summary import AgentSkillCandidateReviewSummary +from ....types.pagev4agent_skill_candidate_review_summary import Pagev4AgentSkillCandidateReviewSummary +from .raw_client import AsyncRawCandidateClient, RawCandidateClient + + +class CandidateClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawCandidateClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawCandidateClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawCandidateClient + """ + return self._raw_client + + def list( + self, + agent_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[AgentSkillCandidateReviewSummary, Pagev4AgentSkillCandidateReviewSummary]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + limit : typing.Optional[int] + Page size (maximum 100) + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[AgentSkillCandidateReviewSummary, Pagev4AgentSkillCandidateReviewSummary] + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + response = client.agent.skill.candidate.list( + agent_uuid="agent_uuid", + ) + for item in response: + yield item + # alternatively, you can paginate page-by-page + for page in response.iter_pages(): + yield page + """ + return self._raw_client.list(agent_uuid, limit=limit, cursor=cursor, request_options=request_options) + + def get( + self, agent_uuid: str, review_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AgentSkillCandidateReview: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + review_uuid : str + Candidate review UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentSkillCandidateReview + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.skill.candidate.get( + agent_uuid="agent_uuid", + review_uuid="review_uuid", + ) + """ + _response = self._raw_client.get(agent_uuid, review_uuid, request_options=request_options) + return _response.data + + +class AsyncCandidateClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawCandidateClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawCandidateClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawCandidateClient + """ + return self._raw_client + + async def list( + self, + agent_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[AgentSkillCandidateReviewSummary, Pagev4AgentSkillCandidateReviewSummary]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + limit : typing.Optional[int] + Page size (maximum 100) + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[AgentSkillCandidateReviewSummary, Pagev4AgentSkillCandidateReviewSummary] + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + response = await client.agent.skill.candidate.list( + agent_uuid="agent_uuid", + ) + async for item in response: + yield item + + # alternatively, you can paginate page-by-page + async for page in response.iter_pages(): + yield page + + + asyncio.run(main()) + """ + return await self._raw_client.list(agent_uuid, limit=limit, cursor=cursor, request_options=request_options) + + async def get( + self, agent_uuid: str, review_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AgentSkillCandidateReview: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + review_uuid : str + Candidate review UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentSkillCandidateReview + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.skill.candidate.get( + agent_uuid="agent_uuid", + review_uuid="review_uuid", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get(agent_uuid, review_uuid, request_options=request_options) + return _response.data diff --git a/src/zep_cloud/agent/skill/candidate/raw_client.py b/src/zep_cloud/agent/skill/candidate/raw_client.py new file mode 100644 index 00000000..6361e239 --- /dev/null +++ b/src/zep_cloud/agent/skill/candidate/raw_client.py @@ -0,0 +1,513 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ....core.api_error import ApiError as core_api_error_ApiError +from ....core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ....core.http_response import AsyncHttpResponse, HttpResponse +from ....core.jsonable_encoder import encode_path_param +from ....core.pagination import AsyncPager, SyncPager +from ....core.parse_error import ParsingError +from ....core.pydantic_utilities import parse_obj_as +from ....core.request_options import RequestOptions +from ....errors.bad_request_error import BadRequestError +from ....errors.conflict_error import ConflictError +from ....errors.forbidden_error import ForbiddenError +from ....errors.not_found_error import NotFoundError +from ....errors.service_unavailable_error import ServiceUnavailableError +from ....errors.unauthorized_error import UnauthorizedError +from ....types.agent_skill_candidate_review import AgentSkillCandidateReview +from ....types.agent_skill_candidate_review_summary import AgentSkillCandidateReviewSummary +from ....types.api_error import ApiError as types_api_error_ApiError +from ....types.pagev4agent_skill_candidate_review_summary import Pagev4AgentSkillCandidateReviewSummary +from pydantic import ValidationError + + +class RawCandidateClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def list( + self, + agent_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[AgentSkillCandidateReviewSummary, Pagev4AgentSkillCandidateReviewSummary]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + limit : typing.Optional[int] + Page size (maximum 100) + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[AgentSkillCandidateReviewSummary, Pagev4AgentSkillCandidateReviewSummary] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skill-candidates", + method="GET", + params={ + "limit": limit, + "cursor": cursor, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + Pagev4AgentSkillCandidateReviewSummary, + parse_obj_as( + type_=Pagev4AgentSkillCandidateReviewSummary, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + _get_next = lambda: self.list( + agent_uuid, + limit=limit, + cursor=_parsed_next, + request_options=request_options, + ) + return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def get( + self, agent_uuid: str, review_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[AgentSkillCandidateReview]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + review_uuid : str + Candidate review UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AgentSkillCandidateReview] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skill-candidates/{encode_path_param(review_uuid)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentSkillCandidateReview, + parse_obj_as( + type_=AgentSkillCandidateReview, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + +class AsyncRawCandidateClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def list( + self, + agent_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[AgentSkillCandidateReviewSummary, Pagev4AgentSkillCandidateReviewSummary]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + limit : typing.Optional[int] + Page size (maximum 100) + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[AgentSkillCandidateReviewSummary, Pagev4AgentSkillCandidateReviewSummary] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skill-candidates", + method="GET", + params={ + "limit": limit, + "cursor": cursor, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + Pagev4AgentSkillCandidateReviewSummary, + parse_obj_as( + type_=Pagev4AgentSkillCandidateReviewSummary, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + + async def _get_next(): + return await self.list( + agent_uuid, + limit=limit, + cursor=_parsed_next, + request_options=request_options, + ) + + return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def get( + self, agent_uuid: str, review_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[AgentSkillCandidateReview]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + review_uuid : str + Candidate review UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AgentSkillCandidateReview] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skill-candidates/{encode_path_param(review_uuid)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentSkillCandidateReview, + parse_obj_as( + type_=AgentSkillCandidateReview, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) diff --git a/src/zep_cloud/agent/skill/client.py b/src/zep_cloud/agent/skill/client.py new file mode 100644 index 00000000..7d4682ef --- /dev/null +++ b/src/zep_cloud/agent/skill/client.py @@ -0,0 +1,1127 @@ +# This file was auto-generated by Fern from our API Definition. + +from __future__ import annotations + +import typing + +from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ...core.pagination import AsyncPager, SyncPager +from ...core.request_options import RequestOptions +from ...types.agent_skill import AgentSkill +from ...types.agent_skill_admission_decision import AgentSkillAdmissionDecision +from ...types.agent_skill_search_hit import AgentSkillSearchHit +from ...types.agent_skill_search_response import AgentSkillSearchResponse +from ...types.agent_skill_version import AgentSkillVersion +from ...types.pagev4agent_skill_search_hit import Pagev4AgentSkillSearchHit +from ...types.skill_definition import SkillDefinition +from ...types.task import Task +from .raw_client import AsyncRawSkillClient, RawSkillClient +from .types.agent_skill_search_request_markdown_format import AgentSkillSearchRequestMarkdownFormat + +if typing.TYPE_CHECKING: + from .candidate.client import AsyncCandidateClient, CandidateClient + from .evaluation.client import AsyncEvaluationClient, EvaluationClient + from .evidence.client import AsyncEvidenceClient, EvidenceClient + from .export.client import AsyncExportClient, ExportClient + from .publication.client import AsyncPublicationClient, PublicationClient + from .relation.client import AsyncRelationClient, RelationClient + from .use.client import AsyncUseClient, UseClient + from .version.client import AsyncVersionClient, VersionClient +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class SkillClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawSkillClient(client_wrapper=client_wrapper) + self._client_wrapper = client_wrapper + self._candidate: typing.Optional[CandidateClient] = None + self._evaluation: typing.Optional[EvaluationClient] = None + self._publication: typing.Optional[PublicationClient] = None + self._evidence: typing.Optional[EvidenceClient] = None + self._relation: typing.Optional[RelationClient] = None + self._version: typing.Optional[VersionClient] = None + self._use: typing.Optional[UseClient] = None + self._export: typing.Optional[ExportClient] = None + + @property + def with_raw_response(self) -> RawSkillClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawSkillClient + """ + return self._raw_client + + def create( + self, + agent_uuid: str, + *, + definition: SkillDefinition, + skill_id: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentSkill: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + definition : SkillDefinition + + skill_id : typing.Optional[str] + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentSkill + OK + + Examples + -------- + from zep_cloud import SkillDefinition, Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.skill.create( + agent_uuid="agent_uuid", + definition=SkillDefinition(), + ) + """ + _response = self._raw_client.create( + agent_uuid, + definition=definition, + skill_id=skill_id, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + def import_package( + self, + agent_uuid: str, + *, + request: typing.Union[bytes, typing.Iterator[bytes], typing.AsyncIterator[bytes]], + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> Task: + """ + Submit a portable Skill archive. The completed Task returns `{"result":{"skill_uuid":""}}`. Approve that Skill before retrieval. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + request : typing.Union[bytes, typing.Iterator[bytes], typing.AsyncIterator[bytes]] + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Task + Accepted + """ + _response = self._raw_client.import_package( + agent_uuid, request=request, idempotency_key=idempotency_key, request_options=request_options + ) + return _response.data + + def list( + self, + agent_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + environments: typing.Optional[typing.Sequence[str]] = OMIT, + kind: typing.Optional[str] = OMIT, + task_family: typing.Optional[str] = OMIT, + tools: typing.Optional[typing.Sequence[str]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[AgentSkillSearchHit, Pagev4AgentSkillSearchHit]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + limit : typing.Optional[int] + Page size (maximum 20) + + cursor : typing.Optional[str] + Opaque page cursor + + environments : typing.Optional[typing.Sequence[str]] + + kind : typing.Optional[str] + + task_family : typing.Optional[str] + + tools : typing.Optional[typing.Sequence[str]] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[AgentSkillSearchHit, Pagev4AgentSkillSearchHit] + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + response = client.agent.skill.list( + agent_uuid="agent_uuid", + ) + for item in response: + yield item + # alternatively, you can paginate page-by-page + for page in response.iter_pages(): + yield page + """ + return self._raw_client.list( + agent_uuid, + limit=limit, + cursor=cursor, + environments=environments, + kind=kind, + task_family=task_family, + tools=tools, + request_options=request_options, + ) + + def search( + self, + agent_uuid: str, + *, + query: str, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + environments: typing.Optional[typing.Sequence[str]] = OMIT, + include_markdown: typing.Optional[bool] = OMIT, + kind: typing.Optional[str] = OMIT, + markdown_format: typing.Optional[AgentSkillSearchRequestMarkdownFormat] = OMIT, + task_family: typing.Optional[str] = OMIT, + tools: typing.Optional[typing.Sequence[str]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[AgentSkillSearchHit, AgentSkillSearchResponse]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + query : str + + limit : typing.Optional[int] + Page size (maximum 20) + + cursor : typing.Optional[str] + Opaque page cursor + + environments : typing.Optional[typing.Sequence[str]] + + include_markdown : typing.Optional[bool] + + kind : typing.Optional[str] + + markdown_format : typing.Optional[AgentSkillSearchRequestMarkdownFormat] + MarkdownFormat selects the form of inline `markdown`. `agent` (the + default) returns the Skill text that an Agent needs: no evidence + markers, the description only in the frontmatter, and no empty + sections. `full` returns the stored SKILL.md with its evidence markers. + + task_family : typing.Optional[str] + + tools : typing.Optional[typing.Sequence[str]] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[AgentSkillSearchHit, AgentSkillSearchResponse] + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + response = client.agent.skill.search( + agent_uuid="agent_uuid", + query="query", + ) + for item in response: + yield item + # alternatively, you can paginate page-by-page + for page in response.iter_pages(): + yield page + """ + return self._raw_client.search( + agent_uuid, + query=query, + limit=limit, + cursor=cursor, + environments=environments, + include_markdown=include_markdown, + kind=kind, + markdown_format=markdown_format, + task_family=task_family, + tools=tools, + request_options=request_options, + ) + + def get( + self, agent_uuid: str, skill_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AgentSkill: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentSkill + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.skill.get( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + ) + """ + _response = self._raw_client.get(agent_uuid, skill_uuid, request_options=request_options) + return _response.data + + def approve( + self, + agent_uuid: str, + skill_uuid: str, + *, + expected_version: int, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentSkillAdmissionDecision: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + expected_version : int + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentSkillAdmissionDecision + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.skill.approve( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + expected_version=1, + ) + """ + _response = self._raw_client.approve( + agent_uuid, + skill_uuid, + expected_version=expected_version, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + def retire( + self, + agent_uuid: str, + skill_uuid: str, + *, + expected_version: int, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentSkill: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + expected_version : int + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentSkill + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.skill.retire( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + expected_version=1, + ) + """ + _response = self._raw_client.retire( + agent_uuid, + skill_uuid, + expected_version=expected_version, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + def create_version( + self, + agent_uuid: str, + skill_uuid: str, + *, + definition: SkillDefinition, + expected_version: int, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentSkillVersion: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + definition : SkillDefinition + + expected_version : int + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentSkillVersion + OK + + Examples + -------- + from zep_cloud import SkillDefinition, Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.skill.create_version( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + definition=SkillDefinition(), + expected_version=1, + ) + """ + _response = self._raw_client.create_version( + agent_uuid, + skill_uuid, + definition=definition, + expected_version=expected_version, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + @property + def candidate(self): + if self._candidate is None: + from .candidate.client import CandidateClient # noqa: E402 + + self._candidate = CandidateClient(client_wrapper=self._client_wrapper) + return self._candidate + + @property + def evaluation(self): + if self._evaluation is None: + from .evaluation.client import EvaluationClient # noqa: E402 + + self._evaluation = EvaluationClient(client_wrapper=self._client_wrapper) + return self._evaluation + + @property + def publication(self): + if self._publication is None: + from .publication.client import PublicationClient # noqa: E402 + + self._publication = PublicationClient(client_wrapper=self._client_wrapper) + return self._publication + + @property + def evidence(self): + if self._evidence is None: + from .evidence.client import EvidenceClient # noqa: E402 + + self._evidence = EvidenceClient(client_wrapper=self._client_wrapper) + return self._evidence + + @property + def relation(self): + if self._relation is None: + from .relation.client import RelationClient # noqa: E402 + + self._relation = RelationClient(client_wrapper=self._client_wrapper) + return self._relation + + @property + def version(self): + if self._version is None: + from .version.client import VersionClient # noqa: E402 + + self._version = VersionClient(client_wrapper=self._client_wrapper) + return self._version + + @property + def use(self): + if self._use is None: + from .use.client import UseClient # noqa: E402 + + self._use = UseClient(client_wrapper=self._client_wrapper) + return self._use + + @property + def export(self): + if self._export is None: + from .export.client import ExportClient # noqa: E402 + + self._export = ExportClient(client_wrapper=self._client_wrapper) + return self._export + + +class AsyncSkillClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawSkillClient(client_wrapper=client_wrapper) + self._client_wrapper = client_wrapper + self._candidate: typing.Optional[AsyncCandidateClient] = None + self._evaluation: typing.Optional[AsyncEvaluationClient] = None + self._publication: typing.Optional[AsyncPublicationClient] = None + self._evidence: typing.Optional[AsyncEvidenceClient] = None + self._relation: typing.Optional[AsyncRelationClient] = None + self._version: typing.Optional[AsyncVersionClient] = None + self._use: typing.Optional[AsyncUseClient] = None + self._export: typing.Optional[AsyncExportClient] = None + + @property + def with_raw_response(self) -> AsyncRawSkillClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawSkillClient + """ + return self._raw_client + + async def create( + self, + agent_uuid: str, + *, + definition: SkillDefinition, + skill_id: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentSkill: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + definition : SkillDefinition + + skill_id : typing.Optional[str] + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentSkill + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep, SkillDefinition + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.skill.create( + agent_uuid="agent_uuid", + definition=SkillDefinition(), + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.create( + agent_uuid, + definition=definition, + skill_id=skill_id, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + async def import_package( + self, + agent_uuid: str, + *, + request: typing.Union[bytes, typing.Iterator[bytes], typing.AsyncIterator[bytes]], + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> Task: + """ + Submit a portable Skill archive. The completed Task returns `{"result":{"skill_uuid":""}}`. Approve that Skill before retrieval. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + request : typing.Union[bytes, typing.Iterator[bytes], typing.AsyncIterator[bytes]] + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Task + Accepted + """ + _response = await self._raw_client.import_package( + agent_uuid, request=request, idempotency_key=idempotency_key, request_options=request_options + ) + return _response.data + + async def list( + self, + agent_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + environments: typing.Optional[typing.Sequence[str]] = OMIT, + kind: typing.Optional[str] = OMIT, + task_family: typing.Optional[str] = OMIT, + tools: typing.Optional[typing.Sequence[str]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[AgentSkillSearchHit, Pagev4AgentSkillSearchHit]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + limit : typing.Optional[int] + Page size (maximum 20) + + cursor : typing.Optional[str] + Opaque page cursor + + environments : typing.Optional[typing.Sequence[str]] + + kind : typing.Optional[str] + + task_family : typing.Optional[str] + + tools : typing.Optional[typing.Sequence[str]] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[AgentSkillSearchHit, Pagev4AgentSkillSearchHit] + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + response = await client.agent.skill.list( + agent_uuid="agent_uuid", + ) + async for item in response: + yield item + + # alternatively, you can paginate page-by-page + async for page in response.iter_pages(): + yield page + + + asyncio.run(main()) + """ + return await self._raw_client.list( + agent_uuid, + limit=limit, + cursor=cursor, + environments=environments, + kind=kind, + task_family=task_family, + tools=tools, + request_options=request_options, + ) + + async def search( + self, + agent_uuid: str, + *, + query: str, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + environments: typing.Optional[typing.Sequence[str]] = OMIT, + include_markdown: typing.Optional[bool] = OMIT, + kind: typing.Optional[str] = OMIT, + markdown_format: typing.Optional[AgentSkillSearchRequestMarkdownFormat] = OMIT, + task_family: typing.Optional[str] = OMIT, + tools: typing.Optional[typing.Sequence[str]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[AgentSkillSearchHit, AgentSkillSearchResponse]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + query : str + + limit : typing.Optional[int] + Page size (maximum 20) + + cursor : typing.Optional[str] + Opaque page cursor + + environments : typing.Optional[typing.Sequence[str]] + + include_markdown : typing.Optional[bool] + + kind : typing.Optional[str] + + markdown_format : typing.Optional[AgentSkillSearchRequestMarkdownFormat] + MarkdownFormat selects the form of inline `markdown`. `agent` (the + default) returns the Skill text that an Agent needs: no evidence + markers, the description only in the frontmatter, and no empty + sections. `full` returns the stored SKILL.md with its evidence markers. + + task_family : typing.Optional[str] + + tools : typing.Optional[typing.Sequence[str]] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[AgentSkillSearchHit, AgentSkillSearchResponse] + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + response = await client.agent.skill.search( + agent_uuid="agent_uuid", + query="query", + ) + async for item in response: + yield item + + # alternatively, you can paginate page-by-page + async for page in response.iter_pages(): + yield page + + + asyncio.run(main()) + """ + return await self._raw_client.search( + agent_uuid, + query=query, + limit=limit, + cursor=cursor, + environments=environments, + include_markdown=include_markdown, + kind=kind, + markdown_format=markdown_format, + task_family=task_family, + tools=tools, + request_options=request_options, + ) + + async def get( + self, agent_uuid: str, skill_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AgentSkill: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentSkill + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.skill.get( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get(agent_uuid, skill_uuid, request_options=request_options) + return _response.data + + async def approve( + self, + agent_uuid: str, + skill_uuid: str, + *, + expected_version: int, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentSkillAdmissionDecision: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + expected_version : int + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentSkillAdmissionDecision + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.skill.approve( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + expected_version=1, + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.approve( + agent_uuid, + skill_uuid, + expected_version=expected_version, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + async def retire( + self, + agent_uuid: str, + skill_uuid: str, + *, + expected_version: int, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentSkill: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + expected_version : int + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentSkill + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.skill.retire( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + expected_version=1, + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.retire( + agent_uuid, + skill_uuid, + expected_version=expected_version, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + async def create_version( + self, + agent_uuid: str, + skill_uuid: str, + *, + definition: SkillDefinition, + expected_version: int, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentSkillVersion: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + definition : SkillDefinition + + expected_version : int + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentSkillVersion + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep, SkillDefinition + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.skill.create_version( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + definition=SkillDefinition(), + expected_version=1, + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.create_version( + agent_uuid, + skill_uuid, + definition=definition, + expected_version=expected_version, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + @property + def candidate(self): + if self._candidate is None: + from .candidate.client import AsyncCandidateClient # noqa: E402 + + self._candidate = AsyncCandidateClient(client_wrapper=self._client_wrapper) + return self._candidate + + @property + def evaluation(self): + if self._evaluation is None: + from .evaluation.client import AsyncEvaluationClient # noqa: E402 + + self._evaluation = AsyncEvaluationClient(client_wrapper=self._client_wrapper) + return self._evaluation + + @property + def publication(self): + if self._publication is None: + from .publication.client import AsyncPublicationClient # noqa: E402 + + self._publication = AsyncPublicationClient(client_wrapper=self._client_wrapper) + return self._publication + + @property + def evidence(self): + if self._evidence is None: + from .evidence.client import AsyncEvidenceClient # noqa: E402 + + self._evidence = AsyncEvidenceClient(client_wrapper=self._client_wrapper) + return self._evidence + + @property + def relation(self): + if self._relation is None: + from .relation.client import AsyncRelationClient # noqa: E402 + + self._relation = AsyncRelationClient(client_wrapper=self._client_wrapper) + return self._relation + + @property + def version(self): + if self._version is None: + from .version.client import AsyncVersionClient # noqa: E402 + + self._version = AsyncVersionClient(client_wrapper=self._client_wrapper) + return self._version + + @property + def use(self): + if self._use is None: + from .use.client import AsyncUseClient # noqa: E402 + + self._use = AsyncUseClient(client_wrapper=self._client_wrapper) + return self._use + + @property + def export(self): + if self._export is None: + from .export.client import AsyncExportClient # noqa: E402 + + self._export = AsyncExportClient(client_wrapper=self._client_wrapper) + return self._export diff --git a/src/zep_cloud/agent/skill/evaluation/__init__.py b/src/zep_cloud/agent/skill/evaluation/__init__.py new file mode 100644 index 00000000..a5bc02d5 --- /dev/null +++ b/src/zep_cloud/agent/skill/evaluation/__init__.py @@ -0,0 +1,49 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .types import ( + CreateAgentSkillCandidateEvaluationRequestEvaluatedBy, + CreateAgentSkillCandidateEvaluationRequestVerdict, + CreateAgentSkillEvaluationRequestEvaluatedBy, + CreateAgentSkillEvaluationRequestVerdict, + ) +_dynamic_imports: typing.Dict[str, str] = { + "CreateAgentSkillCandidateEvaluationRequestEvaluatedBy": ".types", + "CreateAgentSkillCandidateEvaluationRequestVerdict": ".types", + "CreateAgentSkillEvaluationRequestEvaluatedBy": ".types", + "CreateAgentSkillEvaluationRequestVerdict": ".types", +} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = [ + "CreateAgentSkillCandidateEvaluationRequestEvaluatedBy", + "CreateAgentSkillCandidateEvaluationRequestVerdict", + "CreateAgentSkillEvaluationRequestEvaluatedBy", + "CreateAgentSkillEvaluationRequestVerdict", +] diff --git a/src/zep_cloud/agent/skill/evaluation/client.py b/src/zep_cloud/agent/skill/evaluation/client.py new file mode 100644 index 00000000..5b06f17b --- /dev/null +++ b/src/zep_cloud/agent/skill/evaluation/client.py @@ -0,0 +1,420 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ....core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ....core.request_options import RequestOptions +from ....types.agent_skill_candidate_evaluation import AgentSkillCandidateEvaluation +from ....types.agent_skill_evaluation import AgentSkillEvaluation +from .raw_client import AsyncRawEvaluationClient, RawEvaluationClient +from .types.create_agent_skill_candidate_evaluation_request_evaluated_by import ( + CreateAgentSkillCandidateEvaluationRequestEvaluatedBy, +) +from .types.create_agent_skill_candidate_evaluation_request_verdict import ( + CreateAgentSkillCandidateEvaluationRequestVerdict, +) +from .types.create_agent_skill_evaluation_request_evaluated_by import CreateAgentSkillEvaluationRequestEvaluatedBy +from .types.create_agent_skill_evaluation_request_verdict import CreateAgentSkillEvaluationRequestVerdict + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class EvaluationClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawEvaluationClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawEvaluationClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawEvaluationClient + """ + return self._raw_client + + def create_for_candidate( + self, + agent_uuid: str, + review_uuid: str, + candidate_uuid: str, + *, + evaluated_by: CreateAgentSkillCandidateEvaluationRequestEvaluatedBy, + evaluator_version: str, + expected_revision: int, + verdict: CreateAgentSkillCandidateEvaluationRequestVerdict, + controlled_test: typing.Optional[bool] = OMIT, + environment: typing.Optional[str] = OMIT, + evidence_reference: typing.Optional[str] = OMIT, + metrics: typing.Optional[typing.Dict[str, float]] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentSkillCandidateEvaluation: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + review_uuid : str + Candidate review UUID + + candidate_uuid : str + Candidate UUID + + evaluated_by : CreateAgentSkillCandidateEvaluationRequestEvaluatedBy + + evaluator_version : str + + expected_revision : int + + verdict : CreateAgentSkillCandidateEvaluationRequestVerdict + + controlled_test : typing.Optional[bool] + + environment : typing.Optional[str] + + evidence_reference : typing.Optional[str] + + metrics : typing.Optional[typing.Dict[str, float]] + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentSkillCandidateEvaluation + Created + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.skill.evaluation.create_for_candidate( + agent_uuid="agent_uuid", + review_uuid="review_uuid", + candidate_uuid="candidate_uuid", + evaluated_by="customer", + evaluator_version="evaluator_version", + expected_revision=1, + verdict="succeeded", + ) + """ + _response = self._raw_client.create_for_candidate( + agent_uuid, + review_uuid, + candidate_uuid, + evaluated_by=evaluated_by, + evaluator_version=evaluator_version, + expected_revision=expected_revision, + verdict=verdict, + controlled_test=controlled_test, + environment=environment, + evidence_reference=evidence_reference, + metrics=metrics, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + def create( + self, + agent_uuid: str, + skill_uuid: str, + *, + evaluated_by: CreateAgentSkillEvaluationRequestEvaluatedBy, + evaluator_version: str, + skill_version: int, + verdict: CreateAgentSkillEvaluationRequestVerdict, + controlled_test: typing.Optional[bool] = OMIT, + environment: typing.Optional[str] = OMIT, + evidence_reference: typing.Optional[str] = OMIT, + metrics: typing.Optional[typing.Dict[str, float]] = OMIT, + use_uuid: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentSkillEvaluation: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + evaluated_by : CreateAgentSkillEvaluationRequestEvaluatedBy + + evaluator_version : str + + skill_version : int + + verdict : CreateAgentSkillEvaluationRequestVerdict + + controlled_test : typing.Optional[bool] + + environment : typing.Optional[str] + + evidence_reference : typing.Optional[str] + + metrics : typing.Optional[typing.Dict[str, float]] + + use_uuid : typing.Optional[str] + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentSkillEvaluation + Created + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.skill.evaluation.create( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + evaluated_by="customer", + evaluator_version="evaluator_version", + skill_version=1, + verdict="succeeded", + ) + """ + _response = self._raw_client.create( + agent_uuid, + skill_uuid, + evaluated_by=evaluated_by, + evaluator_version=evaluator_version, + skill_version=skill_version, + verdict=verdict, + controlled_test=controlled_test, + environment=environment, + evidence_reference=evidence_reference, + metrics=metrics, + use_uuid=use_uuid, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + +class AsyncEvaluationClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawEvaluationClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawEvaluationClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawEvaluationClient + """ + return self._raw_client + + async def create_for_candidate( + self, + agent_uuid: str, + review_uuid: str, + candidate_uuid: str, + *, + evaluated_by: CreateAgentSkillCandidateEvaluationRequestEvaluatedBy, + evaluator_version: str, + expected_revision: int, + verdict: CreateAgentSkillCandidateEvaluationRequestVerdict, + controlled_test: typing.Optional[bool] = OMIT, + environment: typing.Optional[str] = OMIT, + evidence_reference: typing.Optional[str] = OMIT, + metrics: typing.Optional[typing.Dict[str, float]] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentSkillCandidateEvaluation: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + review_uuid : str + Candidate review UUID + + candidate_uuid : str + Candidate UUID + + evaluated_by : CreateAgentSkillCandidateEvaluationRequestEvaluatedBy + + evaluator_version : str + + expected_revision : int + + verdict : CreateAgentSkillCandidateEvaluationRequestVerdict + + controlled_test : typing.Optional[bool] + + environment : typing.Optional[str] + + evidence_reference : typing.Optional[str] + + metrics : typing.Optional[typing.Dict[str, float]] + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentSkillCandidateEvaluation + Created + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.skill.evaluation.create_for_candidate( + agent_uuid="agent_uuid", + review_uuid="review_uuid", + candidate_uuid="candidate_uuid", + evaluated_by="customer", + evaluator_version="evaluator_version", + expected_revision=1, + verdict="succeeded", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.create_for_candidate( + agent_uuid, + review_uuid, + candidate_uuid, + evaluated_by=evaluated_by, + evaluator_version=evaluator_version, + expected_revision=expected_revision, + verdict=verdict, + controlled_test=controlled_test, + environment=environment, + evidence_reference=evidence_reference, + metrics=metrics, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + async def create( + self, + agent_uuid: str, + skill_uuid: str, + *, + evaluated_by: CreateAgentSkillEvaluationRequestEvaluatedBy, + evaluator_version: str, + skill_version: int, + verdict: CreateAgentSkillEvaluationRequestVerdict, + controlled_test: typing.Optional[bool] = OMIT, + environment: typing.Optional[str] = OMIT, + evidence_reference: typing.Optional[str] = OMIT, + metrics: typing.Optional[typing.Dict[str, float]] = OMIT, + use_uuid: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentSkillEvaluation: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + evaluated_by : CreateAgentSkillEvaluationRequestEvaluatedBy + + evaluator_version : str + + skill_version : int + + verdict : CreateAgentSkillEvaluationRequestVerdict + + controlled_test : typing.Optional[bool] + + environment : typing.Optional[str] + + evidence_reference : typing.Optional[str] + + metrics : typing.Optional[typing.Dict[str, float]] + + use_uuid : typing.Optional[str] + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentSkillEvaluation + Created + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.skill.evaluation.create( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + evaluated_by="customer", + evaluator_version="evaluator_version", + skill_version=1, + verdict="succeeded", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.create( + agent_uuid, + skill_uuid, + evaluated_by=evaluated_by, + evaluator_version=evaluator_version, + skill_version=skill_version, + verdict=verdict, + controlled_test=controlled_test, + environment=environment, + evidence_reference=evidence_reference, + metrics=metrics, + use_uuid=use_uuid, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data diff --git a/src/zep_cloud/agent/skill/evaluation/raw_client.py b/src/zep_cloud/agent/skill/evaluation/raw_client.py new file mode 100644 index 00000000..b3f3d8d1 --- /dev/null +++ b/src/zep_cloud/agent/skill/evaluation/raw_client.py @@ -0,0 +1,678 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ....core.api_error import ApiError as core_api_error_ApiError +from ....core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ....core.http_response import AsyncHttpResponse, HttpResponse +from ....core.idempotency import generate_idempotency_key +from ....core.jsonable_encoder import encode_path_param +from ....core.parse_error import ParsingError +from ....core.pydantic_utilities import parse_obj_as +from ....core.request_options import RequestOptions +from ....errors.bad_request_error import BadRequestError +from ....errors.conflict_error import ConflictError +from ....errors.forbidden_error import ForbiddenError +from ....errors.not_found_error import NotFoundError +from ....errors.service_unavailable_error import ServiceUnavailableError +from ....errors.unauthorized_error import UnauthorizedError +from ....types.agent_skill_candidate_evaluation import AgentSkillCandidateEvaluation +from ....types.agent_skill_evaluation import AgentSkillEvaluation +from ....types.api_error import ApiError as types_api_error_ApiError +from .types.create_agent_skill_candidate_evaluation_request_evaluated_by import ( + CreateAgentSkillCandidateEvaluationRequestEvaluatedBy, +) +from .types.create_agent_skill_candidate_evaluation_request_verdict import ( + CreateAgentSkillCandidateEvaluationRequestVerdict, +) +from .types.create_agent_skill_evaluation_request_evaluated_by import CreateAgentSkillEvaluationRequestEvaluatedBy +from .types.create_agent_skill_evaluation_request_verdict import CreateAgentSkillEvaluationRequestVerdict +from pydantic import ValidationError + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class RawEvaluationClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def create_for_candidate( + self, + agent_uuid: str, + review_uuid: str, + candidate_uuid: str, + *, + evaluated_by: CreateAgentSkillCandidateEvaluationRequestEvaluatedBy, + evaluator_version: str, + expected_revision: int, + verdict: CreateAgentSkillCandidateEvaluationRequestVerdict, + controlled_test: typing.Optional[bool] = OMIT, + environment: typing.Optional[str] = OMIT, + evidence_reference: typing.Optional[str] = OMIT, + metrics: typing.Optional[typing.Dict[str, float]] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[AgentSkillCandidateEvaluation]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + review_uuid : str + Candidate review UUID + + candidate_uuid : str + Candidate UUID + + evaluated_by : CreateAgentSkillCandidateEvaluationRequestEvaluatedBy + + evaluator_version : str + + expected_revision : int + + verdict : CreateAgentSkillCandidateEvaluationRequestVerdict + + controlled_test : typing.Optional[bool] + + environment : typing.Optional[str] + + evidence_reference : typing.Optional[str] + + metrics : typing.Optional[typing.Dict[str, float]] + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AgentSkillCandidateEvaluation] + Created + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skill-candidates/{encode_path_param(review_uuid)}/candidates/{encode_path_param(candidate_uuid)}/evaluations", + method="POST", + json={ + "controlled_test": controlled_test, + "environment": environment, + "evaluated_by": evaluated_by, + "evaluator_version": evaluator_version, + "evidence_reference": evidence_reference, + "expected_revision": expected_revision, + "metrics": metrics, + "verdict": verdict, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentSkillCandidateEvaluation, + parse_obj_as( + type_=AgentSkillCandidateEvaluation, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def create( + self, + agent_uuid: str, + skill_uuid: str, + *, + evaluated_by: CreateAgentSkillEvaluationRequestEvaluatedBy, + evaluator_version: str, + skill_version: int, + verdict: CreateAgentSkillEvaluationRequestVerdict, + controlled_test: typing.Optional[bool] = OMIT, + environment: typing.Optional[str] = OMIT, + evidence_reference: typing.Optional[str] = OMIT, + metrics: typing.Optional[typing.Dict[str, float]] = OMIT, + use_uuid: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[AgentSkillEvaluation]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + evaluated_by : CreateAgentSkillEvaluationRequestEvaluatedBy + + evaluator_version : str + + skill_version : int + + verdict : CreateAgentSkillEvaluationRequestVerdict + + controlled_test : typing.Optional[bool] + + environment : typing.Optional[str] + + evidence_reference : typing.Optional[str] + + metrics : typing.Optional[typing.Dict[str, float]] + + use_uuid : typing.Optional[str] + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AgentSkillEvaluation] + Created + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills/{encode_path_param(skill_uuid)}/evaluations", + method="POST", + json={ + "controlled_test": controlled_test, + "environment": environment, + "evaluated_by": evaluated_by, + "evaluator_version": evaluator_version, + "evidence_reference": evidence_reference, + "metrics": metrics, + "skill_version": skill_version, + "use_uuid": use_uuid, + "verdict": verdict, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentSkillEvaluation, + parse_obj_as( + type_=AgentSkillEvaluation, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + +class AsyncRawEvaluationClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def create_for_candidate( + self, + agent_uuid: str, + review_uuid: str, + candidate_uuid: str, + *, + evaluated_by: CreateAgentSkillCandidateEvaluationRequestEvaluatedBy, + evaluator_version: str, + expected_revision: int, + verdict: CreateAgentSkillCandidateEvaluationRequestVerdict, + controlled_test: typing.Optional[bool] = OMIT, + environment: typing.Optional[str] = OMIT, + evidence_reference: typing.Optional[str] = OMIT, + metrics: typing.Optional[typing.Dict[str, float]] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[AgentSkillCandidateEvaluation]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + review_uuid : str + Candidate review UUID + + candidate_uuid : str + Candidate UUID + + evaluated_by : CreateAgentSkillCandidateEvaluationRequestEvaluatedBy + + evaluator_version : str + + expected_revision : int + + verdict : CreateAgentSkillCandidateEvaluationRequestVerdict + + controlled_test : typing.Optional[bool] + + environment : typing.Optional[str] + + evidence_reference : typing.Optional[str] + + metrics : typing.Optional[typing.Dict[str, float]] + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AgentSkillCandidateEvaluation] + Created + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skill-candidates/{encode_path_param(review_uuid)}/candidates/{encode_path_param(candidate_uuid)}/evaluations", + method="POST", + json={ + "controlled_test": controlled_test, + "environment": environment, + "evaluated_by": evaluated_by, + "evaluator_version": evaluator_version, + "evidence_reference": evidence_reference, + "expected_revision": expected_revision, + "metrics": metrics, + "verdict": verdict, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentSkillCandidateEvaluation, + parse_obj_as( + type_=AgentSkillCandidateEvaluation, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def create( + self, + agent_uuid: str, + skill_uuid: str, + *, + evaluated_by: CreateAgentSkillEvaluationRequestEvaluatedBy, + evaluator_version: str, + skill_version: int, + verdict: CreateAgentSkillEvaluationRequestVerdict, + controlled_test: typing.Optional[bool] = OMIT, + environment: typing.Optional[str] = OMIT, + evidence_reference: typing.Optional[str] = OMIT, + metrics: typing.Optional[typing.Dict[str, float]] = OMIT, + use_uuid: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[AgentSkillEvaluation]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + evaluated_by : CreateAgentSkillEvaluationRequestEvaluatedBy + + evaluator_version : str + + skill_version : int + + verdict : CreateAgentSkillEvaluationRequestVerdict + + controlled_test : typing.Optional[bool] + + environment : typing.Optional[str] + + evidence_reference : typing.Optional[str] + + metrics : typing.Optional[typing.Dict[str, float]] + + use_uuid : typing.Optional[str] + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AgentSkillEvaluation] + Created + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills/{encode_path_param(skill_uuid)}/evaluations", + method="POST", + json={ + "controlled_test": controlled_test, + "environment": environment, + "evaluated_by": evaluated_by, + "evaluator_version": evaluator_version, + "evidence_reference": evidence_reference, + "metrics": metrics, + "skill_version": skill_version, + "use_uuid": use_uuid, + "verdict": verdict, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentSkillEvaluation, + parse_obj_as( + type_=AgentSkillEvaluation, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) diff --git a/src/zep_cloud/agent/skill/evaluation/types/__init__.py b/src/zep_cloud/agent/skill/evaluation/types/__init__.py new file mode 100644 index 00000000..bc7b5f1e --- /dev/null +++ b/src/zep_cloud/agent/skill/evaluation/types/__init__.py @@ -0,0 +1,51 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .create_agent_skill_candidate_evaluation_request_evaluated_by import ( + CreateAgentSkillCandidateEvaluationRequestEvaluatedBy, + ) + from .create_agent_skill_candidate_evaluation_request_verdict import ( + CreateAgentSkillCandidateEvaluationRequestVerdict, + ) + from .create_agent_skill_evaluation_request_evaluated_by import CreateAgentSkillEvaluationRequestEvaluatedBy + from .create_agent_skill_evaluation_request_verdict import CreateAgentSkillEvaluationRequestVerdict +_dynamic_imports: typing.Dict[str, str] = { + "CreateAgentSkillCandidateEvaluationRequestEvaluatedBy": ".create_agent_skill_candidate_evaluation_request_evaluated_by", + "CreateAgentSkillCandidateEvaluationRequestVerdict": ".create_agent_skill_candidate_evaluation_request_verdict", + "CreateAgentSkillEvaluationRequestEvaluatedBy": ".create_agent_skill_evaluation_request_evaluated_by", + "CreateAgentSkillEvaluationRequestVerdict": ".create_agent_skill_evaluation_request_verdict", +} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = [ + "CreateAgentSkillCandidateEvaluationRequestEvaluatedBy", + "CreateAgentSkillCandidateEvaluationRequestVerdict", + "CreateAgentSkillEvaluationRequestEvaluatedBy", + "CreateAgentSkillEvaluationRequestVerdict", +] diff --git a/src/zep_cloud/agent/skill/evaluation/types/create_agent_skill_candidate_evaluation_request_evaluated_by.py b/src/zep_cloud/agent/skill/evaluation/types/create_agent_skill_candidate_evaluation_request_evaluated_by.py new file mode 100644 index 00000000..35115dbc --- /dev/null +++ b/src/zep_cloud/agent/skill/evaluation/types/create_agent_skill_candidate_evaluation_request_evaluated_by.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +CreateAgentSkillCandidateEvaluationRequestEvaluatedBy = typing.Union[ + typing.Literal["customer", "tool", "offline_corpus", "policy"], typing.Any +] diff --git a/src/zep_cloud/agent/skill/evaluation/types/create_agent_skill_candidate_evaluation_request_verdict.py b/src/zep_cloud/agent/skill/evaluation/types/create_agent_skill_candidate_evaluation_request_verdict.py new file mode 100644 index 00000000..1f4e2300 --- /dev/null +++ b/src/zep_cloud/agent/skill/evaluation/types/create_agent_skill_candidate_evaluation_request_verdict.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +CreateAgentSkillCandidateEvaluationRequestVerdict = typing.Union[ + typing.Literal["succeeded", "failed", "partial", "unknown"], typing.Any +] diff --git a/src/zep_cloud/agent/skill/evaluation/types/create_agent_skill_evaluation_request_evaluated_by.py b/src/zep_cloud/agent/skill/evaluation/types/create_agent_skill_evaluation_request_evaluated_by.py new file mode 100644 index 00000000..e881cb31 --- /dev/null +++ b/src/zep_cloud/agent/skill/evaluation/types/create_agent_skill_evaluation_request_evaluated_by.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +CreateAgentSkillEvaluationRequestEvaluatedBy = typing.Union[ + typing.Literal["customer", "tool", "offline_corpus", "policy"], typing.Any +] diff --git a/src/zep_cloud/agent/skill/evaluation/types/create_agent_skill_evaluation_request_verdict.py b/src/zep_cloud/agent/skill/evaluation/types/create_agent_skill_evaluation_request_verdict.py new file mode 100644 index 00000000..b2736a95 --- /dev/null +++ b/src/zep_cloud/agent/skill/evaluation/types/create_agent_skill_evaluation_request_verdict.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +CreateAgentSkillEvaluationRequestVerdict = typing.Union[ + typing.Literal["succeeded", "failed", "partial", "unknown"], typing.Any +] diff --git a/src/zep_cloud/agent/skill/evidence/__init__.py b/src/zep_cloud/agent/skill/evidence/__init__.py new file mode 100644 index 00000000..5cde0202 --- /dev/null +++ b/src/zep_cloud/agent/skill/evidence/__init__.py @@ -0,0 +1,4 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + diff --git a/src/zep_cloud/agent/skill/evidence/client.py b/src/zep_cloud/agent/skill/evidence/client.py new file mode 100644 index 00000000..af1e7f64 --- /dev/null +++ b/src/zep_cloud/agent/skill/evidence/client.py @@ -0,0 +1,157 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ....core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ....core.pagination import AsyncPager, SyncPager +from ....core.request_options import RequestOptions +from ....types.agent_skill_evidence import AgentSkillEvidence +from ....types.pagev4agent_skill_evidence import Pagev4AgentSkillEvidence +from .raw_client import AsyncRawEvidenceClient, RawEvidenceClient + + +class EvidenceClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawEvidenceClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawEvidenceClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawEvidenceClient + """ + return self._raw_client + + def list( + self, + agent_uuid: str, + skill_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[AgentSkillEvidence, Pagev4AgentSkillEvidence]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + limit : typing.Optional[int] + Page size (maximum 100) + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[AgentSkillEvidence, Pagev4AgentSkillEvidence] + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + response = client.agent.skill.evidence.list( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + ) + for item in response: + yield item + # alternatively, you can paginate page-by-page + for page in response.iter_pages(): + yield page + """ + return self._raw_client.list( + agent_uuid, skill_uuid, limit=limit, cursor=cursor, request_options=request_options + ) + + +class AsyncEvidenceClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawEvidenceClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawEvidenceClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawEvidenceClient + """ + return self._raw_client + + async def list( + self, + agent_uuid: str, + skill_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[AgentSkillEvidence, Pagev4AgentSkillEvidence]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + limit : typing.Optional[int] + Page size (maximum 100) + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[AgentSkillEvidence, Pagev4AgentSkillEvidence] + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + response = await client.agent.skill.evidence.list( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + ) + async for item in response: + yield item + + # alternatively, you can paginate page-by-page + async for page in response.iter_pages(): + yield page + + + asyncio.run(main()) + """ + return await self._raw_client.list( + agent_uuid, skill_uuid, limit=limit, cursor=cursor, request_options=request_options + ) diff --git a/src/zep_cloud/agent/skill/evidence/raw_client.py b/src/zep_cloud/agent/skill/evidence/raw_client.py new file mode 100644 index 00000000..abe24326 --- /dev/null +++ b/src/zep_cloud/agent/skill/evidence/raw_client.py @@ -0,0 +1,292 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ....core.api_error import ApiError as core_api_error_ApiError +from ....core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ....core.jsonable_encoder import encode_path_param +from ....core.pagination import AsyncPager, SyncPager +from ....core.parse_error import ParsingError +from ....core.pydantic_utilities import parse_obj_as +from ....core.request_options import RequestOptions +from ....errors.bad_request_error import BadRequestError +from ....errors.forbidden_error import ForbiddenError +from ....errors.not_found_error import NotFoundError +from ....errors.service_unavailable_error import ServiceUnavailableError +from ....errors.unauthorized_error import UnauthorizedError +from ....types.agent_skill_evidence import AgentSkillEvidence +from ....types.api_error import ApiError as types_api_error_ApiError +from ....types.pagev4agent_skill_evidence import Pagev4AgentSkillEvidence +from pydantic import ValidationError + + +class RawEvidenceClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def list( + self, + agent_uuid: str, + skill_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[AgentSkillEvidence, Pagev4AgentSkillEvidence]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + limit : typing.Optional[int] + Page size (maximum 100) + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[AgentSkillEvidence, Pagev4AgentSkillEvidence] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills/{encode_path_param(skill_uuid)}/evidence", + method="GET", + params={ + "limit": limit, + "cursor": cursor, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + Pagev4AgentSkillEvidence, + parse_obj_as( + type_=Pagev4AgentSkillEvidence, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + _get_next = lambda: self.list( + agent_uuid, + skill_uuid, + limit=limit, + cursor=_parsed_next, + request_options=request_options, + ) + return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + +class AsyncRawEvidenceClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def list( + self, + agent_uuid: str, + skill_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[AgentSkillEvidence, Pagev4AgentSkillEvidence]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + limit : typing.Optional[int] + Page size (maximum 100) + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[AgentSkillEvidence, Pagev4AgentSkillEvidence] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills/{encode_path_param(skill_uuid)}/evidence", + method="GET", + params={ + "limit": limit, + "cursor": cursor, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + Pagev4AgentSkillEvidence, + parse_obj_as( + type_=Pagev4AgentSkillEvidence, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + + async def _get_next(): + return await self.list( + agent_uuid, + skill_uuid, + limit=limit, + cursor=_parsed_next, + request_options=request_options, + ) + + return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) diff --git a/src/zep_cloud/agent/skill/export/__init__.py b/src/zep_cloud/agent/skill/export/__init__.py new file mode 100644 index 00000000..5cde0202 --- /dev/null +++ b/src/zep_cloud/agent/skill/export/__init__.py @@ -0,0 +1,4 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + diff --git a/src/zep_cloud/agent/skill/export/client.py b/src/zep_cloud/agent/skill/export/client.py new file mode 100644 index 00000000..306d97cf --- /dev/null +++ b/src/zep_cloud/agent/skill/export/client.py @@ -0,0 +1,255 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ....core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ....core.request_options import RequestOptions +from ....types.task import Task +from .raw_client import AsyncRawExportClient, RawExportClient + + +class ExportClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawExportClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawExportClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawExportClient + """ + return self._raw_client + + def create( + self, + agent_uuid: str, + skill_uuid: str, + version: int, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> Task: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + version : int + Skill version + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Task + Accepted + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.skill.export.create( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + version=1, + ) + """ + _response = self._raw_client.create( + agent_uuid, skill_uuid, version, idempotency_key=idempotency_key, request_options=request_options + ) + return _response.data + + def get( + self, + agent_uuid: str, + skill_uuid: str, + version: int, + task_uuid: str, + *, + request_options: typing.Optional[RequestOptions] = None, + ) -> typing.Iterator[bytes]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + version : int + Skill version + + task_uuid : str + Export Task UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response. + + Returns + ------- + typing.Iterator[bytes] + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.skill.export.get( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + version=1, + task_uuid="task_uuid", + ) + """ + with self._raw_client.get(agent_uuid, skill_uuid, version, task_uuid, request_options=request_options) as r: + yield from r.data + + +class AsyncExportClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawExportClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawExportClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawExportClient + """ + return self._raw_client + + async def create( + self, + agent_uuid: str, + skill_uuid: str, + version: int, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> Task: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + version : int + Skill version + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Task + Accepted + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.skill.export.create( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + version=1, + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.create( + agent_uuid, skill_uuid, version, idempotency_key=idempotency_key, request_options=request_options + ) + return _response.data + + async def get( + self, + agent_uuid: str, + skill_uuid: str, + version: int, + task_uuid: str, + *, + request_options: typing.Optional[RequestOptions] = None, + ) -> typing.AsyncIterator[bytes]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + version : int + Skill version + + task_uuid : str + Export Task UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response. + + Returns + ------- + typing.AsyncIterator[bytes] + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.skill.export.get( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + version=1, + task_uuid="task_uuid", + ) + + + asyncio.run(main()) + """ + async with self._raw_client.get( + agent_uuid, skill_uuid, version, task_uuid, request_options=request_options + ) as r: + async for _chunk in r.data: + yield _chunk diff --git a/src/zep_cloud/agent/skill/export/raw_client.py b/src/zep_cloud/agent/skill/export/raw_client.py new file mode 100644 index 00000000..cdac8d6c --- /dev/null +++ b/src/zep_cloud/agent/skill/export/raw_client.py @@ -0,0 +1,507 @@ +# This file was auto-generated by Fern from our API Definition. + +import contextlib +import typing +from json.decoder import JSONDecodeError + +from ....core.api_error import ApiError as core_api_error_ApiError +from ....core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ....core.http_response import AsyncHttpResponse, HttpResponse +from ....core.idempotency import generate_idempotency_key +from ....core.jsonable_encoder import encode_path_param +from ....core.parse_error import ParsingError +from ....core.pydantic_utilities import parse_obj_as +from ....core.request_options import RequestOptions +from ....errors.bad_request_error import BadRequestError +from ....errors.conflict_error import ConflictError +from ....errors.forbidden_error import ForbiddenError +from ....errors.not_found_error import NotFoundError +from ....errors.service_unavailable_error import ServiceUnavailableError +from ....types.api_error import ApiError as types_api_error_ApiError +from ....types.task import Task +from pydantic import ValidationError + + +class RawExportClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def create( + self, + agent_uuid: str, + skill_uuid: str, + version: int, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[Task]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + version : int + Skill version + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[Task] + Accepted + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills/{encode_path_param(skill_uuid)}/versions/{encode_path_param(version)}/export", + method="POST", + headers={ + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + Task, + parse_obj_as( + type_=Task, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + @contextlib.contextmanager + def get( + self, + agent_uuid: str, + skill_uuid: str, + version: int, + task_uuid: str, + *, + request_options: typing.Optional[RequestOptions] = None, + ) -> typing.Iterator[HttpResponse[typing.Iterator[bytes]]]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + version : int + Skill version + + task_uuid : str + Export Task UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response. + + Returns + ------- + typing.Iterator[HttpResponse[typing.Iterator[bytes]]] + OK + """ + with self._client_wrapper.httpx_client.stream( + f"agents/{encode_path_param(agent_uuid)}/skills/{encode_path_param(skill_uuid)}/versions/{encode_path_param(version)}/export/{encode_path_param(task_uuid)}", + method="GET", + request_options=request_options, + ) as _response: + + def _stream() -> HttpResponse[typing.Iterator[bytes]]: + try: + if 200 <= _response.status_code < 300: + _chunk_size = request_options.get("chunk_size", None) if request_options is not None else None + return HttpResponse( + response=_response, data=(_chunk for _chunk in _response.iter_bytes(chunk_size=_chunk_size)) + ) + _response.read() + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, + headers=dict(_response.headers), + body=_response.json(), + cause=e, + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + yield _stream() + + +class AsyncRawExportClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def create( + self, + agent_uuid: str, + skill_uuid: str, + version: int, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[Task]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + version : int + Skill version + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[Task] + Accepted + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills/{encode_path_param(skill_uuid)}/versions/{encode_path_param(version)}/export", + method="POST", + headers={ + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + Task, + parse_obj_as( + type_=Task, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + @contextlib.asynccontextmanager + async def get( + self, + agent_uuid: str, + skill_uuid: str, + version: int, + task_uuid: str, + *, + request_options: typing.Optional[RequestOptions] = None, + ) -> typing.AsyncIterator[AsyncHttpResponse[typing.AsyncIterator[bytes]]]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + version : int + Skill version + + task_uuid : str + Export Task UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response. + + Returns + ------- + typing.AsyncIterator[AsyncHttpResponse[typing.AsyncIterator[bytes]]] + OK + """ + async with self._client_wrapper.httpx_client.stream( + f"agents/{encode_path_param(agent_uuid)}/skills/{encode_path_param(skill_uuid)}/versions/{encode_path_param(version)}/export/{encode_path_param(task_uuid)}", + method="GET", + request_options=request_options, + ) as _response: + + async def _stream() -> AsyncHttpResponse[typing.AsyncIterator[bytes]]: + try: + if 200 <= _response.status_code < 300: + _chunk_size = request_options.get("chunk_size", None) if request_options is not None else None + return AsyncHttpResponse( + response=_response, + data=(_chunk async for _chunk in _response.aiter_bytes(chunk_size=_chunk_size)), + ) + await _response.aread() + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, + headers=dict(_response.headers), + body=_response.json(), + cause=e, + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + yield await _stream() diff --git a/src/zep_cloud/agent/skill/publication/__init__.py b/src/zep_cloud/agent/skill/publication/__init__.py new file mode 100644 index 00000000..5cde0202 --- /dev/null +++ b/src/zep_cloud/agent/skill/publication/__init__.py @@ -0,0 +1,4 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + diff --git a/src/zep_cloud/agent/skill/publication/client.py b/src/zep_cloud/agent/skill/publication/client.py new file mode 100644 index 00000000..36349a60 --- /dev/null +++ b/src/zep_cloud/agent/skill/publication/client.py @@ -0,0 +1,244 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ....core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ....core.request_options import RequestOptions +from ....types.agent_skill_publication_lineage import AgentSkillPublicationLineage +from .raw_client import AsyncRawPublicationClient, RawPublicationClient + + +class PublicationClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawPublicationClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawPublicationClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawPublicationClient + """ + return self._raw_client + + def lookup( + self, + agent_uuid: str, + *, + source_agent_uuid: str, + source_skill_uuid: str, + source_version: int, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentSkillPublicationLineage: + """ + Find a destination Skill by its source Agent, Skill, and version. The endpoint returns 404 until an automatic publication is ready or after it is invalidated. + + Parameters + ---------- + agent_uuid : str + Destination Agent UUID + + source_agent_uuid : str + Source Agent UUID + + source_skill_uuid : str + Source Skill UUID + + source_version : int + Source version number + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentSkillPublicationLineage + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.skill.publication.lookup( + agent_uuid="agent_uuid", + source_agent_uuid="source_agent_uuid", + source_skill_uuid="source_skill_uuid", + source_version=1, + ) + """ + _response = self._raw_client.lookup( + agent_uuid, + source_agent_uuid=source_agent_uuid, + source_skill_uuid=source_skill_uuid, + source_version=source_version, + request_options=request_options, + ) + return _response.data + + def get( + self, agent_uuid: str, skill_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AgentSkillPublicationLineage: + """ + Get the publication that created a destination Skill. Use its source version and policy identity to verify a copied Skill. The endpoint returns 404 for unpublished and invalidated Skills. + + Parameters + ---------- + agent_uuid : str + Destination Agent UUID + + skill_uuid : str + Destination Skill UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentSkillPublicationLineage + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.skill.publication.get( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + ) + """ + _response = self._raw_client.get(agent_uuid, skill_uuid, request_options=request_options) + return _response.data + + +class AsyncPublicationClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawPublicationClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawPublicationClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawPublicationClient + """ + return self._raw_client + + async def lookup( + self, + agent_uuid: str, + *, + source_agent_uuid: str, + source_skill_uuid: str, + source_version: int, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentSkillPublicationLineage: + """ + Find a destination Skill by its source Agent, Skill, and version. The endpoint returns 404 until an automatic publication is ready or after it is invalidated. + + Parameters + ---------- + agent_uuid : str + Destination Agent UUID + + source_agent_uuid : str + Source Agent UUID + + source_skill_uuid : str + Source Skill UUID + + source_version : int + Source version number + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentSkillPublicationLineage + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.skill.publication.lookup( + agent_uuid="agent_uuid", + source_agent_uuid="source_agent_uuid", + source_skill_uuid="source_skill_uuid", + source_version=1, + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.lookup( + agent_uuid, + source_agent_uuid=source_agent_uuid, + source_skill_uuid=source_skill_uuid, + source_version=source_version, + request_options=request_options, + ) + return _response.data + + async def get( + self, agent_uuid: str, skill_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AgentSkillPublicationLineage: + """ + Get the publication that created a destination Skill. Use its source version and policy identity to verify a copied Skill. The endpoint returns 404 for unpublished and invalidated Skills. + + Parameters + ---------- + agent_uuid : str + Destination Agent UUID + + skill_uuid : str + Destination Skill UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentSkillPublicationLineage + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.skill.publication.get( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get(agent_uuid, skill_uuid, request_options=request_options) + return _response.data diff --git a/src/zep_cloud/agent/skill/publication/raw_client.py b/src/zep_cloud/agent/skill/publication/raw_client.py new file mode 100644 index 00000000..df8e1d54 --- /dev/null +++ b/src/zep_cloud/agent/skill/publication/raw_client.py @@ -0,0 +1,484 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ....core.api_error import ApiError as core_api_error_ApiError +from ....core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ....core.http_response import AsyncHttpResponse, HttpResponse +from ....core.jsonable_encoder import encode_path_param +from ....core.parse_error import ParsingError +from ....core.pydantic_utilities import parse_obj_as +from ....core.request_options import RequestOptions +from ....errors.bad_request_error import BadRequestError +from ....errors.forbidden_error import ForbiddenError +from ....errors.not_found_error import NotFoundError +from ....errors.service_unavailable_error import ServiceUnavailableError +from ....errors.unauthorized_error import UnauthorizedError +from ....types.agent_skill_publication_lineage import AgentSkillPublicationLineage +from ....types.api_error import ApiError as types_api_error_ApiError +from pydantic import ValidationError + + +class RawPublicationClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def lookup( + self, + agent_uuid: str, + *, + source_agent_uuid: str, + source_skill_uuid: str, + source_version: int, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[AgentSkillPublicationLineage]: + """ + Find a destination Skill by its source Agent, Skill, and version. The endpoint returns 404 until an automatic publication is ready or after it is invalidated. + + Parameters + ---------- + agent_uuid : str + Destination Agent UUID + + source_agent_uuid : str + Source Agent UUID + + source_skill_uuid : str + Source Skill UUID + + source_version : int + Source version number + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AgentSkillPublicationLineage] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skill-publications", + method="GET", + params={ + "source_agent_uuid": source_agent_uuid, + "source_skill_uuid": source_skill_uuid, + "source_version": source_version, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentSkillPublicationLineage, + parse_obj_as( + type_=AgentSkillPublicationLineage, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def get( + self, agent_uuid: str, skill_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[AgentSkillPublicationLineage]: + """ + Get the publication that created a destination Skill. Use its source version and policy identity to verify a copied Skill. The endpoint returns 404 for unpublished and invalidated Skills. + + Parameters + ---------- + agent_uuid : str + Destination Agent UUID + + skill_uuid : str + Destination Skill UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AgentSkillPublicationLineage] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills/{encode_path_param(skill_uuid)}/publication", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentSkillPublicationLineage, + parse_obj_as( + type_=AgentSkillPublicationLineage, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + +class AsyncRawPublicationClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def lookup( + self, + agent_uuid: str, + *, + source_agent_uuid: str, + source_skill_uuid: str, + source_version: int, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[AgentSkillPublicationLineage]: + """ + Find a destination Skill by its source Agent, Skill, and version. The endpoint returns 404 until an automatic publication is ready or after it is invalidated. + + Parameters + ---------- + agent_uuid : str + Destination Agent UUID + + source_agent_uuid : str + Source Agent UUID + + source_skill_uuid : str + Source Skill UUID + + source_version : int + Source version number + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AgentSkillPublicationLineage] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skill-publications", + method="GET", + params={ + "source_agent_uuid": source_agent_uuid, + "source_skill_uuid": source_skill_uuid, + "source_version": source_version, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentSkillPublicationLineage, + parse_obj_as( + type_=AgentSkillPublicationLineage, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def get( + self, agent_uuid: str, skill_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[AgentSkillPublicationLineage]: + """ + Get the publication that created a destination Skill. Use its source version and policy identity to verify a copied Skill. The endpoint returns 404 for unpublished and invalidated Skills. + + Parameters + ---------- + agent_uuid : str + Destination Agent UUID + + skill_uuid : str + Destination Skill UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AgentSkillPublicationLineage] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills/{encode_path_param(skill_uuid)}/publication", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentSkillPublicationLineage, + parse_obj_as( + type_=AgentSkillPublicationLineage, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) diff --git a/src/zep_cloud/agent/skill/raw_client.py b/src/zep_cloud/agent/skill/raw_client.py new file mode 100644 index 00000000..6ae9ada9 --- /dev/null +++ b/src/zep_cloud/agent/skill/raw_client.py @@ -0,0 +1,2206 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ...core.api_error import ApiError as core_api_error_ApiError +from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ...core.http_response import AsyncHttpResponse, HttpResponse +from ...core.idempotency import generate_idempotency_key +from ...core.jsonable_encoder import encode_path_param +from ...core.pagination import AsyncPager, SyncPager +from ...core.parse_error import ParsingError +from ...core.pydantic_utilities import parse_obj_as +from ...core.request_options import RequestOptions +from ...core.serialization import convert_and_respect_annotation_metadata +from ...errors.bad_request_error import BadRequestError +from ...errors.conflict_error import ConflictError +from ...errors.content_too_large_error import ContentTooLargeError +from ...errors.forbidden_error import ForbiddenError +from ...errors.not_found_error import NotFoundError +from ...errors.service_unavailable_error import ServiceUnavailableError +from ...errors.unauthorized_error import UnauthorizedError +from ...types.agent_skill import AgentSkill +from ...types.agent_skill_admission_decision import AgentSkillAdmissionDecision +from ...types.agent_skill_search_hit import AgentSkillSearchHit +from ...types.agent_skill_search_response import AgentSkillSearchResponse +from ...types.agent_skill_version import AgentSkillVersion +from ...types.api_error import ApiError as types_api_error_ApiError +from ...types.pagev4agent_skill_search_hit import Pagev4AgentSkillSearchHit +from ...types.skill_definition import SkillDefinition +from ...types.task import Task +from .types.agent_skill_search_request_markdown_format import AgentSkillSearchRequestMarkdownFormat +from pydantic import ValidationError + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class RawSkillClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def create( + self, + agent_uuid: str, + *, + definition: SkillDefinition, + skill_id: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[AgentSkill]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + definition : SkillDefinition + + skill_id : typing.Optional[str] + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AgentSkill] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills", + method="POST", + json={ + "definition": convert_and_respect_annotation_metadata( + object_=definition, annotation=SkillDefinition, direction="write" + ), + "skill_id": skill_id, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentSkill, + parse_obj_as( + type_=AgentSkill, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def import_package( + self, + agent_uuid: str, + *, + request: typing.Union[bytes, typing.Iterator[bytes], typing.AsyncIterator[bytes]], + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[Task]: + """ + Submit a portable Skill archive. The completed Task returns `{"result":{"skill_uuid":""}}`. Approve that Skill before retrieval. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + request : typing.Union[bytes, typing.Iterator[bytes], typing.AsyncIterator[bytes]] + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[Task] + Accepted + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills/import", + method="POST", + content=request, + headers={ + "content-type": "application/zip", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + Task, + parse_obj_as( + type_=Task, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 413: + raise ContentTooLargeError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def list( + self, + agent_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + environments: typing.Optional[typing.Sequence[str]] = OMIT, + kind: typing.Optional[str] = OMIT, + task_family: typing.Optional[str] = OMIT, + tools: typing.Optional[typing.Sequence[str]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[AgentSkillSearchHit, Pagev4AgentSkillSearchHit]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + limit : typing.Optional[int] + Page size (maximum 20) + + cursor : typing.Optional[str] + Opaque page cursor + + environments : typing.Optional[typing.Sequence[str]] + + kind : typing.Optional[str] + + task_family : typing.Optional[str] + + tools : typing.Optional[typing.Sequence[str]] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[AgentSkillSearchHit, Pagev4AgentSkillSearchHit] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills/list", + method="POST", + params={ + "limit": limit, + "cursor": cursor, + }, + json={ + "environments": environments, + "kind": kind, + "task_family": task_family, + "tools": tools, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + Pagev4AgentSkillSearchHit, + parse_obj_as( + type_=Pagev4AgentSkillSearchHit, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + _get_next = lambda: self.list( + agent_uuid, + limit=limit, + cursor=_parsed_next, + environments=environments, + kind=kind, + task_family=task_family, + tools=tools, + request_options=request_options, + ) + return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def search( + self, + agent_uuid: str, + *, + query: str, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + environments: typing.Optional[typing.Sequence[str]] = OMIT, + include_markdown: typing.Optional[bool] = OMIT, + kind: typing.Optional[str] = OMIT, + markdown_format: typing.Optional[AgentSkillSearchRequestMarkdownFormat] = OMIT, + task_family: typing.Optional[str] = OMIT, + tools: typing.Optional[typing.Sequence[str]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[AgentSkillSearchHit, AgentSkillSearchResponse]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + query : str + + limit : typing.Optional[int] + Page size (maximum 20) + + cursor : typing.Optional[str] + Opaque page cursor + + environments : typing.Optional[typing.Sequence[str]] + + include_markdown : typing.Optional[bool] + + kind : typing.Optional[str] + + markdown_format : typing.Optional[AgentSkillSearchRequestMarkdownFormat] + MarkdownFormat selects the form of inline `markdown`. `agent` (the + default) returns the Skill text that an Agent needs: no evidence + markers, the description only in the frontmatter, and no empty + sections. `full` returns the stored SKILL.md with its evidence markers. + + task_family : typing.Optional[str] + + tools : typing.Optional[typing.Sequence[str]] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[AgentSkillSearchHit, AgentSkillSearchResponse] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills/search", + method="POST", + params={ + "limit": limit, + "cursor": cursor, + }, + json={ + "environments": environments, + "include_markdown": include_markdown, + "kind": kind, + "markdown_format": markdown_format, + "query": query, + "task_family": task_family, + "tools": tools, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + AgentSkillSearchResponse, + parse_obj_as( + type_=AgentSkillSearchResponse, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + _get_next = lambda: self.search( + agent_uuid, + query=query, + limit=limit, + cursor=_parsed_next, + environments=environments, + include_markdown=include_markdown, + kind=kind, + markdown_format=markdown_format, + task_family=task_family, + tools=tools, + request_options=request_options, + ) + return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def get( + self, agent_uuid: str, skill_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[AgentSkill]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AgentSkill] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills/{encode_path_param(skill_uuid)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentSkill, + parse_obj_as( + type_=AgentSkill, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def approve( + self, + agent_uuid: str, + skill_uuid: str, + *, + expected_version: int, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[AgentSkillAdmissionDecision]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + expected_version : int + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AgentSkillAdmissionDecision] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills/{encode_path_param(skill_uuid)}/approve", + method="POST", + json={ + "expected_version": expected_version, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentSkillAdmissionDecision, + parse_obj_as( + type_=AgentSkillAdmissionDecision, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def retire( + self, + agent_uuid: str, + skill_uuid: str, + *, + expected_version: int, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[AgentSkill]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + expected_version : int + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AgentSkill] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills/{encode_path_param(skill_uuid)}/retire", + method="POST", + json={ + "expected_version": expected_version, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentSkill, + parse_obj_as( + type_=AgentSkill, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def create_version( + self, + agent_uuid: str, + skill_uuid: str, + *, + definition: SkillDefinition, + expected_version: int, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[AgentSkillVersion]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + definition : SkillDefinition + + expected_version : int + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AgentSkillVersion] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills/{encode_path_param(skill_uuid)}/versions", + method="POST", + json={ + "definition": convert_and_respect_annotation_metadata( + object_=definition, annotation=SkillDefinition, direction="write" + ), + "expected_version": expected_version, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentSkillVersion, + parse_obj_as( + type_=AgentSkillVersion, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + +class AsyncRawSkillClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def create( + self, + agent_uuid: str, + *, + definition: SkillDefinition, + skill_id: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[AgentSkill]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + definition : SkillDefinition + + skill_id : typing.Optional[str] + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AgentSkill] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills", + method="POST", + json={ + "definition": convert_and_respect_annotation_metadata( + object_=definition, annotation=SkillDefinition, direction="write" + ), + "skill_id": skill_id, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentSkill, + parse_obj_as( + type_=AgentSkill, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def import_package( + self, + agent_uuid: str, + *, + request: typing.Union[bytes, typing.Iterator[bytes], typing.AsyncIterator[bytes]], + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[Task]: + """ + Submit a portable Skill archive. The completed Task returns `{"result":{"skill_uuid":""}}`. Approve that Skill before retrieval. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + request : typing.Union[bytes, typing.Iterator[bytes], typing.AsyncIterator[bytes]] + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[Task] + Accepted + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills/import", + method="POST", + content=request, + headers={ + "content-type": "application/zip", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + Task, + parse_obj_as( + type_=Task, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 413: + raise ContentTooLargeError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def list( + self, + agent_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + environments: typing.Optional[typing.Sequence[str]] = OMIT, + kind: typing.Optional[str] = OMIT, + task_family: typing.Optional[str] = OMIT, + tools: typing.Optional[typing.Sequence[str]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[AgentSkillSearchHit, Pagev4AgentSkillSearchHit]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + limit : typing.Optional[int] + Page size (maximum 20) + + cursor : typing.Optional[str] + Opaque page cursor + + environments : typing.Optional[typing.Sequence[str]] + + kind : typing.Optional[str] + + task_family : typing.Optional[str] + + tools : typing.Optional[typing.Sequence[str]] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[AgentSkillSearchHit, Pagev4AgentSkillSearchHit] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills/list", + method="POST", + params={ + "limit": limit, + "cursor": cursor, + }, + json={ + "environments": environments, + "kind": kind, + "task_family": task_family, + "tools": tools, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + Pagev4AgentSkillSearchHit, + parse_obj_as( + type_=Pagev4AgentSkillSearchHit, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + + async def _get_next(): + return await self.list( + agent_uuid, + limit=limit, + cursor=_parsed_next, + environments=environments, + kind=kind, + task_family=task_family, + tools=tools, + request_options=request_options, + ) + + return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def search( + self, + agent_uuid: str, + *, + query: str, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + environments: typing.Optional[typing.Sequence[str]] = OMIT, + include_markdown: typing.Optional[bool] = OMIT, + kind: typing.Optional[str] = OMIT, + markdown_format: typing.Optional[AgentSkillSearchRequestMarkdownFormat] = OMIT, + task_family: typing.Optional[str] = OMIT, + tools: typing.Optional[typing.Sequence[str]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[AgentSkillSearchHit, AgentSkillSearchResponse]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + query : str + + limit : typing.Optional[int] + Page size (maximum 20) + + cursor : typing.Optional[str] + Opaque page cursor + + environments : typing.Optional[typing.Sequence[str]] + + include_markdown : typing.Optional[bool] + + kind : typing.Optional[str] + + markdown_format : typing.Optional[AgentSkillSearchRequestMarkdownFormat] + MarkdownFormat selects the form of inline `markdown`. `agent` (the + default) returns the Skill text that an Agent needs: no evidence + markers, the description only in the frontmatter, and no empty + sections. `full` returns the stored SKILL.md with its evidence markers. + + task_family : typing.Optional[str] + + tools : typing.Optional[typing.Sequence[str]] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[AgentSkillSearchHit, AgentSkillSearchResponse] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills/search", + method="POST", + params={ + "limit": limit, + "cursor": cursor, + }, + json={ + "environments": environments, + "include_markdown": include_markdown, + "kind": kind, + "markdown_format": markdown_format, + "query": query, + "task_family": task_family, + "tools": tools, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + AgentSkillSearchResponse, + parse_obj_as( + type_=AgentSkillSearchResponse, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + + async def _get_next(): + return await self.search( + agent_uuid, + query=query, + limit=limit, + cursor=_parsed_next, + environments=environments, + include_markdown=include_markdown, + kind=kind, + markdown_format=markdown_format, + task_family=task_family, + tools=tools, + request_options=request_options, + ) + + return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def get( + self, agent_uuid: str, skill_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[AgentSkill]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AgentSkill] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills/{encode_path_param(skill_uuid)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentSkill, + parse_obj_as( + type_=AgentSkill, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def approve( + self, + agent_uuid: str, + skill_uuid: str, + *, + expected_version: int, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[AgentSkillAdmissionDecision]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + expected_version : int + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AgentSkillAdmissionDecision] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills/{encode_path_param(skill_uuid)}/approve", + method="POST", + json={ + "expected_version": expected_version, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentSkillAdmissionDecision, + parse_obj_as( + type_=AgentSkillAdmissionDecision, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def retire( + self, + agent_uuid: str, + skill_uuid: str, + *, + expected_version: int, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[AgentSkill]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + expected_version : int + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AgentSkill] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills/{encode_path_param(skill_uuid)}/retire", + method="POST", + json={ + "expected_version": expected_version, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentSkill, + parse_obj_as( + type_=AgentSkill, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def create_version( + self, + agent_uuid: str, + skill_uuid: str, + *, + definition: SkillDefinition, + expected_version: int, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[AgentSkillVersion]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + definition : SkillDefinition + + expected_version : int + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AgentSkillVersion] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills/{encode_path_param(skill_uuid)}/versions", + method="POST", + json={ + "definition": convert_and_respect_annotation_metadata( + object_=definition, annotation=SkillDefinition, direction="write" + ), + "expected_version": expected_version, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentSkillVersion, + parse_obj_as( + type_=AgentSkillVersion, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) diff --git a/src/zep_cloud/agent/skill/relation/__init__.py b/src/zep_cloud/agent/skill/relation/__init__.py new file mode 100644 index 00000000..44734737 --- /dev/null +++ b/src/zep_cloud/agent/skill/relation/__init__.py @@ -0,0 +1,34 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .types import RelationListRequestKindItem +_dynamic_imports: typing.Dict[str, str] = {"RelationListRequestKindItem": ".types"} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = ["RelationListRequestKindItem"] diff --git a/src/zep_cloud/agent/skill/relation/client.py b/src/zep_cloud/agent/skill/relation/client.py new file mode 100644 index 00000000..30d0bb4b --- /dev/null +++ b/src/zep_cloud/agent/skill/relation/client.py @@ -0,0 +1,170 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ....core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ....core.pagination import AsyncPager, SyncPager +from ....core.request_options import RequestOptions +from ....types.agent_skill_relationship import AgentSkillRelationship +from ....types.pagev4agent_skill_relationship import Pagev4AgentSkillRelationship +from .raw_client import AsyncRawRelationClient, RawRelationClient +from .types.relation_list_request_kind_item import RelationListRequestKindItem + + +class RelationClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawRelationClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawRelationClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawRelationClient + """ + return self._raw_client + + def list( + self, + agent_uuid: str, + skill_uuid: str, + *, + kind: typing.Optional[ + typing.Union[RelationListRequestKindItem, typing.Sequence[RelationListRequestKindItem]] + ] = None, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[AgentSkillRelationship, Pagev4AgentSkillRelationship]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + kind : typing.Optional[typing.Union[RelationListRequestKindItem, typing.Sequence[RelationListRequestKindItem]]] + Relationship kinds + + limit : typing.Optional[int] + Page size (maximum 100) + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[AgentSkillRelationship, Pagev4AgentSkillRelationship] + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + response = client.agent.skill.relation.list( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + ) + for item in response: + yield item + # alternatively, you can paginate page-by-page + for page in response.iter_pages(): + yield page + """ + return self._raw_client.list( + agent_uuid, skill_uuid, kind=kind, limit=limit, cursor=cursor, request_options=request_options + ) + + +class AsyncRelationClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawRelationClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawRelationClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawRelationClient + """ + return self._raw_client + + async def list( + self, + agent_uuid: str, + skill_uuid: str, + *, + kind: typing.Optional[ + typing.Union[RelationListRequestKindItem, typing.Sequence[RelationListRequestKindItem]] + ] = None, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[AgentSkillRelationship, Pagev4AgentSkillRelationship]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + kind : typing.Optional[typing.Union[RelationListRequestKindItem, typing.Sequence[RelationListRequestKindItem]]] + Relationship kinds + + limit : typing.Optional[int] + Page size (maximum 100) + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[AgentSkillRelationship, Pagev4AgentSkillRelationship] + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + response = await client.agent.skill.relation.list( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + ) + async for item in response: + yield item + + # alternatively, you can paginate page-by-page + async for page in response.iter_pages(): + yield page + + + asyncio.run(main()) + """ + return await self._raw_client.list( + agent_uuid, skill_uuid, kind=kind, limit=limit, cursor=cursor, request_options=request_options + ) diff --git a/src/zep_cloud/agent/skill/relation/raw_client.py b/src/zep_cloud/agent/skill/relation/raw_client.py new file mode 100644 index 00000000..ce3a0915 --- /dev/null +++ b/src/zep_cloud/agent/skill/relation/raw_client.py @@ -0,0 +1,309 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ....core.api_error import ApiError as core_api_error_ApiError +from ....core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ....core.jsonable_encoder import encode_path_param +from ....core.pagination import AsyncPager, SyncPager +from ....core.parse_error import ParsingError +from ....core.pydantic_utilities import parse_obj_as +from ....core.request_options import RequestOptions +from ....errors.bad_request_error import BadRequestError +from ....errors.forbidden_error import ForbiddenError +from ....errors.not_found_error import NotFoundError +from ....errors.service_unavailable_error import ServiceUnavailableError +from ....errors.unauthorized_error import UnauthorizedError +from ....types.agent_skill_relationship import AgentSkillRelationship +from ....types.api_error import ApiError as types_api_error_ApiError +from ....types.pagev4agent_skill_relationship import Pagev4AgentSkillRelationship +from .types.relation_list_request_kind_item import RelationListRequestKindItem +from pydantic import ValidationError + + +class RawRelationClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def list( + self, + agent_uuid: str, + skill_uuid: str, + *, + kind: typing.Optional[ + typing.Union[RelationListRequestKindItem, typing.Sequence[RelationListRequestKindItem]] + ] = None, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[AgentSkillRelationship, Pagev4AgentSkillRelationship]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + kind : typing.Optional[typing.Union[RelationListRequestKindItem, typing.Sequence[RelationListRequestKindItem]]] + Relationship kinds + + limit : typing.Optional[int] + Page size (maximum 100) + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[AgentSkillRelationship, Pagev4AgentSkillRelationship] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills/{encode_path_param(skill_uuid)}/relations", + method="GET", + params={ + "kind": ",".join(map(str, kind)) if isinstance(kind, (list, tuple, set)) else kind, + "limit": limit, + "cursor": cursor, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + Pagev4AgentSkillRelationship, + parse_obj_as( + type_=Pagev4AgentSkillRelationship, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + _get_next = lambda: self.list( + agent_uuid, + skill_uuid, + kind=kind, + limit=limit, + cursor=_parsed_next, + request_options=request_options, + ) + return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + +class AsyncRawRelationClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def list( + self, + agent_uuid: str, + skill_uuid: str, + *, + kind: typing.Optional[ + typing.Union[RelationListRequestKindItem, typing.Sequence[RelationListRequestKindItem]] + ] = None, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[AgentSkillRelationship, Pagev4AgentSkillRelationship]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + kind : typing.Optional[typing.Union[RelationListRequestKindItem, typing.Sequence[RelationListRequestKindItem]]] + Relationship kinds + + limit : typing.Optional[int] + Page size (maximum 100) + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[AgentSkillRelationship, Pagev4AgentSkillRelationship] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills/{encode_path_param(skill_uuid)}/relations", + method="GET", + params={ + "kind": ",".join(map(str, kind)) if isinstance(kind, (list, tuple, set)) else kind, + "limit": limit, + "cursor": cursor, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + Pagev4AgentSkillRelationship, + parse_obj_as( + type_=Pagev4AgentSkillRelationship, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + + async def _get_next(): + return await self.list( + agent_uuid, + skill_uuid, + kind=kind, + limit=limit, + cursor=_parsed_next, + request_options=request_options, + ) + + return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) diff --git a/src/zep_cloud/agent/skill/relation/types/__init__.py b/src/zep_cloud/agent/skill/relation/types/__init__.py new file mode 100644 index 00000000..a3fb20cf --- /dev/null +++ b/src/zep_cloud/agent/skill/relation/types/__init__.py @@ -0,0 +1,34 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .relation_list_request_kind_item import RelationListRequestKindItem +_dynamic_imports: typing.Dict[str, str] = {"RelationListRequestKindItem": ".relation_list_request_kind_item"} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = ["RelationListRequestKindItem"] diff --git a/src/zep_cloud/agent/skill/relation/types/relation_list_request_kind_item.py b/src/zep_cloud/agent/skill/relation/types/relation_list_request_kind_item.py new file mode 100644 index 00000000..6d6d55f7 --- /dev/null +++ b/src/zep_cloud/agent/skill/relation/types/relation_list_request_kind_item.py @@ -0,0 +1,20 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +RelationListRequestKindItem = typing.Union[ + typing.Literal[ + "composes", + "requires", + "conflicts_with", + "supersedes", + "related", + "uses_tool", + "uses_environment", + "supported_by", + "contradicted_by", + "supersedes_version", + "applied_in", + ], + typing.Any, +] diff --git a/src/zep_cloud/agent/skill/types/__init__.py b/src/zep_cloud/agent/skill/types/__init__.py new file mode 100644 index 00000000..e25d6e5e --- /dev/null +++ b/src/zep_cloud/agent/skill/types/__init__.py @@ -0,0 +1,36 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .agent_skill_search_request_markdown_format import AgentSkillSearchRequestMarkdownFormat +_dynamic_imports: typing.Dict[str, str] = { + "AgentSkillSearchRequestMarkdownFormat": ".agent_skill_search_request_markdown_format" +} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = ["AgentSkillSearchRequestMarkdownFormat"] diff --git a/src/zep_cloud/agent/skill/types/agent_skill_search_request_markdown_format.py b/src/zep_cloud/agent/skill/types/agent_skill_search_request_markdown_format.py new file mode 100644 index 00000000..8b558136 --- /dev/null +++ b/src/zep_cloud/agent/skill/types/agent_skill_search_request_markdown_format.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +AgentSkillSearchRequestMarkdownFormat = typing.Union[typing.Literal["agent", "full"], typing.Any] diff --git a/src/zep_cloud/agent/skill/use/__init__.py b/src/zep_cloud/agent/skill/use/__init__.py new file mode 100644 index 00000000..26a3600b --- /dev/null +++ b/src/zep_cloud/agent/skill/use/__init__.py @@ -0,0 +1,34 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .types import CreateAgentSkillUseRequestUsage +_dynamic_imports: typing.Dict[str, str] = {"CreateAgentSkillUseRequestUsage": ".types"} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = ["CreateAgentSkillUseRequestUsage"] diff --git a/src/zep_cloud/agent/skill/use/client.py b/src/zep_cloud/agent/skill/use/client.py new file mode 100644 index 00000000..d732be75 --- /dev/null +++ b/src/zep_cloud/agent/skill/use/client.py @@ -0,0 +1,319 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ....core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ....core.request_options import RequestOptions +from ....types.add_agent_skill_use_outcome_request import AddAgentSkillUseOutcomeRequest +from ....types.add_agent_skill_use_outcome_request_outcome import AddAgentSkillUseOutcomeRequestOutcome +from ....types.agent_skill_use import AgentSkillUse +from ....types.agent_skill_use_outcome import AgentSkillUseOutcome +from .raw_client import AsyncRawUseClient, RawUseClient +from .types.create_agent_skill_use_request_usage import CreateAgentSkillUseRequestUsage + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class UseClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawUseClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawUseClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawUseClient + """ + return self._raw_client + + def create( + self, + agent_uuid: str, + skill_uuid: str, + *, + search_id: str, + trajectory_uuid: str, + usage: CreateAgentSkillUseRequestUsage, + outcome: typing.Optional[AddAgentSkillUseOutcomeRequest] = OMIT, + reason_code: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentSkillUse: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + search_id : str + + trajectory_uuid : str + + usage : CreateAgentSkillUseRequestUsage + + outcome : typing.Optional[AddAgentSkillUseOutcomeRequest] + + reason_code : typing.Optional[str] + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentSkillUse + Created + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.skill.use.create( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + search_id="search_id", + trajectory_uuid="trajectory_uuid", + usage="selected", + ) + """ + _response = self._raw_client.create( + agent_uuid, + skill_uuid, + search_id=search_id, + trajectory_uuid=trajectory_uuid, + usage=usage, + outcome=outcome, + reason_code=reason_code, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + def add_outcome( + self, + agent_uuid: str, + skill_uuid: str, + use_uuid: str, + *, + outcome: AddAgentSkillUseOutcomeRequestOutcome, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentSkillUseOutcome: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + use_uuid : str + Skill use UUID + + outcome : AddAgentSkillUseOutcomeRequestOutcome + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentSkillUseOutcome + Created + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.skill.use.add_outcome( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + use_uuid="use_uuid", + outcome="succeeded", + ) + """ + _response = self._raw_client.add_outcome( + agent_uuid, + skill_uuid, + use_uuid, + outcome=outcome, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + +class AsyncUseClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawUseClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawUseClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawUseClient + """ + return self._raw_client + + async def create( + self, + agent_uuid: str, + skill_uuid: str, + *, + search_id: str, + trajectory_uuid: str, + usage: CreateAgentSkillUseRequestUsage, + outcome: typing.Optional[AddAgentSkillUseOutcomeRequest] = OMIT, + reason_code: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentSkillUse: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + search_id : str + + trajectory_uuid : str + + usage : CreateAgentSkillUseRequestUsage + + outcome : typing.Optional[AddAgentSkillUseOutcomeRequest] + + reason_code : typing.Optional[str] + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentSkillUse + Created + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.skill.use.create( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + search_id="search_id", + trajectory_uuid="trajectory_uuid", + usage="selected", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.create( + agent_uuid, + skill_uuid, + search_id=search_id, + trajectory_uuid=trajectory_uuid, + usage=usage, + outcome=outcome, + reason_code=reason_code, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + async def add_outcome( + self, + agent_uuid: str, + skill_uuid: str, + use_uuid: str, + *, + outcome: AddAgentSkillUseOutcomeRequestOutcome, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentSkillUseOutcome: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + use_uuid : str + Skill use UUID + + outcome : AddAgentSkillUseOutcomeRequestOutcome + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentSkillUseOutcome + Created + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.skill.use.add_outcome( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + use_uuid="use_uuid", + outcome="succeeded", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.add_outcome( + agent_uuid, + skill_uuid, + use_uuid, + outcome=outcome, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data diff --git a/src/zep_cloud/agent/skill/use/raw_client.py b/src/zep_cloud/agent/skill/use/raw_client.py new file mode 100644 index 00000000..c9ffb84d --- /dev/null +++ b/src/zep_cloud/agent/skill/use/raw_client.py @@ -0,0 +1,479 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ....core.api_error import ApiError as core_api_error_ApiError +from ....core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ....core.http_response import AsyncHttpResponse, HttpResponse +from ....core.idempotency import generate_idempotency_key +from ....core.jsonable_encoder import encode_path_param +from ....core.parse_error import ParsingError +from ....core.pydantic_utilities import parse_obj_as +from ....core.request_options import RequestOptions +from ....core.serialization import convert_and_respect_annotation_metadata +from ....errors.bad_request_error import BadRequestError +from ....errors.conflict_error import ConflictError +from ....errors.forbidden_error import ForbiddenError +from ....errors.not_found_error import NotFoundError +from ....errors.unauthorized_error import UnauthorizedError +from ....types.add_agent_skill_use_outcome_request import AddAgentSkillUseOutcomeRequest +from ....types.add_agent_skill_use_outcome_request_outcome import AddAgentSkillUseOutcomeRequestOutcome +from ....types.agent_skill_use import AgentSkillUse +from ....types.agent_skill_use_outcome import AgentSkillUseOutcome +from ....types.api_error import ApiError as types_api_error_ApiError +from .types.create_agent_skill_use_request_usage import CreateAgentSkillUseRequestUsage +from pydantic import ValidationError + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class RawUseClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def create( + self, + agent_uuid: str, + skill_uuid: str, + *, + search_id: str, + trajectory_uuid: str, + usage: CreateAgentSkillUseRequestUsage, + outcome: typing.Optional[AddAgentSkillUseOutcomeRequest] = OMIT, + reason_code: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[AgentSkillUse]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + search_id : str + + trajectory_uuid : str + + usage : CreateAgentSkillUseRequestUsage + + outcome : typing.Optional[AddAgentSkillUseOutcomeRequest] + + reason_code : typing.Optional[str] + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AgentSkillUse] + Created + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills/{encode_path_param(skill_uuid)}/uses", + method="POST", + json={ + "outcome": convert_and_respect_annotation_metadata( + object_=outcome, annotation=AddAgentSkillUseOutcomeRequest, direction="write" + ), + "reason_code": reason_code, + "search_id": search_id, + "trajectory_uuid": trajectory_uuid, + "usage": usage, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentSkillUse, + parse_obj_as( + type_=AgentSkillUse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def add_outcome( + self, + agent_uuid: str, + skill_uuid: str, + use_uuid: str, + *, + outcome: AddAgentSkillUseOutcomeRequestOutcome, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[AgentSkillUseOutcome]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + use_uuid : str + Skill use UUID + + outcome : AddAgentSkillUseOutcomeRequestOutcome + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AgentSkillUseOutcome] + Created + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills/{encode_path_param(skill_uuid)}/uses/{encode_path_param(use_uuid)}/outcome", + method="POST", + json={ + "outcome": outcome, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentSkillUseOutcome, + parse_obj_as( + type_=AgentSkillUseOutcome, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + +class AsyncRawUseClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def create( + self, + agent_uuid: str, + skill_uuid: str, + *, + search_id: str, + trajectory_uuid: str, + usage: CreateAgentSkillUseRequestUsage, + outcome: typing.Optional[AddAgentSkillUseOutcomeRequest] = OMIT, + reason_code: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[AgentSkillUse]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + search_id : str + + trajectory_uuid : str + + usage : CreateAgentSkillUseRequestUsage + + outcome : typing.Optional[AddAgentSkillUseOutcomeRequest] + + reason_code : typing.Optional[str] + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AgentSkillUse] + Created + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills/{encode_path_param(skill_uuid)}/uses", + method="POST", + json={ + "outcome": convert_and_respect_annotation_metadata( + object_=outcome, annotation=AddAgentSkillUseOutcomeRequest, direction="write" + ), + "reason_code": reason_code, + "search_id": search_id, + "trajectory_uuid": trajectory_uuid, + "usage": usage, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentSkillUse, + parse_obj_as( + type_=AgentSkillUse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def add_outcome( + self, + agent_uuid: str, + skill_uuid: str, + use_uuid: str, + *, + outcome: AddAgentSkillUseOutcomeRequestOutcome, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[AgentSkillUseOutcome]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + use_uuid : str + Skill use UUID + + outcome : AddAgentSkillUseOutcomeRequestOutcome + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AgentSkillUseOutcome] + Created + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills/{encode_path_param(skill_uuid)}/uses/{encode_path_param(use_uuid)}/outcome", + method="POST", + json={ + "outcome": outcome, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentSkillUseOutcome, + parse_obj_as( + type_=AgentSkillUseOutcome, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) diff --git a/src/zep_cloud/agent/skill/use/types/__init__.py b/src/zep_cloud/agent/skill/use/types/__init__.py new file mode 100644 index 00000000..e7e7ce07 --- /dev/null +++ b/src/zep_cloud/agent/skill/use/types/__init__.py @@ -0,0 +1,34 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .create_agent_skill_use_request_usage import CreateAgentSkillUseRequestUsage +_dynamic_imports: typing.Dict[str, str] = {"CreateAgentSkillUseRequestUsage": ".create_agent_skill_use_request_usage"} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = ["CreateAgentSkillUseRequestUsage"] diff --git a/src/zep_cloud/agent/skill/use/types/create_agent_skill_use_request_usage.py b/src/zep_cloud/agent/skill/use/types/create_agent_skill_use_request_usage.py new file mode 100644 index 00000000..d67e840e --- /dev/null +++ b/src/zep_cloud/agent/skill/use/types/create_agent_skill_use_request_usage.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +CreateAgentSkillUseRequestUsage = typing.Union[ + typing.Literal["selected", "used", "partially_used", "ignored", "inapplicable"], typing.Any +] diff --git a/src/zep_cloud/agent/skill/version/__init__.py b/src/zep_cloud/agent/skill/version/__init__.py new file mode 100644 index 00000000..a192e0be --- /dev/null +++ b/src/zep_cloud/agent/skill/version/__init__.py @@ -0,0 +1,37 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .types import VersionGetRequestMarkdownFormat, VersionListRequestMarkdownFormat +_dynamic_imports: typing.Dict[str, str] = { + "VersionGetRequestMarkdownFormat": ".types", + "VersionListRequestMarkdownFormat": ".types", +} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = ["VersionGetRequestMarkdownFormat", "VersionListRequestMarkdownFormat"] diff --git a/src/zep_cloud/agent/skill/version/client.py b/src/zep_cloud/agent/skill/version/client.py new file mode 100644 index 00000000..e9712b00 --- /dev/null +++ b/src/zep_cloud/agent/skill/version/client.py @@ -0,0 +1,517 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ....core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ....core.pagination import AsyncPager, SyncPager +from ....core.request_options import RequestOptions +from ....types.agent_skill_version import AgentSkillVersion +from ....types.agent_skill_version_comparison import AgentSkillVersionComparison +from ....types.pagev4agent_skill_version import Pagev4AgentSkillVersion +from .raw_client import AsyncRawVersionClient, RawVersionClient +from .types.version_get_request_markdown_format import VersionGetRequestMarkdownFormat +from .types.version_list_request_markdown_format import VersionListRequestMarkdownFormat + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class VersionClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawVersionClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawVersionClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawVersionClient + """ + return self._raw_client + + def restore_version( + self, + agent_uuid: str, + skill_uuid: str, + *, + expected_version: int, + version: int, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentSkillVersion: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + expected_version : int + + version : int + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentSkillVersion + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.skill.version.restore_version( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + expected_version=1, + version=1, + ) + """ + _response = self._raw_client.restore_version( + agent_uuid, + skill_uuid, + expected_version=expected_version, + version=version, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + def list( + self, + agent_uuid: str, + skill_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + markdown_format: typing.Optional[VersionListRequestMarkdownFormat] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[AgentSkillVersion, Pagev4AgentSkillVersion]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + limit : typing.Optional[int] + Page size (maximum 100) + + cursor : typing.Optional[str] + Opaque page cursor + + markdown_format : typing.Optional[VersionListRequestMarkdownFormat] + Markdown form: agent (default) or full + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[AgentSkillVersion, Pagev4AgentSkillVersion] + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + response = client.agent.skill.version.list( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + ) + for item in response: + yield item + # alternatively, you can paginate page-by-page + for page in response.iter_pages(): + yield page + """ + return self._raw_client.list( + agent_uuid, + skill_uuid, + limit=limit, + cursor=cursor, + markdown_format=markdown_format, + request_options=request_options, + ) + + def compare( + self, + agent_uuid: str, + skill_uuid: str, + *, + from_version: int, + to_version: int, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentSkillVersionComparison: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + from_version : int + + to_version : int + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentSkillVersionComparison + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.skill.version.compare( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + from_version=1, + to_version=1, + ) + """ + _response = self._raw_client.compare( + agent_uuid, skill_uuid, from_version=from_version, to_version=to_version, request_options=request_options + ) + return _response.data + + def get( + self, + agent_uuid: str, + skill_uuid: str, + version: int, + *, + markdown_format: typing.Optional[VersionGetRequestMarkdownFormat] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentSkillVersion: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + version : int + Skill version + + markdown_format : typing.Optional[VersionGetRequestMarkdownFormat] + Markdown form: agent (default) or full + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentSkillVersion + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.skill.version.get( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + version=1, + ) + """ + _response = self._raw_client.get( + agent_uuid, skill_uuid, version, markdown_format=markdown_format, request_options=request_options + ) + return _response.data + + +class AsyncVersionClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawVersionClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawVersionClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawVersionClient + """ + return self._raw_client + + async def restore_version( + self, + agent_uuid: str, + skill_uuid: str, + *, + expected_version: int, + version: int, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentSkillVersion: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + expected_version : int + + version : int + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentSkillVersion + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.skill.version.restore_version( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + expected_version=1, + version=1, + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.restore_version( + agent_uuid, + skill_uuid, + expected_version=expected_version, + version=version, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + async def list( + self, + agent_uuid: str, + skill_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + markdown_format: typing.Optional[VersionListRequestMarkdownFormat] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[AgentSkillVersion, Pagev4AgentSkillVersion]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + limit : typing.Optional[int] + Page size (maximum 100) + + cursor : typing.Optional[str] + Opaque page cursor + + markdown_format : typing.Optional[VersionListRequestMarkdownFormat] + Markdown form: agent (default) or full + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[AgentSkillVersion, Pagev4AgentSkillVersion] + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + response = await client.agent.skill.version.list( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + ) + async for item in response: + yield item + + # alternatively, you can paginate page-by-page + async for page in response.iter_pages(): + yield page + + + asyncio.run(main()) + """ + return await self._raw_client.list( + agent_uuid, + skill_uuid, + limit=limit, + cursor=cursor, + markdown_format=markdown_format, + request_options=request_options, + ) + + async def compare( + self, + agent_uuid: str, + skill_uuid: str, + *, + from_version: int, + to_version: int, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentSkillVersionComparison: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + from_version : int + + to_version : int + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentSkillVersionComparison + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.skill.version.compare( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + from_version=1, + to_version=1, + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.compare( + agent_uuid, skill_uuid, from_version=from_version, to_version=to_version, request_options=request_options + ) + return _response.data + + async def get( + self, + agent_uuid: str, + skill_uuid: str, + version: int, + *, + markdown_format: typing.Optional[VersionGetRequestMarkdownFormat] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentSkillVersion: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + version : int + Skill version + + markdown_format : typing.Optional[VersionGetRequestMarkdownFormat] + Markdown form: agent (default) or full + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentSkillVersion + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.skill.version.get( + agent_uuid="agent_uuid", + skill_uuid="skill_uuid", + version=1, + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get( + agent_uuid, skill_uuid, version, markdown_format=markdown_format, request_options=request_options + ) + return _response.data diff --git a/src/zep_cloud/agent/skill/version/raw_client.py b/src/zep_cloud/agent/skill/version/raw_client.py new file mode 100644 index 00000000..415040bf --- /dev/null +++ b/src/zep_cloud/agent/skill/version/raw_client.py @@ -0,0 +1,1065 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ....core.api_error import ApiError as core_api_error_ApiError +from ....core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ....core.http_response import AsyncHttpResponse, HttpResponse +from ....core.idempotency import generate_idempotency_key +from ....core.jsonable_encoder import encode_path_param +from ....core.pagination import AsyncPager, SyncPager +from ....core.parse_error import ParsingError +from ....core.pydantic_utilities import parse_obj_as +from ....core.request_options import RequestOptions +from ....errors.bad_request_error import BadRequestError +from ....errors.conflict_error import ConflictError +from ....errors.forbidden_error import ForbiddenError +from ....errors.not_found_error import NotFoundError +from ....errors.service_unavailable_error import ServiceUnavailableError +from ....errors.unauthorized_error import UnauthorizedError +from ....types.agent_skill_version import AgentSkillVersion +from ....types.agent_skill_version_comparison import AgentSkillVersionComparison +from ....types.api_error import ApiError as types_api_error_ApiError +from ....types.pagev4agent_skill_version import Pagev4AgentSkillVersion +from .types.version_get_request_markdown_format import VersionGetRequestMarkdownFormat +from .types.version_list_request_markdown_format import VersionListRequestMarkdownFormat +from pydantic import ValidationError + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class RawVersionClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def restore_version( + self, + agent_uuid: str, + skill_uuid: str, + *, + expected_version: int, + version: int, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[AgentSkillVersion]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + expected_version : int + + version : int + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AgentSkillVersion] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills/{encode_path_param(skill_uuid)}/restore-version", + method="POST", + json={ + "expected_version": expected_version, + "version": version, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentSkillVersion, + parse_obj_as( + type_=AgentSkillVersion, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def list( + self, + agent_uuid: str, + skill_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + markdown_format: typing.Optional[VersionListRequestMarkdownFormat] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[AgentSkillVersion, Pagev4AgentSkillVersion]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + limit : typing.Optional[int] + Page size (maximum 100) + + cursor : typing.Optional[str] + Opaque page cursor + + markdown_format : typing.Optional[VersionListRequestMarkdownFormat] + Markdown form: agent (default) or full + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[AgentSkillVersion, Pagev4AgentSkillVersion] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills/{encode_path_param(skill_uuid)}/versions", + method="GET", + params={ + "limit": limit, + "cursor": cursor, + "markdown_format": markdown_format, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + Pagev4AgentSkillVersion, + parse_obj_as( + type_=Pagev4AgentSkillVersion, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + _get_next = lambda: self.list( + agent_uuid, + skill_uuid, + limit=limit, + cursor=_parsed_next, + markdown_format=markdown_format, + request_options=request_options, + ) + return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def compare( + self, + agent_uuid: str, + skill_uuid: str, + *, + from_version: int, + to_version: int, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[AgentSkillVersionComparison]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + from_version : int + + to_version : int + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AgentSkillVersionComparison] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills/{encode_path_param(skill_uuid)}/versions/compare", + method="POST", + json={ + "from_version": from_version, + "to_version": to_version, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentSkillVersionComparison, + parse_obj_as( + type_=AgentSkillVersionComparison, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def get( + self, + agent_uuid: str, + skill_uuid: str, + version: int, + *, + markdown_format: typing.Optional[VersionGetRequestMarkdownFormat] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[AgentSkillVersion]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + version : int + Skill version + + markdown_format : typing.Optional[VersionGetRequestMarkdownFormat] + Markdown form: agent (default) or full + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AgentSkillVersion] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills/{encode_path_param(skill_uuid)}/versions/{encode_path_param(version)}", + method="GET", + params={ + "markdown_format": markdown_format, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentSkillVersion, + parse_obj_as( + type_=AgentSkillVersion, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + +class AsyncRawVersionClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def restore_version( + self, + agent_uuid: str, + skill_uuid: str, + *, + expected_version: int, + version: int, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[AgentSkillVersion]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + expected_version : int + + version : int + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AgentSkillVersion] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills/{encode_path_param(skill_uuid)}/restore-version", + method="POST", + json={ + "expected_version": expected_version, + "version": version, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentSkillVersion, + parse_obj_as( + type_=AgentSkillVersion, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def list( + self, + agent_uuid: str, + skill_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + markdown_format: typing.Optional[VersionListRequestMarkdownFormat] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[AgentSkillVersion, Pagev4AgentSkillVersion]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + limit : typing.Optional[int] + Page size (maximum 100) + + cursor : typing.Optional[str] + Opaque page cursor + + markdown_format : typing.Optional[VersionListRequestMarkdownFormat] + Markdown form: agent (default) or full + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[AgentSkillVersion, Pagev4AgentSkillVersion] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills/{encode_path_param(skill_uuid)}/versions", + method="GET", + params={ + "limit": limit, + "cursor": cursor, + "markdown_format": markdown_format, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + Pagev4AgentSkillVersion, + parse_obj_as( + type_=Pagev4AgentSkillVersion, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + + async def _get_next(): + return await self.list( + agent_uuid, + skill_uuid, + limit=limit, + cursor=_parsed_next, + markdown_format=markdown_format, + request_options=request_options, + ) + + return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def compare( + self, + agent_uuid: str, + skill_uuid: str, + *, + from_version: int, + to_version: int, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[AgentSkillVersionComparison]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + from_version : int + + to_version : int + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AgentSkillVersionComparison] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills/{encode_path_param(skill_uuid)}/versions/compare", + method="POST", + json={ + "from_version": from_version, + "to_version": to_version, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentSkillVersionComparison, + parse_obj_as( + type_=AgentSkillVersionComparison, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def get( + self, + agent_uuid: str, + skill_uuid: str, + version: int, + *, + markdown_format: typing.Optional[VersionGetRequestMarkdownFormat] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[AgentSkillVersion]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + skill_uuid : str + Skill UUID + + version : int + Skill version + + markdown_format : typing.Optional[VersionGetRequestMarkdownFormat] + Markdown form: agent (default) or full + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AgentSkillVersion] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/skills/{encode_path_param(skill_uuid)}/versions/{encode_path_param(version)}", + method="GET", + params={ + "markdown_format": markdown_format, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentSkillVersion, + parse_obj_as( + type_=AgentSkillVersion, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) diff --git a/src/zep_cloud/agent/skill/version/types/__init__.py b/src/zep_cloud/agent/skill/version/types/__init__.py new file mode 100644 index 00000000..fb89167f --- /dev/null +++ b/src/zep_cloud/agent/skill/version/types/__init__.py @@ -0,0 +1,38 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .version_get_request_markdown_format import VersionGetRequestMarkdownFormat + from .version_list_request_markdown_format import VersionListRequestMarkdownFormat +_dynamic_imports: typing.Dict[str, str] = { + "VersionGetRequestMarkdownFormat": ".version_get_request_markdown_format", + "VersionListRequestMarkdownFormat": ".version_list_request_markdown_format", +} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = ["VersionGetRequestMarkdownFormat", "VersionListRequestMarkdownFormat"] diff --git a/src/zep_cloud/agent/skill/version/types/version_get_request_markdown_format.py b/src/zep_cloud/agent/skill/version/types/version_get_request_markdown_format.py new file mode 100644 index 00000000..55d11ba0 --- /dev/null +++ b/src/zep_cloud/agent/skill/version/types/version_get_request_markdown_format.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +VersionGetRequestMarkdownFormat = typing.Union[typing.Literal["agent", "full"], typing.Any] diff --git a/src/zep_cloud/agent/skill/version/types/version_list_request_markdown_format.py b/src/zep_cloud/agent/skill/version/types/version_list_request_markdown_format.py new file mode 100644 index 00000000..d08b3e8f --- /dev/null +++ b/src/zep_cloud/agent/skill/version/types/version_list_request_markdown_format.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +VersionListRequestMarkdownFormat = typing.Union[typing.Literal["agent", "full"], typing.Any] diff --git a/src/zep_cloud/agent/split/__init__.py b/src/zep_cloud/agent/split/__init__.py new file mode 100644 index 00000000..5cde0202 --- /dev/null +++ b/src/zep_cloud/agent/split/__init__.py @@ -0,0 +1,4 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + diff --git a/src/zep_cloud/agent/split/client.py b/src/zep_cloud/agent/split/client.py new file mode 100644 index 00000000..62df3667 --- /dev/null +++ b/src/zep_cloud/agent/split/client.py @@ -0,0 +1,206 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ...core.request_options import RequestOptions +from ...types.agent_split_plan import AgentSplitPlan +from ...types.agent_split_plan_destination_request import AgentSplitPlanDestinationRequest +from .raw_client import AsyncRawSplitClient, RawSplitClient + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class SplitClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawSplitClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawSplitClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawSplitClient + """ + return self._raw_client + + def plan( + self, + agent_uuid: str, + *, + destinations: typing.Sequence[AgentSplitPlanDestinationRequest], + expected_revision: int, + rationale: str, + review_acknowledged: bool, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentSplitPlan: + """ + Parameters + ---------- + agent_uuid : str + Source Agent UUID + + destinations : typing.Sequence[AgentSplitPlanDestinationRequest] + + expected_revision : int + + rationale : str + + review_acknowledged : bool + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentSplitPlan + OK + + Examples + -------- + from zep_cloud import ( + AgentSplitPlanDestinationRequest, + AgentSplitPlanSkillSelectionRequest, + CreateAgentRequest, + Zep, + ) + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.split.plan( + agent_uuid="agent_uuid", + destinations=[ + AgentSplitPlanDestinationRequest( + agent=CreateAgentRequest( + agent_id="agent_id", + name="name", + security_domain="security_domain", + ), + skills=[ + AgentSplitPlanSkillSelectionRequest( + skill_uuid="skill_uuid", + skill_version_uuid="skill_version_uuid", + version=1, + ) + ], + ) + ], + expected_revision=1, + rationale="rationale", + review_acknowledged=True, + ) + """ + _response = self._raw_client.plan( + agent_uuid, + destinations=destinations, + expected_revision=expected_revision, + rationale=rationale, + review_acknowledged=review_acknowledged, + request_options=request_options, + ) + return _response.data + + +class AsyncSplitClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawSplitClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawSplitClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawSplitClient + """ + return self._raw_client + + async def plan( + self, + agent_uuid: str, + *, + destinations: typing.Sequence[AgentSplitPlanDestinationRequest], + expected_revision: int, + rationale: str, + review_acknowledged: bool, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentSplitPlan: + """ + Parameters + ---------- + agent_uuid : str + Source Agent UUID + + destinations : typing.Sequence[AgentSplitPlanDestinationRequest] + + expected_revision : int + + rationale : str + + review_acknowledged : bool + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentSplitPlan + OK + + Examples + -------- + import asyncio + + from zep_cloud import ( + AgentSplitPlanDestinationRequest, + AgentSplitPlanSkillSelectionRequest, + AsyncZep, + CreateAgentRequest, + ) + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.split.plan( + agent_uuid="agent_uuid", + destinations=[ + AgentSplitPlanDestinationRequest( + agent=CreateAgentRequest( + agent_id="agent_id", + name="name", + security_domain="security_domain", + ), + skills=[ + AgentSplitPlanSkillSelectionRequest( + skill_uuid="skill_uuid", + skill_version_uuid="skill_version_uuid", + version=1, + ) + ], + ) + ], + expected_revision=1, + rationale="rationale", + review_acknowledged=True, + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.plan( + agent_uuid, + destinations=destinations, + expected_revision=expected_revision, + rationale=rationale, + review_acknowledged=review_acknowledged, + request_options=request_options, + ) + return _response.data diff --git a/src/zep_cloud/agent/split/raw_client.py b/src/zep_cloud/agent/split/raw_client.py new file mode 100644 index 00000000..d39d3f43 --- /dev/null +++ b/src/zep_cloud/agent/split/raw_client.py @@ -0,0 +1,296 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ...core.api_error import ApiError as core_api_error_ApiError +from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ...core.http_response import AsyncHttpResponse, HttpResponse +from ...core.idempotency import generate_idempotency_key +from ...core.jsonable_encoder import encode_path_param +from ...core.parse_error import ParsingError +from ...core.pydantic_utilities import parse_obj_as +from ...core.request_options import RequestOptions +from ...core.serialization import convert_and_respect_annotation_metadata +from ...errors.bad_request_error import BadRequestError +from ...errors.conflict_error import ConflictError +from ...errors.forbidden_error import ForbiddenError +from ...errors.not_found_error import NotFoundError +from ...errors.unauthorized_error import UnauthorizedError +from ...types.agent_split_plan import AgentSplitPlan +from ...types.agent_split_plan_destination_request import AgentSplitPlanDestinationRequest +from ...types.api_error import ApiError as types_api_error_ApiError +from pydantic import ValidationError + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class RawSplitClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def plan( + self, + agent_uuid: str, + *, + destinations: typing.Sequence[AgentSplitPlanDestinationRequest], + expected_revision: int, + rationale: str, + review_acknowledged: bool, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[AgentSplitPlan]: + """ + Parameters + ---------- + agent_uuid : str + Source Agent UUID + + destinations : typing.Sequence[AgentSplitPlanDestinationRequest] + + expected_revision : int + + rationale : str + + review_acknowledged : bool + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AgentSplitPlan] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/split-plan", + method="POST", + json={ + "destinations": convert_and_respect_annotation_metadata( + object_=destinations, + annotation=typing.Sequence[AgentSplitPlanDestinationRequest], + direction="write", + ), + "expected_revision": expected_revision, + "rationale": rationale, + "review_acknowledged": review_acknowledged, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentSplitPlan, + parse_obj_as( + type_=AgentSplitPlan, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + +class AsyncRawSplitClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def plan( + self, + agent_uuid: str, + *, + destinations: typing.Sequence[AgentSplitPlanDestinationRequest], + expected_revision: int, + rationale: str, + review_acknowledged: bool, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[AgentSplitPlan]: + """ + Parameters + ---------- + agent_uuid : str + Source Agent UUID + + destinations : typing.Sequence[AgentSplitPlanDestinationRequest] + + expected_revision : int + + rationale : str + + review_acknowledged : bool + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AgentSplitPlan] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/split-plan", + method="POST", + json={ + "destinations": convert_and_respect_annotation_metadata( + object_=destinations, + annotation=typing.Sequence[AgentSplitPlanDestinationRequest], + direction="write", + ), + "expected_revision": expected_revision, + "rationale": rationale, + "review_acknowledged": review_acknowledged, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentSplitPlan, + parse_obj_as( + type_=AgentSplitPlan, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) diff --git a/src/zep_cloud/agent/trajectory/__init__.py b/src/zep_cloud/agent/trajectory/__init__.py new file mode 100644 index 00000000..5530e783 --- /dev/null +++ b/src/zep_cloud/agent/trajectory/__init__.py @@ -0,0 +1,34 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .types import TrajectoryListRequestSourceKind +_dynamic_imports: typing.Dict[str, str] = {"TrajectoryListRequestSourceKind": ".types"} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = ["TrajectoryListRequestSourceKind"] diff --git a/src/zep_cloud/agent/trajectory/client.py b/src/zep_cloud/agent/trajectory/client.py new file mode 100644 index 00000000..fd49d2bf --- /dev/null +++ b/src/zep_cloud/agent/trajectory/client.py @@ -0,0 +1,1887 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ...core.pagination import AsyncPager, SyncPager +from ...core.request_options import RequestOptions +from ...types.agent_trajectory import AgentTrajectory +from ...types.agent_trajectory_close_verifier import AgentTrajectoryCloseVerifier +from ...types.agent_trajectory_event import AgentTrajectoryEvent +from ...types.agent_trajectory_event_context import AgentTrajectoryEventContext +from ...types.agent_trajectory_event_page import AgentTrajectoryEventPage +from ...types.agent_trajectory_event_source import AgentTrajectoryEventSource +from ...types.agent_trajectory_event_type import AgentTrajectoryEventType +from ...types.agent_trajectory_finalization_result import AgentTrajectoryFinalizationResult +from ...types.agent_trajectory_lifecycle import AgentTrajectoryLifecycle +from ...types.agent_trajectory_outcome import AgentTrajectoryOutcome +from ...types.agent_trajectory_page import AgentTrajectoryPage +from ...types.agent_trajectory_sequence_range import AgentTrajectorySequenceRange +from ...types.agent_trajectory_source_deletion_result import AgentTrajectorySourceDeletionResult +from ...types.agent_trajectory_summary_page import AgentTrajectorySummaryPage +from ...types.agent_trajectory_summary_version import AgentTrajectorySummaryVersion +from ...types.agent_trajectory_verification import AgentTrajectoryVerification +from .raw_client import AsyncRawTrajectoryClient, RawTrajectoryClient +from .types.trajectory_list_request_source_kind import TrajectoryListRequestSourceKind + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class TrajectoryClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawTrajectoryClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawTrajectoryClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawTrajectoryClient + """ + return self._raw_client + + def create( + self, + agent_uuid: str, + *, + objective: str, + task_family: str, + learn_from: typing.Optional[bool] = OMIT, + metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + parent_trajectory_uuid: typing.Optional[str] = OMIT, + trajectory_id: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentTrajectory: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + objective : str + The task-instance objective captured for this attempt. + + task_family : str + The task-family slug. + + learn_from : typing.Optional[bool] + Whether eligible evidence may participate in learning. Defaults to true. + + metadata : typing.Optional[typing.Dict[str, typing.Any]] + Developer metadata used to organize and filter Trajectories. + + parent_trajectory_uuid : typing.Optional[str] + The parent Trajectory UUID when this attempt retries an earlier attempt. + + trajectory_id : typing.Optional[str] + The optional customer-assigned identifier, unique within the Agent. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentTrajectory + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.trajectory.create( + agent_uuid="agent_uuid", + objective="objective", + task_family="task_family", + ) + """ + _response = self._raw_client.create( + agent_uuid, + objective=objective, + task_family=task_family, + learn_from=learn_from, + metadata=metadata, + parent_trajectory_uuid=parent_trajectory_uuid, + trajectory_id=trajectory_id, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + def list( + self, + agent_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + import_uuid: typing.Optional[str] = None, + source_kind: typing.Optional[TrajectoryListRequestSourceKind] = None, + metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + outcome: typing.Optional[AgentTrajectoryOutcome] = OMIT, + parent_trajectory_uuid: typing.Optional[str] = OMIT, + status: typing.Optional[AgentTrajectoryLifecycle] = OMIT, + task_family: typing.Optional[str] = OMIT, + verification: typing.Optional[AgentTrajectoryVerification] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[AgentTrajectory, AgentTrajectoryPage]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + limit : typing.Optional[int] + Page size (maximum 100) + + cursor : typing.Optional[str] + Opaque page cursor + + import_uuid : typing.Optional[str] + Filter by owning Trajectory import UUID + + source_kind : typing.Optional[TrajectoryListRequestSourceKind] + Source kind + + metadata : typing.Optional[typing.Dict[str, typing.Any]] + Filters to Trajectories whose metadata contains these key-value pairs. + + outcome : typing.Optional[AgentTrajectoryOutcome] + Filters to one reported outcome. + + parent_trajectory_uuid : typing.Optional[str] + Filters to direct retries of this parent Trajectory. + + status : typing.Optional[AgentTrajectoryLifecycle] + Filters to one lifecycle state. + + task_family : typing.Optional[str] + Filters to an exact task-family slug. + + verification : typing.Optional[AgentTrajectoryVerification] + Filters to one verification strength. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[AgentTrajectory, AgentTrajectoryPage] + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + response = client.agent.trajectory.list( + agent_uuid="agent_uuid", + ) + for item in response: + yield item + # alternatively, you can paginate page-by-page + for page in response.iter_pages(): + yield page + """ + return self._raw_client.list( + agent_uuid, + limit=limit, + cursor=cursor, + import_uuid=import_uuid, + source_kind=source_kind, + metadata=metadata, + outcome=outcome, + parent_trajectory_uuid=parent_trajectory_uuid, + status=status, + task_family=task_family, + verification=verification, + request_options=request_options, + ) + + def get( + self, agent_uuid: str, trajectory_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AgentTrajectory: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentTrajectory + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.trajectory.get( + agent_uuid="agent_uuid", + trajectory_uuid="trajectory_uuid", + ) + """ + _response = self._raw_client.get(agent_uuid, trajectory_uuid, request_options=request_options) + return _response.data + + def delete( + self, + agent_uuid: str, + trajectory_uuid: str, + *, + expected_revision: int, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentTrajectorySourceDeletionResult: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + expected_revision : int + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentTrajectorySourceDeletionResult + Accepted + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.trajectory.delete( + agent_uuid="agent_uuid", + trajectory_uuid="trajectory_uuid", + expected_revision=1, + ) + """ + _response = self._raw_client.delete( + agent_uuid, + trajectory_uuid, + expected_revision=expected_revision, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + def update( + self, + agent_uuid: str, + trajectory_uuid: str, + *, + expected_revision: int, + task_family: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentTrajectory: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + expected_revision : int + The current Trajectory revision used for optimistic concurrency. + + task_family : typing.Optional[str] + Replacement task-family slug. Set to null to clear it. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentTrajectory + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.trajectory.update( + agent_uuid="agent_uuid", + trajectory_uuid="trajectory_uuid", + expected_revision=1, + ) + """ + _response = self._raw_client.update( + agent_uuid, + trajectory_uuid, + expected_revision=expected_revision, + task_family=task_family, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + def abandon( + self, + agent_uuid: str, + trajectory_uuid: str, + *, + highest_accepted_sequence: int, + assertion_uuid: typing.Optional[str] = OMIT, + expected_revision: typing.Optional[int] = OMIT, + missing_sequence_ranges: typing.Optional[typing.Sequence[AgentTrajectorySequenceRange]] = OMIT, + reason: typing.Optional[str] = OMIT, + verification: typing.Optional[AgentTrajectoryVerification] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentTrajectoryFinalizationResult: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + highest_accepted_sequence : int + + assertion_uuid : typing.Optional[str] + + expected_revision : typing.Optional[int] + + missing_sequence_ranges : typing.Optional[typing.Sequence[AgentTrajectorySequenceRange]] + + reason : typing.Optional[str] + + verification : typing.Optional[AgentTrajectoryVerification] + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentTrajectoryFinalizationResult + Accepted + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.trajectory.abandon( + agent_uuid="agent_uuid", + trajectory_uuid="trajectory_uuid", + highest_accepted_sequence=1, + ) + """ + _response = self._raw_client.abandon( + agent_uuid, + trajectory_uuid, + highest_accepted_sequence=highest_accepted_sequence, + assertion_uuid=assertion_uuid, + expected_revision=expected_revision, + missing_sequence_ranges=missing_sequence_ranges, + reason=reason, + verification=verification, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + def close( + self, + agent_uuid: str, + trajectory_uuid: str, + *, + closing_sequence: typing.Optional[int] = OMIT, + expected_revision: typing.Optional[int] = OMIT, + missing_sequence_ranges: typing.Optional[typing.Sequence[AgentTrajectorySequenceRange]] = OMIT, + outcome: typing.Optional[AgentTrajectoryOutcome] = OMIT, + reason: typing.Optional[str] = OMIT, + verification: typing.Optional[AgentTrajectoryVerification] = OMIT, + verifier: typing.Optional[AgentTrajectoryCloseVerifier] = OMIT, + verifier_id: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentTrajectoryFinalizationResult: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + closing_sequence : typing.Optional[int] + + expected_revision : typing.Optional[int] + + missing_sequence_ranges : typing.Optional[typing.Sequence[AgentTrajectorySequenceRange]] + + outcome : typing.Optional[AgentTrajectoryOutcome] + + reason : typing.Optional[str] + + verification : typing.Optional[AgentTrajectoryVerification] + + verifier : typing.Optional[AgentTrajectoryCloseVerifier] + + verifier_id : typing.Optional[str] + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentTrajectoryFinalizationResult + Accepted + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.trajectory.close( + agent_uuid="agent_uuid", + trajectory_uuid="trajectory_uuid", + ) + """ + _response = self._raw_client.close( + agent_uuid, + trajectory_uuid, + closing_sequence=closing_sequence, + expected_revision=expected_revision, + missing_sequence_ranges=missing_sequence_ranges, + outcome=outcome, + reason=reason, + verification=verification, + verifier=verifier, + verifier_id=verifier_id, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + def correct_task_family( + self, + agent_uuid: str, + trajectory_uuid: str, + *, + expected_revision: int, + reason: str, + task_family: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentTrajectoryFinalizationResult: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + expected_revision : int + The current Trajectory revision used for optimistic concurrency. + + reason : str + Why the terminal Trajectory classification is being corrected. + + task_family : typing.Optional[str] + Replacement task-family slug. Set to null to clear it. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentTrajectoryFinalizationResult + Accepted + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.trajectory.correct_task_family( + agent_uuid="agent_uuid", + trajectory_uuid="trajectory_uuid", + expected_revision=1, + reason="reason", + ) + """ + _response = self._raw_client.correct_task_family( + agent_uuid, + trajectory_uuid, + expected_revision=expected_revision, + reason=reason, + task_family=task_family, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + def list_events( + self, + agent_uuid: str, + trajectory_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[AgentTrajectoryEvent, AgentTrajectoryEventPage]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + limit : typing.Optional[int] + Page size (maximum 100) + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[AgentTrajectoryEvent, AgentTrajectoryEventPage] + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + response = client.agent.trajectory.list_events( + agent_uuid="agent_uuid", + trajectory_uuid="trajectory_uuid", + ) + for item in response: + yield item + # alternatively, you can paginate page-by-page + for page in response.iter_pages(): + yield page + """ + return self._raw_client.list_events( + agent_uuid, trajectory_uuid, limit=limit, cursor=cursor, request_options=request_options + ) + + def append_event( + self, + agent_uuid: str, + trajectory_uuid: str, + *, + event_type: AgentTrajectoryEventType, + content: typing.Optional[str] = OMIT, + context: typing.Optional[AgentTrajectoryEventContext] = OMIT, + event_id: typing.Optional[str] = OMIT, + metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + occurred_at: typing.Optional[str] = OMIT, + sequence: typing.Optional[int] = OMIT, + sources: typing.Optional[typing.Sequence[AgentTrajectoryEventSource]] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentTrajectoryEvent: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + event_type : AgentTrajectoryEventType + + content : typing.Optional[str] + + context : typing.Optional[AgentTrajectoryEventContext] + + event_id : typing.Optional[str] + + metadata : typing.Optional[typing.Dict[str, typing.Any]] + + occurred_at : typing.Optional[str] + + sequence : typing.Optional[int] + + sources : typing.Optional[typing.Sequence[AgentTrajectoryEventSource]] + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentTrajectoryEvent + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.trajectory.append_event( + agent_uuid="agent_uuid", + trajectory_uuid="trajectory_uuid", + event_type="input_reference", + ) + """ + _response = self._raw_client.append_event( + agent_uuid, + trajectory_uuid, + event_type=event_type, + content=content, + context=context, + event_id=event_id, + metadata=metadata, + occurred_at=occurred_at, + sequence=sequence, + sources=sources, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + def delete_event( + self, + agent_uuid: str, + trajectory_uuid: str, + event_uuid: str, + *, + expected_revision: int, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentTrajectorySourceDeletionResult: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + event_uuid : str + Event UUID + + expected_revision : int + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentTrajectorySourceDeletionResult + Accepted + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.trajectory.delete_event( + agent_uuid="agent_uuid", + trajectory_uuid="trajectory_uuid", + event_uuid="event_uuid", + expected_revision=1, + ) + """ + _response = self._raw_client.delete_event( + agent_uuid, + trajectory_uuid, + event_uuid, + expected_revision=expected_revision, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + def reopen( + self, + agent_uuid: str, + trajectory_uuid: str, + *, + expected_revision: int, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentTrajectory: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + expected_revision : int + The current Trajectory revision used for optimistic concurrency. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentTrajectory + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.trajectory.reopen( + agent_uuid="agent_uuid", + trajectory_uuid="trajectory_uuid", + expected_revision=1, + ) + """ + _response = self._raw_client.reopen( + agent_uuid, + trajectory_uuid, + expected_revision=expected_revision, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + def get_summary( + self, agent_uuid: str, trajectory_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AgentTrajectorySummaryVersion: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentTrajectorySummaryVersion + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.trajectory.get_summary( + agent_uuid="agent_uuid", + trajectory_uuid="trajectory_uuid", + ) + """ + _response = self._raw_client.get_summary(agent_uuid, trajectory_uuid, request_options=request_options) + return _response.data + + def list_summary_versions( + self, + agent_uuid: str, + trajectory_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[AgentTrajectorySummaryVersion, AgentTrajectorySummaryPage]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + limit : typing.Optional[int] + Page size (maximum 100) + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[AgentTrajectorySummaryVersion, AgentTrajectorySummaryPage] + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + response = client.agent.trajectory.list_summary_versions( + agent_uuid="agent_uuid", + trajectory_uuid="trajectory_uuid", + ) + for item in response: + yield item + # alternatively, you can paginate page-by-page + for page in response.iter_pages(): + yield page + """ + return self._raw_client.list_summary_versions( + agent_uuid, trajectory_uuid, limit=limit, cursor=cursor, request_options=request_options + ) + + +class AsyncTrajectoryClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawTrajectoryClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawTrajectoryClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawTrajectoryClient + """ + return self._raw_client + + async def create( + self, + agent_uuid: str, + *, + objective: str, + task_family: str, + learn_from: typing.Optional[bool] = OMIT, + metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + parent_trajectory_uuid: typing.Optional[str] = OMIT, + trajectory_id: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentTrajectory: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + objective : str + The task-instance objective captured for this attempt. + + task_family : str + The task-family slug. + + learn_from : typing.Optional[bool] + Whether eligible evidence may participate in learning. Defaults to true. + + metadata : typing.Optional[typing.Dict[str, typing.Any]] + Developer metadata used to organize and filter Trajectories. + + parent_trajectory_uuid : typing.Optional[str] + The parent Trajectory UUID when this attempt retries an earlier attempt. + + trajectory_id : typing.Optional[str] + The optional customer-assigned identifier, unique within the Agent. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentTrajectory + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.trajectory.create( + agent_uuid="agent_uuid", + objective="objective", + task_family="task_family", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.create( + agent_uuid, + objective=objective, + task_family=task_family, + learn_from=learn_from, + metadata=metadata, + parent_trajectory_uuid=parent_trajectory_uuid, + trajectory_id=trajectory_id, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + async def list( + self, + agent_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + import_uuid: typing.Optional[str] = None, + source_kind: typing.Optional[TrajectoryListRequestSourceKind] = None, + metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + outcome: typing.Optional[AgentTrajectoryOutcome] = OMIT, + parent_trajectory_uuid: typing.Optional[str] = OMIT, + status: typing.Optional[AgentTrajectoryLifecycle] = OMIT, + task_family: typing.Optional[str] = OMIT, + verification: typing.Optional[AgentTrajectoryVerification] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[AgentTrajectory, AgentTrajectoryPage]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + limit : typing.Optional[int] + Page size (maximum 100) + + cursor : typing.Optional[str] + Opaque page cursor + + import_uuid : typing.Optional[str] + Filter by owning Trajectory import UUID + + source_kind : typing.Optional[TrajectoryListRequestSourceKind] + Source kind + + metadata : typing.Optional[typing.Dict[str, typing.Any]] + Filters to Trajectories whose metadata contains these key-value pairs. + + outcome : typing.Optional[AgentTrajectoryOutcome] + Filters to one reported outcome. + + parent_trajectory_uuid : typing.Optional[str] + Filters to direct retries of this parent Trajectory. + + status : typing.Optional[AgentTrajectoryLifecycle] + Filters to one lifecycle state. + + task_family : typing.Optional[str] + Filters to an exact task-family slug. + + verification : typing.Optional[AgentTrajectoryVerification] + Filters to one verification strength. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[AgentTrajectory, AgentTrajectoryPage] + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + response = await client.agent.trajectory.list( + agent_uuid="agent_uuid", + ) + async for item in response: + yield item + + # alternatively, you can paginate page-by-page + async for page in response.iter_pages(): + yield page + + + asyncio.run(main()) + """ + return await self._raw_client.list( + agent_uuid, + limit=limit, + cursor=cursor, + import_uuid=import_uuid, + source_kind=source_kind, + metadata=metadata, + outcome=outcome, + parent_trajectory_uuid=parent_trajectory_uuid, + status=status, + task_family=task_family, + verification=verification, + request_options=request_options, + ) + + async def get( + self, agent_uuid: str, trajectory_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AgentTrajectory: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentTrajectory + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.trajectory.get( + agent_uuid="agent_uuid", + trajectory_uuid="trajectory_uuid", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get(agent_uuid, trajectory_uuid, request_options=request_options) + return _response.data + + async def delete( + self, + agent_uuid: str, + trajectory_uuid: str, + *, + expected_revision: int, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentTrajectorySourceDeletionResult: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + expected_revision : int + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentTrajectorySourceDeletionResult + Accepted + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.trajectory.delete( + agent_uuid="agent_uuid", + trajectory_uuid="trajectory_uuid", + expected_revision=1, + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.delete( + agent_uuid, + trajectory_uuid, + expected_revision=expected_revision, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + async def update( + self, + agent_uuid: str, + trajectory_uuid: str, + *, + expected_revision: int, + task_family: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentTrajectory: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + expected_revision : int + The current Trajectory revision used for optimistic concurrency. + + task_family : typing.Optional[str] + Replacement task-family slug. Set to null to clear it. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentTrajectory + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.trajectory.update( + agent_uuid="agent_uuid", + trajectory_uuid="trajectory_uuid", + expected_revision=1, + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.update( + agent_uuid, + trajectory_uuid, + expected_revision=expected_revision, + task_family=task_family, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + async def abandon( + self, + agent_uuid: str, + trajectory_uuid: str, + *, + highest_accepted_sequence: int, + assertion_uuid: typing.Optional[str] = OMIT, + expected_revision: typing.Optional[int] = OMIT, + missing_sequence_ranges: typing.Optional[typing.Sequence[AgentTrajectorySequenceRange]] = OMIT, + reason: typing.Optional[str] = OMIT, + verification: typing.Optional[AgentTrajectoryVerification] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentTrajectoryFinalizationResult: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + highest_accepted_sequence : int + + assertion_uuid : typing.Optional[str] + + expected_revision : typing.Optional[int] + + missing_sequence_ranges : typing.Optional[typing.Sequence[AgentTrajectorySequenceRange]] + + reason : typing.Optional[str] + + verification : typing.Optional[AgentTrajectoryVerification] + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentTrajectoryFinalizationResult + Accepted + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.trajectory.abandon( + agent_uuid="agent_uuid", + trajectory_uuid="trajectory_uuid", + highest_accepted_sequence=1, + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.abandon( + agent_uuid, + trajectory_uuid, + highest_accepted_sequence=highest_accepted_sequence, + assertion_uuid=assertion_uuid, + expected_revision=expected_revision, + missing_sequence_ranges=missing_sequence_ranges, + reason=reason, + verification=verification, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + async def close( + self, + agent_uuid: str, + trajectory_uuid: str, + *, + closing_sequence: typing.Optional[int] = OMIT, + expected_revision: typing.Optional[int] = OMIT, + missing_sequence_ranges: typing.Optional[typing.Sequence[AgentTrajectorySequenceRange]] = OMIT, + outcome: typing.Optional[AgentTrajectoryOutcome] = OMIT, + reason: typing.Optional[str] = OMIT, + verification: typing.Optional[AgentTrajectoryVerification] = OMIT, + verifier: typing.Optional[AgentTrajectoryCloseVerifier] = OMIT, + verifier_id: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentTrajectoryFinalizationResult: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + closing_sequence : typing.Optional[int] + + expected_revision : typing.Optional[int] + + missing_sequence_ranges : typing.Optional[typing.Sequence[AgentTrajectorySequenceRange]] + + outcome : typing.Optional[AgentTrajectoryOutcome] + + reason : typing.Optional[str] + + verification : typing.Optional[AgentTrajectoryVerification] + + verifier : typing.Optional[AgentTrajectoryCloseVerifier] + + verifier_id : typing.Optional[str] + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentTrajectoryFinalizationResult + Accepted + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.trajectory.close( + agent_uuid="agent_uuid", + trajectory_uuid="trajectory_uuid", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.close( + agent_uuid, + trajectory_uuid, + closing_sequence=closing_sequence, + expected_revision=expected_revision, + missing_sequence_ranges=missing_sequence_ranges, + outcome=outcome, + reason=reason, + verification=verification, + verifier=verifier, + verifier_id=verifier_id, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + async def correct_task_family( + self, + agent_uuid: str, + trajectory_uuid: str, + *, + expected_revision: int, + reason: str, + task_family: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentTrajectoryFinalizationResult: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + expected_revision : int + The current Trajectory revision used for optimistic concurrency. + + reason : str + Why the terminal Trajectory classification is being corrected. + + task_family : typing.Optional[str] + Replacement task-family slug. Set to null to clear it. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentTrajectoryFinalizationResult + Accepted + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.trajectory.correct_task_family( + agent_uuid="agent_uuid", + trajectory_uuid="trajectory_uuid", + expected_revision=1, + reason="reason", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.correct_task_family( + agent_uuid, + trajectory_uuid, + expected_revision=expected_revision, + reason=reason, + task_family=task_family, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + async def list_events( + self, + agent_uuid: str, + trajectory_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[AgentTrajectoryEvent, AgentTrajectoryEventPage]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + limit : typing.Optional[int] + Page size (maximum 100) + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[AgentTrajectoryEvent, AgentTrajectoryEventPage] + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + response = await client.agent.trajectory.list_events( + agent_uuid="agent_uuid", + trajectory_uuid="trajectory_uuid", + ) + async for item in response: + yield item + + # alternatively, you can paginate page-by-page + async for page in response.iter_pages(): + yield page + + + asyncio.run(main()) + """ + return await self._raw_client.list_events( + agent_uuid, trajectory_uuid, limit=limit, cursor=cursor, request_options=request_options + ) + + async def append_event( + self, + agent_uuid: str, + trajectory_uuid: str, + *, + event_type: AgentTrajectoryEventType, + content: typing.Optional[str] = OMIT, + context: typing.Optional[AgentTrajectoryEventContext] = OMIT, + event_id: typing.Optional[str] = OMIT, + metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + occurred_at: typing.Optional[str] = OMIT, + sequence: typing.Optional[int] = OMIT, + sources: typing.Optional[typing.Sequence[AgentTrajectoryEventSource]] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentTrajectoryEvent: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + event_type : AgentTrajectoryEventType + + content : typing.Optional[str] + + context : typing.Optional[AgentTrajectoryEventContext] + + event_id : typing.Optional[str] + + metadata : typing.Optional[typing.Dict[str, typing.Any]] + + occurred_at : typing.Optional[str] + + sequence : typing.Optional[int] + + sources : typing.Optional[typing.Sequence[AgentTrajectoryEventSource]] + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentTrajectoryEvent + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.trajectory.append_event( + agent_uuid="agent_uuid", + trajectory_uuid="trajectory_uuid", + event_type="input_reference", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.append_event( + agent_uuid, + trajectory_uuid, + event_type=event_type, + content=content, + context=context, + event_id=event_id, + metadata=metadata, + occurred_at=occurred_at, + sequence=sequence, + sources=sources, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + async def delete_event( + self, + agent_uuid: str, + trajectory_uuid: str, + event_uuid: str, + *, + expected_revision: int, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentTrajectorySourceDeletionResult: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + event_uuid : str + Event UUID + + expected_revision : int + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentTrajectorySourceDeletionResult + Accepted + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.trajectory.delete_event( + agent_uuid="agent_uuid", + trajectory_uuid="trajectory_uuid", + event_uuid="event_uuid", + expected_revision=1, + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.delete_event( + agent_uuid, + trajectory_uuid, + event_uuid, + expected_revision=expected_revision, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + async def reopen( + self, + agent_uuid: str, + trajectory_uuid: str, + *, + expected_revision: int, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentTrajectory: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + expected_revision : int + The current Trajectory revision used for optimistic concurrency. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentTrajectory + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.trajectory.reopen( + agent_uuid="agent_uuid", + trajectory_uuid="trajectory_uuid", + expected_revision=1, + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.reopen( + agent_uuid, + trajectory_uuid, + expected_revision=expected_revision, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + async def get_summary( + self, agent_uuid: str, trajectory_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AgentTrajectorySummaryVersion: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentTrajectorySummaryVersion + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.trajectory.get_summary( + agent_uuid="agent_uuid", + trajectory_uuid="trajectory_uuid", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get_summary(agent_uuid, trajectory_uuid, request_options=request_options) + return _response.data + + async def list_summary_versions( + self, + agent_uuid: str, + trajectory_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[AgentTrajectorySummaryVersion, AgentTrajectorySummaryPage]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + limit : typing.Optional[int] + Page size (maximum 100) + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[AgentTrajectorySummaryVersion, AgentTrajectorySummaryPage] + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + response = await client.agent.trajectory.list_summary_versions( + agent_uuid="agent_uuid", + trajectory_uuid="trajectory_uuid", + ) + async for item in response: + yield item + + # alternatively, you can paginate page-by-page + async for page in response.iter_pages(): + yield page + + + asyncio.run(main()) + """ + return await self._raw_client.list_summary_versions( + agent_uuid, trajectory_uuid, limit=limit, cursor=cursor, request_options=request_options + ) diff --git a/src/zep_cloud/agent/trajectory/raw_client.py b/src/zep_cloud/agent/trajectory/raw_client.py new file mode 100644 index 00000000..d1e19ad1 --- /dev/null +++ b/src/zep_cloud/agent/trajectory/raw_client.py @@ -0,0 +1,3002 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ...core.api_error import ApiError as core_api_error_ApiError +from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ...core.http_response import AsyncHttpResponse, HttpResponse +from ...core.idempotency import generate_idempotency_key +from ...core.jsonable_encoder import encode_path_param +from ...core.pagination import AsyncPager, SyncPager +from ...core.parse_error import ParsingError +from ...core.pydantic_utilities import parse_obj_as +from ...core.request_options import RequestOptions +from ...core.serialization import convert_and_respect_annotation_metadata +from ...errors.bad_request_error import BadRequestError +from ...errors.conflict_error import ConflictError +from ...errors.forbidden_error import ForbiddenError +from ...errors.not_found_error import NotFoundError +from ...errors.service_unavailable_error import ServiceUnavailableError +from ...errors.unauthorized_error import UnauthorizedError +from ...types.agent_trajectory import AgentTrajectory +from ...types.agent_trajectory_close_verifier import AgentTrajectoryCloseVerifier +from ...types.agent_trajectory_event import AgentTrajectoryEvent +from ...types.agent_trajectory_event_context import AgentTrajectoryEventContext +from ...types.agent_trajectory_event_page import AgentTrajectoryEventPage +from ...types.agent_trajectory_event_source import AgentTrajectoryEventSource +from ...types.agent_trajectory_event_type import AgentTrajectoryEventType +from ...types.agent_trajectory_finalization_result import AgentTrajectoryFinalizationResult +from ...types.agent_trajectory_lifecycle import AgentTrajectoryLifecycle +from ...types.agent_trajectory_outcome import AgentTrajectoryOutcome +from ...types.agent_trajectory_page import AgentTrajectoryPage +from ...types.agent_trajectory_sequence_range import AgentTrajectorySequenceRange +from ...types.agent_trajectory_source_deletion_result import AgentTrajectorySourceDeletionResult +from ...types.agent_trajectory_summary_page import AgentTrajectorySummaryPage +from ...types.agent_trajectory_summary_version import AgentTrajectorySummaryVersion +from ...types.agent_trajectory_verification import AgentTrajectoryVerification +from ...types.api_error import ApiError as types_api_error_ApiError +from .types.trajectory_list_request_source_kind import TrajectoryListRequestSourceKind +from pydantic import ValidationError + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class RawTrajectoryClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def create( + self, + agent_uuid: str, + *, + objective: str, + task_family: str, + learn_from: typing.Optional[bool] = OMIT, + metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + parent_trajectory_uuid: typing.Optional[str] = OMIT, + trajectory_id: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[AgentTrajectory]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + objective : str + The task-instance objective captured for this attempt. + + task_family : str + The task-family slug. + + learn_from : typing.Optional[bool] + Whether eligible evidence may participate in learning. Defaults to true. + + metadata : typing.Optional[typing.Dict[str, typing.Any]] + Developer metadata used to organize and filter Trajectories. + + parent_trajectory_uuid : typing.Optional[str] + The parent Trajectory UUID when this attempt retries an earlier attempt. + + trajectory_id : typing.Optional[str] + The optional customer-assigned identifier, unique within the Agent. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AgentTrajectory] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectories", + method="POST", + json={ + "learn_from": learn_from, + "metadata": metadata, + "objective": objective, + "parent_trajectory_uuid": parent_trajectory_uuid, + "task_family": task_family, + "trajectory_id": trajectory_id, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentTrajectory, + parse_obj_as( + type_=AgentTrajectory, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def list( + self, + agent_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + import_uuid: typing.Optional[str] = None, + source_kind: typing.Optional[TrajectoryListRequestSourceKind] = None, + metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + outcome: typing.Optional[AgentTrajectoryOutcome] = OMIT, + parent_trajectory_uuid: typing.Optional[str] = OMIT, + status: typing.Optional[AgentTrajectoryLifecycle] = OMIT, + task_family: typing.Optional[str] = OMIT, + verification: typing.Optional[AgentTrajectoryVerification] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[AgentTrajectory, AgentTrajectoryPage]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + limit : typing.Optional[int] + Page size (maximum 100) + + cursor : typing.Optional[str] + Opaque page cursor + + import_uuid : typing.Optional[str] + Filter by owning Trajectory import UUID + + source_kind : typing.Optional[TrajectoryListRequestSourceKind] + Source kind + + metadata : typing.Optional[typing.Dict[str, typing.Any]] + Filters to Trajectories whose metadata contains these key-value pairs. + + outcome : typing.Optional[AgentTrajectoryOutcome] + Filters to one reported outcome. + + parent_trajectory_uuid : typing.Optional[str] + Filters to direct retries of this parent Trajectory. + + status : typing.Optional[AgentTrajectoryLifecycle] + Filters to one lifecycle state. + + task_family : typing.Optional[str] + Filters to an exact task-family slug. + + verification : typing.Optional[AgentTrajectoryVerification] + Filters to one verification strength. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[AgentTrajectory, AgentTrajectoryPage] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectories/list", + method="POST", + params={ + "limit": limit, + "cursor": cursor, + "import_uuid": import_uuid, + "source_kind": source_kind, + }, + json={ + "metadata": metadata, + "outcome": outcome, + "parent_trajectory_uuid": parent_trajectory_uuid, + "status": status, + "task_family": task_family, + "verification": verification, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + AgentTrajectoryPage, + parse_obj_as( + type_=AgentTrajectoryPage, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + _get_next = lambda: self.list( + agent_uuid, + limit=limit, + cursor=_parsed_next, + import_uuid=import_uuid, + source_kind=source_kind, + metadata=metadata, + outcome=outcome, + parent_trajectory_uuid=parent_trajectory_uuid, + status=status, + task_family=task_family, + verification=verification, + request_options=request_options, + ) + return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def get( + self, agent_uuid: str, trajectory_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[AgentTrajectory]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AgentTrajectory] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectories/{encode_path_param(trajectory_uuid)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentTrajectory, + parse_obj_as( + type_=AgentTrajectory, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def delete( + self, + agent_uuid: str, + trajectory_uuid: str, + *, + expected_revision: int, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[AgentTrajectorySourceDeletionResult]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + expected_revision : int + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AgentTrajectorySourceDeletionResult] + Accepted + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectories/{encode_path_param(trajectory_uuid)}", + method="DELETE", + json={ + "expected_revision": expected_revision, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentTrajectorySourceDeletionResult, + parse_obj_as( + type_=AgentTrajectorySourceDeletionResult, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def update( + self, + agent_uuid: str, + trajectory_uuid: str, + *, + expected_revision: int, + task_family: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[AgentTrajectory]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + expected_revision : int + The current Trajectory revision used for optimistic concurrency. + + task_family : typing.Optional[str] + Replacement task-family slug. Set to null to clear it. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AgentTrajectory] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectories/{encode_path_param(trajectory_uuid)}", + method="PATCH", + json={ + "expected_revision": expected_revision, + "task_family": task_family, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentTrajectory, + parse_obj_as( + type_=AgentTrajectory, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def abandon( + self, + agent_uuid: str, + trajectory_uuid: str, + *, + highest_accepted_sequence: int, + assertion_uuid: typing.Optional[str] = OMIT, + expected_revision: typing.Optional[int] = OMIT, + missing_sequence_ranges: typing.Optional[typing.Sequence[AgentTrajectorySequenceRange]] = OMIT, + reason: typing.Optional[str] = OMIT, + verification: typing.Optional[AgentTrajectoryVerification] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[AgentTrajectoryFinalizationResult]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + highest_accepted_sequence : int + + assertion_uuid : typing.Optional[str] + + expected_revision : typing.Optional[int] + + missing_sequence_ranges : typing.Optional[typing.Sequence[AgentTrajectorySequenceRange]] + + reason : typing.Optional[str] + + verification : typing.Optional[AgentTrajectoryVerification] + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AgentTrajectoryFinalizationResult] + Accepted + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectories/{encode_path_param(trajectory_uuid)}/abandon", + method="POST", + json={ + "assertion_uuid": assertion_uuid, + "expected_revision": expected_revision, + "highest_accepted_sequence": highest_accepted_sequence, + "missing_sequence_ranges": convert_and_respect_annotation_metadata( + object_=missing_sequence_ranges, + annotation=typing.Sequence[AgentTrajectorySequenceRange], + direction="write", + ), + "reason": reason, + "verification": verification, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentTrajectoryFinalizationResult, + parse_obj_as( + type_=AgentTrajectoryFinalizationResult, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def close( + self, + agent_uuid: str, + trajectory_uuid: str, + *, + closing_sequence: typing.Optional[int] = OMIT, + expected_revision: typing.Optional[int] = OMIT, + missing_sequence_ranges: typing.Optional[typing.Sequence[AgentTrajectorySequenceRange]] = OMIT, + outcome: typing.Optional[AgentTrajectoryOutcome] = OMIT, + reason: typing.Optional[str] = OMIT, + verification: typing.Optional[AgentTrajectoryVerification] = OMIT, + verifier: typing.Optional[AgentTrajectoryCloseVerifier] = OMIT, + verifier_id: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[AgentTrajectoryFinalizationResult]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + closing_sequence : typing.Optional[int] + + expected_revision : typing.Optional[int] + + missing_sequence_ranges : typing.Optional[typing.Sequence[AgentTrajectorySequenceRange]] + + outcome : typing.Optional[AgentTrajectoryOutcome] + + reason : typing.Optional[str] + + verification : typing.Optional[AgentTrajectoryVerification] + + verifier : typing.Optional[AgentTrajectoryCloseVerifier] + + verifier_id : typing.Optional[str] + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AgentTrajectoryFinalizationResult] + Accepted + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectories/{encode_path_param(trajectory_uuid)}/close", + method="POST", + json={ + "closing_sequence": closing_sequence, + "expected_revision": expected_revision, + "missing_sequence_ranges": convert_and_respect_annotation_metadata( + object_=missing_sequence_ranges, + annotation=typing.Sequence[AgentTrajectorySequenceRange], + direction="write", + ), + "outcome": outcome, + "reason": reason, + "verification": verification, + "verifier": convert_and_respect_annotation_metadata( + object_=verifier, annotation=AgentTrajectoryCloseVerifier, direction="write" + ), + "verifier_id": verifier_id, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentTrajectoryFinalizationResult, + parse_obj_as( + type_=AgentTrajectoryFinalizationResult, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def correct_task_family( + self, + agent_uuid: str, + trajectory_uuid: str, + *, + expected_revision: int, + reason: str, + task_family: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[AgentTrajectoryFinalizationResult]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + expected_revision : int + The current Trajectory revision used for optimistic concurrency. + + reason : str + Why the terminal Trajectory classification is being corrected. + + task_family : typing.Optional[str] + Replacement task-family slug. Set to null to clear it. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AgentTrajectoryFinalizationResult] + Accepted + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectories/{encode_path_param(trajectory_uuid)}/correct-task-family", + method="POST", + json={ + "expected_revision": expected_revision, + "reason": reason, + "task_family": task_family, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentTrajectoryFinalizationResult, + parse_obj_as( + type_=AgentTrajectoryFinalizationResult, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def list_events( + self, + agent_uuid: str, + trajectory_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[AgentTrajectoryEvent, AgentTrajectoryEventPage]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + limit : typing.Optional[int] + Page size (maximum 100) + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[AgentTrajectoryEvent, AgentTrajectoryEventPage] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectories/{encode_path_param(trajectory_uuid)}/events", + method="GET", + params={ + "limit": limit, + "cursor": cursor, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + AgentTrajectoryEventPage, + parse_obj_as( + type_=AgentTrajectoryEventPage, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + _get_next = lambda: self.list_events( + agent_uuid, + trajectory_uuid, + limit=limit, + cursor=_parsed_next, + request_options=request_options, + ) + return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def append_event( + self, + agent_uuid: str, + trajectory_uuid: str, + *, + event_type: AgentTrajectoryEventType, + content: typing.Optional[str] = OMIT, + context: typing.Optional[AgentTrajectoryEventContext] = OMIT, + event_id: typing.Optional[str] = OMIT, + metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + occurred_at: typing.Optional[str] = OMIT, + sequence: typing.Optional[int] = OMIT, + sources: typing.Optional[typing.Sequence[AgentTrajectoryEventSource]] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[AgentTrajectoryEvent]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + event_type : AgentTrajectoryEventType + + content : typing.Optional[str] + + context : typing.Optional[AgentTrajectoryEventContext] + + event_id : typing.Optional[str] + + metadata : typing.Optional[typing.Dict[str, typing.Any]] + + occurred_at : typing.Optional[str] + + sequence : typing.Optional[int] + + sources : typing.Optional[typing.Sequence[AgentTrajectoryEventSource]] + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AgentTrajectoryEvent] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectories/{encode_path_param(trajectory_uuid)}/events", + method="POST", + json={ + "content": content, + "context": convert_and_respect_annotation_metadata( + object_=context, annotation=AgentTrajectoryEventContext, direction="write" + ), + "event_id": event_id, + "event_type": event_type, + "metadata": metadata, + "occurred_at": occurred_at, + "sequence": sequence, + "sources": convert_and_respect_annotation_metadata( + object_=sources, annotation=typing.Sequence[AgentTrajectoryEventSource], direction="write" + ), + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentTrajectoryEvent, + parse_obj_as( + type_=AgentTrajectoryEvent, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def delete_event( + self, + agent_uuid: str, + trajectory_uuid: str, + event_uuid: str, + *, + expected_revision: int, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[AgentTrajectorySourceDeletionResult]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + event_uuid : str + Event UUID + + expected_revision : int + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AgentTrajectorySourceDeletionResult] + Accepted + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectories/{encode_path_param(trajectory_uuid)}/events/{encode_path_param(event_uuid)}", + method="DELETE", + json={ + "expected_revision": expected_revision, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentTrajectorySourceDeletionResult, + parse_obj_as( + type_=AgentTrajectorySourceDeletionResult, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def reopen( + self, + agent_uuid: str, + trajectory_uuid: str, + *, + expected_revision: int, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[AgentTrajectory]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + expected_revision : int + The current Trajectory revision used for optimistic concurrency. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AgentTrajectory] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectories/{encode_path_param(trajectory_uuid)}/reopen", + method="POST", + json={ + "expected_revision": expected_revision, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentTrajectory, + parse_obj_as( + type_=AgentTrajectory, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def get_summary( + self, agent_uuid: str, trajectory_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[AgentTrajectorySummaryVersion]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AgentTrajectorySummaryVersion] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectories/{encode_path_param(trajectory_uuid)}/summary", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentTrajectorySummaryVersion, + parse_obj_as( + type_=AgentTrajectorySummaryVersion, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def list_summary_versions( + self, + agent_uuid: str, + trajectory_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[AgentTrajectorySummaryVersion, AgentTrajectorySummaryPage]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + limit : typing.Optional[int] + Page size (maximum 100) + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[AgentTrajectorySummaryVersion, AgentTrajectorySummaryPage] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectories/{encode_path_param(trajectory_uuid)}/summary/versions", + method="GET", + params={ + "limit": limit, + "cursor": cursor, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + AgentTrajectorySummaryPage, + parse_obj_as( + type_=AgentTrajectorySummaryPage, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + _get_next = lambda: self.list_summary_versions( + agent_uuid, + trajectory_uuid, + limit=limit, + cursor=_parsed_next, + request_options=request_options, + ) + return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + +class AsyncRawTrajectoryClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def create( + self, + agent_uuid: str, + *, + objective: str, + task_family: str, + learn_from: typing.Optional[bool] = OMIT, + metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + parent_trajectory_uuid: typing.Optional[str] = OMIT, + trajectory_id: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[AgentTrajectory]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + objective : str + The task-instance objective captured for this attempt. + + task_family : str + The task-family slug. + + learn_from : typing.Optional[bool] + Whether eligible evidence may participate in learning. Defaults to true. + + metadata : typing.Optional[typing.Dict[str, typing.Any]] + Developer metadata used to organize and filter Trajectories. + + parent_trajectory_uuid : typing.Optional[str] + The parent Trajectory UUID when this attempt retries an earlier attempt. + + trajectory_id : typing.Optional[str] + The optional customer-assigned identifier, unique within the Agent. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AgentTrajectory] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectories", + method="POST", + json={ + "learn_from": learn_from, + "metadata": metadata, + "objective": objective, + "parent_trajectory_uuid": parent_trajectory_uuid, + "task_family": task_family, + "trajectory_id": trajectory_id, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentTrajectory, + parse_obj_as( + type_=AgentTrajectory, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def list( + self, + agent_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + import_uuid: typing.Optional[str] = None, + source_kind: typing.Optional[TrajectoryListRequestSourceKind] = None, + metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + outcome: typing.Optional[AgentTrajectoryOutcome] = OMIT, + parent_trajectory_uuid: typing.Optional[str] = OMIT, + status: typing.Optional[AgentTrajectoryLifecycle] = OMIT, + task_family: typing.Optional[str] = OMIT, + verification: typing.Optional[AgentTrajectoryVerification] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[AgentTrajectory, AgentTrajectoryPage]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + limit : typing.Optional[int] + Page size (maximum 100) + + cursor : typing.Optional[str] + Opaque page cursor + + import_uuid : typing.Optional[str] + Filter by owning Trajectory import UUID + + source_kind : typing.Optional[TrajectoryListRequestSourceKind] + Source kind + + metadata : typing.Optional[typing.Dict[str, typing.Any]] + Filters to Trajectories whose metadata contains these key-value pairs. + + outcome : typing.Optional[AgentTrajectoryOutcome] + Filters to one reported outcome. + + parent_trajectory_uuid : typing.Optional[str] + Filters to direct retries of this parent Trajectory. + + status : typing.Optional[AgentTrajectoryLifecycle] + Filters to one lifecycle state. + + task_family : typing.Optional[str] + Filters to an exact task-family slug. + + verification : typing.Optional[AgentTrajectoryVerification] + Filters to one verification strength. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[AgentTrajectory, AgentTrajectoryPage] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectories/list", + method="POST", + params={ + "limit": limit, + "cursor": cursor, + "import_uuid": import_uuid, + "source_kind": source_kind, + }, + json={ + "metadata": metadata, + "outcome": outcome, + "parent_trajectory_uuid": parent_trajectory_uuid, + "status": status, + "task_family": task_family, + "verification": verification, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + AgentTrajectoryPage, + parse_obj_as( + type_=AgentTrajectoryPage, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + + async def _get_next(): + return await self.list( + agent_uuid, + limit=limit, + cursor=_parsed_next, + import_uuid=import_uuid, + source_kind=source_kind, + metadata=metadata, + outcome=outcome, + parent_trajectory_uuid=parent_trajectory_uuid, + status=status, + task_family=task_family, + verification=verification, + request_options=request_options, + ) + + return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def get( + self, agent_uuid: str, trajectory_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[AgentTrajectory]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AgentTrajectory] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectories/{encode_path_param(trajectory_uuid)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentTrajectory, + parse_obj_as( + type_=AgentTrajectory, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def delete( + self, + agent_uuid: str, + trajectory_uuid: str, + *, + expected_revision: int, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[AgentTrajectorySourceDeletionResult]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + expected_revision : int + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AgentTrajectorySourceDeletionResult] + Accepted + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectories/{encode_path_param(trajectory_uuid)}", + method="DELETE", + json={ + "expected_revision": expected_revision, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentTrajectorySourceDeletionResult, + parse_obj_as( + type_=AgentTrajectorySourceDeletionResult, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def update( + self, + agent_uuid: str, + trajectory_uuid: str, + *, + expected_revision: int, + task_family: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[AgentTrajectory]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + expected_revision : int + The current Trajectory revision used for optimistic concurrency. + + task_family : typing.Optional[str] + Replacement task-family slug. Set to null to clear it. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AgentTrajectory] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectories/{encode_path_param(trajectory_uuid)}", + method="PATCH", + json={ + "expected_revision": expected_revision, + "task_family": task_family, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentTrajectory, + parse_obj_as( + type_=AgentTrajectory, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def abandon( + self, + agent_uuid: str, + trajectory_uuid: str, + *, + highest_accepted_sequence: int, + assertion_uuid: typing.Optional[str] = OMIT, + expected_revision: typing.Optional[int] = OMIT, + missing_sequence_ranges: typing.Optional[typing.Sequence[AgentTrajectorySequenceRange]] = OMIT, + reason: typing.Optional[str] = OMIT, + verification: typing.Optional[AgentTrajectoryVerification] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[AgentTrajectoryFinalizationResult]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + highest_accepted_sequence : int + + assertion_uuid : typing.Optional[str] + + expected_revision : typing.Optional[int] + + missing_sequence_ranges : typing.Optional[typing.Sequence[AgentTrajectorySequenceRange]] + + reason : typing.Optional[str] + + verification : typing.Optional[AgentTrajectoryVerification] + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AgentTrajectoryFinalizationResult] + Accepted + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectories/{encode_path_param(trajectory_uuid)}/abandon", + method="POST", + json={ + "assertion_uuid": assertion_uuid, + "expected_revision": expected_revision, + "highest_accepted_sequence": highest_accepted_sequence, + "missing_sequence_ranges": convert_and_respect_annotation_metadata( + object_=missing_sequence_ranges, + annotation=typing.Sequence[AgentTrajectorySequenceRange], + direction="write", + ), + "reason": reason, + "verification": verification, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentTrajectoryFinalizationResult, + parse_obj_as( + type_=AgentTrajectoryFinalizationResult, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def close( + self, + agent_uuid: str, + trajectory_uuid: str, + *, + closing_sequence: typing.Optional[int] = OMIT, + expected_revision: typing.Optional[int] = OMIT, + missing_sequence_ranges: typing.Optional[typing.Sequence[AgentTrajectorySequenceRange]] = OMIT, + outcome: typing.Optional[AgentTrajectoryOutcome] = OMIT, + reason: typing.Optional[str] = OMIT, + verification: typing.Optional[AgentTrajectoryVerification] = OMIT, + verifier: typing.Optional[AgentTrajectoryCloseVerifier] = OMIT, + verifier_id: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[AgentTrajectoryFinalizationResult]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + closing_sequence : typing.Optional[int] + + expected_revision : typing.Optional[int] + + missing_sequence_ranges : typing.Optional[typing.Sequence[AgentTrajectorySequenceRange]] + + outcome : typing.Optional[AgentTrajectoryOutcome] + + reason : typing.Optional[str] + + verification : typing.Optional[AgentTrajectoryVerification] + + verifier : typing.Optional[AgentTrajectoryCloseVerifier] + + verifier_id : typing.Optional[str] + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AgentTrajectoryFinalizationResult] + Accepted + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectories/{encode_path_param(trajectory_uuid)}/close", + method="POST", + json={ + "closing_sequence": closing_sequence, + "expected_revision": expected_revision, + "missing_sequence_ranges": convert_and_respect_annotation_metadata( + object_=missing_sequence_ranges, + annotation=typing.Sequence[AgentTrajectorySequenceRange], + direction="write", + ), + "outcome": outcome, + "reason": reason, + "verification": verification, + "verifier": convert_and_respect_annotation_metadata( + object_=verifier, annotation=AgentTrajectoryCloseVerifier, direction="write" + ), + "verifier_id": verifier_id, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentTrajectoryFinalizationResult, + parse_obj_as( + type_=AgentTrajectoryFinalizationResult, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def correct_task_family( + self, + agent_uuid: str, + trajectory_uuid: str, + *, + expected_revision: int, + reason: str, + task_family: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[AgentTrajectoryFinalizationResult]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + expected_revision : int + The current Trajectory revision used for optimistic concurrency. + + reason : str + Why the terminal Trajectory classification is being corrected. + + task_family : typing.Optional[str] + Replacement task-family slug. Set to null to clear it. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AgentTrajectoryFinalizationResult] + Accepted + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectories/{encode_path_param(trajectory_uuid)}/correct-task-family", + method="POST", + json={ + "expected_revision": expected_revision, + "reason": reason, + "task_family": task_family, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentTrajectoryFinalizationResult, + parse_obj_as( + type_=AgentTrajectoryFinalizationResult, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def list_events( + self, + agent_uuid: str, + trajectory_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[AgentTrajectoryEvent, AgentTrajectoryEventPage]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + limit : typing.Optional[int] + Page size (maximum 100) + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[AgentTrajectoryEvent, AgentTrajectoryEventPage] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectories/{encode_path_param(trajectory_uuid)}/events", + method="GET", + params={ + "limit": limit, + "cursor": cursor, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + AgentTrajectoryEventPage, + parse_obj_as( + type_=AgentTrajectoryEventPage, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + + async def _get_next(): + return await self.list_events( + agent_uuid, + trajectory_uuid, + limit=limit, + cursor=_parsed_next, + request_options=request_options, + ) + + return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def append_event( + self, + agent_uuid: str, + trajectory_uuid: str, + *, + event_type: AgentTrajectoryEventType, + content: typing.Optional[str] = OMIT, + context: typing.Optional[AgentTrajectoryEventContext] = OMIT, + event_id: typing.Optional[str] = OMIT, + metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + occurred_at: typing.Optional[str] = OMIT, + sequence: typing.Optional[int] = OMIT, + sources: typing.Optional[typing.Sequence[AgentTrajectoryEventSource]] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[AgentTrajectoryEvent]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + event_type : AgentTrajectoryEventType + + content : typing.Optional[str] + + context : typing.Optional[AgentTrajectoryEventContext] + + event_id : typing.Optional[str] + + metadata : typing.Optional[typing.Dict[str, typing.Any]] + + occurred_at : typing.Optional[str] + + sequence : typing.Optional[int] + + sources : typing.Optional[typing.Sequence[AgentTrajectoryEventSource]] + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AgentTrajectoryEvent] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectories/{encode_path_param(trajectory_uuid)}/events", + method="POST", + json={ + "content": content, + "context": convert_and_respect_annotation_metadata( + object_=context, annotation=AgentTrajectoryEventContext, direction="write" + ), + "event_id": event_id, + "event_type": event_type, + "metadata": metadata, + "occurred_at": occurred_at, + "sequence": sequence, + "sources": convert_and_respect_annotation_metadata( + object_=sources, annotation=typing.Sequence[AgentTrajectoryEventSource], direction="write" + ), + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentTrajectoryEvent, + parse_obj_as( + type_=AgentTrajectoryEvent, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def delete_event( + self, + agent_uuid: str, + trajectory_uuid: str, + event_uuid: str, + *, + expected_revision: int, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[AgentTrajectorySourceDeletionResult]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + event_uuid : str + Event UUID + + expected_revision : int + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AgentTrajectorySourceDeletionResult] + Accepted + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectories/{encode_path_param(trajectory_uuid)}/events/{encode_path_param(event_uuid)}", + method="DELETE", + json={ + "expected_revision": expected_revision, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentTrajectorySourceDeletionResult, + parse_obj_as( + type_=AgentTrajectorySourceDeletionResult, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def reopen( + self, + agent_uuid: str, + trajectory_uuid: str, + *, + expected_revision: int, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[AgentTrajectory]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + expected_revision : int + The current Trajectory revision used for optimistic concurrency. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AgentTrajectory] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectories/{encode_path_param(trajectory_uuid)}/reopen", + method="POST", + json={ + "expected_revision": expected_revision, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentTrajectory, + parse_obj_as( + type_=AgentTrajectory, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def get_summary( + self, agent_uuid: str, trajectory_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[AgentTrajectorySummaryVersion]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AgentTrajectorySummaryVersion] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectories/{encode_path_param(trajectory_uuid)}/summary", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentTrajectorySummaryVersion, + parse_obj_as( + type_=AgentTrajectorySummaryVersion, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def list_summary_versions( + self, + agent_uuid: str, + trajectory_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[AgentTrajectorySummaryVersion, AgentTrajectorySummaryPage]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + trajectory_uuid : str + Trajectory UUID + + limit : typing.Optional[int] + Page size (maximum 100) + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[AgentTrajectorySummaryVersion, AgentTrajectorySummaryPage] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectories/{encode_path_param(trajectory_uuid)}/summary/versions", + method="GET", + params={ + "limit": limit, + "cursor": cursor, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + AgentTrajectorySummaryPage, + parse_obj_as( + type_=AgentTrajectorySummaryPage, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + + async def _get_next(): + return await self.list_summary_versions( + agent_uuid, + trajectory_uuid, + limit=limit, + cursor=_parsed_next, + request_options=request_options, + ) + + return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) diff --git a/src/zep_cloud/agent/trajectory/types/__init__.py b/src/zep_cloud/agent/trajectory/types/__init__.py new file mode 100644 index 00000000..2f67b591 --- /dev/null +++ b/src/zep_cloud/agent/trajectory/types/__init__.py @@ -0,0 +1,34 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .trajectory_list_request_source_kind import TrajectoryListRequestSourceKind +_dynamic_imports: typing.Dict[str, str] = {"TrajectoryListRequestSourceKind": ".trajectory_list_request_source_kind"} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = ["TrajectoryListRequestSourceKind"] diff --git a/src/zep_cloud/agent/trajectory/types/trajectory_list_request_source_kind.py b/src/zep_cloud/agent/trajectory/types/trajectory_list_request_source_kind.py new file mode 100644 index 00000000..aa44872b --- /dev/null +++ b/src/zep_cloud/agent/trajectory/types/trajectory_list_request_source_kind.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +TrajectoryListRequestSourceKind = typing.Union[typing.Literal["native", "trace_import"], typing.Any] diff --git a/src/zep_cloud/agent/trajectory_import/__init__.py b/src/zep_cloud/agent/trajectory_import/__init__.py new file mode 100644 index 00000000..f38e6f64 --- /dev/null +++ b/src/zep_cloud/agent/trajectory_import/__init__.py @@ -0,0 +1,35 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .types import TrajectoryImportDeleteRequestTrajectories + from . import run +_dynamic_imports: typing.Dict[str, str] = {"TrajectoryImportDeleteRequestTrajectories": ".types", "run": ".run"} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = ["TrajectoryImportDeleteRequestTrajectories", "run"] diff --git a/src/zep_cloud/agent/trajectory_import/client.py b/src/zep_cloud/agent/trajectory_import/client.py new file mode 100644 index 00000000..f31429f3 --- /dev/null +++ b/src/zep_cloud/agent/trajectory_import/client.py @@ -0,0 +1,947 @@ +# This file was auto-generated by Fern from our API Definition. + +from __future__ import annotations + +import typing + +from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ...core.pagination import AsyncPager, SyncPager +from ...core.request_options import RequestOptions +from ...types.task import Task +from ...types.trajectory_import import TrajectoryImport +from ...types.trajectory_import_page import TrajectoryImportPage +from ...types.trajectory_import_schedule import TrajectoryImportSchedule +from ...types.trajectory_import_selection import TrajectoryImportSelection +from ...types.trajectory_mapping import TrajectoryMapping +from .raw_client import AsyncRawTrajectoryImportClient, RawTrajectoryImportClient +from .types.trajectory_import_delete_request_trajectories import TrajectoryImportDeleteRequestTrajectories + +if typing.TYPE_CHECKING: + from .run.client import AsyncRunClient, RunClient +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class TrajectoryImportClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawTrajectoryImportClient(client_wrapper=client_wrapper) + self._client_wrapper = client_wrapper + self._run: typing.Optional[RunClient] = None + + @property + def with_raw_response(self) -> RawTrajectoryImportClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawTrajectoryImportClient + """ + return self._raw_client + + def list( + self, + agent_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[TrajectoryImport, TrajectoryImportPage]: + """ + List trajectory imports that belong to this Agent. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[TrajectoryImport, TrajectoryImportPage] + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + response = client.agent.trajectory_import.list( + agent_uuid="agent_uuid", + ) + for item in response: + yield item + # alternatively, you can paginate page-by-page + for page in response.iter_pages(): + yield page + """ + return self._raw_client.list(agent_uuid, limit=limit, cursor=cursor, request_options=request_options) + + def create( + self, + agent_uuid: str, + *, + connection_uuid: typing.Optional[str] = OMIT, + learn_from: typing.Optional[bool] = OMIT, + mapping: typing.Optional[TrajectoryMapping] = OMIT, + name: typing.Optional[str] = OMIT, + on_source_change: typing.Optional[str] = OMIT, + provider_project_id: typing.Optional[str] = OMIT, + require_review: typing.Optional[bool] = OMIT, + schedule: typing.Optional[TrajectoryImportSchedule] = OMIT, + selection: typing.Optional[TrajectoryImportSelection] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> TrajectoryImport: + """ + Create a scheduled import or queue a one-time import. Example request: `{"connection_uuid":"8c78a85e-eac2-4f57-b5f5-59a68a1e77a1","provider_project_id":"project-123","name":"Support traces","selection":{"trace_ids":["trace-123"]},"mapping":{"task_family":{"source":"fixed","value":"support"}}}`. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + connection_uuid : typing.Optional[str] + ConnectionUUID identifies the project trace connection. + + learn_from : typing.Optional[bool] + LearnFrom controls whether imported evidence can support Skills. + + mapping : typing.Optional[TrajectoryMapping] + Mapping defines how source traces become Trajectories. Example: {"task_family":{"source":"fixed","value":"support"}}. + + name : typing.Optional[str] + Name is the import display name. + + on_source_change : typing.Optional[str] + OnSourceChange defines how changed source traces are handled. + + provider_project_id : typing.Optional[str] + ProviderProjectID is the source provider project identifier. + + require_review : typing.Optional[bool] + RequireReview requires review for candidates backed by this import. + + schedule : typing.Optional[TrajectoryImportSchedule] + Schedule enables recurring imports when supplied. Example: {"interval_hours":4,"start_from":"24h","settle_minutes":5,"max_open_hours":24}. + + selection : typing.Optional[TrajectoryImportSelection] + Selection defines the traces to import. Example: {"trace_ids":["trace_123"]}. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + TrajectoryImport + Created + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.trajectory_import.create( + agent_uuid="agent_uuid", + ) + """ + _response = self._raw_client.create( + agent_uuid, + connection_uuid=connection_uuid, + learn_from=learn_from, + mapping=mapping, + name=name, + on_source_change=on_source_change, + provider_project_id=provider_project_id, + require_review=require_review, + schedule=schedule, + selection=selection, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + def get( + self, agent_uuid: str, import_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> TrajectoryImport: + """ + Read one trajectory import. The response does not include its source cursor. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + import_uuid : str + Trajectory import UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + TrajectoryImport + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.trajectory_import.get( + agent_uuid="agent_uuid", + import_uuid="import_uuid", + ) + """ + _response = self._raw_client.get(agent_uuid, import_uuid, request_options=request_options) + return _response.data + + def delete( + self, + agent_uuid: str, + import_uuid: str, + *, + trajectories: typing.Optional[TrajectoryImportDeleteRequestTrajectories] = None, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> typing.Optional[Task]: + """ + Set `trajectories=delete` to queue asynchronous Trajectory deletion. The default keeps Trajectories. Example query: `?trajectories=delete`. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + import_uuid : str + Trajectory import UUID + + trajectories : typing.Optional[TrajectoryImportDeleteRequestTrajectories] + Whether to delete imported Trajectories + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + typing.Optional[Task] + Accepted + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.trajectory_import.delete( + agent_uuid="agent_uuid", + import_uuid="import_uuid", + ) + """ + _response = self._raw_client.delete( + agent_uuid, + import_uuid, + trajectories=trajectories, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + def update( + self, + agent_uuid: str, + import_uuid: str, + *, + expected_revision: typing.Optional[int] = OMIT, + learn_from: typing.Optional[bool] = OMIT, + mapping: typing.Optional[TrajectoryMapping] = OMIT, + name: typing.Optional[str] = OMIT, + on_source_change: typing.Optional[str] = OMIT, + require_review: typing.Optional[bool] = OMIT, + schedule: typing.Optional[TrajectoryImportSchedule] = OMIT, + selection: typing.Optional[TrajectoryImportSelection] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> TrajectoryImport: + """ + Use `expected_revision` to reject a stale update. Example request: `{"expected_revision":1,"name":"Updated support traces"}`. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + import_uuid : str + Trajectory import UUID + + expected_revision : typing.Optional[int] + ExpectedRevision is the current import revision. + + learn_from : typing.Optional[bool] + LearnFrom is the new learning setting, when supplied. + + mapping : typing.Optional[TrajectoryMapping] + Mapping is the new mapping, when supplied. Example: {"task_family":{"source":"fixed","value":"support"}}. + + name : typing.Optional[str] + Name is the new import name, when supplied. + + on_source_change : typing.Optional[str] + OnSourceChange is the new change policy, when supplied. + + require_review : typing.Optional[bool] + RequireReview is the new review setting, when supplied. + + schedule : typing.Optional[TrajectoryImportSchedule] + Schedule is the new schedule, when supplied. Example: {"interval_hours":4,"start_from":"24h","settle_minutes":5,"max_open_hours":24}. + + selection : typing.Optional[TrajectoryImportSelection] + Selection is the new selection, when supplied. Example: {"trace_ids":["trace_123"]}. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + TrajectoryImport + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.trajectory_import.update( + agent_uuid="agent_uuid", + import_uuid="import_uuid", + ) + """ + _response = self._raw_client.update( + agent_uuid, + import_uuid, + expected_revision=expected_revision, + learn_from=learn_from, + mapping=mapping, + name=name, + on_source_change=on_source_change, + require_review=require_review, + schedule=schedule, + selection=selection, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + def pause( + self, + agent_uuid: str, + import_uuid: str, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> TrajectoryImport: + """ + Pause a scheduled trajectory import. One-time imports cannot be paused. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + import_uuid : str + Trajectory import UUID + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + TrajectoryImport + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.trajectory_import.pause( + agent_uuid="agent_uuid", + import_uuid="import_uuid", + ) + """ + _response = self._raw_client.pause( + agent_uuid, import_uuid, idempotency_key=idempotency_key, request_options=request_options + ) + return _response.data + + def resume( + self, + agent_uuid: str, + import_uuid: str, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> TrajectoryImport: + """ + Resume a scheduled trajectory import. Zep verifies credentials first when they caused the pause. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + import_uuid : str + Trajectory import UUID + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + TrajectoryImport + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.trajectory_import.resume( + agent_uuid="agent_uuid", + import_uuid="import_uuid", + ) + """ + _response = self._raw_client.resume( + agent_uuid, import_uuid, idempotency_key=idempotency_key, request_options=request_options + ) + return _response.data + + @property + def run(self): + if self._run is None: + from .run.client import RunClient # noqa: E402 + + self._run = RunClient(client_wrapper=self._client_wrapper) + return self._run + + +class AsyncTrajectoryImportClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawTrajectoryImportClient(client_wrapper=client_wrapper) + self._client_wrapper = client_wrapper + self._run: typing.Optional[AsyncRunClient] = None + + @property + def with_raw_response(self) -> AsyncRawTrajectoryImportClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawTrajectoryImportClient + """ + return self._raw_client + + async def list( + self, + agent_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[TrajectoryImport, TrajectoryImportPage]: + """ + List trajectory imports that belong to this Agent. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[TrajectoryImport, TrajectoryImportPage] + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + response = await client.agent.trajectory_import.list( + agent_uuid="agent_uuid", + ) + async for item in response: + yield item + + # alternatively, you can paginate page-by-page + async for page in response.iter_pages(): + yield page + + + asyncio.run(main()) + """ + return await self._raw_client.list(agent_uuid, limit=limit, cursor=cursor, request_options=request_options) + + async def create( + self, + agent_uuid: str, + *, + connection_uuid: typing.Optional[str] = OMIT, + learn_from: typing.Optional[bool] = OMIT, + mapping: typing.Optional[TrajectoryMapping] = OMIT, + name: typing.Optional[str] = OMIT, + on_source_change: typing.Optional[str] = OMIT, + provider_project_id: typing.Optional[str] = OMIT, + require_review: typing.Optional[bool] = OMIT, + schedule: typing.Optional[TrajectoryImportSchedule] = OMIT, + selection: typing.Optional[TrajectoryImportSelection] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> TrajectoryImport: + """ + Create a scheduled import or queue a one-time import. Example request: `{"connection_uuid":"8c78a85e-eac2-4f57-b5f5-59a68a1e77a1","provider_project_id":"project-123","name":"Support traces","selection":{"trace_ids":["trace-123"]},"mapping":{"task_family":{"source":"fixed","value":"support"}}}`. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + connection_uuid : typing.Optional[str] + ConnectionUUID identifies the project trace connection. + + learn_from : typing.Optional[bool] + LearnFrom controls whether imported evidence can support Skills. + + mapping : typing.Optional[TrajectoryMapping] + Mapping defines how source traces become Trajectories. Example: {"task_family":{"source":"fixed","value":"support"}}. + + name : typing.Optional[str] + Name is the import display name. + + on_source_change : typing.Optional[str] + OnSourceChange defines how changed source traces are handled. + + provider_project_id : typing.Optional[str] + ProviderProjectID is the source provider project identifier. + + require_review : typing.Optional[bool] + RequireReview requires review for candidates backed by this import. + + schedule : typing.Optional[TrajectoryImportSchedule] + Schedule enables recurring imports when supplied. Example: {"interval_hours":4,"start_from":"24h","settle_minutes":5,"max_open_hours":24}. + + selection : typing.Optional[TrajectoryImportSelection] + Selection defines the traces to import. Example: {"trace_ids":["trace_123"]}. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + TrajectoryImport + Created + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.trajectory_import.create( + agent_uuid="agent_uuid", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.create( + agent_uuid, + connection_uuid=connection_uuid, + learn_from=learn_from, + mapping=mapping, + name=name, + on_source_change=on_source_change, + provider_project_id=provider_project_id, + require_review=require_review, + schedule=schedule, + selection=selection, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + async def get( + self, agent_uuid: str, import_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> TrajectoryImport: + """ + Read one trajectory import. The response does not include its source cursor. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + import_uuid : str + Trajectory import UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + TrajectoryImport + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.trajectory_import.get( + agent_uuid="agent_uuid", + import_uuid="import_uuid", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get(agent_uuid, import_uuid, request_options=request_options) + return _response.data + + async def delete( + self, + agent_uuid: str, + import_uuid: str, + *, + trajectories: typing.Optional[TrajectoryImportDeleteRequestTrajectories] = None, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> typing.Optional[Task]: + """ + Set `trajectories=delete` to queue asynchronous Trajectory deletion. The default keeps Trajectories. Example query: `?trajectories=delete`. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + import_uuid : str + Trajectory import UUID + + trajectories : typing.Optional[TrajectoryImportDeleteRequestTrajectories] + Whether to delete imported Trajectories + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + typing.Optional[Task] + Accepted + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.trajectory_import.delete( + agent_uuid="agent_uuid", + import_uuid="import_uuid", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.delete( + agent_uuid, + import_uuid, + trajectories=trajectories, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + async def update( + self, + agent_uuid: str, + import_uuid: str, + *, + expected_revision: typing.Optional[int] = OMIT, + learn_from: typing.Optional[bool] = OMIT, + mapping: typing.Optional[TrajectoryMapping] = OMIT, + name: typing.Optional[str] = OMIT, + on_source_change: typing.Optional[str] = OMIT, + require_review: typing.Optional[bool] = OMIT, + schedule: typing.Optional[TrajectoryImportSchedule] = OMIT, + selection: typing.Optional[TrajectoryImportSelection] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> TrajectoryImport: + """ + Use `expected_revision` to reject a stale update. Example request: `{"expected_revision":1,"name":"Updated support traces"}`. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + import_uuid : str + Trajectory import UUID + + expected_revision : typing.Optional[int] + ExpectedRevision is the current import revision. + + learn_from : typing.Optional[bool] + LearnFrom is the new learning setting, when supplied. + + mapping : typing.Optional[TrajectoryMapping] + Mapping is the new mapping, when supplied. Example: {"task_family":{"source":"fixed","value":"support"}}. + + name : typing.Optional[str] + Name is the new import name, when supplied. + + on_source_change : typing.Optional[str] + OnSourceChange is the new change policy, when supplied. + + require_review : typing.Optional[bool] + RequireReview is the new review setting, when supplied. + + schedule : typing.Optional[TrajectoryImportSchedule] + Schedule is the new schedule, when supplied. Example: {"interval_hours":4,"start_from":"24h","settle_minutes":5,"max_open_hours":24}. + + selection : typing.Optional[TrajectoryImportSelection] + Selection is the new selection, when supplied. Example: {"trace_ids":["trace_123"]}. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + TrajectoryImport + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.trajectory_import.update( + agent_uuid="agent_uuid", + import_uuid="import_uuid", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.update( + agent_uuid, + import_uuid, + expected_revision=expected_revision, + learn_from=learn_from, + mapping=mapping, + name=name, + on_source_change=on_source_change, + require_review=require_review, + schedule=schedule, + selection=selection, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + async def pause( + self, + agent_uuid: str, + import_uuid: str, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> TrajectoryImport: + """ + Pause a scheduled trajectory import. One-time imports cannot be paused. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + import_uuid : str + Trajectory import UUID + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + TrajectoryImport + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.trajectory_import.pause( + agent_uuid="agent_uuid", + import_uuid="import_uuid", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.pause( + agent_uuid, import_uuid, idempotency_key=idempotency_key, request_options=request_options + ) + return _response.data + + async def resume( + self, + agent_uuid: str, + import_uuid: str, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> TrajectoryImport: + """ + Resume a scheduled trajectory import. Zep verifies credentials first when they caused the pause. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + import_uuid : str + Trajectory import UUID + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + TrajectoryImport + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.trajectory_import.resume( + agent_uuid="agent_uuid", + import_uuid="import_uuid", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.resume( + agent_uuid, import_uuid, idempotency_key=idempotency_key, request_options=request_options + ) + return _response.data + + @property + def run(self): + if self._run is None: + from .run.client import AsyncRunClient # noqa: E402 + + self._run = AsyncRunClient(client_wrapper=self._client_wrapper) + return self._run diff --git a/src/zep_cloud/agent/trajectory_import/raw_client.py b/src/zep_cloud/agent/trajectory_import/raw_client.py new file mode 100644 index 00000000..01406195 --- /dev/null +++ b/src/zep_cloud/agent/trajectory_import/raw_client.py @@ -0,0 +1,1724 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ...core.api_error import ApiError as core_api_error_ApiError +from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ...core.http_response import AsyncHttpResponse, HttpResponse +from ...core.idempotency import generate_idempotency_key +from ...core.jsonable_encoder import encode_path_param +from ...core.pagination import AsyncPager, SyncPager +from ...core.parse_error import ParsingError +from ...core.pydantic_utilities import parse_obj_as +from ...core.request_options import RequestOptions +from ...core.serialization import convert_and_respect_annotation_metadata +from ...errors.bad_request_error import BadRequestError +from ...errors.conflict_error import ConflictError +from ...errors.forbidden_error import ForbiddenError +from ...errors.not_found_error import NotFoundError +from ...errors.unauthorized_error import UnauthorizedError +from ...errors.unprocessable_entity_error import UnprocessableEntityError +from ...types.api_error import ApiError as types_api_error_ApiError +from ...types.task import Task +from ...types.trajectory_import import TrajectoryImport +from ...types.trajectory_import_page import TrajectoryImportPage +from ...types.trajectory_import_schedule import TrajectoryImportSchedule +from ...types.trajectory_import_selection import TrajectoryImportSelection +from ...types.trajectory_mapping import TrajectoryMapping +from .types.trajectory_import_delete_request_trajectories import TrajectoryImportDeleteRequestTrajectories +from pydantic import ValidationError + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class RawTrajectoryImportClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def list( + self, + agent_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[TrajectoryImport, TrajectoryImportPage]: + """ + List trajectory imports that belong to this Agent. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[TrajectoryImport, TrajectoryImportPage] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectory-imports", + method="GET", + params={ + "limit": limit, + "cursor": cursor, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + TrajectoryImportPage, + parse_obj_as( + type_=TrajectoryImportPage, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + _get_next = lambda: self.list( + agent_uuid, + limit=limit, + cursor=_parsed_next, + request_options=request_options, + ) + return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def create( + self, + agent_uuid: str, + *, + connection_uuid: typing.Optional[str] = OMIT, + learn_from: typing.Optional[bool] = OMIT, + mapping: typing.Optional[TrajectoryMapping] = OMIT, + name: typing.Optional[str] = OMIT, + on_source_change: typing.Optional[str] = OMIT, + provider_project_id: typing.Optional[str] = OMIT, + require_review: typing.Optional[bool] = OMIT, + schedule: typing.Optional[TrajectoryImportSchedule] = OMIT, + selection: typing.Optional[TrajectoryImportSelection] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[TrajectoryImport]: + """ + Create a scheduled import or queue a one-time import. Example request: `{"connection_uuid":"8c78a85e-eac2-4f57-b5f5-59a68a1e77a1","provider_project_id":"project-123","name":"Support traces","selection":{"trace_ids":["trace-123"]},"mapping":{"task_family":{"source":"fixed","value":"support"}}}`. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + connection_uuid : typing.Optional[str] + ConnectionUUID identifies the project trace connection. + + learn_from : typing.Optional[bool] + LearnFrom controls whether imported evidence can support Skills. + + mapping : typing.Optional[TrajectoryMapping] + Mapping defines how source traces become Trajectories. Example: {"task_family":{"source":"fixed","value":"support"}}. + + name : typing.Optional[str] + Name is the import display name. + + on_source_change : typing.Optional[str] + OnSourceChange defines how changed source traces are handled. + + provider_project_id : typing.Optional[str] + ProviderProjectID is the source provider project identifier. + + require_review : typing.Optional[bool] + RequireReview requires review for candidates backed by this import. + + schedule : typing.Optional[TrajectoryImportSchedule] + Schedule enables recurring imports when supplied. Example: {"interval_hours":4,"start_from":"24h","settle_minutes":5,"max_open_hours":24}. + + selection : typing.Optional[TrajectoryImportSelection] + Selection defines the traces to import. Example: {"trace_ids":["trace_123"]}. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[TrajectoryImport] + Created + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectory-imports", + method="POST", + json={ + "connection_uuid": connection_uuid, + "learn_from": learn_from, + "mapping": convert_and_respect_annotation_metadata( + object_=mapping, annotation=TrajectoryMapping, direction="write" + ), + "name": name, + "on_source_change": on_source_change, + "provider_project_id": provider_project_id, + "require_review": require_review, + "schedule": convert_and_respect_annotation_metadata( + object_=schedule, annotation=TrajectoryImportSchedule, direction="write" + ), + "selection": convert_and_respect_annotation_metadata( + object_=selection, annotation=TrajectoryImportSelection, direction="write" + ), + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + TrajectoryImport, + parse_obj_as( + type_=TrajectoryImport, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def get( + self, agent_uuid: str, import_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[TrajectoryImport]: + """ + Read one trajectory import. The response does not include its source cursor. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + import_uuid : str + Trajectory import UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[TrajectoryImport] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectory-imports/{encode_path_param(import_uuid)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + TrajectoryImport, + parse_obj_as( + type_=TrajectoryImport, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def delete( + self, + agent_uuid: str, + import_uuid: str, + *, + trajectories: typing.Optional[TrajectoryImportDeleteRequestTrajectories] = None, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[typing.Optional[Task]]: + """ + Set `trajectories=delete` to queue asynchronous Trajectory deletion. The default keeps Trajectories. Example query: `?trajectories=delete`. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + import_uuid : str + Trajectory import UUID + + trajectories : typing.Optional[TrajectoryImportDeleteRequestTrajectories] + Whether to delete imported Trajectories + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[typing.Optional[Task]] + Accepted + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectory-imports/{encode_path_param(import_uuid)}", + method="DELETE", + params={ + "trajectories": trajectories, + }, + headers={ + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + ) + try: + if _response is None or not _response.text.strip(): + return HttpResponse(response=_response, data=None) + if 200 <= _response.status_code < 300: + _data = typing.cast( + typing.Optional[Task], + parse_obj_as( + type_=typing.Optional[Task], # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def update( + self, + agent_uuid: str, + import_uuid: str, + *, + expected_revision: typing.Optional[int] = OMIT, + learn_from: typing.Optional[bool] = OMIT, + mapping: typing.Optional[TrajectoryMapping] = OMIT, + name: typing.Optional[str] = OMIT, + on_source_change: typing.Optional[str] = OMIT, + require_review: typing.Optional[bool] = OMIT, + schedule: typing.Optional[TrajectoryImportSchedule] = OMIT, + selection: typing.Optional[TrajectoryImportSelection] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[TrajectoryImport]: + """ + Use `expected_revision` to reject a stale update. Example request: `{"expected_revision":1,"name":"Updated support traces"}`. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + import_uuid : str + Trajectory import UUID + + expected_revision : typing.Optional[int] + ExpectedRevision is the current import revision. + + learn_from : typing.Optional[bool] + LearnFrom is the new learning setting, when supplied. + + mapping : typing.Optional[TrajectoryMapping] + Mapping is the new mapping, when supplied. Example: {"task_family":{"source":"fixed","value":"support"}}. + + name : typing.Optional[str] + Name is the new import name, when supplied. + + on_source_change : typing.Optional[str] + OnSourceChange is the new change policy, when supplied. + + require_review : typing.Optional[bool] + RequireReview is the new review setting, when supplied. + + schedule : typing.Optional[TrajectoryImportSchedule] + Schedule is the new schedule, when supplied. Example: {"interval_hours":4,"start_from":"24h","settle_minutes":5,"max_open_hours":24}. + + selection : typing.Optional[TrajectoryImportSelection] + Selection is the new selection, when supplied. Example: {"trace_ids":["trace_123"]}. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[TrajectoryImport] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectory-imports/{encode_path_param(import_uuid)}", + method="PATCH", + json={ + "expected_revision": expected_revision, + "learn_from": learn_from, + "mapping": convert_and_respect_annotation_metadata( + object_=mapping, annotation=TrajectoryMapping, direction="write" + ), + "name": name, + "on_source_change": on_source_change, + "require_review": require_review, + "schedule": convert_and_respect_annotation_metadata( + object_=schedule, annotation=TrajectoryImportSchedule, direction="write" + ), + "selection": convert_and_respect_annotation_metadata( + object_=selection, annotation=TrajectoryImportSelection, direction="write" + ), + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + TrajectoryImport, + parse_obj_as( + type_=TrajectoryImport, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def pause( + self, + agent_uuid: str, + import_uuid: str, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[TrajectoryImport]: + """ + Pause a scheduled trajectory import. One-time imports cannot be paused. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + import_uuid : str + Trajectory import UUID + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[TrajectoryImport] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectory-imports/{encode_path_param(import_uuid)}/pause", + method="POST", + headers={ + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + TrajectoryImport, + parse_obj_as( + type_=TrajectoryImport, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def resume( + self, + agent_uuid: str, + import_uuid: str, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[TrajectoryImport]: + """ + Resume a scheduled trajectory import. Zep verifies credentials first when they caused the pause. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + import_uuid : str + Trajectory import UUID + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[TrajectoryImport] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectory-imports/{encode_path_param(import_uuid)}/resume", + method="POST", + headers={ + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + TrajectoryImport, + parse_obj_as( + type_=TrajectoryImport, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + +class AsyncRawTrajectoryImportClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def list( + self, + agent_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[TrajectoryImport, TrajectoryImportPage]: + """ + List trajectory imports that belong to this Agent. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[TrajectoryImport, TrajectoryImportPage] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectory-imports", + method="GET", + params={ + "limit": limit, + "cursor": cursor, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + TrajectoryImportPage, + parse_obj_as( + type_=TrajectoryImportPage, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + + async def _get_next(): + return await self.list( + agent_uuid, + limit=limit, + cursor=_parsed_next, + request_options=request_options, + ) + + return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def create( + self, + agent_uuid: str, + *, + connection_uuid: typing.Optional[str] = OMIT, + learn_from: typing.Optional[bool] = OMIT, + mapping: typing.Optional[TrajectoryMapping] = OMIT, + name: typing.Optional[str] = OMIT, + on_source_change: typing.Optional[str] = OMIT, + provider_project_id: typing.Optional[str] = OMIT, + require_review: typing.Optional[bool] = OMIT, + schedule: typing.Optional[TrajectoryImportSchedule] = OMIT, + selection: typing.Optional[TrajectoryImportSelection] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[TrajectoryImport]: + """ + Create a scheduled import or queue a one-time import. Example request: `{"connection_uuid":"8c78a85e-eac2-4f57-b5f5-59a68a1e77a1","provider_project_id":"project-123","name":"Support traces","selection":{"trace_ids":["trace-123"]},"mapping":{"task_family":{"source":"fixed","value":"support"}}}`. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + connection_uuid : typing.Optional[str] + ConnectionUUID identifies the project trace connection. + + learn_from : typing.Optional[bool] + LearnFrom controls whether imported evidence can support Skills. + + mapping : typing.Optional[TrajectoryMapping] + Mapping defines how source traces become Trajectories. Example: {"task_family":{"source":"fixed","value":"support"}}. + + name : typing.Optional[str] + Name is the import display name. + + on_source_change : typing.Optional[str] + OnSourceChange defines how changed source traces are handled. + + provider_project_id : typing.Optional[str] + ProviderProjectID is the source provider project identifier. + + require_review : typing.Optional[bool] + RequireReview requires review for candidates backed by this import. + + schedule : typing.Optional[TrajectoryImportSchedule] + Schedule enables recurring imports when supplied. Example: {"interval_hours":4,"start_from":"24h","settle_minutes":5,"max_open_hours":24}. + + selection : typing.Optional[TrajectoryImportSelection] + Selection defines the traces to import. Example: {"trace_ids":["trace_123"]}. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[TrajectoryImport] + Created + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectory-imports", + method="POST", + json={ + "connection_uuid": connection_uuid, + "learn_from": learn_from, + "mapping": convert_and_respect_annotation_metadata( + object_=mapping, annotation=TrajectoryMapping, direction="write" + ), + "name": name, + "on_source_change": on_source_change, + "provider_project_id": provider_project_id, + "require_review": require_review, + "schedule": convert_and_respect_annotation_metadata( + object_=schedule, annotation=TrajectoryImportSchedule, direction="write" + ), + "selection": convert_and_respect_annotation_metadata( + object_=selection, annotation=TrajectoryImportSelection, direction="write" + ), + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + TrajectoryImport, + parse_obj_as( + type_=TrajectoryImport, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def get( + self, agent_uuid: str, import_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[TrajectoryImport]: + """ + Read one trajectory import. The response does not include its source cursor. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + import_uuid : str + Trajectory import UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[TrajectoryImport] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectory-imports/{encode_path_param(import_uuid)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + TrajectoryImport, + parse_obj_as( + type_=TrajectoryImport, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def delete( + self, + agent_uuid: str, + import_uuid: str, + *, + trajectories: typing.Optional[TrajectoryImportDeleteRequestTrajectories] = None, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[typing.Optional[Task]]: + """ + Set `trajectories=delete` to queue asynchronous Trajectory deletion. The default keeps Trajectories. Example query: `?trajectories=delete`. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + import_uuid : str + Trajectory import UUID + + trajectories : typing.Optional[TrajectoryImportDeleteRequestTrajectories] + Whether to delete imported Trajectories + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[typing.Optional[Task]] + Accepted + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectory-imports/{encode_path_param(import_uuid)}", + method="DELETE", + params={ + "trajectories": trajectories, + }, + headers={ + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + ) + try: + if _response is None or not _response.text.strip(): + return AsyncHttpResponse(response=_response, data=None) + if 200 <= _response.status_code < 300: + _data = typing.cast( + typing.Optional[Task], + parse_obj_as( + type_=typing.Optional[Task], # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def update( + self, + agent_uuid: str, + import_uuid: str, + *, + expected_revision: typing.Optional[int] = OMIT, + learn_from: typing.Optional[bool] = OMIT, + mapping: typing.Optional[TrajectoryMapping] = OMIT, + name: typing.Optional[str] = OMIT, + on_source_change: typing.Optional[str] = OMIT, + require_review: typing.Optional[bool] = OMIT, + schedule: typing.Optional[TrajectoryImportSchedule] = OMIT, + selection: typing.Optional[TrajectoryImportSelection] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[TrajectoryImport]: + """ + Use `expected_revision` to reject a stale update. Example request: `{"expected_revision":1,"name":"Updated support traces"}`. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + import_uuid : str + Trajectory import UUID + + expected_revision : typing.Optional[int] + ExpectedRevision is the current import revision. + + learn_from : typing.Optional[bool] + LearnFrom is the new learning setting, when supplied. + + mapping : typing.Optional[TrajectoryMapping] + Mapping is the new mapping, when supplied. Example: {"task_family":{"source":"fixed","value":"support"}}. + + name : typing.Optional[str] + Name is the new import name, when supplied. + + on_source_change : typing.Optional[str] + OnSourceChange is the new change policy, when supplied. + + require_review : typing.Optional[bool] + RequireReview is the new review setting, when supplied. + + schedule : typing.Optional[TrajectoryImportSchedule] + Schedule is the new schedule, when supplied. Example: {"interval_hours":4,"start_from":"24h","settle_minutes":5,"max_open_hours":24}. + + selection : typing.Optional[TrajectoryImportSelection] + Selection is the new selection, when supplied. Example: {"trace_ids":["trace_123"]}. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[TrajectoryImport] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectory-imports/{encode_path_param(import_uuid)}", + method="PATCH", + json={ + "expected_revision": expected_revision, + "learn_from": learn_from, + "mapping": convert_and_respect_annotation_metadata( + object_=mapping, annotation=TrajectoryMapping, direction="write" + ), + "name": name, + "on_source_change": on_source_change, + "require_review": require_review, + "schedule": convert_and_respect_annotation_metadata( + object_=schedule, annotation=TrajectoryImportSchedule, direction="write" + ), + "selection": convert_and_respect_annotation_metadata( + object_=selection, annotation=TrajectoryImportSelection, direction="write" + ), + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + TrajectoryImport, + parse_obj_as( + type_=TrajectoryImport, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def pause( + self, + agent_uuid: str, + import_uuid: str, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[TrajectoryImport]: + """ + Pause a scheduled trajectory import. One-time imports cannot be paused. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + import_uuid : str + Trajectory import UUID + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[TrajectoryImport] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectory-imports/{encode_path_param(import_uuid)}/pause", + method="POST", + headers={ + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + TrajectoryImport, + parse_obj_as( + type_=TrajectoryImport, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def resume( + self, + agent_uuid: str, + import_uuid: str, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[TrajectoryImport]: + """ + Resume a scheduled trajectory import. Zep verifies credentials first when they caused the pause. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + import_uuid : str + Trajectory import UUID + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[TrajectoryImport] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectory-imports/{encode_path_param(import_uuid)}/resume", + method="POST", + headers={ + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + TrajectoryImport, + parse_obj_as( + type_=TrajectoryImport, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) diff --git a/src/zep_cloud/agent/trajectory_import/run/__init__.py b/src/zep_cloud/agent/trajectory_import/run/__init__.py new file mode 100644 index 00000000..7680b252 --- /dev/null +++ b/src/zep_cloud/agent/trajectory_import/run/__init__.py @@ -0,0 +1,34 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from . import item +_dynamic_imports: typing.Dict[str, str] = {"item": ".item"} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = ["item"] diff --git a/src/zep_cloud/agent/trajectory_import/run/client.py b/src/zep_cloud/agent/trajectory_import/run/client.py new file mode 100644 index 00000000..cc7efade --- /dev/null +++ b/src/zep_cloud/agent/trajectory_import/run/client.py @@ -0,0 +1,387 @@ +# This file was auto-generated by Fern from our API Definition. + +from __future__ import annotations + +import typing + +from ....core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ....core.pagination import AsyncPager, SyncPager +from ....core.request_options import RequestOptions +from ....types.task import Task +from ....types.trajectory_import_run import TrajectoryImportRun +from ....types.trajectory_import_run_page import TrajectoryImportRunPage +from .raw_client import AsyncRawRunClient, RawRunClient + +if typing.TYPE_CHECKING: + from .item.client import AsyncItemClient, ItemClient + + +class RunClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawRunClient(client_wrapper=client_wrapper) + self._client_wrapper = client_wrapper + self._item: typing.Optional[ItemClient] = None + + @property + def with_raw_response(self) -> RawRunClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawRunClient + """ + return self._raw_client + + def list( + self, + agent_uuid: str, + import_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[TrajectoryImportRun, TrajectoryImportRunPage]: + """ + List runs that belong to this trajectory import. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + import_uuid : str + Trajectory import UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[TrajectoryImportRun, TrajectoryImportRunPage] + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + response = client.agent.trajectory_import.run.list( + agent_uuid="agent_uuid", + import_uuid="import_uuid", + ) + for item in response: + yield item + # alternatively, you can paginate page-by-page + for page in response.iter_pages(): + yield page + """ + return self._raw_client.list( + agent_uuid, import_uuid, limit=limit, cursor=cursor, request_options=request_options + ) + + def create( + self, + agent_uuid: str, + import_uuid: str, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> Task: + """ + Create a pending run and its Task. This operation does not start the run. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + import_uuid : str + Trajectory import UUID + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Task + Accepted + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.trajectory_import.run.create( + agent_uuid="agent_uuid", + import_uuid="import_uuid", + ) + """ + _response = self._raw_client.create( + agent_uuid, import_uuid, idempotency_key=idempotency_key, request_options=request_options + ) + return _response.data + + def get( + self, + agent_uuid: str, + import_uuid: str, + run_uuid: str, + *, + request_options: typing.Optional[RequestOptions] = None, + ) -> TrajectoryImportRun: + """ + Read one run that belongs to this trajectory import. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + import_uuid : str + Trajectory import UUID + + run_uuid : str + Run UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + TrajectoryImportRun + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.trajectory_import.run.get( + agent_uuid="agent_uuid", + import_uuid="import_uuid", + run_uuid="run_uuid", + ) + """ + _response = self._raw_client.get(agent_uuid, import_uuid, run_uuid, request_options=request_options) + return _response.data + + @property + def item(self): + if self._item is None: + from .item.client import ItemClient # noqa: E402 + + self._item = ItemClient(client_wrapper=self._client_wrapper) + return self._item + + +class AsyncRunClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawRunClient(client_wrapper=client_wrapper) + self._client_wrapper = client_wrapper + self._item: typing.Optional[AsyncItemClient] = None + + @property + def with_raw_response(self) -> AsyncRawRunClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawRunClient + """ + return self._raw_client + + async def list( + self, + agent_uuid: str, + import_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[TrajectoryImportRun, TrajectoryImportRunPage]: + """ + List runs that belong to this trajectory import. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + import_uuid : str + Trajectory import UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[TrajectoryImportRun, TrajectoryImportRunPage] + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + response = await client.agent.trajectory_import.run.list( + agent_uuid="agent_uuid", + import_uuid="import_uuid", + ) + async for item in response: + yield item + + # alternatively, you can paginate page-by-page + async for page in response.iter_pages(): + yield page + + + asyncio.run(main()) + """ + return await self._raw_client.list( + agent_uuid, import_uuid, limit=limit, cursor=cursor, request_options=request_options + ) + + async def create( + self, + agent_uuid: str, + import_uuid: str, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> Task: + """ + Create a pending run and its Task. This operation does not start the run. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + import_uuid : str + Trajectory import UUID + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Task + Accepted + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.trajectory_import.run.create( + agent_uuid="agent_uuid", + import_uuid="import_uuid", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.create( + agent_uuid, import_uuid, idempotency_key=idempotency_key, request_options=request_options + ) + return _response.data + + async def get( + self, + agent_uuid: str, + import_uuid: str, + run_uuid: str, + *, + request_options: typing.Optional[RequestOptions] = None, + ) -> TrajectoryImportRun: + """ + Read one run that belongs to this trajectory import. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + import_uuid : str + Trajectory import UUID + + run_uuid : str + Run UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + TrajectoryImportRun + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.trajectory_import.run.get( + agent_uuid="agent_uuid", + import_uuid="import_uuid", + run_uuid="run_uuid", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get(agent_uuid, import_uuid, run_uuid, request_options=request_options) + return _response.data + + @property + def item(self): + if self._item is None: + from .item.client import AsyncItemClient # noqa: E402 + + self._item = AsyncItemClient(client_wrapper=self._client_wrapper) + return self._item diff --git a/src/zep_cloud/agent/trajectory_import/run/item/__init__.py b/src/zep_cloud/agent/trajectory_import/run/item/__init__.py new file mode 100644 index 00000000..5cde0202 --- /dev/null +++ b/src/zep_cloud/agent/trajectory_import/run/item/__init__.py @@ -0,0 +1,4 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + diff --git a/src/zep_cloud/agent/trajectory_import/run/item/client.py b/src/zep_cloud/agent/trajectory_import/run/item/client.py new file mode 100644 index 00000000..cd799a59 --- /dev/null +++ b/src/zep_cloud/agent/trajectory_import/run/item/client.py @@ -0,0 +1,171 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from .....core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from .....core.pagination import AsyncPager, SyncPager +from .....core.request_options import RequestOptions +from .....types.trajectory_import_run_item import TrajectoryImportRunItem +from .....types.trajectory_import_run_item_page import TrajectoryImportRunItemPage +from .raw_client import AsyncRawItemClient, RawItemClient + + +class ItemClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawItemClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawItemClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawItemClient + """ + return self._raw_client + + def list( + self, + agent_uuid: str, + import_uuid: str, + run_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[TrajectoryImportRunItem, TrajectoryImportRunItemPage]: + """ + List trace results for this run. Run items do not include source payload. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + import_uuid : str + Trajectory import UUID + + run_uuid : str + Run UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[TrajectoryImportRunItem, TrajectoryImportRunItemPage] + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + response = client.agent.trajectory_import.run.item.list( + agent_uuid="agent_uuid", + import_uuid="import_uuid", + run_uuid="run_uuid", + ) + for item in response: + yield item + # alternatively, you can paginate page-by-page + for page in response.iter_pages(): + yield page + """ + return self._raw_client.list( + agent_uuid, import_uuid, run_uuid, limit=limit, cursor=cursor, request_options=request_options + ) + + +class AsyncItemClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawItemClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawItemClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawItemClient + """ + return self._raw_client + + async def list( + self, + agent_uuid: str, + import_uuid: str, + run_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[TrajectoryImportRunItem, TrajectoryImportRunItemPage]: + """ + List trace results for this run. Run items do not include source payload. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + import_uuid : str + Trajectory import UUID + + run_uuid : str + Run UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[TrajectoryImportRunItem, TrajectoryImportRunItemPage] + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + response = await client.agent.trajectory_import.run.item.list( + agent_uuid="agent_uuid", + import_uuid="import_uuid", + run_uuid="run_uuid", + ) + async for item in response: + yield item + + # alternatively, you can paginate page-by-page + async for page in response.iter_pages(): + yield page + + + asyncio.run(main()) + """ + return await self._raw_client.list( + agent_uuid, import_uuid, run_uuid, limit=limit, cursor=cursor, request_options=request_options + ) diff --git a/src/zep_cloud/agent/trajectory_import/run/item/raw_client.py b/src/zep_cloud/agent/trajectory_import/run/item/raw_client.py new file mode 100644 index 00000000..2b304e7d --- /dev/null +++ b/src/zep_cloud/agent/trajectory_import/run/item/raw_client.py @@ -0,0 +1,260 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from .....core.api_error import ApiError as core_api_error_ApiError +from .....core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from .....core.jsonable_encoder import encode_path_param +from .....core.pagination import AsyncPager, SyncPager +from .....core.parse_error import ParsingError +from .....core.pydantic_utilities import parse_obj_as +from .....core.request_options import RequestOptions +from .....errors.forbidden_error import ForbiddenError +from .....errors.not_found_error import NotFoundError +from .....errors.unauthorized_error import UnauthorizedError +from .....types.api_error import ApiError as types_api_error_ApiError +from .....types.trajectory_import_run_item import TrajectoryImportRunItem +from .....types.trajectory_import_run_item_page import TrajectoryImportRunItemPage +from pydantic import ValidationError + + +class RawItemClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def list( + self, + agent_uuid: str, + import_uuid: str, + run_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[TrajectoryImportRunItem, TrajectoryImportRunItemPage]: + """ + List trace results for this run. Run items do not include source payload. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + import_uuid : str + Trajectory import UUID + + run_uuid : str + Run UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[TrajectoryImportRunItem, TrajectoryImportRunItemPage] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectory-imports/{encode_path_param(import_uuid)}/runs/{encode_path_param(run_uuid)}/items", + method="GET", + params={ + "limit": limit, + "cursor": cursor, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + TrajectoryImportRunItemPage, + parse_obj_as( + type_=TrajectoryImportRunItemPage, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + _get_next = lambda: self.list( + agent_uuid, + import_uuid, + run_uuid, + limit=limit, + cursor=_parsed_next, + request_options=request_options, + ) + return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + +class AsyncRawItemClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def list( + self, + agent_uuid: str, + import_uuid: str, + run_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[TrajectoryImportRunItem, TrajectoryImportRunItemPage]: + """ + List trace results for this run. Run items do not include source payload. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + import_uuid : str + Trajectory import UUID + + run_uuid : str + Run UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[TrajectoryImportRunItem, TrajectoryImportRunItemPage] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectory-imports/{encode_path_param(import_uuid)}/runs/{encode_path_param(run_uuid)}/items", + method="GET", + params={ + "limit": limit, + "cursor": cursor, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + TrajectoryImportRunItemPage, + parse_obj_as( + type_=TrajectoryImportRunItemPage, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + + async def _get_next(): + return await self.list( + agent_uuid, + import_uuid, + run_uuid, + limit=limit, + cursor=_parsed_next, + request_options=request_options, + ) + + return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) diff --git a/src/zep_cloud/agent/trajectory_import/run/raw_client.py b/src/zep_cloud/agent/trajectory_import/run/raw_client.py new file mode 100644 index 00000000..a3bae331 --- /dev/null +++ b/src/zep_cloud/agent/trajectory_import/run/raw_client.py @@ -0,0 +1,644 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ....core.api_error import ApiError as core_api_error_ApiError +from ....core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ....core.http_response import AsyncHttpResponse, HttpResponse +from ....core.idempotency import generate_idempotency_key +from ....core.jsonable_encoder import encode_path_param +from ....core.pagination import AsyncPager, SyncPager +from ....core.parse_error import ParsingError +from ....core.pydantic_utilities import parse_obj_as +from ....core.request_options import RequestOptions +from ....errors.conflict_error import ConflictError +from ....errors.forbidden_error import ForbiddenError +from ....errors.not_found_error import NotFoundError +from ....errors.unauthorized_error import UnauthorizedError +from ....types.api_error import ApiError as types_api_error_ApiError +from ....types.task import Task +from ....types.trajectory_import_run import TrajectoryImportRun +from ....types.trajectory_import_run_page import TrajectoryImportRunPage +from pydantic import ValidationError + + +class RawRunClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def list( + self, + agent_uuid: str, + import_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[TrajectoryImportRun, TrajectoryImportRunPage]: + """ + List runs that belong to this trajectory import. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + import_uuid : str + Trajectory import UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[TrajectoryImportRun, TrajectoryImportRunPage] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectory-imports/{encode_path_param(import_uuid)}/runs", + method="GET", + params={ + "limit": limit, + "cursor": cursor, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + TrajectoryImportRunPage, + parse_obj_as( + type_=TrajectoryImportRunPage, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + _get_next = lambda: self.list( + agent_uuid, + import_uuid, + limit=limit, + cursor=_parsed_next, + request_options=request_options, + ) + return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def create( + self, + agent_uuid: str, + import_uuid: str, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[Task]: + """ + Create a pending run and its Task. This operation does not start the run. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + import_uuid : str + Trajectory import UUID + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[Task] + Accepted + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectory-imports/{encode_path_param(import_uuid)}/runs", + method="POST", + headers={ + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + Task, + parse_obj_as( + type_=Task, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def get( + self, + agent_uuid: str, + import_uuid: str, + run_uuid: str, + *, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[TrajectoryImportRun]: + """ + Read one run that belongs to this trajectory import. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + import_uuid : str + Trajectory import UUID + + run_uuid : str + Run UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[TrajectoryImportRun] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectory-imports/{encode_path_param(import_uuid)}/runs/{encode_path_param(run_uuid)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + TrajectoryImportRun, + parse_obj_as( + type_=TrajectoryImportRun, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + +class AsyncRawRunClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def list( + self, + agent_uuid: str, + import_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[TrajectoryImportRun, TrajectoryImportRunPage]: + """ + List runs that belong to this trajectory import. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + import_uuid : str + Trajectory import UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[TrajectoryImportRun, TrajectoryImportRunPage] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectory-imports/{encode_path_param(import_uuid)}/runs", + method="GET", + params={ + "limit": limit, + "cursor": cursor, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + TrajectoryImportRunPage, + parse_obj_as( + type_=TrajectoryImportRunPage, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + + async def _get_next(): + return await self.list( + agent_uuid, + import_uuid, + limit=limit, + cursor=_parsed_next, + request_options=request_options, + ) + + return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def create( + self, + agent_uuid: str, + import_uuid: str, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[Task]: + """ + Create a pending run and its Task. This operation does not start the run. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + import_uuid : str + Trajectory import UUID + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[Task] + Accepted + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectory-imports/{encode_path_param(import_uuid)}/runs", + method="POST", + headers={ + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + Task, + parse_obj_as( + type_=Task, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def get( + self, + agent_uuid: str, + import_uuid: str, + run_uuid: str, + *, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[TrajectoryImportRun]: + """ + Read one run that belongs to this trajectory import. + + Parameters + ---------- + agent_uuid : str + Agent UUID + + import_uuid : str + Trajectory import UUID + + run_uuid : str + Run UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[TrajectoryImportRun] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/trajectory-imports/{encode_path_param(import_uuid)}/runs/{encode_path_param(run_uuid)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + TrajectoryImportRun, + parse_obj_as( + type_=TrajectoryImportRun, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) diff --git a/src/zep_cloud/agent/trajectory_import/types/__init__.py b/src/zep_cloud/agent/trajectory_import/types/__init__.py new file mode 100644 index 00000000..f7fba247 --- /dev/null +++ b/src/zep_cloud/agent/trajectory_import/types/__init__.py @@ -0,0 +1,36 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .trajectory_import_delete_request_trajectories import TrajectoryImportDeleteRequestTrajectories +_dynamic_imports: typing.Dict[str, str] = { + "TrajectoryImportDeleteRequestTrajectories": ".trajectory_import_delete_request_trajectories" +} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = ["TrajectoryImportDeleteRequestTrajectories"] diff --git a/src/zep_cloud/agent/trajectory_import/types/trajectory_import_delete_request_trajectories.py b/src/zep_cloud/agent/trajectory_import/types/trajectory_import_delete_request_trajectories.py new file mode 100644 index 00000000..5c7b0d61 --- /dev/null +++ b/src/zep_cloud/agent/trajectory_import/types/trajectory_import_delete_request_trajectories.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +TrajectoryImportDeleteRequestTrajectories = typing.Union[typing.Literal["keep", "delete"], typing.Any] diff --git a/src/zep_cloud/agent/verifier/__init__.py b/src/zep_cloud/agent/verifier/__init__.py new file mode 100644 index 00000000..5cde0202 --- /dev/null +++ b/src/zep_cloud/agent/verifier/__init__.py @@ -0,0 +1,4 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + diff --git a/src/zep_cloud/agent/verifier/client.py b/src/zep_cloud/agent/verifier/client.py new file mode 100644 index 00000000..b3469e08 --- /dev/null +++ b/src/zep_cloud/agent/verifier/client.py @@ -0,0 +1,682 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ...core.pagination import AsyncPager, SyncPager +from ...core.request_options import RequestOptions +from ...types.agent_verification_strength import AgentVerificationStrength +from ...types.agent_verifier import AgentVerifier +from ...types.agent_verifier_evidence_invalidation_result import AgentVerifierEvidenceInvalidationResult +from ...types.agent_verifier_principal_binding_input import AgentVerifierPrincipalBindingInput +from ...types.agent_verifier_status import AgentVerifierStatus +from ...types.pagev4agent_verifier import Pagev4AgentVerifier +from .raw_client import AsyncRawVerifierClient, RawVerifierClient + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class VerifierClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawVerifierClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawVerifierClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawVerifierClient + """ + return self._raw_client + + def list( + self, + agent_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + class_: typing.Optional[str] = OMIT, + principal_id: typing.Optional[str] = OMIT, + principal_type: typing.Optional[str] = OMIT, + status: typing.Optional[AgentVerifierStatus] = OMIT, + verifier_id: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[AgentVerifier, Pagev4AgentVerifier]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Page cursor + + class_ : typing.Optional[str] + Filters to an exact immutable verifier class. + + principal_id : typing.Optional[str] + Filters to registrations bound to this exact principal identifier. + + principal_type : typing.Optional[str] + Filters to registrations bound to this principal type. + + status : typing.Optional[AgentVerifierStatus] + Filters to active or revoked registrations. Omit to include both. + + verifier_id : typing.Optional[str] + Filters to an exact developer-assigned verifier identifier. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[AgentVerifier, Pagev4AgentVerifier] + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + response = client.agent.verifier.list( + agent_uuid="agent_uuid", + ) + for item in response: + yield item + # alternatively, you can paginate page-by-page + for page in response.iter_pages(): + yield page + """ + return self._raw_client.list( + agent_uuid, + limit=limit, + cursor=cursor, + class_=class_, + principal_id=principal_id, + principal_type=principal_type, + status=status, + verifier_id=verifier_id, + request_options=request_options, + ) + + def get( + self, agent_uuid: str, verifier_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AgentVerifier: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + verifier_uuid : str + Verifier UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentVerifier + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.verifier.get( + agent_uuid="agent_uuid", + verifier_uuid="verifier_uuid", + ) + """ + _response = self._raw_client.get(agent_uuid, verifier_uuid, request_options=request_options) + return _response.data + + def update( + self, + agent_uuid: str, + verifier_uuid: str, + *, + expected_revision: int, + capabilities: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + permitted_strengths: typing.Optional[typing.Sequence[AgentVerificationStrength]] = OMIT, + principal_bindings: typing.Optional[typing.Sequence[AgentVerifierPrincipalBindingInput]] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentVerifier: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + verifier_uuid : str + Verifier UUID + + expected_revision : int + The current verifier revision used for optimistic concurrency. + + capabilities : typing.Optional[typing.Dict[str, typing.Any]] + Replacement capabilities. Set to null to clear them. + + metadata : typing.Optional[typing.Dict[str, typing.Any]] + Replacement metadata. Set to null to clear it. + + permitted_strengths : typing.Optional[typing.Sequence[AgentVerificationStrength]] + Replacement permitted strengths. The list cannot be empty or null. + + principal_bindings : typing.Optional[typing.Sequence[AgentVerifierPrincipalBindingInput]] + Replacement exact principal bindings. The list cannot be empty or null. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentVerifier + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.verifier.update( + agent_uuid="agent_uuid", + verifier_uuid="verifier_uuid", + expected_revision=1, + ) + """ + _response = self._raw_client.update( + agent_uuid, + verifier_uuid, + expected_revision=expected_revision, + capabilities=capabilities, + metadata=metadata, + permitted_strengths=permitted_strengths, + principal_bindings=principal_bindings, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + def invalidate_evidence( + self, + agent_uuid: str, + verifier_uuid: str, + *, + reason: str, + verifier_revisions: typing.Sequence[int], + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentVerifierEvidenceInvalidationResult: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + verifier_uuid : str + Verifier UUID + + reason : str + Why evidence from these verifier revisions is invalid. + + verifier_revisions : typing.Sequence[int] + Verifier revisions whose accepted evidence is no longer valid. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentVerifierEvidenceInvalidationResult + Accepted + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.verifier.invalidate_evidence( + agent_uuid="agent_uuid", + verifier_uuid="verifier_uuid", + reason="reason", + verifier_revisions=[1], + ) + """ + _response = self._raw_client.invalidate_evidence( + agent_uuid, + verifier_uuid, + reason=reason, + verifier_revisions=verifier_revisions, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + def revoke( + self, + agent_uuid: str, + verifier_uuid: str, + *, + expected_revision: int, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentVerifier: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + verifier_uuid : str + Verifier UUID + + expected_revision : int + The current verifier revision used for optimistic concurrency. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentVerifier + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.agent.verifier.revoke( + agent_uuid="agent_uuid", + verifier_uuid="verifier_uuid", + expected_revision=1, + ) + """ + _response = self._raw_client.revoke( + agent_uuid, + verifier_uuid, + expected_revision=expected_revision, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + +class AsyncVerifierClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawVerifierClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawVerifierClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawVerifierClient + """ + return self._raw_client + + async def list( + self, + agent_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + class_: typing.Optional[str] = OMIT, + principal_id: typing.Optional[str] = OMIT, + principal_type: typing.Optional[str] = OMIT, + status: typing.Optional[AgentVerifierStatus] = OMIT, + verifier_id: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[AgentVerifier, Pagev4AgentVerifier]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Page cursor + + class_ : typing.Optional[str] + Filters to an exact immutable verifier class. + + principal_id : typing.Optional[str] + Filters to registrations bound to this exact principal identifier. + + principal_type : typing.Optional[str] + Filters to registrations bound to this principal type. + + status : typing.Optional[AgentVerifierStatus] + Filters to active or revoked registrations. Omit to include both. + + verifier_id : typing.Optional[str] + Filters to an exact developer-assigned verifier identifier. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[AgentVerifier, Pagev4AgentVerifier] + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + response = await client.agent.verifier.list( + agent_uuid="agent_uuid", + ) + async for item in response: + yield item + + # alternatively, you can paginate page-by-page + async for page in response.iter_pages(): + yield page + + + asyncio.run(main()) + """ + return await self._raw_client.list( + agent_uuid, + limit=limit, + cursor=cursor, + class_=class_, + principal_id=principal_id, + principal_type=principal_type, + status=status, + verifier_id=verifier_id, + request_options=request_options, + ) + + async def get( + self, agent_uuid: str, verifier_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AgentVerifier: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + verifier_uuid : str + Verifier UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentVerifier + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.verifier.get( + agent_uuid="agent_uuid", + verifier_uuid="verifier_uuid", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get(agent_uuid, verifier_uuid, request_options=request_options) + return _response.data + + async def update( + self, + agent_uuid: str, + verifier_uuid: str, + *, + expected_revision: int, + capabilities: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + permitted_strengths: typing.Optional[typing.Sequence[AgentVerificationStrength]] = OMIT, + principal_bindings: typing.Optional[typing.Sequence[AgentVerifierPrincipalBindingInput]] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentVerifier: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + verifier_uuid : str + Verifier UUID + + expected_revision : int + The current verifier revision used for optimistic concurrency. + + capabilities : typing.Optional[typing.Dict[str, typing.Any]] + Replacement capabilities. Set to null to clear them. + + metadata : typing.Optional[typing.Dict[str, typing.Any]] + Replacement metadata. Set to null to clear it. + + permitted_strengths : typing.Optional[typing.Sequence[AgentVerificationStrength]] + Replacement permitted strengths. The list cannot be empty or null. + + principal_bindings : typing.Optional[typing.Sequence[AgentVerifierPrincipalBindingInput]] + Replacement exact principal bindings. The list cannot be empty or null. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentVerifier + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.verifier.update( + agent_uuid="agent_uuid", + verifier_uuid="verifier_uuid", + expected_revision=1, + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.update( + agent_uuid, + verifier_uuid, + expected_revision=expected_revision, + capabilities=capabilities, + metadata=metadata, + permitted_strengths=permitted_strengths, + principal_bindings=principal_bindings, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + async def invalidate_evidence( + self, + agent_uuid: str, + verifier_uuid: str, + *, + reason: str, + verifier_revisions: typing.Sequence[int], + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentVerifierEvidenceInvalidationResult: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + verifier_uuid : str + Verifier UUID + + reason : str + Why evidence from these verifier revisions is invalid. + + verifier_revisions : typing.Sequence[int] + Verifier revisions whose accepted evidence is no longer valid. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentVerifierEvidenceInvalidationResult + Accepted + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.verifier.invalidate_evidence( + agent_uuid="agent_uuid", + verifier_uuid="verifier_uuid", + reason="reason", + verifier_revisions=[1], + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.invalidate_evidence( + agent_uuid, + verifier_uuid, + reason=reason, + verifier_revisions=verifier_revisions, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + async def revoke( + self, + agent_uuid: str, + verifier_uuid: str, + *, + expected_revision: int, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AgentVerifier: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + verifier_uuid : str + Verifier UUID + + expected_revision : int + The current verifier revision used for optimistic concurrency. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AgentVerifier + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.agent.verifier.revoke( + agent_uuid="agent_uuid", + verifier_uuid="verifier_uuid", + expected_revision=1, + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.revoke( + agent_uuid, + verifier_uuid, + expected_revision=expected_revision, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data diff --git a/src/zep_cloud/agent/verifier/raw_client.py b/src/zep_cloud/agent/verifier/raw_client.py new file mode 100644 index 00000000..4476d5c5 --- /dev/null +++ b/src/zep_cloud/agent/verifier/raw_client.py @@ -0,0 +1,1096 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ...core.api_error import ApiError as core_api_error_ApiError +from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ...core.http_response import AsyncHttpResponse, HttpResponse +from ...core.idempotency import generate_idempotency_key +from ...core.jsonable_encoder import encode_path_param +from ...core.pagination import AsyncPager, SyncPager +from ...core.parse_error import ParsingError +from ...core.pydantic_utilities import parse_obj_as +from ...core.request_options import RequestOptions +from ...core.serialization import convert_and_respect_annotation_metadata +from ...errors.bad_request_error import BadRequestError +from ...errors.conflict_error import ConflictError +from ...errors.not_found_error import NotFoundError +from ...types.agent_verification_strength import AgentVerificationStrength +from ...types.agent_verifier import AgentVerifier +from ...types.agent_verifier_evidence_invalidation_result import AgentVerifierEvidenceInvalidationResult +from ...types.agent_verifier_principal_binding_input import AgentVerifierPrincipalBindingInput +from ...types.agent_verifier_status import AgentVerifierStatus +from ...types.api_error import ApiError as types_api_error_ApiError +from ...types.pagev4agent_verifier import Pagev4AgentVerifier +from pydantic import ValidationError + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class RawVerifierClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def list( + self, + agent_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + class_: typing.Optional[str] = OMIT, + principal_id: typing.Optional[str] = OMIT, + principal_type: typing.Optional[str] = OMIT, + status: typing.Optional[AgentVerifierStatus] = OMIT, + verifier_id: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[AgentVerifier, Pagev4AgentVerifier]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Page cursor + + class_ : typing.Optional[str] + Filters to an exact immutable verifier class. + + principal_id : typing.Optional[str] + Filters to registrations bound to this exact principal identifier. + + principal_type : typing.Optional[str] + Filters to registrations bound to this principal type. + + status : typing.Optional[AgentVerifierStatus] + Filters to active or revoked registrations. Omit to include both. + + verifier_id : typing.Optional[str] + Filters to an exact developer-assigned verifier identifier. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[AgentVerifier, Pagev4AgentVerifier] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/verifiers/list", + method="POST", + params={ + "limit": limit, + "cursor": cursor, + }, + json={ + "class": class_, + "principal_id": principal_id, + "principal_type": principal_type, + "status": status, + "verifier_id": verifier_id, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + Pagev4AgentVerifier, + parse_obj_as( + type_=Pagev4AgentVerifier, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + _get_next = lambda: self.list( + agent_uuid, + limit=limit, + cursor=_parsed_next, + class_=class_, + principal_id=principal_id, + principal_type=principal_type, + status=status, + verifier_id=verifier_id, + request_options=request_options, + ) + return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def get( + self, agent_uuid: str, verifier_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[AgentVerifier]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + verifier_uuid : str + Verifier UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AgentVerifier] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/verifiers/{encode_path_param(verifier_uuid)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentVerifier, + parse_obj_as( + type_=AgentVerifier, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def update( + self, + agent_uuid: str, + verifier_uuid: str, + *, + expected_revision: int, + capabilities: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + permitted_strengths: typing.Optional[typing.Sequence[AgentVerificationStrength]] = OMIT, + principal_bindings: typing.Optional[typing.Sequence[AgentVerifierPrincipalBindingInput]] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[AgentVerifier]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + verifier_uuid : str + Verifier UUID + + expected_revision : int + The current verifier revision used for optimistic concurrency. + + capabilities : typing.Optional[typing.Dict[str, typing.Any]] + Replacement capabilities. Set to null to clear them. + + metadata : typing.Optional[typing.Dict[str, typing.Any]] + Replacement metadata. Set to null to clear it. + + permitted_strengths : typing.Optional[typing.Sequence[AgentVerificationStrength]] + Replacement permitted strengths. The list cannot be empty or null. + + principal_bindings : typing.Optional[typing.Sequence[AgentVerifierPrincipalBindingInput]] + Replacement exact principal bindings. The list cannot be empty or null. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AgentVerifier] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/verifiers/{encode_path_param(verifier_uuid)}", + method="PATCH", + json={ + "capabilities": capabilities, + "expected_revision": expected_revision, + "metadata": metadata, + "permitted_strengths": permitted_strengths, + "principal_bindings": convert_and_respect_annotation_metadata( + object_=principal_bindings, + annotation=typing.Optional[typing.Sequence[AgentVerifierPrincipalBindingInput]], + direction="write", + ), + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentVerifier, + parse_obj_as( + type_=AgentVerifier, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def invalidate_evidence( + self, + agent_uuid: str, + verifier_uuid: str, + *, + reason: str, + verifier_revisions: typing.Sequence[int], + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[AgentVerifierEvidenceInvalidationResult]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + verifier_uuid : str + Verifier UUID + + reason : str + Why evidence from these verifier revisions is invalid. + + verifier_revisions : typing.Sequence[int] + Verifier revisions whose accepted evidence is no longer valid. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AgentVerifierEvidenceInvalidationResult] + Accepted + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/verifiers/{encode_path_param(verifier_uuid)}/invalidate-evidence", + method="POST", + json={ + "reason": reason, + "verifier_revisions": verifier_revisions, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentVerifierEvidenceInvalidationResult, + parse_obj_as( + type_=AgentVerifierEvidenceInvalidationResult, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def revoke( + self, + agent_uuid: str, + verifier_uuid: str, + *, + expected_revision: int, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[AgentVerifier]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + verifier_uuid : str + Verifier UUID + + expected_revision : int + The current verifier revision used for optimistic concurrency. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AgentVerifier] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/verifiers/{encode_path_param(verifier_uuid)}/revoke", + method="POST", + json={ + "expected_revision": expected_revision, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentVerifier, + parse_obj_as( + type_=AgentVerifier, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + +class AsyncRawVerifierClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def list( + self, + agent_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + class_: typing.Optional[str] = OMIT, + principal_id: typing.Optional[str] = OMIT, + principal_type: typing.Optional[str] = OMIT, + status: typing.Optional[AgentVerifierStatus] = OMIT, + verifier_id: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[AgentVerifier, Pagev4AgentVerifier]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Page cursor + + class_ : typing.Optional[str] + Filters to an exact immutable verifier class. + + principal_id : typing.Optional[str] + Filters to registrations bound to this exact principal identifier. + + principal_type : typing.Optional[str] + Filters to registrations bound to this principal type. + + status : typing.Optional[AgentVerifierStatus] + Filters to active or revoked registrations. Omit to include both. + + verifier_id : typing.Optional[str] + Filters to an exact developer-assigned verifier identifier. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[AgentVerifier, Pagev4AgentVerifier] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/verifiers/list", + method="POST", + params={ + "limit": limit, + "cursor": cursor, + }, + json={ + "class": class_, + "principal_id": principal_id, + "principal_type": principal_type, + "status": status, + "verifier_id": verifier_id, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + Pagev4AgentVerifier, + parse_obj_as( + type_=Pagev4AgentVerifier, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + + async def _get_next(): + return await self.list( + agent_uuid, + limit=limit, + cursor=_parsed_next, + class_=class_, + principal_id=principal_id, + principal_type=principal_type, + status=status, + verifier_id=verifier_id, + request_options=request_options, + ) + + return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def get( + self, agent_uuid: str, verifier_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[AgentVerifier]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + verifier_uuid : str + Verifier UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AgentVerifier] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/verifiers/{encode_path_param(verifier_uuid)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentVerifier, + parse_obj_as( + type_=AgentVerifier, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def update( + self, + agent_uuid: str, + verifier_uuid: str, + *, + expected_revision: int, + capabilities: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + permitted_strengths: typing.Optional[typing.Sequence[AgentVerificationStrength]] = OMIT, + principal_bindings: typing.Optional[typing.Sequence[AgentVerifierPrincipalBindingInput]] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[AgentVerifier]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + verifier_uuid : str + Verifier UUID + + expected_revision : int + The current verifier revision used for optimistic concurrency. + + capabilities : typing.Optional[typing.Dict[str, typing.Any]] + Replacement capabilities. Set to null to clear them. + + metadata : typing.Optional[typing.Dict[str, typing.Any]] + Replacement metadata. Set to null to clear it. + + permitted_strengths : typing.Optional[typing.Sequence[AgentVerificationStrength]] + Replacement permitted strengths. The list cannot be empty or null. + + principal_bindings : typing.Optional[typing.Sequence[AgentVerifierPrincipalBindingInput]] + Replacement exact principal bindings. The list cannot be empty or null. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AgentVerifier] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/verifiers/{encode_path_param(verifier_uuid)}", + method="PATCH", + json={ + "capabilities": capabilities, + "expected_revision": expected_revision, + "metadata": metadata, + "permitted_strengths": permitted_strengths, + "principal_bindings": convert_and_respect_annotation_metadata( + object_=principal_bindings, + annotation=typing.Optional[typing.Sequence[AgentVerifierPrincipalBindingInput]], + direction="write", + ), + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentVerifier, + parse_obj_as( + type_=AgentVerifier, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def invalidate_evidence( + self, + agent_uuid: str, + verifier_uuid: str, + *, + reason: str, + verifier_revisions: typing.Sequence[int], + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[AgentVerifierEvidenceInvalidationResult]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + verifier_uuid : str + Verifier UUID + + reason : str + Why evidence from these verifier revisions is invalid. + + verifier_revisions : typing.Sequence[int] + Verifier revisions whose accepted evidence is no longer valid. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AgentVerifierEvidenceInvalidationResult] + Accepted + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/verifiers/{encode_path_param(verifier_uuid)}/invalidate-evidence", + method="POST", + json={ + "reason": reason, + "verifier_revisions": verifier_revisions, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentVerifierEvidenceInvalidationResult, + parse_obj_as( + type_=AgentVerifierEvidenceInvalidationResult, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def revoke( + self, + agent_uuid: str, + verifier_uuid: str, + *, + expected_revision: int, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[AgentVerifier]: + """ + Parameters + ---------- + agent_uuid : str + Agent UUID + + verifier_uuid : str + Verifier UUID + + expected_revision : int + The current verifier revision used for optimistic concurrency. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AgentVerifier] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"agents/{encode_path_param(agent_uuid)}/verifiers/{encode_path_param(verifier_uuid)}/revoke", + method="POST", + json={ + "expected_revision": expected_revision, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AgentVerifier, + parse_obj_as( + type_=AgentVerifier, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) diff --git a/src/zep_cloud/base_client.py b/src/zep_cloud/base_client.py index 01b419a6..67218112 100644 --- a/src/zep_cloud/base_client.py +++ b/src/zep_cloud/base_client.py @@ -12,13 +12,16 @@ from .environment import ZepEnvironment if typing.TYPE_CHECKING: + from .agent.client import AgentClient, AsyncAgentClient from .batch.client import AsyncBatchClient, BatchClient from .context.client import AsyncContextClient, ContextClient + from .debug_log.client import AsyncDebugLogClient, DebugLogClient from .graph.client import AsyncGraphClient, GraphClient from .lookup.client import AsyncLookupClient, LookupClient from .project.client import AsyncProjectClient, ProjectClient from .task.client import AsyncTaskClient, TaskClient from .thread.client import AsyncThreadClient, ThreadClient + from .trace_connection.client import AsyncTraceConnectionClient, TraceConnectionClient from .user.client import AsyncUserClient, UserClient from .user_group.client import AsyncUserGroupClient, UserGroupClient @@ -48,6 +51,15 @@ class BaseClient: timeout : typing.Optional[float] The timeout to be used, in seconds, for requests. By default the timeout is 60 seconds, unless a custom httpx client is used, in which case this default is not enforced. + max_retries : typing.Optional[int] + The default maximum number of retries for failed requests. Defaults to 2. Per-request `max_retries` in `request_options` takes precedence over this value. + + stream_reconnection_enabled : typing.Optional[bool] + Whether to automatically reconnect on stream disconnection for resumable streaming endpoints. Defaults to True. Per-request `stream_reconnection_enabled` in `request_options` takes precedence over this value. + + max_stream_reconnection_attempts : typing.Optional[int] + The maximum number of reconnection attempts for resumable streaming endpoints. Defaults to no limit. Per-request `max_stream_reconnection_attempts` in `request_options` takes precedence over this value. + follow_redirects : typing.Optional[bool] Whether the default httpx client follows redirects or not, this is irrelevant if a custom httpx client is passed in. @@ -71,16 +83,19 @@ def __init__( *, base_url: typing.Optional[str] = None, environment: ZepEnvironment = ZepEnvironment.DEFAULT, - api_key: typing.Optional[str] = os.getenv("ZEP_API_KEY"), + api_key: typing.Optional[str] = None, headers: typing.Optional[typing.Dict[str, str]] = None, timeout: typing.Optional[float] = None, + max_retries: typing.Optional[int] = None, + stream_reconnection_enabled: typing.Optional[bool] = None, + max_stream_reconnection_attempts: typing.Optional[int] = None, follow_redirects: typing.Optional[bool] = True, httpx_client: typing.Optional[httpx.Client] = None, logging: typing.Optional[typing.Union[LogConfig, Logger]] = None, ): - _defaulted_timeout = ( - timeout if timeout is not None else 60 if httpx_client is None else httpx_client.timeout.read - ) + _defaulted_timeout = timeout if timeout is not None else 60 if httpx_client is None else None + _defaulted_max_retries = max_retries if max_retries is not None else 2 + api_key = api_key if api_key is not None else os.getenv("ZEP_API_KEY") if api_key is None: raise ApiError(body="The client must be instantiated be either passing in api_key or setting ZEP_API_KEY") self._client_wrapper = SyncClientWrapper( @@ -93,18 +108,32 @@ def __init__( if follow_redirects is not None else httpx.Client(timeout=_defaulted_timeout), timeout=_defaulted_timeout, + max_retries=_defaulted_max_retries, + stream_reconnection_enabled=stream_reconnection_enabled, + max_stream_reconnection_attempts=max_stream_reconnection_attempts, logging=logging, ) + self._agent: typing.Optional[AgentClient] = None self._batch: typing.Optional[BatchClient] = None self._context: typing.Optional[ContextClient] = None + self._debug_log: typing.Optional[DebugLogClient] = None self._graph: typing.Optional[GraphClient] = None self._lookup: typing.Optional[LookupClient] = None self._project: typing.Optional[ProjectClient] = None self._task: typing.Optional[TaskClient] = None self._thread: typing.Optional[ThreadClient] = None + self._trace_connection: typing.Optional[TraceConnectionClient] = None self._user_group: typing.Optional[UserGroupClient] = None self._user: typing.Optional[UserClient] = None + @property + def agent(self): + if self._agent is None: + from .agent.client import AgentClient # noqa: E402 + + self._agent = AgentClient(client_wrapper=self._client_wrapper) + return self._agent + @property def batch(self): if self._batch is None: @@ -121,6 +150,14 @@ def context(self): self._context = ContextClient(client_wrapper=self._client_wrapper) return self._context + @property + def debug_log(self): + if self._debug_log is None: + from .debug_log.client import DebugLogClient # noqa: E402 + + self._debug_log = DebugLogClient(client_wrapper=self._client_wrapper) + return self._debug_log + @property def graph(self): if self._graph is None: @@ -161,6 +198,14 @@ def thread(self): self._thread = ThreadClient(client_wrapper=self._client_wrapper) return self._thread + @property + def trace_connection(self): + if self._trace_connection is None: + from .trace_connection.client import TraceConnectionClient # noqa: E402 + + self._trace_connection = TraceConnectionClient(client_wrapper=self._client_wrapper) + return self._trace_connection + @property def user_group(self): if self._user_group is None: @@ -178,6 +223,24 @@ def user(self): return self._user +def _make_default_async_client( + timeout: typing.Optional[float], + follow_redirects: typing.Optional[bool], +) -> httpx.AsyncClient: + try: + import httpx_aiohttp # type: ignore[import-not-found] + except ImportError: + pass + else: + if follow_redirects is not None: + return httpx_aiohttp.HttpxAiohttpClient(timeout=timeout, follow_redirects=follow_redirects) + return httpx_aiohttp.HttpxAiohttpClient(timeout=timeout) + + if follow_redirects is not None: + return httpx.AsyncClient(timeout=timeout, follow_redirects=follow_redirects) + return httpx.AsyncClient(timeout=timeout) + + class AsyncBaseClient: """ Use this class to access the different functions within the SDK. You can instantiate any number of clients with different configuration that will propagate to these functions. @@ -203,6 +266,15 @@ class AsyncBaseClient: timeout : typing.Optional[float] The timeout to be used, in seconds, for requests. By default the timeout is 60 seconds, unless a custom httpx client is used, in which case this default is not enforced. + max_retries : typing.Optional[int] + The default maximum number of retries for failed requests. Defaults to 2. Per-request `max_retries` in `request_options` takes precedence over this value. + + stream_reconnection_enabled : typing.Optional[bool] + Whether to automatically reconnect on stream disconnection for resumable streaming endpoints. Defaults to True. Per-request `stream_reconnection_enabled` in `request_options` takes precedence over this value. + + max_stream_reconnection_attempts : typing.Optional[int] + The maximum number of reconnection attempts for resumable streaming endpoints. Defaults to no limit. Per-request `max_stream_reconnection_attempts` in `request_options` takes precedence over this value. + follow_redirects : typing.Optional[bool] Whether the default httpx client follows redirects or not, this is irrelevant if a custom httpx client is passed in. @@ -226,16 +298,19 @@ def __init__( *, base_url: typing.Optional[str] = None, environment: ZepEnvironment = ZepEnvironment.DEFAULT, - api_key: typing.Optional[str] = os.getenv("ZEP_API_KEY"), + api_key: typing.Optional[str] = None, headers: typing.Optional[typing.Dict[str, str]] = None, timeout: typing.Optional[float] = None, + max_retries: typing.Optional[int] = None, + stream_reconnection_enabled: typing.Optional[bool] = None, + max_stream_reconnection_attempts: typing.Optional[int] = None, follow_redirects: typing.Optional[bool] = True, httpx_client: typing.Optional[httpx.AsyncClient] = None, logging: typing.Optional[typing.Union[LogConfig, Logger]] = None, ): - _defaulted_timeout = ( - timeout if timeout is not None else 60 if httpx_client is None else httpx_client.timeout.read - ) + _defaulted_timeout = timeout if timeout is not None else 60 if httpx_client is None else None + _defaulted_max_retries = max_retries if max_retries is not None else 2 + api_key = api_key if api_key is not None else os.getenv("ZEP_API_KEY") if api_key is None: raise ApiError(body="The client must be instantiated be either passing in api_key or setting ZEP_API_KEY") self._client_wrapper = AsyncClientWrapper( @@ -244,22 +319,34 @@ def __init__( headers=headers, httpx_client=httpx_client if httpx_client is not None - else httpx.AsyncClient(timeout=_defaulted_timeout, follow_redirects=follow_redirects) - if follow_redirects is not None - else httpx.AsyncClient(timeout=_defaulted_timeout), + else _make_default_async_client(timeout=_defaulted_timeout, follow_redirects=follow_redirects), timeout=_defaulted_timeout, + max_retries=_defaulted_max_retries, + stream_reconnection_enabled=stream_reconnection_enabled, + max_stream_reconnection_attempts=max_stream_reconnection_attempts, logging=logging, ) + self._agent: typing.Optional[AsyncAgentClient] = None self._batch: typing.Optional[AsyncBatchClient] = None self._context: typing.Optional[AsyncContextClient] = None + self._debug_log: typing.Optional[AsyncDebugLogClient] = None self._graph: typing.Optional[AsyncGraphClient] = None self._lookup: typing.Optional[AsyncLookupClient] = None self._project: typing.Optional[AsyncProjectClient] = None self._task: typing.Optional[AsyncTaskClient] = None self._thread: typing.Optional[AsyncThreadClient] = None + self._trace_connection: typing.Optional[AsyncTraceConnectionClient] = None self._user_group: typing.Optional[AsyncUserGroupClient] = None self._user: typing.Optional[AsyncUserClient] = None + @property + def agent(self): + if self._agent is None: + from .agent.client import AsyncAgentClient # noqa: E402 + + self._agent = AsyncAgentClient(client_wrapper=self._client_wrapper) + return self._agent + @property def batch(self): if self._batch is None: @@ -276,6 +363,14 @@ def context(self): self._context = AsyncContextClient(client_wrapper=self._client_wrapper) return self._context + @property + def debug_log(self): + if self._debug_log is None: + from .debug_log.client import AsyncDebugLogClient # noqa: E402 + + self._debug_log = AsyncDebugLogClient(client_wrapper=self._client_wrapper) + return self._debug_log + @property def graph(self): if self._graph is None: @@ -316,6 +411,14 @@ def thread(self): self._thread = AsyncThreadClient(client_wrapper=self._client_wrapper) return self._thread + @property + def trace_connection(self): + if self._trace_connection is None: + from .trace_connection.client import AsyncTraceConnectionClient # noqa: E402 + + self._trace_connection = AsyncTraceConnectionClient(client_wrapper=self._client_wrapper) + return self._trace_connection + @property def user_group(self): if self._user_group is None: diff --git a/src/zep_cloud/batch/__init__.py b/src/zep_cloud/batch/__init__.py index 5cde0202..86ddd684 100644 --- a/src/zep_cloud/batch/__init__.py +++ b/src/zep_cloud/batch/__init__.py @@ -2,3 +2,33 @@ # isort: skip_file +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .types import BatchListRequestStatus +_dynamic_imports: typing.Dict[str, str] = {"BatchListRequestStatus": ".types"} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = ["BatchListRequestStatus"] diff --git a/src/zep_cloud/batch/client.py b/src/zep_cloud/batch/client.py index c9b61dc7..e9a27277 100644 --- a/src/zep_cloud/batch/client.py +++ b/src/zep_cloud/batch/client.py @@ -13,6 +13,7 @@ from ..types.batch_page import BatchPage from ..types.process_batch_result import ProcessBatchResult from .raw_client import AsyncRawBatchClient, RawBatchClient +from .types.batch_list_request_status import BatchListRequestStatus # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -38,7 +39,7 @@ def list( *, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, - status: typing.Optional[str] = None, + status: typing.Optional[BatchListRequestStatus] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Batch, BatchPage]: """ @@ -50,7 +51,7 @@ def list( cursor : typing.Optional[str] Opaque page cursor - status : typing.Optional[str] + status : typing.Optional[BatchListRequestStatus] Batch status filter request_options : typing.Optional[RequestOptions] @@ -68,11 +69,7 @@ def list( client = Zep( api_key="YOUR_API_KEY", ) - response = client.batch.list( - limit=1, - cursor="cursor", - status="status", - ) + response = client.batch.list() for item in response: yield item # alternatively, you can paginate page-by-page @@ -236,8 +233,6 @@ def list_items( ) response = client.batch.list_items( batch_uuid="batch_uuid", - limit=1, - cursor="cursor", ) for item in response: yield item @@ -355,7 +350,7 @@ async def list( *, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, - status: typing.Optional[str] = None, + status: typing.Optional[BatchListRequestStatus] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Batch, BatchPage]: """ @@ -367,7 +362,7 @@ async def list( cursor : typing.Optional[str] Opaque page cursor - status : typing.Optional[str] + status : typing.Optional[BatchListRequestStatus] Batch status filter request_options : typing.Optional[RequestOptions] @@ -390,11 +385,7 @@ async def list( async def main() -> None: - response = await client.batch.list( - limit=1, - cursor="cursor", - status="status", - ) + response = await client.batch.list() async for item in response: yield item @@ -591,8 +582,6 @@ async def list_items( async def main() -> None: response = await client.batch.list_items( batch_uuid="batch_uuid", - limit=1, - cursor="cursor", ) async for item in response: yield item diff --git a/src/zep_cloud/batch/raw_client.py b/src/zep_cloud/batch/raw_client.py index 0fc22bc3..d2f8be55 100644 --- a/src/zep_cloud/batch/raw_client.py +++ b/src/zep_cloud/batch/raw_client.py @@ -6,7 +6,8 @@ from ..core.api_error import ApiError as core_api_error_ApiError from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ..core.http_response import AsyncHttpResponse, HttpResponse -from ..core.jsonable_encoder import jsonable_encoder +from ..core.idempotency import generate_idempotency_key +from ..core.jsonable_encoder import encode_path_param from ..core.pagination import AsyncPager, SyncPager from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as @@ -24,6 +25,7 @@ from ..types.batch_items_response import BatchItemsResponse from ..types.batch_page import BatchPage from ..types.process_batch_result import ProcessBatchResult +from .types.batch_list_request_status import BatchListRequestStatus from pydantic import ValidationError # this is used as the default value for optional parameters @@ -39,7 +41,7 @@ def list( *, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, - status: typing.Optional[str] = None, + status: typing.Optional[BatchListRequestStatus] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Batch, BatchPage]: """ @@ -51,7 +53,7 @@ def list( cursor : typing.Optional[str] Opaque page cursor - status : typing.Optional[str] + status : typing.Optional[BatchListRequestStatus] Batch status filter request_options : typing.Optional[RequestOptions] @@ -180,7 +182,7 @@ def create( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -268,7 +270,7 @@ def get(self, batch_uuid: str, *, request_options: typing.Optional[RequestOption OK """ _response = self._client_wrapper.httpx_client.request( - f"batches/{jsonable_encoder(batch_uuid)}", + f"batches/{encode_path_param(batch_uuid)}", method="GET", request_options=request_options, ) @@ -351,10 +353,10 @@ def delete( HttpResponse[None] """ _response = self._client_wrapper.httpx_client.request( - f"batches/{jsonable_encoder(batch_uuid)}", + f"batches/{encode_path_param(batch_uuid)}", method="DELETE", headers={ - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, ) @@ -447,7 +449,7 @@ def list_items( OK """ _response = self._client_wrapper.httpx_client.request( - f"batches/{jsonable_encoder(batch_uuid)}/items", + f"batches/{encode_path_param(batch_uuid)}/items", method="GET", params={ "limit": limit, @@ -548,7 +550,7 @@ def add_items( OK """ _response = self._client_wrapper.httpx_client.request( - f"batches/{jsonable_encoder(batch_uuid)}/items", + f"batches/{encode_path_param(batch_uuid)}/items", method="POST", json={ "items": convert_and_respect_annotation_metadata( @@ -557,7 +559,7 @@ def add_items( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -653,10 +655,10 @@ def process( Accepted """ _response = self._client_wrapper.httpx_client.request( - f"batches/{jsonable_encoder(batch_uuid)}/process", + f"batches/{encode_path_param(batch_uuid)}/process", method="POST", headers={ - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, ) @@ -737,7 +739,7 @@ async def list( *, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, - status: typing.Optional[str] = None, + status: typing.Optional[BatchListRequestStatus] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Batch, BatchPage]: """ @@ -749,7 +751,7 @@ async def list( cursor : typing.Optional[str] Opaque page cursor - status : typing.Optional[str] + status : typing.Optional[BatchListRequestStatus] Batch status filter request_options : typing.Optional[RequestOptions] @@ -881,7 +883,7 @@ async def create( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -971,7 +973,7 @@ async def get( OK """ _response = await self._client_wrapper.httpx_client.request( - f"batches/{jsonable_encoder(batch_uuid)}", + f"batches/{encode_path_param(batch_uuid)}", method="GET", request_options=request_options, ) @@ -1054,10 +1056,10 @@ async def delete( AsyncHttpResponse[None] """ _response = await self._client_wrapper.httpx_client.request( - f"batches/{jsonable_encoder(batch_uuid)}", + f"batches/{encode_path_param(batch_uuid)}", method="DELETE", headers={ - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, ) @@ -1150,7 +1152,7 @@ async def list_items( OK """ _response = await self._client_wrapper.httpx_client.request( - f"batches/{jsonable_encoder(batch_uuid)}/items", + f"batches/{encode_path_param(batch_uuid)}/items", method="GET", params={ "limit": limit, @@ -1254,7 +1256,7 @@ async def add_items( OK """ _response = await self._client_wrapper.httpx_client.request( - f"batches/{jsonable_encoder(batch_uuid)}/items", + f"batches/{encode_path_param(batch_uuid)}/items", method="POST", json={ "items": convert_and_respect_annotation_metadata( @@ -1263,7 +1265,7 @@ async def add_items( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -1359,10 +1361,10 @@ async def process( Accepted """ _response = await self._client_wrapper.httpx_client.request( - f"batches/{jsonable_encoder(batch_uuid)}/process", + f"batches/{encode_path_param(batch_uuid)}/process", method="POST", headers={ - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, ) diff --git a/src/zep_cloud/batch/types/__init__.py b/src/zep_cloud/batch/types/__init__.py new file mode 100644 index 00000000..9ba76c90 --- /dev/null +++ b/src/zep_cloud/batch/types/__init__.py @@ -0,0 +1,34 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .batch_list_request_status import BatchListRequestStatus +_dynamic_imports: typing.Dict[str, str] = {"BatchListRequestStatus": ".batch_list_request_status"} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = ["BatchListRequestStatus"] diff --git a/src/zep_cloud/batch/types/batch_list_request_status.py b/src/zep_cloud/batch/types/batch_list_request_status.py new file mode 100644 index 00000000..dca48268 --- /dev/null +++ b/src/zep_cloud/batch/types/batch_list_request_status.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +BatchListRequestStatus = typing.Union[ + typing.Literal["draft", "invalid", "queued", "processing", "succeeded", "partial", "failed", "canceled"], typing.Any +] diff --git a/src/zep_cloud/client.py b/src/zep_cloud/client.py index 658e8d46..09969e70 100644 --- a/src/zep_cloud/client.py +++ b/src/zep_cloud/client.py @@ -1,6 +1,5 @@ # This file was auto-generated by Fern from our API Definition. -import os import typing import httpx @@ -15,9 +14,12 @@ def __init__( *, base_url: typing.Optional[str] = None, environment: ZepEnvironment = ZepEnvironment.DEFAULT, - api_key: typing.Optional[str] = os.getenv("ZEP_API_KEY"), + api_key: typing.Optional[str] = None, headers: typing.Optional[typing.Dict[str, str]] = None, timeout: typing.Optional[float] = None, + max_retries: typing.Optional[int] = None, + stream_reconnection_enabled: typing.Optional[bool] = None, + max_stream_reconnection_attempts: typing.Optional[int] = None, follow_redirects: typing.Optional[bool] = True, httpx_client: typing.Optional[httpx.Client] = None, logging: typing.Optional[typing.Union[LogConfig, Logger]] = None, @@ -28,6 +30,9 @@ def __init__( api_key=api_key, headers=headers, timeout=timeout, + max_retries=max_retries, + stream_reconnection_enabled=stream_reconnection_enabled, + max_stream_reconnection_attempts=max_stream_reconnection_attempts, follow_redirects=follow_redirects, httpx_client=httpx_client, logging=logging, @@ -40,9 +45,12 @@ def __init__( *, base_url: typing.Optional[str] = None, environment: ZepEnvironment = ZepEnvironment.DEFAULT, - api_key: typing.Optional[str] = os.getenv("ZEP_API_KEY"), + api_key: typing.Optional[str] = None, headers: typing.Optional[typing.Dict[str, str]] = None, timeout: typing.Optional[float] = None, + max_retries: typing.Optional[int] = None, + stream_reconnection_enabled: typing.Optional[bool] = None, + max_stream_reconnection_attempts: typing.Optional[int] = None, follow_redirects: typing.Optional[bool] = True, httpx_client: typing.Optional[httpx.AsyncClient] = None, logging: typing.Optional[typing.Union[LogConfig, Logger]] = None, @@ -53,6 +61,9 @@ def __init__( api_key=api_key, headers=headers, timeout=timeout, + max_retries=max_retries, + stream_reconnection_enabled=stream_reconnection_enabled, + max_stream_reconnection_attempts=max_stream_reconnection_attempts, follow_redirects=follow_redirects, httpx_client=httpx_client, logging=logging, diff --git a/src/zep_cloud/context/client.py b/src/zep_cloud/context/client.py index 1d509fbf..d18880bf 100644 --- a/src/zep_cloud/context/client.py +++ b/src/zep_cloud/context/client.py @@ -75,7 +75,6 @@ def list_templates( limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, name: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[ContextTemplate, ContextTemplatePage]: """ @@ -90,8 +89,6 @@ def list_templates( name : typing.Optional[str] Filters results to the context template with this exact name. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -107,19 +104,14 @@ def list_templates( client = Zep( api_key="YOUR_API_KEY", ) - response = client.context.list_templates( - limit=1, - cursor="cursor", - ) + response = client.context.list_templates() for item in response: yield item # alternatively, you can paginate page-by-page for page in response.iter_pages(): yield page """ - return self._raw_client.list_templates( - limit=limit, cursor=cursor, name=name, idempotency_key=idempotency_key, request_options=request_options - ) + return self._raw_client.list_templates(limit=limit, cursor=cursor, name=name, request_options=request_options) def get_template( self, template_uuid: str, *, request_options: typing.Optional[RequestOptions] = None @@ -312,7 +304,6 @@ async def list_templates( limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, name: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[ContextTemplate, ContextTemplatePage]: """ @@ -327,8 +318,6 @@ async def list_templates( name : typing.Optional[str] Filters results to the context template with this exact name. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -349,10 +338,7 @@ async def list_templates( async def main() -> None: - response = await client.context.list_templates( - limit=1, - cursor="cursor", - ) + response = await client.context.list_templates() async for item in response: yield item @@ -364,7 +350,7 @@ async def main() -> None: asyncio.run(main()) """ return await self._raw_client.list_templates( - limit=limit, cursor=cursor, name=name, idempotency_key=idempotency_key, request_options=request_options + limit=limit, cursor=cursor, name=name, request_options=request_options ) async def get_template( diff --git a/src/zep_cloud/context/raw_client.py b/src/zep_cloud/context/raw_client.py index 4df61098..1ced36a3 100644 --- a/src/zep_cloud/context/raw_client.py +++ b/src/zep_cloud/context/raw_client.py @@ -6,7 +6,8 @@ from ..core.api_error import ApiError as core_api_error_ApiError from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ..core.http_response import AsyncHttpResponse, HttpResponse -from ..core.jsonable_encoder import jsonable_encoder +from ..core.idempotency import generate_idempotency_key +from ..core.jsonable_encoder import encode_path_param from ..core.pagination import AsyncPager, SyncPager from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as @@ -64,7 +65,7 @@ def create_template( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -142,7 +143,6 @@ def list_templates( limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, name: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[ContextTemplate, ContextTemplatePage]: """ @@ -157,8 +157,6 @@ def list_templates( name : typing.Optional[str] Filters results to the context template with this exact name. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -179,7 +177,7 @@ def list_templates( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -200,7 +198,6 @@ def list_templates( limit=limit, cursor=_parsed_next, name=name, - idempotency_key=idempotency_key, request_options=request_options, ) return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) @@ -237,17 +234,6 @@ def list_templates( ), ), ) - if _response.status_code == 409: - raise ConflictError( - headers=dict(_response.headers), - body=typing.cast( - types_api_error_ApiError, - parse_obj_as( - type_=types_api_error_ApiError, # type: ignore - object_=_response.json(), - ), - ), - ) _response_json = _response.json() except JSONDecodeError: raise core_api_error_ApiError( @@ -279,7 +265,7 @@ def get_template( OK """ _response = self._client_wrapper.httpx_client.request( - f"context-templates/{jsonable_encoder(template_uuid)}", + f"context-templates/{encode_path_param(template_uuid)}", method="GET", request_options=request_options, ) @@ -371,7 +357,7 @@ def update_template( OK """ _response = self._client_wrapper.httpx_client.request( - f"context-templates/{jsonable_encoder(template_uuid)}", + f"context-templates/{encode_path_param(template_uuid)}", method="PUT", json={ "name": name, @@ -379,7 +365,7 @@ def update_template( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -474,10 +460,10 @@ def delete_template( HttpResponse[None] """ _response = self._client_wrapper.httpx_client.request( - f"context-templates/{jsonable_encoder(template_uuid)}", + f"context-templates/{encode_path_param(template_uuid)}", method="DELETE", headers={ - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, ) @@ -582,7 +568,7 @@ async def create_template( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -660,7 +646,6 @@ async def list_templates( limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, name: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[ContextTemplate, ContextTemplatePage]: """ @@ -675,8 +660,6 @@ async def list_templates( name : typing.Optional[str] Filters results to the context template with this exact name. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -697,7 +680,7 @@ async def list_templates( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -720,7 +703,6 @@ async def _get_next(): limit=limit, cursor=_parsed_next, name=name, - idempotency_key=idempotency_key, request_options=request_options, ) @@ -758,17 +740,6 @@ async def _get_next(): ), ), ) - if _response.status_code == 409: - raise ConflictError( - headers=dict(_response.headers), - body=typing.cast( - types_api_error_ApiError, - parse_obj_as( - type_=types_api_error_ApiError, # type: ignore - object_=_response.json(), - ), - ), - ) _response_json = _response.json() except JSONDecodeError: raise core_api_error_ApiError( @@ -800,7 +771,7 @@ async def get_template( OK """ _response = await self._client_wrapper.httpx_client.request( - f"context-templates/{jsonable_encoder(template_uuid)}", + f"context-templates/{encode_path_param(template_uuid)}", method="GET", request_options=request_options, ) @@ -892,7 +863,7 @@ async def update_template( OK """ _response = await self._client_wrapper.httpx_client.request( - f"context-templates/{jsonable_encoder(template_uuid)}", + f"context-templates/{encode_path_param(template_uuid)}", method="PUT", json={ "name": name, @@ -900,7 +871,7 @@ async def update_template( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -995,10 +966,10 @@ async def delete_template( AsyncHttpResponse[None] """ _response = await self._client_wrapper.httpx_client.request( - f"context-templates/{jsonable_encoder(template_uuid)}", + f"context-templates/{encode_path_param(template_uuid)}", method="DELETE", headers={ - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, ) diff --git a/src/zep_cloud/core/__init__.py b/src/zep_cloud/core/__init__.py index 2a2b56e7..0d107fb5 100644 --- a/src/zep_cloud/core/__init__.py +++ b/src/zep_cloud/core/__init__.py @@ -12,7 +12,8 @@ from .file import File, convert_file_dict_to_httpx_tuples, with_content_type from .http_client import AsyncHttpClient, HttpClient from .http_response import AsyncHttpResponse, HttpResponse - from .jsonable_encoder import jsonable_encoder + from .idempotency import generate_idempotency_key + from .jsonable_encoder import encode_path_param, jsonable_encoder from .logging import ConsoleLogger, ILogger, LogConfig, LogLevel, Logger, create_logger from .pagination import AsyncPager, SyncPager from .parse_error import ParsingError @@ -56,7 +57,9 @@ "convert_and_respect_annotation_metadata": ".serialization", "convert_file_dict_to_httpx_tuples": ".file", "create_logger": ".logging", + "encode_path_param": ".jsonable_encoder", "encode_query": ".query_encoder", + "generate_idempotency_key": ".idempotency", "jsonable_encoder": ".jsonable_encoder", "parse_obj_as": ".pydantic_utilities", "parse_rfc2822_datetime": ".datetime_utils", @@ -117,7 +120,9 @@ def __dir__(): "convert_and_respect_annotation_metadata", "convert_file_dict_to_httpx_tuples", "create_logger", + "encode_path_param", "encode_query", + "generate_idempotency_key", "jsonable_encoder", "parse_obj_as", "parse_rfc2822_datetime", diff --git a/src/zep_cloud/core/client_wrapper.py b/src/zep_cloud/core/client_wrapper.py index bd63d096..c64512c2 100644 --- a/src/zep_cloud/core/client_wrapper.py +++ b/src/zep_cloud/core/client_wrapper.py @@ -15,24 +15,30 @@ def __init__( headers: typing.Optional[typing.Dict[str, str]] = None, base_url: str, timeout: typing.Optional[float] = None, + max_retries: int = 2, + stream_reconnection_enabled: typing.Optional[bool] = None, + max_stream_reconnection_attempts: typing.Optional[int] = None, logging: typing.Optional[typing.Union[LogConfig, Logger]] = None, ): self.api_key = api_key self._headers = headers self._base_url = base_url self._timeout = timeout + self._max_retries = max_retries + self._stream_reconnection_enabled = stream_reconnection_enabled + self._max_stream_reconnection_attempts = max_stream_reconnection_attempts self._logging = logging def get_headers(self) -> typing.Dict[str, str]: import platform headers: typing.Dict[str, str] = { - "User-Agent": "zep-cloud/4.0.0a5", + "User-Agent": "zep-cloud/4.0.0b1", "X-Fern-Language": "Python", "X-Fern-Runtime": f"python/{platform.python_version()}", "X-Fern-Platform": f"{platform.system().lower()}/{platform.release()}", "X-Fern-SDK-Name": "zep-cloud", - "X-Fern-SDK-Version": "4.0.0a5", + "X-Fern-SDK-Version": "4.0.0b1", **(self.get_custom_headers() or {}), } headers["Authorization"] = f"Api-Key {self.api_key}" @@ -47,6 +53,15 @@ def get_base_url(self) -> str: def get_timeout(self) -> typing.Optional[float]: return self._timeout + def get_max_retries(self) -> int: + return self._max_retries + + def get_stream_reconnection_enabled(self) -> bool: + return self._stream_reconnection_enabled if self._stream_reconnection_enabled is not None else True + + def get_max_stream_reconnection_attempts(self) -> typing.Optional[int]: + return self._max_stream_reconnection_attempts + class SyncClientWrapper(BaseClientWrapper): def __init__( @@ -56,15 +71,28 @@ def __init__( headers: typing.Optional[typing.Dict[str, str]] = None, base_url: str, timeout: typing.Optional[float] = None, + max_retries: int = 2, + stream_reconnection_enabled: typing.Optional[bool] = None, + max_stream_reconnection_attempts: typing.Optional[int] = None, logging: typing.Optional[typing.Union[LogConfig, Logger]] = None, httpx_client: httpx.Client, ): - super().__init__(api_key=api_key, headers=headers, base_url=base_url, timeout=timeout, logging=logging) + super().__init__( + api_key=api_key, + headers=headers, + base_url=base_url, + timeout=timeout, + max_retries=max_retries, + stream_reconnection_enabled=stream_reconnection_enabled, + max_stream_reconnection_attempts=max_stream_reconnection_attempts, + logging=logging, + ) self.httpx_client = HttpClient( httpx_client=httpx_client, base_headers=self.get_headers, base_timeout=self.get_timeout, base_url=self.get_base_url, + base_max_retries=self.get_max_retries(), logging_config=self._logging, ) @@ -77,17 +105,30 @@ def __init__( headers: typing.Optional[typing.Dict[str, str]] = None, base_url: str, timeout: typing.Optional[float] = None, + max_retries: int = 2, + stream_reconnection_enabled: typing.Optional[bool] = None, + max_stream_reconnection_attempts: typing.Optional[int] = None, logging: typing.Optional[typing.Union[LogConfig, Logger]] = None, async_token: typing.Optional[typing.Callable[[], typing.Awaitable[str]]] = None, httpx_client: httpx.AsyncClient, ): - super().__init__(api_key=api_key, headers=headers, base_url=base_url, timeout=timeout, logging=logging) + super().__init__( + api_key=api_key, + headers=headers, + base_url=base_url, + timeout=timeout, + max_retries=max_retries, + stream_reconnection_enabled=stream_reconnection_enabled, + max_stream_reconnection_attempts=max_stream_reconnection_attempts, + logging=logging, + ) self._async_token = async_token self.httpx_client = AsyncHttpClient( httpx_client=httpx_client, base_headers=self.get_headers, base_timeout=self.get_timeout, base_url=self.get_base_url, + base_max_retries=self.get_max_retries(), async_base_headers=self.async_get_headers, logging_config=self._logging, ) diff --git a/src/zep_cloud/core/http_client.py b/src/zep_cloud/core/http_client.py index ee937589..609855ba 100644 --- a/src/zep_cloud/core/http_client.py +++ b/src/zep_cloud/core/http_client.py @@ -3,6 +3,7 @@ import asyncio import email.utils import re +import socket import time import typing from contextlib import asynccontextmanager, contextmanager @@ -23,6 +24,39 @@ JITTER_FACTOR = 0.2 # 20% random jitter +def get_keepalive_socket_options( + idle: int = 60, + intvl: int = 30, + cnt: int = 5, +) -> typing.List[typing.Tuple[int, int, int]]: + """ + Build TCP keepalive socket options for the current platform. + + Keepalive probes keep otherwise-idle connections alive so that long, + non-streaming requests survive idle-connection reaping by a firewall, + load balancer, or NAT. The available socket constants are OS-dependent, + so each option is guarded and only emitted when the platform defines it: + + - ``SO_KEEPALIVE`` is portable (Linux/macOS/Windows). + - The idle-before-first-probe knob is ``TCP_KEEPIDLE`` on Linux and modern + Windows, but ``TCP_KEEPALIVE`` on macOS. + - ``TCP_KEEPINTVL`` / ``TCP_KEEPCNT`` exist on Linux/macOS/modern Windows. + + Passing these tuples to ``httpx.HTTPTransport(socket_options=...)`` / + ``httpx.AsyncHTTPTransport(socket_options=...)`` applies them to every + connection the transport opens. + """ + opts: typing.List[typing.Tuple[int, int, int]] = [(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)] + idle_const = getattr(socket, "TCP_KEEPIDLE", None) or getattr(socket, "TCP_KEEPALIVE", None) + if idle_const: + opts.append((socket.IPPROTO_TCP, idle_const, idle)) + if hasattr(socket, "TCP_KEEPINTVL"): + opts.append((socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, intvl)) + if hasattr(socket, "TCP_KEEPCNT"): + opts.append((socket.IPPROTO_TCP, socket.TCP_KEEPCNT, cnt)) + return opts + + def _parse_retry_after(response_headers: httpx.Headers) -> typing.Optional[float]: """ This function parses the `Retry-After` header in a HTTP response and returns the number of seconds to wait. @@ -118,9 +152,14 @@ def _retry_timeout(response: httpx.Response, retries: int) -> float: return _add_symmetric_jitter(backoff) +def _retry_timeout_from_retries(retries: int) -> float: + """Determine retry timeout using exponential backoff when no response is available.""" + backoff = min(INITIAL_RETRY_DELAY_SECONDS * pow(2.0, retries), MAX_RETRY_DELAY_SECONDS) + return _add_symmetric_jitter(backoff) + + def _should_retry(response: httpx.Response) -> bool: - retryable_400s = [429, 408, 409] - return response.status_code >= 500 or response.status_code in retryable_400s + return response.status_code >= 500 or response.status_code in [429, 408, 409] _SENSITIVE_HEADERS = frozenset( @@ -145,8 +184,33 @@ def _should_retry(response: httpx.Response) -> bool: ) +_AUTH_HEADERS: typing.FrozenSet[str] = frozenset({"authorization"}) + + def _redact_headers(headers: typing.Dict[str, str]) -> typing.Dict[str, str]: - return {k: ("[REDACTED]" if k.lower() in _SENSITIVE_HEADERS else v) for k, v in headers.items()} + return { + k: ("[REDACTED]" if k.lower() in _SENSITIVE_HEADERS or k.lower() in _AUTH_HEADERS else v) + for k, v in headers.items() + } + + +def _merge_headers(*header_dicts: typing.Optional[typing.Dict[str, typing.Any]]) -> typing.Dict[str, typing.Any]: + """ + Merge header dicts left to right. Header names are case-insensitive, so a later + `x-api-key` replaces an earlier `X-API-Key` instead of producing two headers. + """ + merged: typing.Dict[str, typing.Any] = {} + keys_by_lower: typing.Dict[str, str] = {} + for header_dict in header_dicts: + if not header_dict: + continue + for key, value in header_dict.items(): + existing_key = keys_by_lower.get(key.lower()) + if existing_key is not None: + del merged[existing_key] + keys_by_lower[key.lower()] = key + merged[key] = value + return merged def _build_url(base_url: str, path: typing.Optional[str]) -> str: @@ -233,7 +297,16 @@ def get_request_body( data: typing.Optional[typing.Any], request_options: typing.Optional[RequestOptions], omit: typing.Optional[typing.Any], + optional_body: bool = False, ) -> typing.Tuple[typing.Optional[typing.Any], typing.Optional[typing.Any]]: + # A whole body left at the sentinel was never passed by the caller, so it is absent + # rather than empty: the request carries no content and no `Content-Type`. + if omit is not None: + if json is omit: + json = None + if data is omit: + data = None + json_body = None data_body = None if data is not None: @@ -249,14 +322,36 @@ def get_request_body( # Only collapse empty dict to None when the body was not explicitly provided # and there are no additional body parameters. This preserves explicit empty # bodies (e.g., when an endpoint has a request body type but all fields are optional). - if json_body == {} and json is None and not has_additional_body_parameters: + # `optional_body` marks an endpoint whose body the API does not require, where a body + # that ends up empty means the caller passed none of its properties, so the request is + # sent with no content and no `Content-Type`. + if json_body == {} and (json is None or optional_body) and not has_additional_body_parameters: json_body = None - if data_body == {} and data is None and not has_additional_body_parameters: + if data_body == {} and (data is None or optional_body) and not has_additional_body_parameters: data_body = None return json_body, data_body +def drop_content_type_without_body( + headers: typing.Dict[str, typing.Any], + *, + json_body: typing.Optional[typing.Any], + data_body: typing.Optional[typing.Any], + optional_body: bool, +) -> typing.Dict[str, typing.Any]: + """Strip ``Content-Type`` from a request that carries no body. + + ``get_request_body`` drops the body of an ``optional_body`` endpoint when the caller + supplied none of it, but the endpoint still passes the content type it would have used. + A request that sends nothing must not advertise a media type, so a server that branches + on the header sees a bodyless call for what it is. + """ + if not optional_body or json_body is not None or data_body is not None: + return headers + return {key: value for key, value in headers.items() if key.lower() != "content-type"} + + class HttpClient: def __init__( self, @@ -265,11 +360,13 @@ def __init__( base_timeout: typing.Callable[[], typing.Optional[float]], base_headers: typing.Callable[[], typing.Dict[str, str]], base_url: typing.Optional[typing.Callable[[], str]] = None, + base_max_retries: int = 2, logging_config: typing.Optional[typing.Union[LogConfig, Logger]] = None, ): self.base_url = base_url self.base_timeout = base_timeout self.base_headers = base_headers + self.base_max_retries = base_max_retries self.httpx_client = httpx_client self.logger = create_logger(logging_config) @@ -302,16 +399,22 @@ def request( request_options: typing.Optional[RequestOptions] = None, retries: int = 0, omit: typing.Optional[typing.Any] = None, + optional_body: bool = False, force_multipart: typing.Optional[bool] = None, ) -> httpx.Response: base_url = self.get_base_url(base_url) - timeout = ( - request_options.get("timeout_in_seconds") + _timeout = ( + request_options.get("timeout") + if request_options is not None and request_options.get("timeout") is not None + else request_options.get("timeout_in_seconds") if request_options is not None and request_options.get("timeout_in_seconds") is not None else self.base_timeout() ) + timeout = _timeout if _timeout is not None else httpx.USE_CLIENT_DEFAULT - json_body, data_body = get_request_body(json=json, data=data, request_options=request_options, omit=omit) + json_body, data_body = get_request_body( + json=json, data=data, request_options=request_options, omit=omit, optional_body=optional_body + ) request_files: typing.Optional[RequestFiles] = ( convert_file_dict_to_httpx_tuples(remove_omit_from_dict(remove_none_from_dict(files), omit)) @@ -347,13 +450,16 @@ def request( _request_url = _build_url(base_url, path) _request_headers = jsonable_encoder( remove_none_from_dict( - { - **self.base_headers(), - **(headers if headers is not None else {}), - **(request_options.get("additional_headers", {}) or {} if request_options is not None else {}), - } + _merge_headers( + self.base_headers(), + headers, + request_options.get("additional_headers") if request_options is not None else None, + ) ) ) + _request_headers = drop_content_type_without_body( + _request_headers, json_body=json_body, data_body=data_body, optional_body=optional_body + ) if self.logger.is_debug(): self.logger.debug( @@ -364,19 +470,44 @@ def request( has_body=json_body is not None or data_body is not None, ) - response = self.httpx_client.request( - method=method, - url=_request_url, - headers=_request_headers, - params=_encoded_params if _encoded_params else None, - json=json_body, - data=data_body, - content=content, - files=request_files, - timeout=timeout, + max_retries: int = ( + request_options.get("max_retries", self.base_max_retries) + if request_options is not None + else self.base_max_retries ) - max_retries: int = request_options.get("max_retries", 2) if request_options is not None else 2 + try: + response = self.httpx_client.request( + method=method, + url=_request_url, + headers=_request_headers, + params=_encoded_params if _encoded_params else None, + json=json_body, + data=data_body, + content=content, + files=request_files, + timeout=timeout, + ) + except (httpx.ConnectError, httpx.RemoteProtocolError): + if retries < max_retries: + time.sleep(_retry_timeout_from_retries(retries=retries)) + return self.request( + path=path, + method=method, + base_url=base_url, + params=params, + json=json, + data=data, + content=content, + files=files, + headers=headers, + request_options=request_options, + retries=retries + 1, + omit=omit, + force_multipart=force_multipart, + ) + raise + if _should_retry(response=response): if retries < max_retries: time.sleep(_retry_timeout(response=response, retries=retries)) @@ -386,12 +517,14 @@ def request( base_url=base_url, params=params, json=json, + data=data, content=content, files=files, headers=headers, request_options=request_options, retries=retries + 1, omit=omit, + force_multipart=force_multipart, ) if self.logger.is_debug(): @@ -435,14 +568,18 @@ def stream( request_options: typing.Optional[RequestOptions] = None, retries: int = 0, omit: typing.Optional[typing.Any] = None, + optional_body: bool = False, force_multipart: typing.Optional[bool] = None, ) -> typing.Iterator[httpx.Response]: base_url = self.get_base_url(base_url) - timeout = ( - request_options.get("timeout_in_seconds") + _timeout = ( + request_options.get("timeout") + if request_options is not None and request_options.get("timeout") is not None + else request_options.get("timeout_in_seconds") if request_options is not None and request_options.get("timeout_in_seconds") is not None else self.base_timeout() ) + timeout = _timeout if _timeout is not None else httpx.USE_CLIENT_DEFAULT request_files: typing.Optional[RequestFiles] = ( convert_file_dict_to_httpx_tuples(remove_omit_from_dict(remove_none_from_dict(files), omit)) @@ -453,7 +590,9 @@ def stream( if (request_files is None or len(request_files) == 0) and force_multipart: request_files = FORCE_MULTIPART - json_body, data_body = get_request_body(json=json, data=data, request_options=request_options, omit=omit) + json_body, data_body = get_request_body( + json=json, data=data, request_options=request_options, omit=omit, optional_body=optional_body + ) data_body = _maybe_filter_none_from_multipart_data(data_body, request_files, force_multipart) @@ -480,13 +619,16 @@ def stream( _request_url = _build_url(base_url, path) _request_headers = jsonable_encoder( remove_none_from_dict( - { - **self.base_headers(), - **(headers if headers is not None else {}), - **(request_options.get("additional_headers", {}) if request_options is not None else {}), - } + _merge_headers( + self.base_headers(), + headers, + request_options.get("additional_headers") if request_options is not None else None, + ) ) ) + _request_headers = drop_content_type_without_body( + _request_headers, json_body=json_body, data_body=data_body, optional_body=optional_body + ) if self.logger.is_debug(): self.logger.debug( @@ -518,12 +660,14 @@ def __init__( base_timeout: typing.Callable[[], typing.Optional[float]], base_headers: typing.Callable[[], typing.Dict[str, str]], base_url: typing.Optional[typing.Callable[[], str]] = None, + base_max_retries: int = 2, async_base_headers: typing.Optional[typing.Callable[[], typing.Awaitable[typing.Dict[str, str]]]] = None, logging_config: typing.Optional[typing.Union[LogConfig, Logger]] = None, ): self.base_url = base_url self.base_timeout = base_timeout self.base_headers = base_headers + self.base_max_retries = base_max_retries self.async_base_headers = async_base_headers self.httpx_client = httpx_client self.logger = create_logger(logging_config) @@ -562,14 +706,18 @@ async def request( request_options: typing.Optional[RequestOptions] = None, retries: int = 0, omit: typing.Optional[typing.Any] = None, + optional_body: bool = False, force_multipart: typing.Optional[bool] = None, ) -> httpx.Response: base_url = self.get_base_url(base_url) - timeout = ( - request_options.get("timeout_in_seconds") + _timeout = ( + request_options.get("timeout") + if request_options is not None and request_options.get("timeout") is not None + else request_options.get("timeout_in_seconds") if request_options is not None and request_options.get("timeout_in_seconds") is not None else self.base_timeout() ) + timeout = _timeout if _timeout is not None else httpx.USE_CLIENT_DEFAULT request_files: typing.Optional[RequestFiles] = ( convert_file_dict_to_httpx_tuples(remove_omit_from_dict(remove_none_from_dict(files), omit)) @@ -580,7 +728,9 @@ async def request( if (request_files is None or len(request_files) == 0) and force_multipart: request_files = FORCE_MULTIPART - json_body, data_body = get_request_body(json=json, data=data, request_options=request_options, omit=omit) + json_body, data_body = get_request_body( + json=json, data=data, request_options=request_options, omit=omit, optional_body=optional_body + ) data_body = _maybe_filter_none_from_multipart_data(data_body, request_files, force_multipart) @@ -610,13 +760,16 @@ async def request( _request_url = _build_url(base_url, path) _request_headers = jsonable_encoder( remove_none_from_dict( - { - **_headers, - **(headers if headers is not None else {}), - **(request_options.get("additional_headers", {}) or {} if request_options is not None else {}), - } + _merge_headers( + _headers, + headers, + request_options.get("additional_headers") if request_options is not None else None, + ) ) ) + _request_headers = drop_content_type_without_body( + _request_headers, json_body=json_body, data_body=data_body, optional_body=optional_body + ) if self.logger.is_debug(): self.logger.debug( @@ -627,19 +780,44 @@ async def request( has_body=json_body is not None or data_body is not None, ) - response = await self.httpx_client.request( - method=method, - url=_request_url, - headers=_request_headers, - params=_encoded_params if _encoded_params else None, - json=json_body, - data=data_body, - content=content, - files=request_files, - timeout=timeout, + max_retries: int = ( + request_options.get("max_retries", self.base_max_retries) + if request_options is not None + else self.base_max_retries ) - max_retries: int = request_options.get("max_retries", 2) if request_options is not None else 2 + try: + response = await self.httpx_client.request( + method=method, + url=_request_url, + headers=_request_headers, + params=_encoded_params if _encoded_params else None, + json=json_body, + data=data_body, + content=content, + files=request_files, + timeout=timeout, + ) + except (httpx.ConnectError, httpx.RemoteProtocolError): + if retries < max_retries: + await asyncio.sleep(_retry_timeout_from_retries(retries=retries)) + return await self.request( + path=path, + method=method, + base_url=base_url, + params=params, + json=json, + data=data, + content=content, + files=files, + headers=headers, + request_options=request_options, + retries=retries + 1, + omit=omit, + force_multipart=force_multipart, + ) + raise + if _should_retry(response=response): if retries < max_retries: await asyncio.sleep(_retry_timeout(response=response, retries=retries)) @@ -649,12 +827,14 @@ async def request( base_url=base_url, params=params, json=json, + data=data, content=content, files=files, headers=headers, request_options=request_options, retries=retries + 1, omit=omit, + force_multipart=force_multipart, ) if self.logger.is_debug(): @@ -698,14 +878,18 @@ async def stream( request_options: typing.Optional[RequestOptions] = None, retries: int = 0, omit: typing.Optional[typing.Any] = None, + optional_body: bool = False, force_multipart: typing.Optional[bool] = None, ) -> typing.AsyncIterator[httpx.Response]: base_url = self.get_base_url(base_url) - timeout = ( - request_options.get("timeout_in_seconds") + _timeout = ( + request_options.get("timeout") + if request_options is not None and request_options.get("timeout") is not None + else request_options.get("timeout_in_seconds") if request_options is not None and request_options.get("timeout_in_seconds") is not None else self.base_timeout() ) + timeout = _timeout if _timeout is not None else httpx.USE_CLIENT_DEFAULT request_files: typing.Optional[RequestFiles] = ( convert_file_dict_to_httpx_tuples(remove_omit_from_dict(remove_none_from_dict(files), omit)) @@ -716,7 +900,9 @@ async def stream( if (request_files is None or len(request_files) == 0) and force_multipart: request_files = FORCE_MULTIPART - json_body, data_body = get_request_body(json=json, data=data, request_options=request_options, omit=omit) + json_body, data_body = get_request_body( + json=json, data=data, request_options=request_options, omit=omit, optional_body=optional_body + ) data_body = _maybe_filter_none_from_multipart_data(data_body, request_files, force_multipart) @@ -746,13 +932,16 @@ async def stream( _request_url = _build_url(base_url, path) _request_headers = jsonable_encoder( remove_none_from_dict( - { - **_headers, - **(headers if headers is not None else {}), - **(request_options.get("additional_headers", {}) if request_options is not None else {}), - } + _merge_headers( + _headers, + headers, + request_options.get("additional_headers") if request_options is not None else None, + ) ) ) + _request_headers = drop_content_type_without_body( + _request_headers, json_body=json_body, data_body=data_body, optional_body=optional_body + ) if self.logger.is_debug(): self.logger.debug( diff --git a/src/zep_cloud/core/http_response.py b/src/zep_cloud/core/http_response.py index 00bb1096..9aa1e188 100644 --- a/src/zep_cloud/core/http_response.py +++ b/src/zep_cloud/core/http_response.py @@ -24,6 +24,10 @@ def headers(self) -> Dict[str, str]: def status_code(self) -> int: return self._response.status_code + @property + def response(self) -> httpx.Response: + return self._response + class HttpResponse(Generic[T], BaseHttpResponse): """HTTP response wrapper that exposes response headers and data.""" diff --git a/src/zep_cloud/core/http_sse/_api.py b/src/zep_cloud/core/http_sse/_api.py index f900b3b6..9ca5602c 100644 --- a/src/zep_cloud/core/http_sse/_api.py +++ b/src/zep_cloud/core/http_sse/_api.py @@ -1,29 +1,82 @@ # This file was auto-generated by Fern from our API Definition. +import codecs import re +import time from contextlib import asynccontextmanager, contextmanager -from typing import Any, AsyncGenerator, AsyncIterator, Iterator, cast +from typing import ( + Any, + AsyncContextManager, + AsyncGenerator, + AsyncIterator, + Callable, + ContextManager, + Iterator, + Optional, +) +import anyio import httpx from ._decoders import SSEDecoder from ._exceptions import SSEError from ._models import ServerSentEvent +MAX_LINE_SIZE: int = 1_048_576 # 1 MiB +# Reconnection defaults, mirroring the TypeScript SDK's Stream implementation. +DEFAULT_MAX_RECONNECTION_ATTEMPTS: int = 5 +DEFAULT_RECONNECT_DELAY_MS: int = 1_000 +MAX_RECONNECT_DELAY_MS: int = 30_000 + + +# A reconnect callback re-issues the original request (with a ``Last-Event-ID`` +# header set to the supplied event id) and returns a *context manager* yielding +# a fresh streaming ``httpx.Response``. Sync clients supply a sync context +# manager; async clients supply an async one. class EventSource: - def __init__(self, response: httpx.Response) -> None: + def __init__( + self, + response: httpx.Response, + *, + resumable: bool = False, + stream_reconnection_enabled: bool = True, + max_stream_reconnection_attempts: Optional[int] = None, + stream_terminator: Optional[str] = None, + reconnect: Optional[Callable[[str], Any]] = None, + ) -> None: self._response = response + self._resumable = resumable + self._stream_reconnection_enabled = stream_reconnection_enabled + self._max_stream_reconnection_attempts = max_stream_reconnection_attempts + self._stream_terminator = stream_terminator + self._reconnect = reconnect + + @staticmethod + def _is_event_stream(response: httpx.Response) -> bool: + content_type = response.headers.get("content-type", "").partition(";")[0] + return "text/event-stream" in content_type def _check_content_type(self) -> None: - content_type = self._response.headers.get("content-type", "").partition(";")[0] - if "text/event-stream" not in content_type: + if not self._is_event_stream(self._response): + content_type = self._response.headers.get("content-type", "").partition(";")[0] raise SSEError( f"Expected response header Content-Type to contain 'text/event-stream', got {content_type!r}" ) - def _get_charset(self) -> str: + def _is_reconnect_response_usable(self, response: httpx.Response) -> bool: + """Whether a reconnected response can be resumed as an SSE stream. + + ``httpx.stream`` does not raise on non-success status, so a resume that + returns an error page (e.g. ``200 text/html`` or a ``500`` body) would + otherwise be parsed as SSE and yield garbage/zero events. Such a + response is treated as a failed attempt (back off and retry) instead. + """ + return response.status_code < 400 and self._is_event_stream(response) + + def _get_charset(self, response: Optional[httpx.Response] = None) -> str: """Extract charset from Content-Type header, fallback to UTF-8.""" - content_type = self._response.headers.get("content-type", "") + resolved = response if response is not None else self._response + content_type = resolved.headers.get("content-type", "") # Parse charset parameter using regex charset_match = re.search(r"charset=([^;\s]+)", content_type, re.IGNORECASE) @@ -45,46 +98,336 @@ def _get_charset(self) -> str: def response(self) -> httpx.Response: return self._response - def iter_sse(self) -> Iterator[ServerSentEvent]: - self._check_content_type() - decoder = SSEDecoder() - charset = self._get_charset() - - buffer = "" - for chunk in self._response.iter_bytes(): - # Decode chunk using detected charset - text_chunk = chunk.decode(charset, errors="replace") - buffer += text_chunk - - # Process complete lines - while "\n" in buffer: - line, buffer = buffer.split("\n", 1) - line = line.rstrip("\r") + @staticmethod + def _normalize_sse_line_endings(buf: str) -> str: + """Normalize line endings per the SSE spec (\\r\\n → \\n, bare \\r → \\n). + + A trailing \\r is preserved because it may pair with a leading \\n in + the next chunk to form a single \\r\\n terminator. + """ + buf = buf.replace("\r\n", "\n") + if buf.endswith("\r"): + return buf[:-1].replace("\r", "\n") + "\r" + return buf.replace("\r", "\n") + + def _new_text_decoder(self, response: Optional[httpx.Response] = None) -> "codecs.IncrementalDecoder": + return codecs.getincrementaldecoder(self._get_charset(response))(errors="replace") + + def _reconnect_applicable(self) -> bool: + """Whether reconnection is configured for this stream at all. + + This is the terminator-gating half of the reconnect decision, kept + separate from :meth:`_should_reconnect` (which additionally requires a + last *dispatched* id and an unexhausted attempt budget). The split lets + a mid-stream transport error terminate consistently: + - a stream that can never reconnect (non-resumable, no terminator, + disabled, or no callback) must re-raise the error to the caller, so a + truncated stream is not mistaken for a clean completion; + - a resumable stream that has merely run out of attempts (or has no id + to resume from) ends cleanly — the same way an exhausted empty/error + -body resume already does, matching the TypeScript ``return``. + """ + return ( + self._resumable + and self._stream_terminator is not None + and self._stream_reconnection_enabled + and self._reconnect is not None + ) + + def _should_reconnect(self, last_dispatched_id: Optional[str], reconnect_attempts: int) -> bool: + """Decide whether a prematurely-ended stream should be reconnected. + + Mirrors the TypeScript ``shouldReconnect`` gating: + - only resumable SSE endpoints with a configured terminator, reconnect + enabled, and a reconnect callback are eligible (see + :meth:`_reconnect_applicable`); + - a last *dispatched* event id must exist to resume from; + - the consecutive-failed-attempt cap must not be exceeded. + """ + if not self._reconnect_applicable(): + return False + if not last_dispatched_id: + return False + max_attempts = ( + self._max_stream_reconnection_attempts + if self._max_stream_reconnection_attempts is not None + else DEFAULT_MAX_RECONNECTION_ATTEMPTS + ) + if reconnect_attempts >= max_attempts: + return False + return True + + def _reconnect_delay_seconds(self, last_retry: Optional[int]) -> float: + """Backoff before a reconnect. + + Uses the server's most recent ``retry:`` directive (milliseconds) when + present, otherwise a default of ``DEFAULT_RECONNECT_DELAY_MS``, clamped + to ``MAX_RECONNECT_DELAY_MS``. + """ + base_ms = last_retry if (last_retry is not None and last_retry > 0) else DEFAULT_RECONNECT_DELAY_MS + return min(base_ms, MAX_RECONNECT_DELAY_MS) / 1000.0 + + def _sleep_before_reconnect(self, last_retry: Optional[int]) -> None: + # ``time.sleep`` blocks the calling thread but remains interruptible by + # signals (e.g. ``KeyboardInterrupt``), which propagate out and abort + # the reconnect without issuing another request. + time.sleep(self._reconnect_delay_seconds(last_retry)) + + async def _asleep_before_reconnect(self, last_retry: Optional[int]) -> None: + # ``anyio.sleep`` is cancellation-aware: if the consumer cancels the task + # or closes the async generator mid-delay, this raises (and no further + # request is issued) instead of blocking for the whole interval. + await anyio.sleep(self._reconnect_delay_seconds(last_retry)) + + def _decode_response( + self, + response: httpx.Response, + decoder: SSEDecoder, + text_decoder: "codecs.IncrementalDecoder", + ) -> Iterator[ServerSentEvent]: + buf = "" + for chunk in response.iter_bytes(): + buf += text_decoder.decode(chunk) + buf = self._normalize_sse_line_endings(buf) + + while "\n" in buf: + line, buf = buf.split("\n", 1) sse = decoder.decode(line) - # when we reach a "\n\n" => line = '' - # => decoder will attempt to return an SSE Event if sse is not None: yield sse - # Process any remaining data in buffer - if buffer.strip(): - line = buffer.rstrip("\r") + if len(buf) > MAX_LINE_SIZE: + raise SSEError( + f"SSE line exceeded maximum size of {MAX_LINE_SIZE} characters without encountering a newline" + ) + + yield from self._flush_decoder(buf, decoder, text_decoder) + + async def _adecode_response( + self, + response: httpx.Response, + decoder: SSEDecoder, + text_decoder: "codecs.IncrementalDecoder", + ) -> AsyncGenerator[ServerSentEvent, None]: + buf = "" + async for chunk in response.aiter_bytes(): + buf += text_decoder.decode(chunk) + buf = self._normalize_sse_line_endings(buf) + + while "\n" in buf: + line, buf = buf.split("\n", 1) + sse = decoder.decode(line) + if sse is not None: + yield sse + + if len(buf) > MAX_LINE_SIZE: + raise SSEError( + f"SSE line exceeded maximum size of {MAX_LINE_SIZE} characters without encountering a newline" + ) + + for sse in self._flush_decoder(buf, decoder, text_decoder): + yield sse + + def _flush_decoder( + self, + buf: str, + decoder: SSEDecoder, + text_decoder: "codecs.IncrementalDecoder", + ) -> Iterator[ServerSentEvent]: + # Flush any remaining bytes from the incremental decoder + buf += text_decoder.decode(b"", final=True) + buf = buf.replace("\r\n", "\n").replace("\r", "\n") + + if len(buf) > MAX_LINE_SIZE: + raise SSEError( + f"SSE line exceeded maximum size of {MAX_LINE_SIZE} characters without encountering a newline" + ) + + while "\n" in buf: + line, buf = buf.split("\n", 1) sse = decoder.decode(line) if sse is not None: yield sse + if buf.strip(): + sse = decoder.decode(buf) + if sse is not None: + yield sse + + def iter_sse(self) -> Iterator[ServerSentEvent]: + self._check_content_type() + decoder = SSEDecoder() + text_decoder = self._new_text_decoder() + + last_dispatched_id: Optional[str] = None + last_retry: Optional[int] = None + # Consecutive failed reconnection attempts. Reset to 0 whenever an event + # is successfully dispatched (reset-on-progress) — matching browser + # `EventSource` semantics: a server that emits >=1 event then drops on + # every connection can reconnect indefinitely. + reconnect_attempts = 0 + + # ``None`` means there is no live stream to read this iteration (e.g. a + # failed reconnect); the loop then re-evaluates the reconnect decision + # without re-reading an exhausted response. + response: Optional[httpx.Response] = self._response + # Context manager for a response we opened ourselves and must close. + # The initial response is owned by the caller, so it starts as None. + owned_cm: Optional[ContextManager[httpx.Response]] = None + try: + while True: + if response is not None: + events = self._decode_response(response, decoder, text_decoder) + while True: + try: + sse = next(events) + except StopIteration: + break + except SSEError: + # A protocol violation (e.g. an oversized line) is a + # genuine error, not a dropped connection; propagate it. + # Listed first because ``SSEError`` subclasses + # ``httpx.TransportError``. + raise + except httpx.TransportError: + # A transport error mid-stream (e.g. the server dropped + # the connection: ``ReadError``/``RemoteProtocolError``) + # is a premature end. Only swallow it when reconnection + # is configured for this stream; otherwise re-raise so a + # non-resumable stream still surfaces the error to the + # caller instead of looking like a clean completion. + # When reconnection is applicable but the attempt budget + # is exhausted, we ``break`` and end cleanly below — the + # same way an exhausted empty/error-body resume does, so + # give-up is consistent regardless of failure shape. + # ``next`` is used rather than ``for`` so this cannot + # swallow a ``GeneratorExit`` raised at a ``yield``. + if not self._reconnect_applicable(): + raise + break + yield sse + if sse.id: + last_dispatched_id = sse.id + if sse.retry is not None: + last_retry = sse.retry + reconnect_attempts = 0 + + if not self._should_reconnect(last_dispatched_id, reconnect_attempts): + return + reconnect_attempts += 1 + + self._sleep_before_reconnect(last_retry) + + # Close the previously-opened reconnect response before opening + # a new one so we never hold more than one extra connection. + if owned_cm is not None: + owned_cm.__exit__(None, None, None) + owned_cm = None + + assert self._reconnect is not None # guaranteed by _should_reconnect + try: + cm: ContextManager[httpx.Response] = self._reconnect(last_dispatched_id or "") + new_response = cm.__enter__() + except Exception: + # A failed reconnect consumes an attempt; back off and retry. + response = None + continue + owned_cm = cm + if new_response is None or not self._is_reconnect_response_usable(new_response): + # Null/empty body or a non-SSE/error response (e.g. 204/304, + # a 500, or an HTML error page): treat as a failed attempt. + response = None + continue + + response = new_response + # Drop any partial event left over from the dropped stream, but + # keep the last event id (per the SSE spec) and start a fresh + # incremental text decoder for the new connection. + decoder.reset_in_progress_event() + text_decoder = self._new_text_decoder(new_response) + finally: + if owned_cm is not None: + owned_cm.__exit__(None, None, None) + async def aiter_sse(self) -> AsyncGenerator[ServerSentEvent, None]: self._check_content_type() decoder = SSEDecoder() - lines = cast(AsyncGenerator[str, None], self._response.aiter_lines()) + text_decoder = self._new_text_decoder() + + last_dispatched_id: Optional[str] = None + last_retry: Optional[int] = None + reconnect_attempts = 0 + + response: Optional[httpx.Response] = self._response + owned_cm: Optional[AsyncContextManager[httpx.Response]] = None try: - async for line in lines: - line = line.rstrip("\n") - sse = decoder.decode(line) - if sse is not None: - yield sse + while True: + if response is not None: + events = self._adecode_response(response, decoder, text_decoder) + while True: + try: + sse = await events.__anext__() + except StopAsyncIteration: + break + except SSEError: + # A protocol violation (e.g. an oversized line) is a + # genuine error, not a dropped connection; propagate it. + # Listed first because ``SSEError`` subclasses + # ``httpx.TransportError``. + raise + except httpx.TransportError: + # A transport error mid-stream (e.g. the server dropped + # the connection: ``ReadError``/``RemoteProtocolError``) + # is a premature end. Only swallow it when reconnection + # is configured for this stream; otherwise re-raise so a + # non-resumable stream still surfaces the error to the + # caller instead of looking like a clean completion. + # When reconnection is applicable but the attempt budget + # is exhausted, we ``break`` and end cleanly below — the + # same way an exhausted empty/error-body resume does, so + # give-up is consistent regardless of failure shape. + if not self._reconnect_applicable(): + raise + break + yield sse + if sse.id: + last_dispatched_id = sse.id + if sse.retry is not None: + last_retry = sse.retry + reconnect_attempts = 0 + + if not self._should_reconnect(last_dispatched_id, reconnect_attempts): + return + reconnect_attempts += 1 + + await self._asleep_before_reconnect(last_retry) + + if owned_cm is not None: + await owned_cm.__aexit__(None, None, None) + owned_cm = None + + assert self._reconnect is not None # guaranteed by _should_reconnect + try: + cm: AsyncContextManager[httpx.Response] = self._reconnect(last_dispatched_id or "") + new_response = await cm.__aenter__() + except Exception: + response = None + continue + owned_cm = cm + if new_response is None or not self._is_reconnect_response_usable(new_response): + response = None + continue + + response = new_response + decoder.reset_in_progress_event() + text_decoder = self._new_text_decoder(new_response) finally: - await lines.aclose() + if owned_cm is not None: + # Shield the close so a cancellation delivered while reading a + # reconnected response still fully tears the connection down + # instead of leaking it until the client is closed. + with anyio.CancelScope(shield=True): + await owned_cm.__aexit__(None, None, None) @contextmanager diff --git a/src/zep_cloud/core/http_sse/_decoders.py b/src/zep_cloud/core/http_sse/_decoders.py index 339b0890..1f6b35ec 100644 --- a/src/zep_cloud/core/http_sse/_decoders.py +++ b/src/zep_cloud/core/http_sse/_decoders.py @@ -12,6 +12,19 @@ def __init__(self) -> None: self._last_event_id = "" self._retry: Optional[int] = None + def reset_in_progress_event(self) -> None: + """Discard any partially-parsed (undispatched) event. + + Used when a stream ends mid-event before reconnecting: the buffered + ``event``/``data``/``retry`` fields of the never-dispatched event must + be dropped so they do not corrupt the first event of the reconnected + stream. Per the SSE spec the last event id is *not* reset here — it + persists across connections. + """ + self._event = "" + self._data = [] + self._retry = None + def decode(self, line: str) -> Optional[ServerSentEvent]: # See: https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation # noqa: E501 diff --git a/src/zep_cloud/core/idempotency.py b/src/zep_cloud/core/idempotency.py new file mode 100644 index 00000000..f6ddf4b8 --- /dev/null +++ b/src/zep_cloud/core/idempotency.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import uuid + + +def generate_idempotency_key() -> str: + return str(uuid.uuid4()) diff --git a/src/zep_cloud/core/jsonable_encoder.py b/src/zep_cloud/core/jsonable_encoder.py index f8beaeaf..f638cc9a 100644 --- a/src/zep_cloud/core/jsonable_encoder.py +++ b/src/zep_cloud/core/jsonable_encoder.py @@ -15,6 +15,7 @@ from pathlib import PurePath from types import GeneratorType from typing import Any, Callable, Dict, List, Optional, Set, Union +from urllib.parse import quote import pydantic from .datetime_utils import serialize_datetime @@ -106,3 +107,27 @@ def fallback_serializer(o: Any) -> Any: return jsonable_encoder(data, custom_encoder=custom_encoder) return to_jsonable_with_fallback(obj, fallback_serializer) + + +def encode_path_param(obj: Any) -> str: + """Encode a value for use in a URL path segment. + + Ensures proper string conversion for all types, including + booleans which need lowercase 'true'/'false' rather than + Python's 'True'/'False'. + """ + if isinstance(obj, bool): + return "true" if obj else "false" + return str(jsonable_encoder(obj)) + + +def quote_path_param(obj: Any) -> str: + """Encode a value for use in a URL path segment, percent-encoding it. + + Same as encode_path_param, except the result is percent-encoded so + that a value containing "/" or ".." cannot change which endpoint + the request resolves to. + """ + if isinstance(obj, bool): + return "true" if obj else "false" + return quote(str(jsonable_encoder(obj)), safe="") diff --git a/src/zep_cloud/core/pagination.py b/src/zep_cloud/core/pagination.py index 760b0899..a4bc1947 100644 --- a/src/zep_cloud/core/pagination.py +++ b/src/zep_cloud/core/pagination.py @@ -3,7 +3,20 @@ from __future__ import annotations from dataclasses import dataclass -from typing import AsyncIterator, Awaitable, Callable, Generic, Iterator, List, Optional, TypeVar +from typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Generic, + Iterator, + List, + Mapping, + Optional, + Sequence, + TypeVar, + get_args, +) # Generic to represent the underlying type of the results within a page T = TypeVar("T") @@ -80,3 +93,73 @@ async def iter_pages(self) -> AsyncIterator[AsyncPager[T, R]]: async def next_page(self) -> Optional[AsyncPager[T, R]]: return await self.get_next() if self.get_next is not None else None + + +def get_nested_page_value(container: Any, path: Sequence[str], default: Any = None) -> Any: + """ + Read a nested paging value (e.g. `options.offset`) from a request parameter that may be + a dict, a model, None, or omitted (`...`). Returns `default` when any segment is missing. + """ + value = container + for key in path: + if value is None or value is ...: + return default + value = value.get(key) if isinstance(value, Mapping) else getattr(value, key, None) + return default if value is None or value is ... else value + + +def with_nested_page_value(container: Any, path: Sequence[str], value: Any, container_type: Any = None) -> Any: + """ + Return a copy of a request parameter with the nested paging value at `path` replaced, + creating omitted containers and keeping every other field. When `container_type` (or the + annotation of the parent model's field) is a model, created containers are built through that + model so field aliases (e.g. `page_offset` -> `pageOffset`) apply on the wire. + """ + if len(path) == 0: + return value + key, rest = path[0], path[1:] + if container is None or container is ...: + return _build_container(container_type, {key: with_nested_page_value(None, rest, value)}) + if isinstance(container, Mapping): + return {**container, key: with_nested_page_value(container.get(key), rest, value)} + updated = with_nested_page_value( + getattr(container, key, None), rest, value, _get_field_annotation(type(container), key) + ) + if hasattr(container, "model_copy"): + return container.model_copy(update={key: updated}) + return container.copy(update={key: updated}) + + +def _build_container(container_type: Any, data: Mapping[str, Any]) -> Any: + model = _find_model_class(container_type) + if model is None: + return data + try: + if hasattr(model, "model_validate"): + return model.model_validate(data) + return model.parse_obj(data) + except (TypeError, ValueError): + return data + + +def _find_model_class(annotation: Any) -> Any: + models = [] + pending = [annotation] + while pending: + candidate = pending.pop() + if isinstance(candidate, type): + if hasattr(candidate, "model_validate") or hasattr(candidate, "parse_obj"): + models.append(candidate) + else: + pending.extend(get_args(candidate)) + return models[0] if len(models) == 1 else None + + +def _get_field_annotation(model: Any, key: str) -> Any: + fields = getattr(model, "model_fields", None) + if isinstance(fields, Mapping): + return fields[key].annotation if key in fields else None + legacy_fields = getattr(model, "__fields__", None) + if isinstance(legacy_fields, Mapping) and key in legacy_fields: + return legacy_fields[key].outer_type_ + return None diff --git a/src/zep_cloud/core/pydantic_utilities.py b/src/zep_cloud/core/pydantic_utilities.py index fea3a08d..70816b99 100644 --- a/src/zep_cloud/core/pydantic_utilities.py +++ b/src/zep_cloud/core/pydantic_utilities.py @@ -5,6 +5,7 @@ import inspect import json import logging +import weakref from collections import defaultdict from dataclasses import asdict from typing import ( @@ -135,111 +136,21 @@ def _decimal_encoder(dec_value: Any) -> Any: Model = TypeVar("Model", bound=pydantic.BaseModel) -def _get_discriminator_and_variants(type_: Type[Any]) -> Tuple[Optional[str], Optional[List[Type[Any]]]]: - """ - Extract the discriminator field name and union variants from a discriminated union type. - Supports Annotated[Union[...], Field(discriminator=...)] patterns. - Returns (discriminator, variants) or (None, None) if not a discriminated union. - """ - origin = typing_extensions.get_origin(type_) - - if origin is typing_extensions.Annotated: - args = typing_extensions.get_args(type_) - if len(args) >= 2: - inner_type = args[0] - # Check annotations for discriminator - discriminator = None - for annotation in args[1:]: - if hasattr(annotation, "discriminator"): - discriminator = getattr(annotation, "discriminator", None) - break - - if discriminator: - inner_origin = typing_extensions.get_origin(inner_type) - if inner_origin is Union: - variants = list(typing_extensions.get_args(inner_type)) - return discriminator, variants - return None, None - - -def _get_field_annotation(model: Type[Any], field_name: str) -> Optional[Type[Any]]: - """Get the type annotation of a field from a Pydantic model.""" - if IS_PYDANTIC_V2: - fields = getattr(model, "model_fields", {}) - field_info = fields.get(field_name) - if field_info: - return cast(Optional[Type[Any]], field_info.annotation) - else: - fields = getattr(model, "__fields__", {}) - field_info = fields.get(field_name) - if field_info: - return cast(Optional[Type[Any]], field_info.outer_type_) - return None - - -def _find_variant_by_discriminator( - variants: List[Type[Any]], - discriminator: str, - discriminator_value: Any, -) -> Optional[Type[Any]]: - """Find the union variant that matches the discriminator value.""" - for variant in variants: - if not (inspect.isclass(variant) and issubclass(variant, pydantic.BaseModel)): - continue - - disc_annotation = _get_field_annotation(variant, discriminator) - if disc_annotation and is_literal_type(disc_annotation): - literal_args = get_args(disc_annotation) - if literal_args and literal_args[0] == discriminator_value: - return variant - return None - - -def _is_string_type(type_: Type[Any]) -> bool: - """Check if a type is str or Optional[str].""" - if type_ is str: - return True - - origin = typing_extensions.get_origin(type_) - if origin is Union: - args = typing_extensions.get_args(type_) - # Optional[str] = Union[str, None] - non_none_args = [a for a in args if a is not type(None)] - if len(non_none_args) == 1 and non_none_args[0] is str: - return True - - return False - - def parse_sse_obj(sse: "ServerSentEvent", type_: Type[T]) -> T: """ Parse a ServerSentEvent into the appropriate type. - Handles two scenarios based on where the discriminator field is located: + This function handles data-level discrimination where the discriminator + (e.g., 'type') is inside the 'data' payload. It parses the SSE data field + as JSON and deserializes it into the target type. - 1. Data-level discrimination: The discriminator (e.g., 'type') is inside the 'data' payload. - The union describes the data content, not the SSE envelope. - -> Returns: json.loads(data) parsed into the type - - Example: ChatStreamResponse with discriminator='type' - Input: ServerSentEvent(event="message", data='{"type": "content-delta", ...}', id="") - Output: ContentDeltaEvent (parsed from data, SSE envelope stripped) - - 2. Event-level discrimination: The discriminator (e.g., 'event') is at the SSE event level. - The union describes the full SSE event structure. - -> Returns: SSE envelope with 'data' field JSON-parsed only if the variant expects non-string - - Example: JobStreamResponse with discriminator='event' - Input: ServerSentEvent(event="ERROR", data='{"code": "FAILED", ...}', id="123") - Output: JobStreamResponse_Error with data as ErrorData object - - But for variants where data is str (like STATUS_UPDATE): - Input: ServerSentEvent(event="STATUS_UPDATE", data='{"status": "processing"}', id="1") - Output: JobStreamResponse_StatusUpdate with data as string (not parsed) + Note: Protocol-level discrimination (where the discriminator comes from + the SSE event: field) is handled at code-generation time and does not + use this function. Args: sse: The ServerSentEvent object to parse - type_: The target discriminated union type + type_: The target type to deserialize into Returns: The parsed object of type T @@ -248,66 +159,82 @@ def parse_sse_obj(sse: "ServerSentEvent", type_: Type[T]) -> T: This function is only available in SDK contexts where http_sse module exists. """ sse_event = asdict(sse) - discriminator, variants = _get_discriminator_and_variants(type_) - - if discriminator is None or variants is None: - # Not a discriminated union - parse the data field as JSON - data_value = sse_event.get("data") - if isinstance(data_value, str) and data_value: - try: - parsed_data = json.loads(data_value) - return parse_obj_as(type_, parsed_data) - except json.JSONDecodeError as e: - _logger.warning( - "Failed to parse SSE data field as JSON: %s, data: %s", - e, - data_value[:100] if len(data_value) > 100 else data_value, - ) - return parse_obj_as(type_, sse_event) - data_value = sse_event.get("data") + if isinstance(data_value, str) and data_value: + try: + parsed_data = json.loads(data_value) + return parse_obj_as(type_, parsed_data) + except json.JSONDecodeError as e: + _logger.warning( + "Failed to parse SSE data field as JSON: %s, data: %s", + e, + data_value[:100] if len(data_value) > 100 else data_value, + ) + return parse_obj_as(type_, sse_event) - # Check if discriminator is at the top level (event-level discrimination) - if discriminator in sse_event: - # Case 2: Event-level discrimination - # Find the matching variant to check if 'data' field needs JSON parsing - disc_value = sse_event.get(discriminator) - matching_variant = _find_variant_by_discriminator(variants, discriminator, disc_value) - - if matching_variant is not None: - # Check what type the variant expects for 'data' - data_type = _get_field_annotation(matching_variant, "data") - if data_type is not None and not _is_string_type(data_type): - # Variant expects non-string data - parse JSON - if isinstance(data_value, str) and data_value: - try: - parsed_data = json.loads(data_value) - new_object = dict(sse_event) - new_object["data"] = parsed_data - return parse_obj_as(type_, new_object) - except json.JSONDecodeError as e: - _logger.warning( - "Failed to parse SSE data field as JSON for event-level discrimination: %s, data: %s", - e, - data_value[:100] if len(data_value) > 100 else data_value, - ) - # Either no matching variant, data is string type, or JSON parse failed - return parse_obj_as(type_, sse_event) - else: - # Case 1: Data-level discrimination - # The discriminator is inside the data payload - extract and parse data only - if isinstance(data_value, str) and data_value: - try: - parsed_data = json.loads(data_value) - return parse_obj_as(type_, parsed_data) - except json.JSONDecodeError as e: - _logger.warning( - "Failed to parse SSE data field as JSON for data-level discrimination: %s, data: %s", - e, - data_value[:100] if len(data_value) > 100 else data_value, - ) - return parse_obj_as(type_, sse_event) +_type_adapter_cache: Dict[int, Any] = {} + + +def _get_type_adapter(type_: Type[Any]) -> Any: + key = id(type_) + adapter = _type_adapter_cache.get(key) + if adapter is None: + adapter = pydantic.TypeAdapter(type_) # type: ignore[attr-defined] + _type_adapter_cache[key] = adapter + return adapter + + +_field_alias_cache: "weakref.WeakKeyDictionary[type, Tuple[Dict[str, str], Tuple[str, ...]]]" = ( + weakref.WeakKeyDictionary() +) + + +def _get_field_aliases(model: type) -> Tuple[Dict[str, str], Tuple[str, ...]]: + """ + Map of field name to Pydantic alias for the fields whose alias differs from their name, together with the + keys that are ambiguous (an alias of one field and the name of another). Computed once per model class. + """ + cached = _field_alias_cache.get(model) + if cached is None: + fields: Mapping[str, Any] = ( + getattr(model, "model_fields", {}) if IS_PYDANTIC_V2 else getattr(model, "__fields__", {}) + ) + name_to_alias: Dict[str, str] = {} + for name, field in fields.items(): + alias = getattr(field, "alias", None) + if alias is not None and alias != name: + name_to_alias[name] = alias + cached = (name_to_alias, tuple(alias for alias in name_to_alias.values() if alias in fields)) + _field_alias_cache[model] = cached + return cached + + +def _coerce_keys_to_aliases(model: type, data: Any) -> Any: + """ + Accept Python field names in input by rewriting them to their Pydantic aliases, + while avoiding silent collisions when a key could refer to multiple fields. + """ + if not isinstance(data, Mapping): + return data + + name_to_alias, ambiguous_keys = _get_field_aliases(model) + for key in ambiguous_keys: + if key in data and name_to_alias.get(key, key) not in data: + raise ValueError( + f"Ambiguous input key '{key}': it is both a field name and an alias. " + "Provide the explicit alias key to disambiguate." + ) + + if not name_to_alias or not any(name in data for name in name_to_alias): + return data if isinstance(data, dict) else dict(data) + + rewritten: Dict[str, Any] = dict(data) + for name, alias in name_to_alias.items(): + if name in data and alias not in rewritten: + rewritten[alias] = rewritten.pop(name) + + return rewritten def parse_obj_as(type_: Type[T], object_: Any) -> T: @@ -319,20 +246,7 @@ def parse_obj_as(type_: Type[T], object_: Any) -> T: # - If the model encodes aliasing only via FieldMetadata annotations, then we MUST pre-dealias because Pydantic # will not recognize those aliases during validation. if inspect.isclass(type_) and issubclass(type_, pydantic.BaseModel): - has_pydantic_aliases = False - if IS_PYDANTIC_V2: - for field_name, field_info in getattr(type_, "model_fields", {}).items(): # type: ignore[attr-defined] - alias = getattr(field_info, "alias", None) - if alias is not None and alias != field_name: - has_pydantic_aliases = True - break - else: - for field in getattr(type_, "__fields__", {}).values(): - alias = getattr(field, "alias", None) - name = getattr(field, "name", None) - if alias is not None and name is not None and alias != name: - has_pydantic_aliases = True - break + has_pydantic_aliases = bool(_get_field_aliases(type_)[0]) dealiased_object = ( object_ @@ -342,8 +256,8 @@ def parse_obj_as(type_: Type[T], object_: Any) -> T: else: dealiased_object = convert_and_respect_annotation_metadata(object_=object_, annotation=type_, direction="read") if IS_PYDANTIC_V2: - adapter = pydantic.TypeAdapter(type_) # type: ignore[attr-defined] - return adapter.validate_python(dealiased_object) + adapter = _get_type_adapter(type_) + return adapter.validate_python(dealiased_object) # type: ignore[no-any-return] return pydantic.parse_obj_as(type_, dealiased_object) @@ -365,39 +279,7 @@ class UniversalBaseModel(pydantic.BaseModel): @pydantic.model_validator(mode="before") # type: ignore[attr-defined] @classmethod def _coerce_field_names_to_aliases(cls, data: Any) -> Any: - """ - Accept Python field names in input by rewriting them to their Pydantic aliases, - while avoiding silent collisions when a key could refer to multiple fields. - """ - if not isinstance(data, Mapping): - return data - - fields = getattr(cls, "model_fields", {}) # type: ignore[attr-defined] - name_to_alias: Dict[str, str] = {} - alias_to_name: Dict[str, str] = {} - - for name, field_info in fields.items(): - alias = getattr(field_info, "alias", None) or name - name_to_alias[name] = alias - if alias != name: - alias_to_name[alias] = name - - # Detect ambiguous keys: a key that is an alias for one field and a name for another. - ambiguous_keys = set(alias_to_name.keys()).intersection(set(name_to_alias.keys())) - for key in ambiguous_keys: - if key in data and name_to_alias[key] not in data: - raise ValueError( - f"Ambiguous input key '{key}': it is both a field name and an alias. " - "Provide the explicit alias key to disambiguate." - ) - - original_keys = set(data.keys()) - rewritten: Dict[str, Any] = dict(data) - for name, alias in name_to_alias.items(): - if alias != name and name in original_keys and alias not in rewritten: - rewritten[alias] = rewritten.pop(name) - - return rewritten + return _coerce_keys_to_aliases(cls, data) @pydantic.model_serializer(mode="plain", when_used="json") # type: ignore[attr-defined] def serialize_model(self) -> Any: # type: ignore[name-defined] @@ -413,37 +295,7 @@ class Config: @pydantic.root_validator(pre=True) def _coerce_field_names_to_aliases(cls, values: Any) -> Any: - """ - Pydantic v1 equivalent of _coerce_field_names_to_aliases. - """ - if not isinstance(values, Mapping): - return values - - fields = getattr(cls, "__fields__", {}) - name_to_alias: Dict[str, str] = {} - alias_to_name: Dict[str, str] = {} - - for name, field in fields.items(): - alias = getattr(field, "alias", None) or name - name_to_alias[name] = alias - if alias != name: - alias_to_name[alias] = name - - ambiguous_keys = set(alias_to_name.keys()).intersection(set(name_to_alias.keys())) - for key in ambiguous_keys: - if key in values and name_to_alias[key] not in values: - raise ValueError( - f"Ambiguous input key '{key}': it is both a field name and an alias. " - "Provide the explicit alias key to disambiguate." - ) - - original_keys = set(values.keys()) - rewritten: Dict[str, Any] = dict(values) - for name, alias in name_to_alias.items(): - if alias != name and name in original_keys and alias not in rewritten: - rewritten[alias] = rewritten.pop(name) - - return rewritten + return _coerce_keys_to_aliases(cls, values) # type: ignore[arg-type] @classmethod def model_construct(cls: Type["Model"], _fields_set: Optional[Set[str]] = None, **values: Any) -> "Model": diff --git a/src/zep_cloud/core/request_options.py b/src/zep_cloud/core/request_options.py index 1b388044..caa6f669 100644 --- a/src/zep_cloud/core/request_options.py +++ b/src/zep_cloud/core/request_options.py @@ -14,7 +14,9 @@ class RequestOptions(typing.TypedDict, total=False): This is used primarily as an optional final parameter for service functions. Attributes: - - timeout_in_seconds: int. The number of seconds to await an API call before timing out. + - timeout: float. The number of seconds to await an API call before timing out. + + - timeout_in_seconds: int. Deprecated alias for `timeout`; both are in seconds. Prefer `timeout`. - max_retries: int. The max number of retries to attempt if the API call fails. @@ -27,9 +29,12 @@ class RequestOptions(typing.TypedDict, total=False): - chunk_size: int. The size, in bytes, to process each chunk of data being streamed back within the response. This equates to leveraging `chunk_size` within `requests` or `httpx`, and is only leveraged for file downloads. """ + timeout: NotRequired[float] timeout_in_seconds: NotRequired[int] max_retries: NotRequired[int] additional_headers: NotRequired[typing.Dict[str, typing.Any]] additional_query_parameters: NotRequired[typing.Dict[str, typing.Any]] additional_body_parameters: NotRequired[typing.Dict[str, typing.Any]] chunk_size: NotRequired[int] + stream_reconnection_enabled: NotRequired[bool] + max_stream_reconnection_attempts: NotRequired[int] diff --git a/src/zep_cloud/core/serialization.py b/src/zep_cloud/core/serialization.py index c36e865c..1d753e26 100644 --- a/src/zep_cloud/core/serialization.py +++ b/src/zep_cloud/core/serialization.py @@ -26,6 +26,75 @@ def __init__(self, *, alias: str) -> None: self.alias = alias +# Resolving type hints (typing.get_type_hints) is expensive because it eval/compiles +# forward-reference annotations. The result is constant for a given type, so we cache it. +# This is critical for hot paths like SSE event parsing, where the same (often large +# discriminated-union) type is converted on every single event. +_type_hints_cache: typing.Dict[typing.Any, typing.Dict[str, typing.Any]] = {} + + +def _get_cached_type_hints(expected_type: typing.Any) -> typing.Dict[str, typing.Any]: + try: + cached = _type_hints_cache.get(expected_type) + except TypeError: + # Unhashable type; resolve without caching. + return _resolve_type_hints(expected_type) + if cached is None: + cached = _resolve_type_hints(expected_type) + _type_hints_cache[expected_type] = cached + return cached + + +def _resolve_type_hints(expected_type: typing.Any) -> typing.Dict[str, typing.Any]: + try: + return typing_extensions.get_type_hints(expected_type, include_extras=True) + except NameError: + # The type contains a circular reference, so we use the __annotations__ attribute directly. + return getattr(expected_type, "__annotations__", {}) + + +# Whether convert_and_respect_annotation_metadata can possibly rewrite anything for a given +# annotation, i.e. whether any reachable model/TypedDict field carries a FieldMetadata alias. +# This is constant per type, so we cache it and use it to short-circuit the recursive walk. +_requires_conversion_cache: typing.Dict[typing.Any, bool] = {} + + +def _requires_conversion(type_: typing.Any) -> bool: + try: + cached = _requires_conversion_cache.get(type_) + except TypeError: + # Unhashable annotation; compute without caching. + return _compute_requires_conversion(type_, set()) + if cached is None: + cached = _compute_requires_conversion(type_, set()) + _requires_conversion_cache[type_] = cached + return cached + + +def _compute_requires_conversion(type_: typing.Any, seen: typing.Set[typing.Any]) -> bool: + clean_type = _remove_annotations(type_) + + try: + if clean_type in seen: + return False + seen = seen | {clean_type} + except TypeError: + # Unhashable type; skip cycle tracking (the type graph is finite in practice). + pass + + # Models / TypedDicts: a field alias here means we must dealias; otherwise recurse into fields. + if (inspect.isclass(clean_type) and issubclass(clean_type, pydantic.BaseModel)) or typing_extensions.is_typeddict( + clean_type + ): + annotations = _get_cached_type_hints(clean_type) + if _get_alias_to_field_name(annotations): + return True + return any(_compute_requires_conversion(hint, seen) for hint in annotations.values()) + + # Containers / unions: recurse into the type arguments (List/Set/Sequence/Dict/Union/etc.). + return any(_compute_requires_conversion(arg, seen) for arg in typing_extensions.get_args(clean_type)) + + def convert_and_respect_annotation_metadata( *, object_: typing.Any, @@ -57,6 +126,13 @@ def convert_and_respect_annotation_metadata( return None if inner_type is None: inner_type = annotation + # The only thing this function ever rewrites is keys that carry a FieldMetadata + # alias. If nothing in the (cached) type graph has such an alias, the conversion is + # a content-identity transform, so we can skip the entire recursive walk. This is + # the hot path for SSE streaming, where a large discriminated union would otherwise + # be traversed on every single event. + if not _requires_conversion(annotation): + return object_ clean_type = _remove_annotations(inner_type) # Pydantic models @@ -160,12 +236,7 @@ def _convert_mapping( direction: typing.Literal["read", "write"], ) -> typing.Mapping[str, object]: converted_object: typing.Dict[str, object] = {} - try: - annotations = typing_extensions.get_type_hints(expected_type, include_extras=True) - except NameError: - # The TypedDict contains a circular reference, so - # we use the __annotations__ attribute directly. - annotations = getattr(expected_type, "__annotations__", {}) + annotations = _get_cached_type_hints(expected_type) aliases_to_field_names = _get_alias_to_field_name(annotations) for key, value in object_.items(): if direction == "read" and key in aliases_to_field_names: @@ -221,12 +292,12 @@ def _remove_annotations(type_: typing.Any) -> typing.Any: def get_alias_to_field_mapping(type_: typing.Any) -> typing.Dict[str, str]: - annotations = typing_extensions.get_type_hints(type_, include_extras=True) + annotations = _get_cached_type_hints(type_) return _get_alias_to_field_name(annotations) def get_field_to_alias_mapping(type_: typing.Any) -> typing.Dict[str, str]: - annotations = typing_extensions.get_type_hints(type_, include_extras=True) + annotations = _get_cached_type_hints(type_) return _get_field_to_alias_name(annotations) diff --git a/src/zep_cloud/debug_log/__init__.py b/src/zep_cloud/debug_log/__init__.py new file mode 100644 index 00000000..5cde0202 --- /dev/null +++ b/src/zep_cloud/debug_log/__init__.py @@ -0,0 +1,4 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + diff --git a/src/zep_cloud/debug_log/client.py b/src/zep_cloud/debug_log/client.py new file mode 100644 index 00000000..2278329b --- /dev/null +++ b/src/zep_cloud/debug_log/client.py @@ -0,0 +1,108 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.request_options import RequestOptions +from ..types.debug_logging_enablement import DebugLoggingEnablement +from .raw_client import AsyncRawDebugLogClient, RawDebugLogClient + + +class DebugLogClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawDebugLogClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawDebugLogClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawDebugLogClient + """ + return self._raw_client + + def enable( + self, *, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None + ) -> DebugLoggingEnablement: + """ + Enables debug logging for the project for one hour, or for 24 hours on the Enterprise plan. Episodes ingested while debug logging is enabled have a debug log (see `graph.episode.get_debug_logs`). On the Flex, Flex Plus, and Enterprise plans, the operation also enables ingestion tracing (see `graph.episode.list_ingestion_traces`); `ingestion_trace_enabled` reports the result. A repeated call starts the duration again. + + Parameters + ---------- + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + DebugLoggingEnablement + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.debug_log.enable() + """ + _response = self._raw_client.enable(idempotency_key=idempotency_key, request_options=request_options) + return _response.data + + +class AsyncDebugLogClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawDebugLogClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawDebugLogClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawDebugLogClient + """ + return self._raw_client + + async def enable( + self, *, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None + ) -> DebugLoggingEnablement: + """ + Enables debug logging for the project for one hour, or for 24 hours on the Enterprise plan. Episodes ingested while debug logging is enabled have a debug log (see `graph.episode.get_debug_logs`). On the Flex, Flex Plus, and Enterprise plans, the operation also enables ingestion tracing (see `graph.episode.list_ingestion_traces`); `ingestion_trace_enabled` reports the result. A repeated call starts the duration again. + + Parameters + ---------- + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + DebugLoggingEnablement + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.debug_log.enable() + + + asyncio.run(main()) + """ + _response = await self._raw_client.enable(idempotency_key=idempotency_key, request_options=request_options) + return _response.data diff --git a/src/zep_cloud/debug_log/raw_client.py b/src/zep_cloud/debug_log/raw_client.py new file mode 100644 index 00000000..dd41cb2d --- /dev/null +++ b/src/zep_cloud/debug_log/raw_client.py @@ -0,0 +1,192 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ..core.api_error import ApiError as core_api_error_ApiError +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.http_response import AsyncHttpResponse, HttpResponse +from ..core.idempotency import generate_idempotency_key +from ..core.parse_error import ParsingError +from ..core.pydantic_utilities import parse_obj_as +from ..core.request_options import RequestOptions +from ..errors.bad_request_error import BadRequestError +from ..errors.forbidden_error import ForbiddenError +from ..errors.unauthorized_error import UnauthorizedError +from ..types.api_error import ApiError as types_api_error_ApiError +from ..types.debug_logging_enablement import DebugLoggingEnablement +from pydantic import ValidationError + + +class RawDebugLogClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def enable( + self, *, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[DebugLoggingEnablement]: + """ + Enables debug logging for the project for one hour, or for 24 hours on the Enterprise plan. Episodes ingested while debug logging is enabled have a debug log (see `graph.episode.get_debug_logs`). On the Flex, Flex Plus, and Enterprise plans, the operation also enables ingestion tracing (see `graph.episode.list_ingestion_traces`); `ingestion_trace_enabled` reports the result. A repeated call starts the duration again. + + Parameters + ---------- + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[DebugLoggingEnablement] + OK + """ + _response = self._client_wrapper.httpx_client.request( + "debug-logs/enable", + method="POST", + headers={ + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + DebugLoggingEnablement, + parse_obj_as( + type_=DebugLoggingEnablement, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + +class AsyncRawDebugLogClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def enable( + self, *, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[DebugLoggingEnablement]: + """ + Enables debug logging for the project for one hour, or for 24 hours on the Enterprise plan. Episodes ingested while debug logging is enabled have a debug log (see `graph.episode.get_debug_logs`). On the Flex, Flex Plus, and Enterprise plans, the operation also enables ingestion tracing (see `graph.episode.list_ingestion_traces`); `ingestion_trace_enabled` reports the result. A repeated call starts the duration again. + + Parameters + ---------- + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[DebugLoggingEnablement] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + "debug-logs/enable", + method="POST", + headers={ + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + DebugLoggingEnablement, + parse_obj_as( + type_=DebugLoggingEnablement, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) diff --git a/src/zep_cloud/errors/__init__.py b/src/zep_cloud/errors/__init__.py index b6b9eb9e..a98dbc3f 100644 --- a/src/zep_cloud/errors/__init__.py +++ b/src/zep_cloud/errors/__init__.py @@ -6,17 +6,25 @@ from importlib import import_module if typing.TYPE_CHECKING: + from .bad_gateway_error import BadGatewayError from .bad_request_error import BadRequestError from .conflict_error import ConflictError + from .content_too_large_error import ContentTooLargeError from .forbidden_error import ForbiddenError from .not_found_error import NotFoundError + from .service_unavailable_error import ServiceUnavailableError from .unauthorized_error import UnauthorizedError + from .unprocessable_entity_error import UnprocessableEntityError _dynamic_imports: typing.Dict[str, str] = { + "BadGatewayError": ".bad_gateway_error", "BadRequestError": ".bad_request_error", "ConflictError": ".conflict_error", + "ContentTooLargeError": ".content_too_large_error", "ForbiddenError": ".forbidden_error", "NotFoundError": ".not_found_error", + "ServiceUnavailableError": ".service_unavailable_error", "UnauthorizedError": ".unauthorized_error", + "UnprocessableEntityError": ".unprocessable_entity_error", } @@ -41,4 +49,14 @@ def __dir__(): return sorted(lazy_attrs) -__all__ = ["BadRequestError", "ConflictError", "ForbiddenError", "NotFoundError", "UnauthorizedError"] +__all__ = [ + "BadGatewayError", + "BadRequestError", + "ConflictError", + "ContentTooLargeError", + "ForbiddenError", + "NotFoundError", + "ServiceUnavailableError", + "UnauthorizedError", + "UnprocessableEntityError", +] diff --git a/src/zep_cloud/errors/bad_gateway_error.py b/src/zep_cloud/errors/bad_gateway_error.py new file mode 100644 index 00000000..d22e8f56 --- /dev/null +++ b/src/zep_cloud/errors/bad_gateway_error.py @@ -0,0 +1,11 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core.api_error import ApiError as core_api_error_ApiError +from ..types.api_error import ApiError as types_api_error_ApiError + + +class BadGatewayError(core_api_error_ApiError): + def __init__(self, body: types_api_error_ApiError, headers: typing.Optional[typing.Dict[str, str]] = None): + super().__init__(status_code=502, headers=headers, body=body) diff --git a/src/zep_cloud/errors/content_too_large_error.py b/src/zep_cloud/errors/content_too_large_error.py new file mode 100644 index 00000000..4333c399 --- /dev/null +++ b/src/zep_cloud/errors/content_too_large_error.py @@ -0,0 +1,11 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core.api_error import ApiError as core_api_error_ApiError +from ..types.api_error import ApiError as types_api_error_ApiError + + +class ContentTooLargeError(core_api_error_ApiError): + def __init__(self, body: types_api_error_ApiError, headers: typing.Optional[typing.Dict[str, str]] = None): + super().__init__(status_code=413, headers=headers, body=body) diff --git a/src/zep_cloud/errors/service_unavailable_error.py b/src/zep_cloud/errors/service_unavailable_error.py new file mode 100644 index 00000000..75c14a8d --- /dev/null +++ b/src/zep_cloud/errors/service_unavailable_error.py @@ -0,0 +1,11 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core.api_error import ApiError as core_api_error_ApiError +from ..types.api_error import ApiError as types_api_error_ApiError + + +class ServiceUnavailableError(core_api_error_ApiError): + def __init__(self, body: types_api_error_ApiError, headers: typing.Optional[typing.Dict[str, str]] = None): + super().__init__(status_code=503, headers=headers, body=body) diff --git a/src/zep_cloud/errors/unprocessable_entity_error.py b/src/zep_cloud/errors/unprocessable_entity_error.py new file mode 100644 index 00000000..5f95f963 --- /dev/null +++ b/src/zep_cloud/errors/unprocessable_entity_error.py @@ -0,0 +1,11 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core.api_error import ApiError as core_api_error_ApiError +from ..types.api_error import ApiError as types_api_error_ApiError + + +class UnprocessableEntityError(core_api_error_ApiError): + def __init__(self, body: types_api_error_ApiError, headers: typing.Optional[typing.Dict[str, str]] = None): + super().__init__(status_code=422, headers=headers, body=body) diff --git a/src/zep_cloud/graph/__init__.py b/src/zep_cloud/graph/__init__.py index d586c4f7..3cdf6b6c 100644 --- a/src/zep_cloud/graph/__init__.py +++ b/src/zep_cloud/graph/__init__.py @@ -6,18 +6,41 @@ from importlib import import_module if typing.TYPE_CHECKING: - from .types import V4GraphContextRequestRecencyBias, V4SubgraphRequestDirection - from . import document_summary, edge, episode, node, observation, thread_summary - from .episode import V4AddEpisodeRequestType - from .node import V4NeighborsRequestDirection + from .types import ( + GraphContextRequestRecencyBias, + GraphListRequestOrder, + GraphListRequestOrderBy, + SubgraphRequestDirection, + ) + from . import document_summary, edge, episode, hyperedge, node, observation, thread_summary + from .episode import AddEpisodeRequestType, EpisodeListRequestOrder, EpisodeListRequestOrderBy + from .hyperedge import HyperedgeListRequestOrder, HyperedgeListRequestOrderBy + from .node import ( + NeighborsRequestDirection, + NodeListNeighborsRequestOrder, + NodeListNeighborsRequestOrderBy, + NodeListRequestOrder, + NodeListRequestOrderBy, + ) _dynamic_imports: typing.Dict[str, str] = { - "V4AddEpisodeRequestType": ".episode", - "V4GraphContextRequestRecencyBias": ".types", - "V4NeighborsRequestDirection": ".node", - "V4SubgraphRequestDirection": ".types", + "AddEpisodeRequestType": ".episode", + "EpisodeListRequestOrder": ".episode", + "EpisodeListRequestOrderBy": ".episode", + "GraphContextRequestRecencyBias": ".types", + "GraphListRequestOrder": ".types", + "GraphListRequestOrderBy": ".types", + "HyperedgeListRequestOrder": ".hyperedge", + "HyperedgeListRequestOrderBy": ".hyperedge", + "NeighborsRequestDirection": ".node", + "NodeListNeighborsRequestOrder": ".node", + "NodeListNeighborsRequestOrderBy": ".node", + "NodeListRequestOrder": ".node", + "NodeListRequestOrderBy": ".node", + "SubgraphRequestDirection": ".types", "document_summary": ".document_summary", "edge": ".edge", "episode": ".episode", + "hyperedge": ".hyperedge", "node": ".node", "observation": ".observation", "thread_summary": ".thread_summary", @@ -46,13 +69,24 @@ def __dir__(): __all__ = [ - "V4AddEpisodeRequestType", - "V4GraphContextRequestRecencyBias", - "V4NeighborsRequestDirection", - "V4SubgraphRequestDirection", + "AddEpisodeRequestType", + "EpisodeListRequestOrder", + "EpisodeListRequestOrderBy", + "GraphContextRequestRecencyBias", + "GraphListRequestOrder", + "GraphListRequestOrderBy", + "HyperedgeListRequestOrder", + "HyperedgeListRequestOrderBy", + "NeighborsRequestDirection", + "NodeListNeighborsRequestOrder", + "NodeListNeighborsRequestOrderBy", + "NodeListRequestOrder", + "NodeListRequestOrderBy", + "SubgraphRequestDirection", "document_summary", "edge", "episode", + "hyperedge", "node", "observation", "thread_summary", diff --git a/src/zep_cloud/graph/client.py b/src/zep_cloud/graph/client.py index 51b998f5..ed20fa74 100644 --- a/src/zep_cloud/graph/client.py +++ b/src/zep_cloud/graph/client.py @@ -8,7 +8,10 @@ from ..core.pagination import AsyncPager, SyncPager from ..core.request_options import RequestOptions from ..types.async_result import AsyncResult +from ..types.clone_graph_request import CloneGraphRequest from ..types.clone_graph_result import CloneGraphResult +from ..types.content_policy_event import ContentPolicyEvent +from ..types.content_policy_event_page import ContentPolicyEventPage from ..types.custom_instruction import CustomInstruction from ..types.edge import Edge from ..types.edge_page import EdgePage @@ -17,6 +20,8 @@ from ..types.episode import Episode from ..types.episode_page import EpisodePage from ..types.graph import Graph +from ..types.graph_content_policy import GraphContentPolicy +from ..types.graph_content_policy_request import GraphContentPolicyRequest from ..types.graph_context_response import GraphContextResponse from ..types.graph_delete_result import GraphDeleteResult from ..types.graph_page import GraphPage @@ -29,18 +34,21 @@ from ..types.observation_type import ObservationType from ..types.ontology import Ontology from ..types.search_filters import SearchFilters +from ..types.search_request_reranker import SearchRequestReranker from ..types.subgraph_response import SubgraphResponse from ..types.thread_summary import ThreadSummary from ..types.thread_summary_page import ThreadSummaryPage -from ..types.v4search_request_reranker import V4SearchRequestReranker from .raw_client import AsyncRawGraphClient, RawGraphClient -from .types.v4graph_context_request_recency_bias import V4GraphContextRequestRecencyBias -from .types.v4subgraph_request_direction import V4SubgraphRequestDirection +from .types.graph_context_request_recency_bias import GraphContextRequestRecencyBias +from .types.graph_list_request_order import GraphListRequestOrder +from .types.graph_list_request_order_by import GraphListRequestOrderBy +from .types.subgraph_request_direction import SubgraphRequestDirection if typing.TYPE_CHECKING: from .document_summary.client import AsyncDocumentSummaryClient, DocumentSummaryClient from .edge.client import AsyncEdgeClient, EdgeClient from .episode.client import AsyncEpisodeClient, EpisodeClient + from .hyperedge.client import AsyncHyperedgeClient, HyperedgeClient from .node.client import AsyncNodeClient, NodeClient from .observation.client import AsyncObservationClient, ObservationClient from .thread_summary.client import AsyncThreadSummaryClient, ThreadSummaryClient @@ -55,6 +63,7 @@ def __init__(self, *, client_wrapper: SyncClientWrapper): self._document_summary: typing.Optional[DocumentSummaryClient] = None self._episode: typing.Optional[EpisodeClient] = None self._edge: typing.Optional[EdgeClient] = None + self._hyperedge: typing.Optional[HyperedgeClient] = None self._node: typing.Optional[NodeClient] = None self._observation: typing.Optional[ObservationClient] = None self._thread_summary: typing.Optional[ThreadSummaryClient] = None @@ -73,8 +82,8 @@ def with_raw_response(self) -> RawGraphClient: def create( self, *, + content_policy: typing.Optional[GraphContentPolicyRequest] = OMIT, description: typing.Optional[str] = OMIT, - graph_id: typing.Optional[str] = OMIT, name: typing.Optional[str] = OMIT, time_zone: typing.Optional[str] = OMIT, idempotency_key: typing.Optional[str] = None, @@ -83,12 +92,14 @@ def create( """ Parameters ---------- + content_policy : typing.Optional[GraphContentPolicyRequest] + Content policy additions for the graph. The graph binds the current + project content policy plus these additions, and the binding does not + change after creation. + description : typing.Optional[str] A description of the graph. - graph_id : typing.Optional[str] - An optional developer-assigned identifier for the graph. - name : typing.Optional[str] A display name for the graph. @@ -115,8 +126,8 @@ def create( client.graph.create() """ _response = self._raw_client.create( + content_policy=content_policy, description=description, - graph_id=graph_id, name=name, time_zone=time_zone, idempotency_key=idempotency_key, @@ -129,10 +140,9 @@ def list( *, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, - order_by: typing.Optional[str] = None, - order: typing.Optional[str] = None, + order_by: typing.Optional[GraphListRequestOrderBy] = None, + order: typing.Optional[GraphListRequestOrder] = None, search: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Graph, GraphPage]: """ @@ -144,18 +154,16 @@ def list( cursor : typing.Optional[str] Opaque page cursor - order_by : typing.Optional[str] + order_by : typing.Optional[GraphListRequestOrderBy] Sort field - order : typing.Optional[str] + order : typing.Optional[GraphListRequestOrder] asc or desc search : typing.Optional[str] Filters results to graphs whose name, description, or graph ID contains this text. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -171,12 +179,7 @@ def list( client = Zep( api_key="YOUR_API_KEY", ) - response = client.graph.list( - limit=1, - cursor="cursor", - order_by="order_by", - order="order", - ) + response = client.graph.list() for item in response: yield item # alternatively, you can paginate page-by-page @@ -184,13 +187,7 @@ def list( yield page """ return self._raw_client.list( - limit=limit, - cursor=cursor, - order_by=order_by, - order=order, - search=search, - idempotency_key=idempotency_key, - request_options=request_options, + limit=limit, cursor=cursor, order_by=order_by, order=order, search=search, request_options=request_options ) def lookup( @@ -199,7 +196,6 @@ def lookup( graph_id: typing.Optional[str] = OMIT, thread_id: typing.Optional[str] = OMIT, user_id: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> Graph: """ @@ -217,8 +213,6 @@ def lookup( The developer-assigned user ID to resolve to a UUID. Mutually exclusive with thread_id and graph_id. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -237,11 +231,7 @@ def lookup( client.graph.lookup() """ _response = self._raw_client.lookup( - graph_id=graph_id, - thread_id=thread_id, - user_id=user_id, - idempotency_key=idempotency_key, - request_options=request_options, + graph_id=graph_id, thread_id=thread_id, user_id=user_id, request_options=request_options ) return _response.data @@ -373,7 +363,7 @@ def clone( self, graph_uuid: str, *, - target_graph_id: typing.Optional[str] = OMIT, + request: CloneGraphRequest, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> CloneGraphResult: @@ -383,8 +373,7 @@ def clone( graph_uuid : str Graph UUID - target_graph_id : typing.Optional[str] - An optional name for the cloned graph. + request : CloneGraphRequest idempotency_key : typing.Optional[str] @@ -405,16 +394,101 @@ def clone( ) client.graph.clone( graph_uuid="graph_uuid", + request={"key": "value"}, ) """ _response = self._raw_client.clone( - graph_uuid, - target_graph_id=target_graph_id, - idempotency_key=idempotency_key, - request_options=request_options, + graph_uuid, request=request, idempotency_key=idempotency_key, request_options=request_options + ) + return _response.data + + def get_content_policy( + self, graph_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> GraphContentPolicy: + """ + Returns the content policy the graph bound at creation. The policy of a graph does not change after creation. A graph without a content policy returns revision 0 with no categories and no rules. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + GraphContentPolicy + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.graph.get_content_policy( + graph_uuid="graph_uuid", ) + """ + _response = self._raw_client.get_content_policy(graph_uuid, request_options=request_options) return _response.data + def list_content_policy_events( + self, + graph_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[ContentPolicyEvent, ContentPolicyEventPage]: + """ + Lists the content policy decisions recorded for a graph, newest first. Each event carries identifiers only. A graph without a content policy returns an empty list. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + filters : typing.Optional[typing.Dict[str, typing.Any]] + Exact-match filters. Supported keys: episode_uuid and drop_reason. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[ContentPolicyEvent, ContentPolicyEventPage] + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + response = client.graph.list_content_policy_events( + graph_uuid="graph_uuid", + ) + for item in response: + yield item + # alternatively, you can paginate page-by-page + for page in response.iter_pages(): + yield page + """ + return self._raw_client.list_content_policy_events( + graph_uuid, limit=limit, cursor=cursor, filters=filters, request_options=request_options + ) + def get_context( self, graph_uuid: str, @@ -423,9 +497,8 @@ def get_context( filters: typing.Optional[SearchFilters] = OMIT, include_results: typing.Optional[bool] = OMIT, max_characters: typing.Optional[int] = OMIT, - recency_bias: typing.Optional[V4GraphContextRequestRecencyBias] = OMIT, + recency_bias: typing.Optional[GraphContextRequestRecencyBias] = OMIT, template_uuid: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> GraphContextResponse: """ @@ -447,14 +520,12 @@ def get_context( max_characters : typing.Optional[int] The maximum number of characters in the assembled context block. - recency_bias : typing.Optional[V4GraphContextRequestRecencyBias] + recency_bias : typing.Optional[GraphContextRequestRecencyBias] Adjusts result selection to favor more recent graph data. template_uuid : typing.Optional[str] The UUID of a context template used to render the context block. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -483,7 +554,6 @@ def get_context( max_characters=max_characters, recency_bias=recency_bias, template_uuid=template_uuid, - idempotency_key=idempotency_key, request_options=request_options, ) return _response.data @@ -696,6 +766,7 @@ def set_ontology( graph_uuid: str, *, edge_types: typing.Optional[typing.Sequence[EdgeType]] = OMIT, + entity_type_hierarchy: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, entity_types: typing.Optional[typing.Sequence[EntityType]] = OMIT, inherited: typing.Optional[bool] = OMIT, idempotency_key: typing.Optional[str] = None, @@ -710,6 +781,9 @@ def set_ontology( edge_types : typing.Optional[typing.Sequence[EdgeType]] The edge types defined in the ontology in effect at this scope. + entity_type_hierarchy : typing.Optional[typing.Dict[str, typing.Any]] + The entity type hierarchy (spec ontology-1). Omitted when the ontology is flat. + entity_types : typing.Optional[typing.Sequence[EntityType]] The entity types defined in the ontology in effect at this scope. @@ -741,6 +815,7 @@ def set_ontology( _response = self._raw_client.set_ontology( graph_uuid, edge_types=edge_types, + entity_type_hierarchy=entity_type_hierarchy, entity_types=entity_types, inherited=inherited, idempotency_key=idempotency_key, @@ -759,8 +834,7 @@ def search_edges( center_node_uuid: typing.Optional[str] = OMIT, filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - reranker: typing.Optional[V4SearchRequestReranker] = OMIT, - idempotency_key: typing.Optional[str] = None, + reranker: typing.Optional[SearchRequestReranker] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Edge, EdgePage]: """ @@ -792,11 +866,9 @@ def search_edges( The diversity weighting used for maximal marginal relevance reranking. Required when reranker is mmr. - reranker : typing.Optional[V4SearchRequestReranker] + reranker : typing.Optional[SearchRequestReranker] The reranking strategy applied to retrieved results. Defaults to rrf. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -814,8 +886,6 @@ def search_edges( ) response = client.graph.search_edges( graph_uuid="graph_uuid", - limit=1, - cursor="cursor", query="query", ) for item in response: @@ -834,7 +904,6 @@ def search_edges( filters=filters, mmr_lambda=mmr_lambda, reranker=reranker, - idempotency_key=idempotency_key, request_options=request_options, ) @@ -849,8 +918,7 @@ def search_episodes( center_node_uuid: typing.Optional[str] = OMIT, filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - reranker: typing.Optional[V4SearchRequestReranker] = OMIT, - idempotency_key: typing.Optional[str] = None, + reranker: typing.Optional[SearchRequestReranker] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Episode, EpisodePage]: """ @@ -882,11 +950,9 @@ def search_episodes( The diversity weighting used for maximal marginal relevance reranking. Required when reranker is mmr. - reranker : typing.Optional[V4SearchRequestReranker] + reranker : typing.Optional[SearchRequestReranker] The reranking strategy applied to retrieved results. Defaults to rrf. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -904,8 +970,6 @@ def search_episodes( ) response = client.graph.search_episodes( graph_uuid="graph_uuid", - limit=1, - cursor="cursor", query="query", ) for item in response: @@ -924,7 +988,6 @@ def search_episodes( filters=filters, mmr_lambda=mmr_lambda, reranker=reranker, - idempotency_key=idempotency_key, request_options=request_options, ) @@ -939,8 +1002,7 @@ def search_nodes( center_node_uuid: typing.Optional[str] = OMIT, filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - reranker: typing.Optional[V4SearchRequestReranker] = OMIT, - idempotency_key: typing.Optional[str] = None, + reranker: typing.Optional[SearchRequestReranker] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Node, NodePage]: """ @@ -972,11 +1034,9 @@ def search_nodes( The diversity weighting used for maximal marginal relevance reranking. Required when reranker is mmr. - reranker : typing.Optional[V4SearchRequestReranker] + reranker : typing.Optional[SearchRequestReranker] The reranking strategy applied to retrieved results. Defaults to rrf. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -994,8 +1054,6 @@ def search_nodes( ) response = client.graph.search_nodes( graph_uuid="graph_uuid", - limit=1, - cursor="cursor", query="query", ) for item in response: @@ -1014,7 +1072,6 @@ def search_nodes( filters=filters, mmr_lambda=mmr_lambda, reranker=reranker, - idempotency_key=idempotency_key, request_options=request_options, ) @@ -1029,8 +1086,7 @@ def search_observations( center_node_uuid: typing.Optional[str] = OMIT, filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - reranker: typing.Optional[V4SearchRequestReranker] = OMIT, - idempotency_key: typing.Optional[str] = None, + reranker: typing.Optional[SearchRequestReranker] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Observation, ObservationPage]: """ @@ -1062,11 +1118,9 @@ def search_observations( The diversity weighting used for maximal marginal relevance reranking. Required when reranker is mmr. - reranker : typing.Optional[V4SearchRequestReranker] + reranker : typing.Optional[SearchRequestReranker] The reranking strategy applied to retrieved results. Defaults to rrf. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1084,8 +1138,6 @@ def search_observations( ) response = client.graph.search_observations( graph_uuid="graph_uuid", - limit=1, - cursor="cursor", query="query", ) for item in response: @@ -1104,7 +1156,6 @@ def search_observations( filters=filters, mmr_lambda=mmr_lambda, reranker=reranker, - idempotency_key=idempotency_key, request_options=request_options, ) @@ -1119,8 +1170,7 @@ def search_thread_summaries( center_node_uuid: typing.Optional[str] = OMIT, filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - reranker: typing.Optional[V4SearchRequestReranker] = OMIT, - idempotency_key: typing.Optional[str] = None, + reranker: typing.Optional[SearchRequestReranker] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[ThreadSummary, ThreadSummaryPage]: """ @@ -1152,11 +1202,9 @@ def search_thread_summaries( The diversity weighting used for maximal marginal relevance reranking. Required when reranker is mmr. - reranker : typing.Optional[V4SearchRequestReranker] + reranker : typing.Optional[SearchRequestReranker] The reranking strategy applied to retrieved results. Defaults to rrf. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1174,8 +1222,6 @@ def search_thread_summaries( ) response = client.graph.search_thread_summaries( graph_uuid="graph_uuid", - limit=1, - cursor="cursor", query="query", ) for item in response: @@ -1194,7 +1240,6 @@ def search_thread_summaries( filters=filters, mmr_lambda=mmr_lambda, reranker=reranker, - idempotency_key=idempotency_key, request_options=request_options, ) @@ -1204,11 +1249,10 @@ def get_subgraph( *, seed_node_uuids: typing.Sequence[str], depth: typing.Optional[int] = OMIT, - direction: typing.Optional[V4SubgraphRequestDirection] = OMIT, + direction: typing.Optional[SubgraphRequestDirection] = OMIT, filters: typing.Optional[SearchFilters] = OMIT, max_edges: typing.Optional[int] = OMIT, max_nodes: typing.Optional[int] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SubgraphResponse: """ @@ -1223,7 +1267,7 @@ def get_subgraph( depth : typing.Optional[int] The maximum traversal depth from the seed nodes. Defaults to 1. - direction : typing.Optional[V4SubgraphRequestDirection] + direction : typing.Optional[SubgraphRequestDirection] The edge orientation to follow during expansion: in, out, or both. Defaults to both. @@ -1236,8 +1280,6 @@ def get_subgraph( max_nodes : typing.Optional[int] The maximum number of nodes in the response. Defaults to 100. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1266,7 +1308,6 @@ def get_subgraph( filters=filters, max_edges=max_edges, max_nodes=max_nodes, - idempotency_key=idempotency_key, request_options=request_options, ) return _response.data @@ -1332,6 +1373,14 @@ def edge(self): self._edge = EdgeClient(client_wrapper=self._client_wrapper) return self._edge + @property + def hyperedge(self): + if self._hyperedge is None: + from .hyperedge.client import HyperedgeClient # noqa: E402 + + self._hyperedge = HyperedgeClient(client_wrapper=self._client_wrapper) + return self._hyperedge + @property def node(self): if self._node is None: @@ -1364,6 +1413,7 @@ def __init__(self, *, client_wrapper: AsyncClientWrapper): self._document_summary: typing.Optional[AsyncDocumentSummaryClient] = None self._episode: typing.Optional[AsyncEpisodeClient] = None self._edge: typing.Optional[AsyncEdgeClient] = None + self._hyperedge: typing.Optional[AsyncHyperedgeClient] = None self._node: typing.Optional[AsyncNodeClient] = None self._observation: typing.Optional[AsyncObservationClient] = None self._thread_summary: typing.Optional[AsyncThreadSummaryClient] = None @@ -1382,8 +1432,8 @@ def with_raw_response(self) -> AsyncRawGraphClient: async def create( self, *, + content_policy: typing.Optional[GraphContentPolicyRequest] = OMIT, description: typing.Optional[str] = OMIT, - graph_id: typing.Optional[str] = OMIT, name: typing.Optional[str] = OMIT, time_zone: typing.Optional[str] = OMIT, idempotency_key: typing.Optional[str] = None, @@ -1392,12 +1442,14 @@ async def create( """ Parameters ---------- + content_policy : typing.Optional[GraphContentPolicyRequest] + Content policy additions for the graph. The graph binds the current + project content policy plus these additions, and the binding does not + change after creation. + description : typing.Optional[str] A description of the graph. - graph_id : typing.Optional[str] - An optional developer-assigned identifier for the graph. - name : typing.Optional[str] A display name for the graph. @@ -1432,8 +1484,8 @@ async def main() -> None: asyncio.run(main()) """ _response = await self._raw_client.create( + content_policy=content_policy, description=description, - graph_id=graph_id, name=name, time_zone=time_zone, idempotency_key=idempotency_key, @@ -1446,10 +1498,9 @@ async def list( *, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, - order_by: typing.Optional[str] = None, - order: typing.Optional[str] = None, + order_by: typing.Optional[GraphListRequestOrderBy] = None, + order: typing.Optional[GraphListRequestOrder] = None, search: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Graph, GraphPage]: """ @@ -1461,18 +1512,16 @@ async def list( cursor : typing.Optional[str] Opaque page cursor - order_by : typing.Optional[str] + order_by : typing.Optional[GraphListRequestOrderBy] Sort field - order : typing.Optional[str] + order : typing.Optional[GraphListRequestOrder] asc or desc search : typing.Optional[str] Filters results to graphs whose name, description, or graph ID contains this text. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1493,12 +1542,7 @@ async def list( async def main() -> None: - response = await client.graph.list( - limit=1, - cursor="cursor", - order_by="order_by", - order="order", - ) + response = await client.graph.list() async for item in response: yield item @@ -1510,13 +1554,7 @@ async def main() -> None: asyncio.run(main()) """ return await self._raw_client.list( - limit=limit, - cursor=cursor, - order_by=order_by, - order=order, - search=search, - idempotency_key=idempotency_key, - request_options=request_options, + limit=limit, cursor=cursor, order_by=order_by, order=order, search=search, request_options=request_options ) async def lookup( @@ -1525,7 +1563,6 @@ async def lookup( graph_id: typing.Optional[str] = OMIT, thread_id: typing.Optional[str] = OMIT, user_id: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> Graph: """ @@ -1543,8 +1580,6 @@ async def lookup( The developer-assigned user ID to resolve to a UUID. Mutually exclusive with thread_id and graph_id. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1571,11 +1606,7 @@ async def main() -> None: asyncio.run(main()) """ _response = await self._raw_client.lookup( - graph_id=graph_id, - thread_id=thread_id, - user_id=user_id, - idempotency_key=idempotency_key, - request_options=request_options, + graph_id=graph_id, thread_id=thread_id, user_id=user_id, request_options=request_options ) return _response.data @@ -1731,7 +1762,7 @@ async def clone( self, graph_uuid: str, *, - target_graph_id: typing.Optional[str] = OMIT, + request: CloneGraphRequest, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> CloneGraphResult: @@ -1741,8 +1772,7 @@ async def clone( graph_uuid : str Graph UUID - target_graph_id : typing.Optional[str] - An optional name for the cloned graph. + request : CloneGraphRequest idempotency_key : typing.Optional[str] @@ -1768,19 +1798,121 @@ async def clone( async def main() -> None: await client.graph.clone( graph_uuid="graph_uuid", + request={"key": "value"}, ) asyncio.run(main()) """ _response = await self._raw_client.clone( - graph_uuid, - target_graph_id=target_graph_id, - idempotency_key=idempotency_key, - request_options=request_options, + graph_uuid, request=request, idempotency_key=idempotency_key, request_options=request_options + ) + return _response.data + + async def get_content_policy( + self, graph_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> GraphContentPolicy: + """ + Returns the content policy the graph bound at creation. The policy of a graph does not change after creation. A graph without a content policy returns revision 0 with no categories and no rules. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + GraphContentPolicy + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", ) + + + async def main() -> None: + await client.graph.get_content_policy( + graph_uuid="graph_uuid", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get_content_policy(graph_uuid, request_options=request_options) return _response.data + async def list_content_policy_events( + self, + graph_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[ContentPolicyEvent, ContentPolicyEventPage]: + """ + Lists the content policy decisions recorded for a graph, newest first. Each event carries identifiers only. A graph without a content policy returns an empty list. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + filters : typing.Optional[typing.Dict[str, typing.Any]] + Exact-match filters. Supported keys: episode_uuid and drop_reason. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[ContentPolicyEvent, ContentPolicyEventPage] + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + response = await client.graph.list_content_policy_events( + graph_uuid="graph_uuid", + ) + async for item in response: + yield item + + # alternatively, you can paginate page-by-page + async for page in response.iter_pages(): + yield page + + + asyncio.run(main()) + """ + return await self._raw_client.list_content_policy_events( + graph_uuid, limit=limit, cursor=cursor, filters=filters, request_options=request_options + ) + async def get_context( self, graph_uuid: str, @@ -1789,9 +1921,8 @@ async def get_context( filters: typing.Optional[SearchFilters] = OMIT, include_results: typing.Optional[bool] = OMIT, max_characters: typing.Optional[int] = OMIT, - recency_bias: typing.Optional[V4GraphContextRequestRecencyBias] = OMIT, + recency_bias: typing.Optional[GraphContextRequestRecencyBias] = OMIT, template_uuid: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> GraphContextResponse: """ @@ -1813,14 +1944,12 @@ async def get_context( max_characters : typing.Optional[int] The maximum number of characters in the assembled context block. - recency_bias : typing.Optional[V4GraphContextRequestRecencyBias] + recency_bias : typing.Optional[GraphContextRequestRecencyBias] Adjusts result selection to favor more recent graph data. template_uuid : typing.Optional[str] The UUID of a context template used to render the context block. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1857,7 +1986,6 @@ async def main() -> None: max_characters=max_characters, recency_bias=recency_bias, template_uuid=template_uuid, - idempotency_key=idempotency_key, request_options=request_options, ) return _response.data @@ -2112,6 +2240,7 @@ async def set_ontology( graph_uuid: str, *, edge_types: typing.Optional[typing.Sequence[EdgeType]] = OMIT, + entity_type_hierarchy: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, entity_types: typing.Optional[typing.Sequence[EntityType]] = OMIT, inherited: typing.Optional[bool] = OMIT, idempotency_key: typing.Optional[str] = None, @@ -2126,6 +2255,9 @@ async def set_ontology( edge_types : typing.Optional[typing.Sequence[EdgeType]] The edge types defined in the ontology in effect at this scope. + entity_type_hierarchy : typing.Optional[typing.Dict[str, typing.Any]] + The entity type hierarchy (spec ontology-1). Omitted when the ontology is flat. + entity_types : typing.Optional[typing.Sequence[EntityType]] The entity types defined in the ontology in effect at this scope. @@ -2165,6 +2297,7 @@ async def main() -> None: _response = await self._raw_client.set_ontology( graph_uuid, edge_types=edge_types, + entity_type_hierarchy=entity_type_hierarchy, entity_types=entity_types, inherited=inherited, idempotency_key=idempotency_key, @@ -2183,8 +2316,7 @@ async def search_edges( center_node_uuid: typing.Optional[str] = OMIT, filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - reranker: typing.Optional[V4SearchRequestReranker] = OMIT, - idempotency_key: typing.Optional[str] = None, + reranker: typing.Optional[SearchRequestReranker] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Edge, EdgePage]: """ @@ -2216,11 +2348,9 @@ async def search_edges( The diversity weighting used for maximal marginal relevance reranking. Required when reranker is mmr. - reranker : typing.Optional[V4SearchRequestReranker] + reranker : typing.Optional[SearchRequestReranker] The reranking strategy applied to retrieved results. Defaults to rrf. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -2243,8 +2373,6 @@ async def search_edges( async def main() -> None: response = await client.graph.search_edges( graph_uuid="graph_uuid", - limit=1, - cursor="cursor", query="query", ) async for item in response: @@ -2267,7 +2395,6 @@ async def main() -> None: filters=filters, mmr_lambda=mmr_lambda, reranker=reranker, - idempotency_key=idempotency_key, request_options=request_options, ) @@ -2282,8 +2409,7 @@ async def search_episodes( center_node_uuid: typing.Optional[str] = OMIT, filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - reranker: typing.Optional[V4SearchRequestReranker] = OMIT, - idempotency_key: typing.Optional[str] = None, + reranker: typing.Optional[SearchRequestReranker] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Episode, EpisodePage]: """ @@ -2315,11 +2441,9 @@ async def search_episodes( The diversity weighting used for maximal marginal relevance reranking. Required when reranker is mmr. - reranker : typing.Optional[V4SearchRequestReranker] + reranker : typing.Optional[SearchRequestReranker] The reranking strategy applied to retrieved results. Defaults to rrf. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -2342,8 +2466,6 @@ async def search_episodes( async def main() -> None: response = await client.graph.search_episodes( graph_uuid="graph_uuid", - limit=1, - cursor="cursor", query="query", ) async for item in response: @@ -2366,7 +2488,6 @@ async def main() -> None: filters=filters, mmr_lambda=mmr_lambda, reranker=reranker, - idempotency_key=idempotency_key, request_options=request_options, ) @@ -2381,8 +2502,7 @@ async def search_nodes( center_node_uuid: typing.Optional[str] = OMIT, filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - reranker: typing.Optional[V4SearchRequestReranker] = OMIT, - idempotency_key: typing.Optional[str] = None, + reranker: typing.Optional[SearchRequestReranker] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Node, NodePage]: """ @@ -2414,11 +2534,9 @@ async def search_nodes( The diversity weighting used for maximal marginal relevance reranking. Required when reranker is mmr. - reranker : typing.Optional[V4SearchRequestReranker] + reranker : typing.Optional[SearchRequestReranker] The reranking strategy applied to retrieved results. Defaults to rrf. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -2441,8 +2559,6 @@ async def search_nodes( async def main() -> None: response = await client.graph.search_nodes( graph_uuid="graph_uuid", - limit=1, - cursor="cursor", query="query", ) async for item in response: @@ -2465,7 +2581,6 @@ async def main() -> None: filters=filters, mmr_lambda=mmr_lambda, reranker=reranker, - idempotency_key=idempotency_key, request_options=request_options, ) @@ -2480,8 +2595,7 @@ async def search_observations( center_node_uuid: typing.Optional[str] = OMIT, filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - reranker: typing.Optional[V4SearchRequestReranker] = OMIT, - idempotency_key: typing.Optional[str] = None, + reranker: typing.Optional[SearchRequestReranker] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Observation, ObservationPage]: """ @@ -2513,11 +2627,9 @@ async def search_observations( The diversity weighting used for maximal marginal relevance reranking. Required when reranker is mmr. - reranker : typing.Optional[V4SearchRequestReranker] + reranker : typing.Optional[SearchRequestReranker] The reranking strategy applied to retrieved results. Defaults to rrf. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -2540,8 +2652,6 @@ async def search_observations( async def main() -> None: response = await client.graph.search_observations( graph_uuid="graph_uuid", - limit=1, - cursor="cursor", query="query", ) async for item in response: @@ -2564,7 +2674,6 @@ async def main() -> None: filters=filters, mmr_lambda=mmr_lambda, reranker=reranker, - idempotency_key=idempotency_key, request_options=request_options, ) @@ -2579,8 +2688,7 @@ async def search_thread_summaries( center_node_uuid: typing.Optional[str] = OMIT, filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - reranker: typing.Optional[V4SearchRequestReranker] = OMIT, - idempotency_key: typing.Optional[str] = None, + reranker: typing.Optional[SearchRequestReranker] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[ThreadSummary, ThreadSummaryPage]: """ @@ -2612,11 +2720,9 @@ async def search_thread_summaries( The diversity weighting used for maximal marginal relevance reranking. Required when reranker is mmr. - reranker : typing.Optional[V4SearchRequestReranker] + reranker : typing.Optional[SearchRequestReranker] The reranking strategy applied to retrieved results. Defaults to rrf. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -2639,8 +2745,6 @@ async def search_thread_summaries( async def main() -> None: response = await client.graph.search_thread_summaries( graph_uuid="graph_uuid", - limit=1, - cursor="cursor", query="query", ) async for item in response: @@ -2663,7 +2767,6 @@ async def main() -> None: filters=filters, mmr_lambda=mmr_lambda, reranker=reranker, - idempotency_key=idempotency_key, request_options=request_options, ) @@ -2673,11 +2776,10 @@ async def get_subgraph( *, seed_node_uuids: typing.Sequence[str], depth: typing.Optional[int] = OMIT, - direction: typing.Optional[V4SubgraphRequestDirection] = OMIT, + direction: typing.Optional[SubgraphRequestDirection] = OMIT, filters: typing.Optional[SearchFilters] = OMIT, max_edges: typing.Optional[int] = OMIT, max_nodes: typing.Optional[int] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SubgraphResponse: """ @@ -2692,7 +2794,7 @@ async def get_subgraph( depth : typing.Optional[int] The maximum traversal depth from the seed nodes. Defaults to 1. - direction : typing.Optional[V4SubgraphRequestDirection] + direction : typing.Optional[SubgraphRequestDirection] The edge orientation to follow during expansion: in, out, or both. Defaults to both. @@ -2705,8 +2807,6 @@ async def get_subgraph( max_nodes : typing.Optional[int] The maximum number of nodes in the response. Defaults to 100. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -2743,7 +2843,6 @@ async def main() -> None: filters=filters, max_edges=max_edges, max_nodes=max_nodes, - idempotency_key=idempotency_key, request_options=request_options, ) return _response.data @@ -2819,6 +2918,14 @@ def edge(self): self._edge = AsyncEdgeClient(client_wrapper=self._client_wrapper) return self._edge + @property + def hyperedge(self): + if self._hyperedge is None: + from .hyperedge.client import AsyncHyperedgeClient # noqa: E402 + + self._hyperedge = AsyncHyperedgeClient(client_wrapper=self._client_wrapper) + return self._hyperedge + @property def node(self): if self._node is None: diff --git a/src/zep_cloud/graph/document_summary/client.py b/src/zep_cloud/graph/document_summary/client.py index 1337ac1b..cb2f14b2 100644 --- a/src/zep_cloud/graph/document_summary/client.py +++ b/src/zep_cloud/graph/document_summary/client.py @@ -35,7 +35,6 @@ def list( limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[DocumentSummary, DocumentSummaryPage]: """ @@ -53,8 +52,6 @@ def list( filters : typing.Optional[typing.Dict[str, typing.Any]] Filters constraining which items are returned. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -72,8 +69,6 @@ def list( ) response = client.graph.document_summary.list( graph_uuid="graph_uuid", - limit=1, - cursor="cursor", ) for item in response: yield item @@ -82,12 +77,7 @@ def list( yield page """ return self._raw_client.list( - graph_uuid, - limit=limit, - cursor=cursor, - filters=filters, - idempotency_key=idempotency_key, - request_options=request_options, + graph_uuid, limit=limit, cursor=cursor, filters=filters, request_options=request_options ) @@ -113,7 +103,6 @@ async def list( limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[DocumentSummary, DocumentSummaryPage]: """ @@ -131,8 +120,6 @@ async def list( filters : typing.Optional[typing.Dict[str, typing.Any]] Filters constraining which items are returned. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -155,8 +142,6 @@ async def list( async def main() -> None: response = await client.graph.document_summary.list( graph_uuid="graph_uuid", - limit=1, - cursor="cursor", ) async for item in response: yield item @@ -169,10 +154,5 @@ async def main() -> None: asyncio.run(main()) """ return await self._raw_client.list( - graph_uuid, - limit=limit, - cursor=cursor, - filters=filters, - idempotency_key=idempotency_key, - request_options=request_options, + graph_uuid, limit=limit, cursor=cursor, filters=filters, request_options=request_options ) diff --git a/src/zep_cloud/graph/document_summary/raw_client.py b/src/zep_cloud/graph/document_summary/raw_client.py index 2f58d5be..9fd1c45b 100644 --- a/src/zep_cloud/graph/document_summary/raw_client.py +++ b/src/zep_cloud/graph/document_summary/raw_client.py @@ -5,7 +5,8 @@ from ...core.api_error import ApiError as core_api_error_ApiError from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper -from ...core.jsonable_encoder import jsonable_encoder +from ...core.idempotency import generate_idempotency_key +from ...core.jsonable_encoder import encode_path_param from ...core.pagination import AsyncPager, SyncPager from ...core.parse_error import ParsingError from ...core.pydantic_utilities import parse_obj_as @@ -35,7 +36,6 @@ def list( limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[DocumentSummary, DocumentSummaryPage]: """ @@ -53,8 +53,6 @@ def list( filters : typing.Optional[typing.Dict[str, typing.Any]] Filters constraining which items are returned. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -64,7 +62,7 @@ def list( OK """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/document-summaries/list", + f"graphs/{encode_path_param(graph_uuid)}/document-summaries/list", method="POST", params={ "limit": limit, @@ -75,7 +73,7 @@ def list( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -97,7 +95,6 @@ def list( limit=limit, cursor=_parsed_next, filters=filters, - idempotency_key=idempotency_key, request_options=request_options, ) return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) @@ -181,7 +178,6 @@ async def list( limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[DocumentSummary, DocumentSummaryPage]: """ @@ -199,8 +195,6 @@ async def list( filters : typing.Optional[typing.Dict[str, typing.Any]] Filters constraining which items are returned. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -210,7 +204,7 @@ async def list( OK """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/document-summaries/list", + f"graphs/{encode_path_param(graph_uuid)}/document-summaries/list", method="POST", params={ "limit": limit, @@ -221,7 +215,7 @@ async def list( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -245,7 +239,6 @@ async def _get_next(): limit=limit, cursor=_parsed_next, filters=filters, - idempotency_key=idempotency_key, request_options=request_options, ) diff --git a/src/zep_cloud/graph/edge/client.py b/src/zep_cloud/graph/edge/client.py index e8919f75..a232f962 100644 --- a/src/zep_cloud/graph/edge/client.py +++ b/src/zep_cloud/graph/edge/client.py @@ -5,10 +5,10 @@ from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ...core.pagination import AsyncPager, SyncPager from ...core.request_options import RequestOptions -from ...types.add_edge_result import AddEdgeResult +from ...types.add_edges_result import AddEdgesResult from ...types.async_result import AsyncResult from ...types.edge import Edge -from ...types.edge_node_ref import EdgeNodeRef +from ...types.edge_input import EdgeInput from ...types.edge_page import EdgePage from .raw_client import AsyncRawEdgeClient, RawEdgeClient @@ -35,53 +35,27 @@ def add( self, graph_uuid: str, *, - fact: str, - fact_name: str, - source_node: EdgeNodeRef, - target_node: EdgeNodeRef, - attributes: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - expired_at: typing.Optional[str] = OMIT, - invalid_at: typing.Optional[str] = OMIT, - metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - valid_at: typing.Optional[str] = OMIT, + edges: typing.Sequence[EdgeInput], + deduplicate: typing.Optional[bool] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, - ) -> AddEdgeResult: + ) -> AddEdgesResult: """ + Adds 1 to 100 edges. A name creates a node when deduplicate is false. When deduplicate is true, Zep matches a node by name first. + Example: {"edges":[{"fact":"Ada works at Acme Corp","fact_name":"WORKS_AT","source_node":{"uuid":"f47ac10b-58cc-4372-a567-0e02b2c3d479"},"target_node":{"uuid":"f47ac10b-58cc-4372-a567-0e02b2c3d480"}},{"fact":"Ada leads a team","fact_name":"LEADS","source_node":{"name":"Ada Lovelace","labels":["Person"]},"target_node":{"name":"Engineering","labels":["Department"]}}],"deduplicate":false} + Parameters ---------- graph_uuid : str Graph UUID - fact : str - The fact text describing the relationship between the source and target - nodes. - - fact_name : str - The name of the edge, in upper snake case, for example RELATES_TO. - - source_node : EdgeNodeRef - The source node of the edge, referenced by uuid or created or matched by - name. - - target_node : EdgeNodeRef - The target node of the edge, referenced by uuid or created or matched by - name. - - attributes : typing.Optional[typing.Dict[str, typing.Any]] - Additional attributes to store on the edge. - - expired_at : typing.Optional[str] - The time at which the fact was superseded or invalidated. - - invalid_at : typing.Optional[str] - The time at which the fact stopped being true. + edges : typing.Sequence[EdgeInput] + The edges to add to the graph. The request accepts 1 to 100 edges. - metadata : typing.Optional[typing.Dict[str, typing.Any]] - Metadata attached to the episode created for this edge. - - valid_at : typing.Optional[str] - The time at which the fact became true. + deduplicate : typing.Optional[bool] + When true, Zep compares each edge with graph edges and can merge a + duplicate or invalidate a contradicted edge. This adds an LLM call per + edge. The default is false. idempotency_key : typing.Optional[str] @@ -90,35 +64,32 @@ def add( Returns ------- - AddEdgeResult + AddEdgesResult Accepted Examples -------- - from zep_cloud import EdgeNodeRef, Zep + from zep_cloud import EdgeInput, EdgeNodeRef, Zep client = Zep( api_key="YOUR_API_KEY", ) client.graph.edge.add( graph_uuid="graph_uuid", - fact="fact", - fact_name="fact_name", - source_node=EdgeNodeRef(), - target_node=EdgeNodeRef(), + edges=[ + EdgeInput( + fact="Ada works at Acme Corp", + fact_name="WORKS_AT", + source_node=EdgeNodeRef(), + target_node=EdgeNodeRef(), + ) + ], ) """ _response = self._raw_client.add( graph_uuid, - fact=fact, - fact_name=fact_name, - source_node=source_node, - target_node=target_node, - attributes=attributes, - expired_at=expired_at, - invalid_at=invalid_at, - metadata=metadata, - valid_at=valid_at, + edges=edges, + deduplicate=deduplicate, idempotency_key=idempotency_key, request_options=request_options, ) @@ -131,7 +102,6 @@ def list( limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Edge, EdgePage]: """ @@ -149,8 +119,6 @@ def list( filters : typing.Optional[typing.Dict[str, typing.Any]] Filters constraining which items are returned. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -168,8 +136,6 @@ def list( ) response = client.graph.edge.list( graph_uuid="graph_uuid", - limit=1, - cursor="cursor", ) for item in response: yield item @@ -178,12 +144,7 @@ def list( yield page """ return self._raw_client.list( - graph_uuid, - limit=limit, - cursor=cursor, - filters=filters, - idempotency_key=idempotency_key, - request_options=request_options, + graph_uuid, limit=limit, cursor=cursor, filters=filters, request_options=request_options ) def get(self, graph_uuid: str, edge_uuid: str, *, request_options: typing.Optional[RequestOptions] = None) -> Edge: @@ -274,6 +235,11 @@ def update( request_options: typing.Optional[RequestOptions] = None, ) -> Edge: """ + Updates one edge. When the edge belongs to a hyperedge, changing fact + rewrites it on every member of that hyperedge in one all-or-nothing + write, because the members share it. Attribute-only edits touch this + edge alone. + Parameters ---------- graph_uuid : str @@ -342,53 +308,27 @@ async def add( self, graph_uuid: str, *, - fact: str, - fact_name: str, - source_node: EdgeNodeRef, - target_node: EdgeNodeRef, - attributes: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - expired_at: typing.Optional[str] = OMIT, - invalid_at: typing.Optional[str] = OMIT, - metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - valid_at: typing.Optional[str] = OMIT, + edges: typing.Sequence[EdgeInput], + deduplicate: typing.Optional[bool] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, - ) -> AddEdgeResult: + ) -> AddEdgesResult: """ + Adds 1 to 100 edges. A name creates a node when deduplicate is false. When deduplicate is true, Zep matches a node by name first. + Example: {"edges":[{"fact":"Ada works at Acme Corp","fact_name":"WORKS_AT","source_node":{"uuid":"f47ac10b-58cc-4372-a567-0e02b2c3d479"},"target_node":{"uuid":"f47ac10b-58cc-4372-a567-0e02b2c3d480"}},{"fact":"Ada leads a team","fact_name":"LEADS","source_node":{"name":"Ada Lovelace","labels":["Person"]},"target_node":{"name":"Engineering","labels":["Department"]}}],"deduplicate":false} + Parameters ---------- graph_uuid : str Graph UUID - fact : str - The fact text describing the relationship between the source and target - nodes. - - fact_name : str - The name of the edge, in upper snake case, for example RELATES_TO. - - source_node : EdgeNodeRef - The source node of the edge, referenced by uuid or created or matched by - name. - - target_node : EdgeNodeRef - The target node of the edge, referenced by uuid or created or matched by - name. - - attributes : typing.Optional[typing.Dict[str, typing.Any]] - Additional attributes to store on the edge. - - expired_at : typing.Optional[str] - The time at which the fact was superseded or invalidated. - - invalid_at : typing.Optional[str] - The time at which the fact stopped being true. + edges : typing.Sequence[EdgeInput] + The edges to add to the graph. The request accepts 1 to 100 edges. - metadata : typing.Optional[typing.Dict[str, typing.Any]] - Metadata attached to the episode created for this edge. - - valid_at : typing.Optional[str] - The time at which the fact became true. + deduplicate : typing.Optional[bool] + When true, Zep compares each edge with graph edges and can merge a + duplicate or invalidate a contradicted edge. This adds an LLM call per + edge. The default is false. idempotency_key : typing.Optional[str] @@ -397,14 +337,14 @@ async def add( Returns ------- - AddEdgeResult + AddEdgesResult Accepted Examples -------- import asyncio - from zep_cloud import AsyncZep, EdgeNodeRef + from zep_cloud import AsyncZep, EdgeInput, EdgeNodeRef client = AsyncZep( api_key="YOUR_API_KEY", @@ -414,10 +354,14 @@ async def add( async def main() -> None: await client.graph.edge.add( graph_uuid="graph_uuid", - fact="fact", - fact_name="fact_name", - source_node=EdgeNodeRef(), - target_node=EdgeNodeRef(), + edges=[ + EdgeInput( + fact="Ada works at Acme Corp", + fact_name="WORKS_AT", + source_node=EdgeNodeRef(), + target_node=EdgeNodeRef(), + ) + ], ) @@ -425,15 +369,8 @@ async def main() -> None: """ _response = await self._raw_client.add( graph_uuid, - fact=fact, - fact_name=fact_name, - source_node=source_node, - target_node=target_node, - attributes=attributes, - expired_at=expired_at, - invalid_at=invalid_at, - metadata=metadata, - valid_at=valid_at, + edges=edges, + deduplicate=deduplicate, idempotency_key=idempotency_key, request_options=request_options, ) @@ -446,7 +383,6 @@ async def list( limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Edge, EdgePage]: """ @@ -464,8 +400,6 @@ async def list( filters : typing.Optional[typing.Dict[str, typing.Any]] Filters constraining which items are returned. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -488,8 +422,6 @@ async def list( async def main() -> None: response = await client.graph.edge.list( graph_uuid="graph_uuid", - limit=1, - cursor="cursor", ) async for item in response: yield item @@ -502,12 +434,7 @@ async def main() -> None: asyncio.run(main()) """ return await self._raw_client.list( - graph_uuid, - limit=limit, - cursor=cursor, - filters=filters, - idempotency_key=idempotency_key, - request_options=request_options, + graph_uuid, limit=limit, cursor=cursor, filters=filters, request_options=request_options ) async def get( @@ -616,6 +543,11 @@ async def update( request_options: typing.Optional[RequestOptions] = None, ) -> Edge: """ + Updates one edge. When the edge belongs to a hyperedge, changing fact + rewrites it on every member of that hyperedge in one all-or-nothing + write, because the members share it. Attribute-only edits touch this + edge alone. + Parameters ---------- graph_uuid : str diff --git a/src/zep_cloud/graph/edge/raw_client.py b/src/zep_cloud/graph/edge/raw_client.py index 712942e3..a81a58ae 100644 --- a/src/zep_cloud/graph/edge/raw_client.py +++ b/src/zep_cloud/graph/edge/raw_client.py @@ -6,7 +6,8 @@ from ...core.api_error import ApiError as core_api_error_ApiError from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ...core.http_response import AsyncHttpResponse, HttpResponse -from ...core.jsonable_encoder import jsonable_encoder +from ...core.idempotency import generate_idempotency_key +from ...core.jsonable_encoder import encode_path_param from ...core.pagination import AsyncPager, SyncPager from ...core.parse_error import ParsingError from ...core.pydantic_utilities import parse_obj_as @@ -17,11 +18,11 @@ from ...errors.forbidden_error import ForbiddenError from ...errors.not_found_error import NotFoundError from ...errors.unauthorized_error import UnauthorizedError -from ...types.add_edge_result import AddEdgeResult +from ...types.add_edges_result import AddEdgesResult from ...types.api_error import ApiError as types_api_error_ApiError from ...types.async_result import AsyncResult from ...types.edge import Edge -from ...types.edge_node_ref import EdgeNodeRef +from ...types.edge_input import EdgeInput from ...types.edge_page import EdgePage from pydantic import ValidationError @@ -37,53 +38,27 @@ def add( self, graph_uuid: str, *, - fact: str, - fact_name: str, - source_node: EdgeNodeRef, - target_node: EdgeNodeRef, - attributes: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - expired_at: typing.Optional[str] = OMIT, - invalid_at: typing.Optional[str] = OMIT, - metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - valid_at: typing.Optional[str] = OMIT, + edges: typing.Sequence[EdgeInput], + deduplicate: typing.Optional[bool] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, - ) -> HttpResponse[AddEdgeResult]: + ) -> HttpResponse[AddEdgesResult]: """ + Adds 1 to 100 edges. A name creates a node when deduplicate is false. When deduplicate is true, Zep matches a node by name first. + Example: {"edges":[{"fact":"Ada works at Acme Corp","fact_name":"WORKS_AT","source_node":{"uuid":"f47ac10b-58cc-4372-a567-0e02b2c3d479"},"target_node":{"uuid":"f47ac10b-58cc-4372-a567-0e02b2c3d480"}},{"fact":"Ada leads a team","fact_name":"LEADS","source_node":{"name":"Ada Lovelace","labels":["Person"]},"target_node":{"name":"Engineering","labels":["Department"]}}],"deduplicate":false} + Parameters ---------- graph_uuid : str Graph UUID - fact : str - The fact text describing the relationship between the source and target - nodes. - - fact_name : str - The name of the edge, in upper snake case, for example RELATES_TO. - - source_node : EdgeNodeRef - The source node of the edge, referenced by uuid or created or matched by - name. - - target_node : EdgeNodeRef - The target node of the edge, referenced by uuid or created or matched by - name. - - attributes : typing.Optional[typing.Dict[str, typing.Any]] - Additional attributes to store on the edge. - - expired_at : typing.Optional[str] - The time at which the fact was superseded or invalidated. + edges : typing.Sequence[EdgeInput] + The edges to add to the graph. The request accepts 1 to 100 edges. - invalid_at : typing.Optional[str] - The time at which the fact stopped being true. - - metadata : typing.Optional[typing.Dict[str, typing.Any]] - Metadata attached to the episode created for this edge. - - valid_at : typing.Optional[str] - The time at which the fact became true. + deduplicate : typing.Optional[bool] + When true, Zep compares each edge with graph edges and can merge a + duplicate or invalidate a contradicted edge. This adds an LLM call per + edge. The default is false. idempotency_key : typing.Optional[str] @@ -92,30 +67,21 @@ def add( Returns ------- - HttpResponse[AddEdgeResult] + HttpResponse[AddEdgesResult] Accepted """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/edges", + f"graphs/{encode_path_param(graph_uuid)}/edges", method="POST", json={ - "attributes": attributes, - "expired_at": expired_at, - "fact": fact, - "fact_name": fact_name, - "invalid_at": invalid_at, - "metadata": metadata, - "source_node": convert_and_respect_annotation_metadata( - object_=source_node, annotation=EdgeNodeRef, direction="write" - ), - "target_node": convert_and_respect_annotation_metadata( - object_=target_node, annotation=EdgeNodeRef, direction="write" + "deduplicate": deduplicate, + "edges": convert_and_respect_annotation_metadata( + object_=edges, annotation=typing.Sequence[EdgeInput], direction="write" ), - "valid_at": valid_at, }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -123,9 +89,9 @@ def add( try: if 200 <= _response.status_code < 300: _data = typing.cast( - AddEdgeResult, + AddEdgesResult, parse_obj_as( - type_=AddEdgeResult, # type: ignore + type_=AddEdgesResult, # type: ignore object_=_response.json(), ), ) @@ -205,7 +171,6 @@ def list( limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Edge, EdgePage]: """ @@ -223,8 +188,6 @@ def list( filters : typing.Optional[typing.Dict[str, typing.Any]] Filters constraining which items are returned. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -234,7 +197,7 @@ def list( OK """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/edges/list", + f"graphs/{encode_path_param(graph_uuid)}/edges/list", method="POST", params={ "limit": limit, @@ -245,7 +208,7 @@ def list( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -267,7 +230,6 @@ def list( limit=limit, cursor=_parsed_next, filters=filters, - idempotency_key=idempotency_key, request_options=request_options, ) return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) @@ -360,7 +322,7 @@ def get( OK """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/edges/{jsonable_encoder(edge_uuid)}", + f"graphs/{encode_path_param(graph_uuid)}/edges/{encode_path_param(edge_uuid)}", method="GET", request_options=request_options, ) @@ -459,10 +421,10 @@ def delete( Accepted """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/edges/{jsonable_encoder(edge_uuid)}", + f"graphs/{encode_path_param(graph_uuid)}/edges/{encode_path_param(edge_uuid)}", method="DELETE", headers={ - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, ) @@ -555,6 +517,11 @@ def update( request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[Edge]: """ + Updates one edge. When the edge belongs to a hyperedge, changing fact + rewrites it on every member of that hyperedge in one all-or-nothing + write, because the members share it. Attribute-only edits touch this + edge alone. + Parameters ---------- graph_uuid : str @@ -582,7 +549,7 @@ def update( OK """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/edges/{jsonable_encoder(edge_uuid)}", + f"graphs/{encode_path_param(graph_uuid)}/edges/{encode_path_param(edge_uuid)}", method="PATCH", json={ "attributes": attributes, @@ -590,7 +557,7 @@ def update( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -682,53 +649,27 @@ async def add( self, graph_uuid: str, *, - fact: str, - fact_name: str, - source_node: EdgeNodeRef, - target_node: EdgeNodeRef, - attributes: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - expired_at: typing.Optional[str] = OMIT, - invalid_at: typing.Optional[str] = OMIT, - metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - valid_at: typing.Optional[str] = OMIT, + edges: typing.Sequence[EdgeInput], + deduplicate: typing.Optional[bool] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, - ) -> AsyncHttpResponse[AddEdgeResult]: + ) -> AsyncHttpResponse[AddEdgesResult]: """ + Adds 1 to 100 edges. A name creates a node when deduplicate is false. When deduplicate is true, Zep matches a node by name first. + Example: {"edges":[{"fact":"Ada works at Acme Corp","fact_name":"WORKS_AT","source_node":{"uuid":"f47ac10b-58cc-4372-a567-0e02b2c3d479"},"target_node":{"uuid":"f47ac10b-58cc-4372-a567-0e02b2c3d480"}},{"fact":"Ada leads a team","fact_name":"LEADS","source_node":{"name":"Ada Lovelace","labels":["Person"]},"target_node":{"name":"Engineering","labels":["Department"]}}],"deduplicate":false} + Parameters ---------- graph_uuid : str Graph UUID - fact : str - The fact text describing the relationship between the source and target - nodes. - - fact_name : str - The name of the edge, in upper snake case, for example RELATES_TO. - - source_node : EdgeNodeRef - The source node of the edge, referenced by uuid or created or matched by - name. - - target_node : EdgeNodeRef - The target node of the edge, referenced by uuid or created or matched by - name. - - attributes : typing.Optional[typing.Dict[str, typing.Any]] - Additional attributes to store on the edge. - - expired_at : typing.Optional[str] - The time at which the fact was superseded or invalidated. + edges : typing.Sequence[EdgeInput] + The edges to add to the graph. The request accepts 1 to 100 edges. - invalid_at : typing.Optional[str] - The time at which the fact stopped being true. - - metadata : typing.Optional[typing.Dict[str, typing.Any]] - Metadata attached to the episode created for this edge. - - valid_at : typing.Optional[str] - The time at which the fact became true. + deduplicate : typing.Optional[bool] + When true, Zep compares each edge with graph edges and can merge a + duplicate or invalidate a contradicted edge. This adds an LLM call per + edge. The default is false. idempotency_key : typing.Optional[str] @@ -737,30 +678,21 @@ async def add( Returns ------- - AsyncHttpResponse[AddEdgeResult] + AsyncHttpResponse[AddEdgesResult] Accepted """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/edges", + f"graphs/{encode_path_param(graph_uuid)}/edges", method="POST", json={ - "attributes": attributes, - "expired_at": expired_at, - "fact": fact, - "fact_name": fact_name, - "invalid_at": invalid_at, - "metadata": metadata, - "source_node": convert_and_respect_annotation_metadata( - object_=source_node, annotation=EdgeNodeRef, direction="write" - ), - "target_node": convert_and_respect_annotation_metadata( - object_=target_node, annotation=EdgeNodeRef, direction="write" + "deduplicate": deduplicate, + "edges": convert_and_respect_annotation_metadata( + object_=edges, annotation=typing.Sequence[EdgeInput], direction="write" ), - "valid_at": valid_at, }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -768,9 +700,9 @@ async def add( try: if 200 <= _response.status_code < 300: _data = typing.cast( - AddEdgeResult, + AddEdgesResult, parse_obj_as( - type_=AddEdgeResult, # type: ignore + type_=AddEdgesResult, # type: ignore object_=_response.json(), ), ) @@ -850,7 +782,6 @@ async def list( limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Edge, EdgePage]: """ @@ -868,8 +799,6 @@ async def list( filters : typing.Optional[typing.Dict[str, typing.Any]] Filters constraining which items are returned. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -879,7 +808,7 @@ async def list( OK """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/edges/list", + f"graphs/{encode_path_param(graph_uuid)}/edges/list", method="POST", params={ "limit": limit, @@ -890,7 +819,7 @@ async def list( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -914,7 +843,6 @@ async def _get_next(): limit=limit, cursor=_parsed_next, filters=filters, - idempotency_key=idempotency_key, request_options=request_options, ) @@ -1008,7 +936,7 @@ async def get( OK """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/edges/{jsonable_encoder(edge_uuid)}", + f"graphs/{encode_path_param(graph_uuid)}/edges/{encode_path_param(edge_uuid)}", method="GET", request_options=request_options, ) @@ -1107,10 +1035,10 @@ async def delete( Accepted """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/edges/{jsonable_encoder(edge_uuid)}", + f"graphs/{encode_path_param(graph_uuid)}/edges/{encode_path_param(edge_uuid)}", method="DELETE", headers={ - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, ) @@ -1203,6 +1131,11 @@ async def update( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[Edge]: """ + Updates one edge. When the edge belongs to a hyperedge, changing fact + rewrites it on every member of that hyperedge in one all-or-nothing + write, because the members share it. Attribute-only edits touch this + edge alone. + Parameters ---------- graph_uuid : str @@ -1230,7 +1163,7 @@ async def update( OK """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/edges/{jsonable_encoder(edge_uuid)}", + f"graphs/{encode_path_param(graph_uuid)}/edges/{encode_path_param(edge_uuid)}", method="PATCH", json={ "attributes": attributes, @@ -1238,7 +1171,7 @@ async def update( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, diff --git a/src/zep_cloud/graph/episode/__init__.py b/src/zep_cloud/graph/episode/__init__.py index e0a9a0ef..39434134 100644 --- a/src/zep_cloud/graph/episode/__init__.py +++ b/src/zep_cloud/graph/episode/__init__.py @@ -6,8 +6,12 @@ from importlib import import_module if typing.TYPE_CHECKING: - from .types import V4AddEpisodeRequestType -_dynamic_imports: typing.Dict[str, str] = {"V4AddEpisodeRequestType": ".types"} + from .types import AddEpisodeRequestType, EpisodeListRequestOrder, EpisodeListRequestOrderBy +_dynamic_imports: typing.Dict[str, str] = { + "AddEpisodeRequestType": ".types", + "EpisodeListRequestOrder": ".types", + "EpisodeListRequestOrderBy": ".types", +} def __getattr__(attr_name: str) -> typing.Any: @@ -31,4 +35,4 @@ def __dir__(): return sorted(lazy_attrs) -__all__ = ["V4AddEpisodeRequestType"] +__all__ = ["AddEpisodeRequestType", "EpisodeListRequestOrder", "EpisodeListRequestOrderBy"] diff --git a/src/zep_cloud/graph/episode/client.py b/src/zep_cloud/graph/episode/client.py index d4f8b96d..e3de894c 100644 --- a/src/zep_cloud/graph/episode/client.py +++ b/src/zep_cloud/graph/episode/client.py @@ -8,9 +8,14 @@ from ...types.add_episode_result import AddEpisodeResult from ...types.async_result import AsyncResult from ...types.episode import Episode +from ...types.episode_debug_log import EpisodeDebugLog from ...types.episode_page import EpisodePage +from ...types.ingestion_trace import IngestionTrace +from ...types.ingestion_trace_page import IngestionTracePage from .raw_client import AsyncRawEpisodeClient, RawEpisodeClient -from .types.v4add_episode_request_type import V4AddEpisodeRequestType +from .types.add_episode_request_type import AddEpisodeRequestType +from .types.episode_list_request_order import EpisodeListRequestOrder +from .types.episode_list_request_order_by import EpisodeListRequestOrderBy # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -73,8 +78,6 @@ def list_for_document( response = client.graph.episode.list_for_document( graph_uuid="graph_uuid", document_id="document_id", - limit=1, - cursor="cursor", ) for item in response: yield item @@ -96,7 +99,7 @@ def add( metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, source_description: typing.Optional[str] = OMIT, strict_ontology: typing.Optional[bool] = OMIT, - type: typing.Optional[V4AddEpisodeRequestType] = OMIT, + type: typing.Optional[AddEpisodeRequestType] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AddEpisodeResult: @@ -117,7 +120,7 @@ def add( Groups this episode as a chunk of a document on the graph. metadata : typing.Optional[typing.Dict[str, typing.Any]] - Metadata to store on the episode. + Metadata to store on the episode. Max 10 keys. Values must be strings, numbers, booleans, or arrays of scalars. source_description : typing.Optional[str] A description of the source of this episode. @@ -126,7 +129,7 @@ def add( When true, prevents extraction of generic entity nodes that do not match the configured ontology. - type : typing.Optional[V4AddEpisodeRequestType] + type : typing.Optional[AddEpisodeRequestType] The data format of the episode: text, json, or message. Defaults to text. idempotency_key : typing.Optional[str] @@ -171,11 +174,19 @@ def list( *, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, + order_by: typing.Optional[EpisodeListRequestOrderBy] = None, + order: typing.Optional[EpisodeListRequestOrder] = None, filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Episode, EpisodePage]: """ + Lists the episodes of a graph. `filters.mentioned_node_uuids` restricts + the results to episodes that mention any of the listed node UUIDs. The + list can also contain episode UUIDs: an episode UUID matches that episode, + so one request can return a known set of episodes. At most 256 entries. + `filters.metadata_filters` restricts the results to episodes whose stored + metadata matches the predicate. + Parameters ---------- graph_uuid : str @@ -187,11 +198,15 @@ def list( cursor : typing.Optional[str] Opaque page cursor + order_by : typing.Optional[EpisodeListRequestOrderBy] + Sort field + + order : typing.Optional[EpisodeListRequestOrder] + Sort direction: asc or desc + filters : typing.Optional[typing.Dict[str, typing.Any]] Filters constraining which items are returned. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -209,8 +224,6 @@ def list( ) response = client.graph.episode.list( graph_uuid="graph_uuid", - limit=1, - cursor="cursor", ) for item in response: yield item @@ -222,8 +235,9 @@ def list( graph_uuid, limit=limit, cursor=cursor, + order_by=order_by, + order=order, filters=filters, - idempotency_key=idempotency_key, request_options=request_options, ) @@ -325,7 +339,7 @@ def update( Episode UUID metadata : typing.Optional[typing.Dict[str, typing.Any]] - Metadata to merge onto the episode; a key set to null is removed. + Metadata to merge onto the episode; a key set to null is removed. Max 10 keys after the merge. Values must be strings, numbers, booleans, or arrays of scalars. idempotency_key : typing.Optional[str] @@ -358,6 +372,98 @@ def update( ) return _response.data + def get_debug_logs( + self, graph_uuid: str, episode_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> EpisodeDebugLog: + """ + Returns the ingestion workflow log of an episode. The log exists only when debug logging was enabled for the project when the episode was ingested (see `debug_log.enable`). The log holds episode content, so an API key with an ABAC policy needs an explicit grant of this action; the `readonly` macro does not grant it. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + episode_uuid : str + Episode UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + EpisodeDebugLog + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.graph.episode.get_debug_logs( + graph_uuid="graph_uuid", + episode_uuid="episode_uuid", + ) + """ + _response = self._raw_client.get_debug_logs(graph_uuid, episode_uuid, request_options=request_options) + return _response.data + + def list_ingestion_traces( + self, + graph_uuid: str, + episode_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[IngestionTrace, IngestionTracePage]: + """ + Returns the ingestion traces of an episode, oldest first. Each trace records the input and the output of one ingestion step, with an explanation on each output entry that has one. Traces exist only when ingestion tracing was enabled for the project when the episode was ingested (see `debug_log.enable`). An episode with no traces returns a page with an empty `items` array. Traces hold episode content, prompt input, and model output, so an API key with an ABAC policy needs an explicit grant of this action; the `readonly` macro does not grant it. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + episode_uuid : str + Episode UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[IngestionTrace, IngestionTracePage] + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + response = client.graph.episode.list_ingestion_traces( + graph_uuid="graph_uuid", + episode_uuid="episode_uuid", + ) + for item in response: + yield item + # alternatively, you can paginate page-by-page + for page in response.iter_pages(): + yield page + """ + return self._raw_client.list_ingestion_traces( + graph_uuid, episode_uuid, limit=limit, cursor=cursor, request_options=request_options + ) + class AsyncEpisodeClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): @@ -421,8 +527,6 @@ async def main() -> None: response = await client.graph.episode.list_for_document( graph_uuid="graph_uuid", document_id="document_id", - limit=1, - cursor="cursor", ) async for item in response: yield item @@ -448,7 +552,7 @@ async def add( metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, source_description: typing.Optional[str] = OMIT, strict_ontology: typing.Optional[bool] = OMIT, - type: typing.Optional[V4AddEpisodeRequestType] = OMIT, + type: typing.Optional[AddEpisodeRequestType] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AddEpisodeResult: @@ -469,7 +573,7 @@ async def add( Groups this episode as a chunk of a document on the graph. metadata : typing.Optional[typing.Dict[str, typing.Any]] - Metadata to store on the episode. + Metadata to store on the episode. Max 10 keys. Values must be strings, numbers, booleans, or arrays of scalars. source_description : typing.Optional[str] A description of the source of this episode. @@ -478,7 +582,7 @@ async def add( When true, prevents extraction of generic entity nodes that do not match the configured ontology. - type : typing.Optional[V4AddEpisodeRequestType] + type : typing.Optional[AddEpisodeRequestType] The data format of the episode: text, json, or message. Defaults to text. idempotency_key : typing.Optional[str] @@ -531,11 +635,19 @@ async def list( *, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, + order_by: typing.Optional[EpisodeListRequestOrderBy] = None, + order: typing.Optional[EpisodeListRequestOrder] = None, filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Episode, EpisodePage]: """ + Lists the episodes of a graph. `filters.mentioned_node_uuids` restricts + the results to episodes that mention any of the listed node UUIDs. The + list can also contain episode UUIDs: an episode UUID matches that episode, + so one request can return a known set of episodes. At most 256 entries. + `filters.metadata_filters` restricts the results to episodes whose stored + metadata matches the predicate. + Parameters ---------- graph_uuid : str @@ -547,11 +659,15 @@ async def list( cursor : typing.Optional[str] Opaque page cursor + order_by : typing.Optional[EpisodeListRequestOrderBy] + Sort field + + order : typing.Optional[EpisodeListRequestOrder] + Sort direction: asc or desc + filters : typing.Optional[typing.Dict[str, typing.Any]] Filters constraining which items are returned. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -574,8 +690,6 @@ async def list( async def main() -> None: response = await client.graph.episode.list( graph_uuid="graph_uuid", - limit=1, - cursor="cursor", ) async for item in response: yield item @@ -591,8 +705,9 @@ async def main() -> None: graph_uuid, limit=limit, cursor=cursor, + order_by=order_by, + order=order, filters=filters, - idempotency_key=idempotency_key, request_options=request_options, ) @@ -710,7 +825,7 @@ async def update( Episode UUID metadata : typing.Optional[typing.Dict[str, typing.Any]] - Metadata to merge onto the episode; a key set to null is removed. + Metadata to merge onto the episode; a key set to null is removed. Max 10 keys after the merge. Values must be strings, numbers, booleans, or arrays of scalars. idempotency_key : typing.Optional[str] @@ -750,3 +865,112 @@ async def main() -> None: request_options=request_options, ) return _response.data + + async def get_debug_logs( + self, graph_uuid: str, episode_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> EpisodeDebugLog: + """ + Returns the ingestion workflow log of an episode. The log exists only when debug logging was enabled for the project when the episode was ingested (see `debug_log.enable`). The log holds episode content, so an API key with an ABAC policy needs an explicit grant of this action; the `readonly` macro does not grant it. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + episode_uuid : str + Episode UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + EpisodeDebugLog + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.graph.episode.get_debug_logs( + graph_uuid="graph_uuid", + episode_uuid="episode_uuid", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get_debug_logs(graph_uuid, episode_uuid, request_options=request_options) + return _response.data + + async def list_ingestion_traces( + self, + graph_uuid: str, + episode_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[IngestionTrace, IngestionTracePage]: + """ + Returns the ingestion traces of an episode, oldest first. Each trace records the input and the output of one ingestion step, with an explanation on each output entry that has one. Traces exist only when ingestion tracing was enabled for the project when the episode was ingested (see `debug_log.enable`). An episode with no traces returns a page with an empty `items` array. Traces hold episode content, prompt input, and model output, so an API key with an ABAC policy needs an explicit grant of this action; the `readonly` macro does not grant it. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + episode_uuid : str + Episode UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[IngestionTrace, IngestionTracePage] + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + response = await client.graph.episode.list_ingestion_traces( + graph_uuid="graph_uuid", + episode_uuid="episode_uuid", + ) + async for item in response: + yield item + + # alternatively, you can paginate page-by-page + async for page in response.iter_pages(): + yield page + + + asyncio.run(main()) + """ + return await self._raw_client.list_ingestion_traces( + graph_uuid, episode_uuid, limit=limit, cursor=cursor, request_options=request_options + ) diff --git a/src/zep_cloud/graph/episode/raw_client.py b/src/zep_cloud/graph/episode/raw_client.py index 0e5fb735..92f2b723 100644 --- a/src/zep_cloud/graph/episode/raw_client.py +++ b/src/zep_cloud/graph/episode/raw_client.py @@ -6,7 +6,8 @@ from ...core.api_error import ApiError as core_api_error_ApiError from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ...core.http_response import AsyncHttpResponse, HttpResponse -from ...core.jsonable_encoder import jsonable_encoder +from ...core.idempotency import generate_idempotency_key +from ...core.jsonable_encoder import encode_path_param from ...core.pagination import AsyncPager, SyncPager from ...core.parse_error import ParsingError from ...core.pydantic_utilities import parse_obj_as @@ -20,8 +21,13 @@ from ...types.api_error import ApiError as types_api_error_ApiError from ...types.async_result import AsyncResult from ...types.episode import Episode +from ...types.episode_debug_log import EpisodeDebugLog from ...types.episode_page import EpisodePage -from .types.v4add_episode_request_type import V4AddEpisodeRequestType +from ...types.ingestion_trace import IngestionTrace +from ...types.ingestion_trace_page import IngestionTracePage +from .types.add_episode_request_type import AddEpisodeRequestType +from .types.episode_list_request_order import EpisodeListRequestOrder +from .types.episode_list_request_order_by import EpisodeListRequestOrderBy from pydantic import ValidationError # this is used as the default value for optional parameters @@ -65,7 +71,7 @@ def list_for_document( OK """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/documents/{jsonable_encoder(document_id)}/episodes", + f"graphs/{encode_path_param(graph_uuid)}/documents/{encode_path_param(document_id)}/episodes", method="GET", params={ "limit": limit, @@ -171,7 +177,7 @@ def add( metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, source_description: typing.Optional[str] = OMIT, strict_ontology: typing.Optional[bool] = OMIT, - type: typing.Optional[V4AddEpisodeRequestType] = OMIT, + type: typing.Optional[AddEpisodeRequestType] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[AddEpisodeResult]: @@ -192,7 +198,7 @@ def add( Groups this episode as a chunk of a document on the graph. metadata : typing.Optional[typing.Dict[str, typing.Any]] - Metadata to store on the episode. + Metadata to store on the episode. Max 10 keys. Values must be strings, numbers, booleans, or arrays of scalars. source_description : typing.Optional[str] A description of the source of this episode. @@ -201,7 +207,7 @@ def add( When true, prevents extraction of generic entity nodes that do not match the configured ontology. - type : typing.Optional[V4AddEpisodeRequestType] + type : typing.Optional[AddEpisodeRequestType] The data format of the episode: text, json, or message. Defaults to text. idempotency_key : typing.Optional[str] @@ -215,7 +221,7 @@ def add( Accepted """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/episodes", + f"graphs/{encode_path_param(graph_uuid)}/episodes", method="POST", json={ "created_at": created_at, @@ -228,7 +234,7 @@ def add( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -317,11 +323,19 @@ def list( *, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, + order_by: typing.Optional[EpisodeListRequestOrderBy] = None, + order: typing.Optional[EpisodeListRequestOrder] = None, filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Episode, EpisodePage]: """ + Lists the episodes of a graph. `filters.mentioned_node_uuids` restricts + the results to episodes that mention any of the listed node UUIDs. The + list can also contain episode UUIDs: an episode UUID matches that episode, + so one request can return a known set of episodes. At most 256 entries. + `filters.metadata_filters` restricts the results to episodes whose stored + metadata matches the predicate. + Parameters ---------- graph_uuid : str @@ -333,11 +347,15 @@ def list( cursor : typing.Optional[str] Opaque page cursor + order_by : typing.Optional[EpisodeListRequestOrderBy] + Sort field + + order : typing.Optional[EpisodeListRequestOrder] + Sort direction: asc or desc + filters : typing.Optional[typing.Dict[str, typing.Any]] Filters constraining which items are returned. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -347,18 +365,20 @@ def list( OK """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/episodes/list", + f"graphs/{encode_path_param(graph_uuid)}/episodes/list", method="POST", params={ "limit": limit, "cursor": cursor, + "order_by": order_by, + "order": order, }, json={ "filters": filters, }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -379,8 +399,9 @@ def list( graph_uuid, limit=limit, cursor=_parsed_next, + order_by=order_by, + order=order, filters=filters, - idempotency_key=idempotency_key, request_options=request_options, ) return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) @@ -462,7 +483,7 @@ def get( OK """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/episodes/{jsonable_encoder(episode_uuid)}", + f"graphs/{encode_path_param(graph_uuid)}/episodes/{encode_path_param(episode_uuid)}", method="GET", request_options=request_options, ) @@ -561,10 +582,10 @@ def delete( Accepted """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/episodes/{jsonable_encoder(episode_uuid)}", + f"graphs/{encode_path_param(graph_uuid)}/episodes/{encode_path_param(episode_uuid)}", method="DELETE", headers={ - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, ) @@ -665,7 +686,7 @@ def update( Episode UUID metadata : typing.Optional[typing.Dict[str, typing.Any]] - Metadata to merge onto the episode; a key set to null is removed. + Metadata to merge onto the episode; a key set to null is removed. Max 10 keys after the merge. Values must be strings, numbers, booleans, or arrays of scalars. idempotency_key : typing.Optional[str] @@ -678,14 +699,14 @@ def update( OK """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/episodes/{jsonable_encoder(episode_uuid)}", + f"graphs/{encode_path_param(graph_uuid)}/episodes/{encode_path_param(episode_uuid)}", method="PATCH", json={ "metadata": metadata, }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -768,6 +789,220 @@ def update( status_code=_response.status_code, headers=dict(_response.headers), body=_response_json ) + def get_debug_logs( + self, graph_uuid: str, episode_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[EpisodeDebugLog]: + """ + Returns the ingestion workflow log of an episode. The log exists only when debug logging was enabled for the project when the episode was ingested (see `debug_log.enable`). The log holds episode content, so an API key with an ABAC policy needs an explicit grant of this action; the `readonly` macro does not grant it. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + episode_uuid : str + Episode UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[EpisodeDebugLog] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"graphs/{encode_path_param(graph_uuid)}/episodes/{encode_path_param(episode_uuid)}/debug-logs", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + EpisodeDebugLog, + parse_obj_as( + type_=EpisodeDebugLog, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def list_ingestion_traces( + self, + graph_uuid: str, + episode_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[IngestionTrace, IngestionTracePage]: + """ + Returns the ingestion traces of an episode, oldest first. Each trace records the input and the output of one ingestion step, with an explanation on each output entry that has one. Traces exist only when ingestion tracing was enabled for the project when the episode was ingested (see `debug_log.enable`). An episode with no traces returns a page with an empty `items` array. Traces hold episode content, prompt input, and model output, so an API key with an ABAC policy needs an explicit grant of this action; the `readonly` macro does not grant it. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + episode_uuid : str + Episode UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[IngestionTrace, IngestionTracePage] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"graphs/{encode_path_param(graph_uuid)}/episodes/{encode_path_param(episode_uuid)}/ingestion-traces", + method="GET", + params={ + "limit": limit, + "cursor": cursor, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + IngestionTracePage, + parse_obj_as( + type_=IngestionTracePage, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + _get_next = lambda: self.list_ingestion_traces( + graph_uuid, + episode_uuid, + limit=limit, + cursor=_parsed_next, + request_options=request_options, + ) + return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + class AsyncRawEpisodeClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): @@ -806,7 +1041,7 @@ async def list_for_document( OK """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/documents/{jsonable_encoder(document_id)}/episodes", + f"graphs/{encode_path_param(graph_uuid)}/documents/{encode_path_param(document_id)}/episodes", method="GET", params={ "limit": limit, @@ -915,7 +1150,7 @@ async def add( metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, source_description: typing.Optional[str] = OMIT, strict_ontology: typing.Optional[bool] = OMIT, - type: typing.Optional[V4AddEpisodeRequestType] = OMIT, + type: typing.Optional[AddEpisodeRequestType] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[AddEpisodeResult]: @@ -936,7 +1171,7 @@ async def add( Groups this episode as a chunk of a document on the graph. metadata : typing.Optional[typing.Dict[str, typing.Any]] - Metadata to store on the episode. + Metadata to store on the episode. Max 10 keys. Values must be strings, numbers, booleans, or arrays of scalars. source_description : typing.Optional[str] A description of the source of this episode. @@ -945,7 +1180,7 @@ async def add( When true, prevents extraction of generic entity nodes that do not match the configured ontology. - type : typing.Optional[V4AddEpisodeRequestType] + type : typing.Optional[AddEpisodeRequestType] The data format of the episode: text, json, or message. Defaults to text. idempotency_key : typing.Optional[str] @@ -959,7 +1194,7 @@ async def add( Accepted """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/episodes", + f"graphs/{encode_path_param(graph_uuid)}/episodes", method="POST", json={ "created_at": created_at, @@ -972,7 +1207,7 @@ async def add( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -1061,11 +1296,19 @@ async def list( *, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, + order_by: typing.Optional[EpisodeListRequestOrderBy] = None, + order: typing.Optional[EpisodeListRequestOrder] = None, filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Episode, EpisodePage]: """ + Lists the episodes of a graph. `filters.mentioned_node_uuids` restricts + the results to episodes that mention any of the listed node UUIDs. The + list can also contain episode UUIDs: an episode UUID matches that episode, + so one request can return a known set of episodes. At most 256 entries. + `filters.metadata_filters` restricts the results to episodes whose stored + metadata matches the predicate. + Parameters ---------- graph_uuid : str @@ -1077,11 +1320,15 @@ async def list( cursor : typing.Optional[str] Opaque page cursor + order_by : typing.Optional[EpisodeListRequestOrderBy] + Sort field + + order : typing.Optional[EpisodeListRequestOrder] + Sort direction: asc or desc + filters : typing.Optional[typing.Dict[str, typing.Any]] Filters constraining which items are returned. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1091,18 +1338,20 @@ async def list( OK """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/episodes/list", + f"graphs/{encode_path_param(graph_uuid)}/episodes/list", method="POST", params={ "limit": limit, "cursor": cursor, + "order_by": order_by, + "order": order, }, json={ "filters": filters, }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -1125,8 +1374,9 @@ async def _get_next(): graph_uuid, limit=limit, cursor=_parsed_next, + order_by=order_by, + order=order, filters=filters, - idempotency_key=idempotency_key, request_options=request_options, ) @@ -1209,7 +1459,7 @@ async def get( OK """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/episodes/{jsonable_encoder(episode_uuid)}", + f"graphs/{encode_path_param(graph_uuid)}/episodes/{encode_path_param(episode_uuid)}", method="GET", request_options=request_options, ) @@ -1308,10 +1558,10 @@ async def delete( Accepted """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/episodes/{jsonable_encoder(episode_uuid)}", + f"graphs/{encode_path_param(graph_uuid)}/episodes/{encode_path_param(episode_uuid)}", method="DELETE", headers={ - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, ) @@ -1412,7 +1662,7 @@ async def update( Episode UUID metadata : typing.Optional[typing.Dict[str, typing.Any]] - Metadata to merge onto the episode; a key set to null is removed. + Metadata to merge onto the episode; a key set to null is removed. Max 10 keys after the merge. Values must be strings, numbers, booleans, or arrays of scalars. idempotency_key : typing.Optional[str] @@ -1425,14 +1675,14 @@ async def update( OK """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/episodes/{jsonable_encoder(episode_uuid)}", + f"graphs/{encode_path_param(graph_uuid)}/episodes/{encode_path_param(episode_uuid)}", method="PATCH", json={ "metadata": metadata, }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -1514,3 +1764,220 @@ async def update( raise core_api_error_ApiError( status_code=_response.status_code, headers=dict(_response.headers), body=_response_json ) + + async def get_debug_logs( + self, graph_uuid: str, episode_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[EpisodeDebugLog]: + """ + Returns the ingestion workflow log of an episode. The log exists only when debug logging was enabled for the project when the episode was ingested (see `debug_log.enable`). The log holds episode content, so an API key with an ABAC policy needs an explicit grant of this action; the `readonly` macro does not grant it. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + episode_uuid : str + Episode UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[EpisodeDebugLog] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"graphs/{encode_path_param(graph_uuid)}/episodes/{encode_path_param(episode_uuid)}/debug-logs", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + EpisodeDebugLog, + parse_obj_as( + type_=EpisodeDebugLog, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def list_ingestion_traces( + self, + graph_uuid: str, + episode_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[IngestionTrace, IngestionTracePage]: + """ + Returns the ingestion traces of an episode, oldest first. Each trace records the input and the output of one ingestion step, with an explanation on each output entry that has one. Traces exist only when ingestion tracing was enabled for the project when the episode was ingested (see `debug_log.enable`). An episode with no traces returns a page with an empty `items` array. Traces hold episode content, prompt input, and model output, so an API key with an ABAC policy needs an explicit grant of this action; the `readonly` macro does not grant it. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + episode_uuid : str + Episode UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[IngestionTrace, IngestionTracePage] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"graphs/{encode_path_param(graph_uuid)}/episodes/{encode_path_param(episode_uuid)}/ingestion-traces", + method="GET", + params={ + "limit": limit, + "cursor": cursor, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + IngestionTracePage, + parse_obj_as( + type_=IngestionTracePage, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + + async def _get_next(): + return await self.list_ingestion_traces( + graph_uuid, + episode_uuid, + limit=limit, + cursor=_parsed_next, + request_options=request_options, + ) + + return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) diff --git a/src/zep_cloud/graph/episode/types/__init__.py b/src/zep_cloud/graph/episode/types/__init__.py index 159e4f05..63d5e628 100644 --- a/src/zep_cloud/graph/episode/types/__init__.py +++ b/src/zep_cloud/graph/episode/types/__init__.py @@ -6,8 +6,14 @@ from importlib import import_module if typing.TYPE_CHECKING: - from .v4add_episode_request_type import V4AddEpisodeRequestType -_dynamic_imports: typing.Dict[str, str] = {"V4AddEpisodeRequestType": ".v4add_episode_request_type"} + from .add_episode_request_type import AddEpisodeRequestType + from .episode_list_request_order import EpisodeListRequestOrder + from .episode_list_request_order_by import EpisodeListRequestOrderBy +_dynamic_imports: typing.Dict[str, str] = { + "AddEpisodeRequestType": ".add_episode_request_type", + "EpisodeListRequestOrder": ".episode_list_request_order", + "EpisodeListRequestOrderBy": ".episode_list_request_order_by", +} def __getattr__(attr_name: str) -> typing.Any: @@ -31,4 +37,4 @@ def __dir__(): return sorted(lazy_attrs) -__all__ = ["V4AddEpisodeRequestType"] +__all__ = ["AddEpisodeRequestType", "EpisodeListRequestOrder", "EpisodeListRequestOrderBy"] diff --git a/src/zep_cloud/graph/episode/types/add_episode_request_type.py b/src/zep_cloud/graph/episode/types/add_episode_request_type.py new file mode 100644 index 00000000..068c05bc --- /dev/null +++ b/src/zep_cloud/graph/episode/types/add_episode_request_type.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +AddEpisodeRequestType = typing.Union[typing.Literal["text", "json", "message"], typing.Any] diff --git a/src/zep_cloud/graph/episode/types/episode_list_request_order.py b/src/zep_cloud/graph/episode/types/episode_list_request_order.py new file mode 100644 index 00000000..fa24224d --- /dev/null +++ b/src/zep_cloud/graph/episode/types/episode_list_request_order.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +EpisodeListRequestOrder = typing.Union[typing.Literal["asc", "desc"], typing.Any] diff --git a/src/zep_cloud/graph/episode/types/episode_list_request_order_by.py b/src/zep_cloud/graph/episode/types/episode_list_request_order_by.py new file mode 100644 index 00000000..746d4199 --- /dev/null +++ b/src/zep_cloud/graph/episode/types/episode_list_request_order_by.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +EpisodeListRequestOrderBy = typing.Union[typing.Literal["created_at", "uuid"], typing.Any] diff --git a/src/zep_cloud/graph/episode/types/v4add_episode_request_type.py b/src/zep_cloud/graph/episode/types/v4add_episode_request_type.py deleted file mode 100644 index 7c330ae1..00000000 --- a/src/zep_cloud/graph/episode/types/v4add_episode_request_type.py +++ /dev/null @@ -1,5 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -V4AddEpisodeRequestType = typing.Union[typing.Literal["text", "json", "message"], typing.Any] diff --git a/src/zep_cloud/graph/hyperedge/__init__.py b/src/zep_cloud/graph/hyperedge/__init__.py new file mode 100644 index 00000000..d7608962 --- /dev/null +++ b/src/zep_cloud/graph/hyperedge/__init__.py @@ -0,0 +1,37 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .types import HyperedgeListRequestOrder, HyperedgeListRequestOrderBy +_dynamic_imports: typing.Dict[str, str] = { + "HyperedgeListRequestOrder": ".types", + "HyperedgeListRequestOrderBy": ".types", +} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = ["HyperedgeListRequestOrder", "HyperedgeListRequestOrderBy"] diff --git a/src/zep_cloud/graph/hyperedge/client.py b/src/zep_cloud/graph/hyperedge/client.py new file mode 100644 index 00000000..e48190fc --- /dev/null +++ b/src/zep_cloud/graph/hyperedge/client.py @@ -0,0 +1,959 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ...core.pagination import AsyncPager, SyncPager +from ...core.request_options import RequestOptions +from ...types.add_hyperedge_edge_result import AddHyperedgeEdgeResult +from ...types.add_hyperedge_result import AddHyperedgeResult +from ...types.async_result import AsyncResult +from ...types.edge_node_ref import EdgeNodeRef +from ...types.hyperedge import Hyperedge +from ...types.hyperedge_input import HyperedgeInput +from ...types.hyperedge_page import HyperedgePage +from .raw_client import AsyncRawHyperedgeClient, RawHyperedgeClient +from .types.hyperedge_list_request_order import HyperedgeListRequestOrder +from .types.hyperedge_list_request_order_by import HyperedgeListRequestOrderBy + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class HyperedgeClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawHyperedgeClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawHyperedgeClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawHyperedgeClient + """ + return self._raw_client + + def add( + self, + graph_uuid: str, + *, + edges: typing.Sequence[HyperedgeInput], + fact: str, + attributes: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + expired_at: typing.Optional[str] = OMIT, + invalid_at: typing.Optional[str] = OMIT, + metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + valid_at: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AddHyperedgeResult: + """ + Creates one hyperedge: a fact that relates more than two nodes, written + onto one member edge per node pair. The member edges must span at least + three distinct nodes, since two nodes are a pair of edges rather than a + hyperedge; a single pair uses graph.edge.add. Zep assigns the hyperedge + identifier and every member edge identifier at accept time, and the + members become readable when the task completes. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + edges : typing.Sequence[HyperedgeInput] + The member edges to create. Each pair becomes one edge carrying the + shared fact. + + fact : str + The natural-language fact, written onto every member edge. + + attributes : typing.Optional[typing.Dict[str, typing.Any]] + Additional attributes to store on every member edge. + + expired_at : typing.Optional[str] + The time at which the fact was superseded or invalidated. + + invalid_at : typing.Optional[str] + The time at which the fact stopped being true. + + metadata : typing.Optional[typing.Dict[str, typing.Any]] + Metadata attached to the episode created for this hyperedge. + + valid_at : typing.Optional[str] + The time at which the fact became true. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AddHyperedgeResult + Accepted + + Examples + -------- + from zep_cloud import EdgeNodeRef, HyperedgeInput, Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.graph.hyperedge.add( + graph_uuid="graph_uuid", + edges=[ + HyperedgeInput( + name="name", + source_node=EdgeNodeRef(), + target_node=EdgeNodeRef(), + ) + ], + fact="fact", + ) + """ + _response = self._raw_client.add( + graph_uuid, + edges=edges, + fact=fact, + attributes=attributes, + expired_at=expired_at, + invalid_at=invalid_at, + metadata=metadata, + valid_at=valid_at, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + def list( + self, + graph_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + order_by: typing.Optional[HyperedgeListRequestOrderBy] = None, + order: typing.Optional[HyperedgeListRequestOrder] = None, + filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[Hyperedge, HyperedgePage]: + """ + Returns the graph's hyperedges. A hyperedge is listed while it has at + least one member edge. Supported filters are node_uuids, edge_uuids and + episode_uuids: a hyperedge matches a list when any of its members does, + and must match every list supplied. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + order_by : typing.Optional[HyperedgeListRequestOrderBy] + Sort key: uuid or created_at + + order : typing.Optional[HyperedgeListRequestOrder] + Sort direction: asc or desc + + filters : typing.Optional[typing.Dict[str, typing.Any]] + Filters constraining which items are returned. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[Hyperedge, HyperedgePage] + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + response = client.graph.hyperedge.list( + graph_uuid="graph_uuid", + ) + for item in response: + yield item + # alternatively, you can paginate page-by-page + for page in response.iter_pages(): + yield page + """ + return self._raw_client.list( + graph_uuid, + limit=limit, + cursor=cursor, + order_by=order_by, + order=order, + filters=filters, + request_options=request_options, + ) + + def get( + self, graph_uuid: str, hyperedge_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> Hyperedge: + """ + Returns one hyperedge assembled from its member edges. The fact and the + validity timestamps are shared by every member and are reported on the + hyperedge; each member reports only its own name and endpoints. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + hyperedge_uuid : str + Hyperedge UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Hyperedge + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.graph.hyperedge.get( + graph_uuid="graph_uuid", + hyperedge_uuid="hyperedge_uuid", + ) + """ + _response = self._raw_client.get(graph_uuid, hyperedge_uuid, request_options=request_options) + return _response.data + + def delete( + self, + graph_uuid: str, + hyperedge_uuid: str, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncResult: + """ + Deletes every member edge of the hyperedge. After the task completes the + hyperedge and each of its members are gone. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + hyperedge_uuid : str + Hyperedge UUID + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncResult + Accepted + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.graph.hyperedge.delete( + graph_uuid="graph_uuid", + hyperedge_uuid="hyperedge_uuid", + ) + """ + _response = self._raw_client.delete( + graph_uuid, hyperedge_uuid, idempotency_key=idempotency_key, request_options=request_options + ) + return _response.data + + def update( + self, + graph_uuid: str, + hyperedge_uuid: str, + *, + fact: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> Hyperedge: + """ + Updates the shared fact and writes it onto every member edge in one + all-or-nothing write: either every member carries the new fact or none + does. Only fact is accepted, because it is the only field the members + share. name belongs to each member edge, and membership changes use + create_edge and delete_edge. Updating fact on one member through + graph.edge.update cascades the same way. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + hyperedge_uuid : str + Hyperedge UUID + + fact : typing.Optional[str] + The natural-language fact, rewritten onto every member edge. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Hyperedge + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.graph.hyperedge.update( + graph_uuid="graph_uuid", + hyperedge_uuid="hyperedge_uuid", + ) + """ + _response = self._raw_client.update( + graph_uuid, hyperedge_uuid, fact=fact, idempotency_key=idempotency_key, request_options=request_options + ) + return _response.data + + def create_edge( + self, + graph_uuid: str, + hyperedge_uuid: str, + *, + name: str, + source_node: EdgeNodeRef, + target_node: EdgeNodeRef, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AddHyperedgeEdgeResult: + """ + Adds one member edge to an existing hyperedge. The new member inherits the + hyperedge's fact and timestamps and joins its episodes, so only its own + name and node pair are supplied. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + hyperedge_uuid : str + Hyperedge UUID + + name : str + The name of the new member edge, in upper snake case. + + source_node : EdgeNodeRef + The source node of the new member. + + target_node : EdgeNodeRef + The target node of the new member. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AddHyperedgeEdgeResult + Accepted + + Examples + -------- + from zep_cloud import EdgeNodeRef, Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.graph.hyperedge.create_edge( + graph_uuid="graph_uuid", + hyperedge_uuid="hyperedge_uuid", + name="name", + source_node=EdgeNodeRef(), + target_node=EdgeNodeRef(), + ) + """ + _response = self._raw_client.create_edge( + graph_uuid, + hyperedge_uuid, + name=name, + source_node=source_node, + target_node=target_node, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + def delete_edge( + self, + graph_uuid: str, + hyperedge_uuid: str, + edge_uuid: str, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncResult: + """ + Removes one member edge from the hyperedge. The remaining members stay in + the hyperedge, and deleting the last member removes the hyperedge itself. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + hyperedge_uuid : str + Hyperedge UUID + + edge_uuid : str + Edge UUID + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncResult + Accepted + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.graph.hyperedge.delete_edge( + graph_uuid="graph_uuid", + hyperedge_uuid="hyperedge_uuid", + edge_uuid="edge_uuid", + ) + """ + _response = self._raw_client.delete_edge( + graph_uuid, hyperedge_uuid, edge_uuid, idempotency_key=idempotency_key, request_options=request_options + ) + return _response.data + + +class AsyncHyperedgeClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawHyperedgeClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawHyperedgeClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawHyperedgeClient + """ + return self._raw_client + + async def add( + self, + graph_uuid: str, + *, + edges: typing.Sequence[HyperedgeInput], + fact: str, + attributes: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + expired_at: typing.Optional[str] = OMIT, + invalid_at: typing.Optional[str] = OMIT, + metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + valid_at: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AddHyperedgeResult: + """ + Creates one hyperedge: a fact that relates more than two nodes, written + onto one member edge per node pair. The member edges must span at least + three distinct nodes, since two nodes are a pair of edges rather than a + hyperedge; a single pair uses graph.edge.add. Zep assigns the hyperedge + identifier and every member edge identifier at accept time, and the + members become readable when the task completes. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + edges : typing.Sequence[HyperedgeInput] + The member edges to create. Each pair becomes one edge carrying the + shared fact. + + fact : str + The natural-language fact, written onto every member edge. + + attributes : typing.Optional[typing.Dict[str, typing.Any]] + Additional attributes to store on every member edge. + + expired_at : typing.Optional[str] + The time at which the fact was superseded or invalidated. + + invalid_at : typing.Optional[str] + The time at which the fact stopped being true. + + metadata : typing.Optional[typing.Dict[str, typing.Any]] + Metadata attached to the episode created for this hyperedge. + + valid_at : typing.Optional[str] + The time at which the fact became true. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AddHyperedgeResult + Accepted + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep, EdgeNodeRef, HyperedgeInput + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.graph.hyperedge.add( + graph_uuid="graph_uuid", + edges=[ + HyperedgeInput( + name="name", + source_node=EdgeNodeRef(), + target_node=EdgeNodeRef(), + ) + ], + fact="fact", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.add( + graph_uuid, + edges=edges, + fact=fact, + attributes=attributes, + expired_at=expired_at, + invalid_at=invalid_at, + metadata=metadata, + valid_at=valid_at, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + async def list( + self, + graph_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + order_by: typing.Optional[HyperedgeListRequestOrderBy] = None, + order: typing.Optional[HyperedgeListRequestOrder] = None, + filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[Hyperedge, HyperedgePage]: + """ + Returns the graph's hyperedges. A hyperedge is listed while it has at + least one member edge. Supported filters are node_uuids, edge_uuids and + episode_uuids: a hyperedge matches a list when any of its members does, + and must match every list supplied. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + order_by : typing.Optional[HyperedgeListRequestOrderBy] + Sort key: uuid or created_at + + order : typing.Optional[HyperedgeListRequestOrder] + Sort direction: asc or desc + + filters : typing.Optional[typing.Dict[str, typing.Any]] + Filters constraining which items are returned. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[Hyperedge, HyperedgePage] + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + response = await client.graph.hyperedge.list( + graph_uuid="graph_uuid", + ) + async for item in response: + yield item + + # alternatively, you can paginate page-by-page + async for page in response.iter_pages(): + yield page + + + asyncio.run(main()) + """ + return await self._raw_client.list( + graph_uuid, + limit=limit, + cursor=cursor, + order_by=order_by, + order=order, + filters=filters, + request_options=request_options, + ) + + async def get( + self, graph_uuid: str, hyperedge_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> Hyperedge: + """ + Returns one hyperedge assembled from its member edges. The fact and the + validity timestamps are shared by every member and are reported on the + hyperedge; each member reports only its own name and endpoints. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + hyperedge_uuid : str + Hyperedge UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Hyperedge + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.graph.hyperedge.get( + graph_uuid="graph_uuid", + hyperedge_uuid="hyperedge_uuid", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get(graph_uuid, hyperedge_uuid, request_options=request_options) + return _response.data + + async def delete( + self, + graph_uuid: str, + hyperedge_uuid: str, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncResult: + """ + Deletes every member edge of the hyperedge. After the task completes the + hyperedge and each of its members are gone. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + hyperedge_uuid : str + Hyperedge UUID + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncResult + Accepted + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.graph.hyperedge.delete( + graph_uuid="graph_uuid", + hyperedge_uuid="hyperedge_uuid", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.delete( + graph_uuid, hyperedge_uuid, idempotency_key=idempotency_key, request_options=request_options + ) + return _response.data + + async def update( + self, + graph_uuid: str, + hyperedge_uuid: str, + *, + fact: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> Hyperedge: + """ + Updates the shared fact and writes it onto every member edge in one + all-or-nothing write: either every member carries the new fact or none + does. Only fact is accepted, because it is the only field the members + share. name belongs to each member edge, and membership changes use + create_edge and delete_edge. Updating fact on one member through + graph.edge.update cascades the same way. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + hyperedge_uuid : str + Hyperedge UUID + + fact : typing.Optional[str] + The natural-language fact, rewritten onto every member edge. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Hyperedge + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.graph.hyperedge.update( + graph_uuid="graph_uuid", + hyperedge_uuid="hyperedge_uuid", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.update( + graph_uuid, hyperedge_uuid, fact=fact, idempotency_key=idempotency_key, request_options=request_options + ) + return _response.data + + async def create_edge( + self, + graph_uuid: str, + hyperedge_uuid: str, + *, + name: str, + source_node: EdgeNodeRef, + target_node: EdgeNodeRef, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AddHyperedgeEdgeResult: + """ + Adds one member edge to an existing hyperedge. The new member inherits the + hyperedge's fact and timestamps and joins its episodes, so only its own + name and node pair are supplied. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + hyperedge_uuid : str + Hyperedge UUID + + name : str + The name of the new member edge, in upper snake case. + + source_node : EdgeNodeRef + The source node of the new member. + + target_node : EdgeNodeRef + The target node of the new member. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AddHyperedgeEdgeResult + Accepted + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep, EdgeNodeRef + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.graph.hyperedge.create_edge( + graph_uuid="graph_uuid", + hyperedge_uuid="hyperedge_uuid", + name="name", + source_node=EdgeNodeRef(), + target_node=EdgeNodeRef(), + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.create_edge( + graph_uuid, + hyperedge_uuid, + name=name, + source_node=source_node, + target_node=target_node, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + async def delete_edge( + self, + graph_uuid: str, + hyperedge_uuid: str, + edge_uuid: str, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncResult: + """ + Removes one member edge from the hyperedge. The remaining members stay in + the hyperedge, and deleting the last member removes the hyperedge itself. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + hyperedge_uuid : str + Hyperedge UUID + + edge_uuid : str + Edge UUID + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncResult + Accepted + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.graph.hyperedge.delete_edge( + graph_uuid="graph_uuid", + hyperedge_uuid="hyperedge_uuid", + edge_uuid="edge_uuid", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.delete_edge( + graph_uuid, hyperedge_uuid, edge_uuid, idempotency_key=idempotency_key, request_options=request_options + ) + return _response.data diff --git a/src/zep_cloud/graph/hyperedge/raw_client.py b/src/zep_cloud/graph/hyperedge/raw_client.py new file mode 100644 index 00000000..76f14b33 --- /dev/null +++ b/src/zep_cloud/graph/hyperedge/raw_client.py @@ -0,0 +1,1786 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ...core.api_error import ApiError as core_api_error_ApiError +from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ...core.http_response import AsyncHttpResponse, HttpResponse +from ...core.idempotency import generate_idempotency_key +from ...core.jsonable_encoder import encode_path_param +from ...core.pagination import AsyncPager, SyncPager +from ...core.parse_error import ParsingError +from ...core.pydantic_utilities import parse_obj_as +from ...core.request_options import RequestOptions +from ...core.serialization import convert_and_respect_annotation_metadata +from ...errors.bad_request_error import BadRequestError +from ...errors.conflict_error import ConflictError +from ...errors.forbidden_error import ForbiddenError +from ...errors.not_found_error import NotFoundError +from ...errors.service_unavailable_error import ServiceUnavailableError +from ...errors.unauthorized_error import UnauthorizedError +from ...types.add_hyperedge_edge_result import AddHyperedgeEdgeResult +from ...types.add_hyperedge_result import AddHyperedgeResult +from ...types.api_error import ApiError as types_api_error_ApiError +from ...types.async_result import AsyncResult +from ...types.edge_node_ref import EdgeNodeRef +from ...types.hyperedge import Hyperedge +from ...types.hyperedge_input import HyperedgeInput +from ...types.hyperedge_page import HyperedgePage +from .types.hyperedge_list_request_order import HyperedgeListRequestOrder +from .types.hyperedge_list_request_order_by import HyperedgeListRequestOrderBy +from pydantic import ValidationError + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class RawHyperedgeClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def add( + self, + graph_uuid: str, + *, + edges: typing.Sequence[HyperedgeInput], + fact: str, + attributes: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + expired_at: typing.Optional[str] = OMIT, + invalid_at: typing.Optional[str] = OMIT, + metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + valid_at: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[AddHyperedgeResult]: + """ + Creates one hyperedge: a fact that relates more than two nodes, written + onto one member edge per node pair. The member edges must span at least + three distinct nodes, since two nodes are a pair of edges rather than a + hyperedge; a single pair uses graph.edge.add. Zep assigns the hyperedge + identifier and every member edge identifier at accept time, and the + members become readable when the task completes. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + edges : typing.Sequence[HyperedgeInput] + The member edges to create. Each pair becomes one edge carrying the + shared fact. + + fact : str + The natural-language fact, written onto every member edge. + + attributes : typing.Optional[typing.Dict[str, typing.Any]] + Additional attributes to store on every member edge. + + expired_at : typing.Optional[str] + The time at which the fact was superseded or invalidated. + + invalid_at : typing.Optional[str] + The time at which the fact stopped being true. + + metadata : typing.Optional[typing.Dict[str, typing.Any]] + Metadata attached to the episode created for this hyperedge. + + valid_at : typing.Optional[str] + The time at which the fact became true. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AddHyperedgeResult] + Accepted + """ + _response = self._client_wrapper.httpx_client.request( + f"graphs/{encode_path_param(graph_uuid)}/hyperedges", + method="POST", + json={ + "attributes": attributes, + "edges": convert_and_respect_annotation_metadata( + object_=edges, annotation=typing.Sequence[HyperedgeInput], direction="write" + ), + "expired_at": expired_at, + "fact": fact, + "invalid_at": invalid_at, + "metadata": metadata, + "valid_at": valid_at, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AddHyperedgeResult, + parse_obj_as( + type_=AddHyperedgeResult, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def list( + self, + graph_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + order_by: typing.Optional[HyperedgeListRequestOrderBy] = None, + order: typing.Optional[HyperedgeListRequestOrder] = None, + filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[Hyperedge, HyperedgePage]: + """ + Returns the graph's hyperedges. A hyperedge is listed while it has at + least one member edge. Supported filters are node_uuids, edge_uuids and + episode_uuids: a hyperedge matches a list when any of its members does, + and must match every list supplied. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + order_by : typing.Optional[HyperedgeListRequestOrderBy] + Sort key: uuid or created_at + + order : typing.Optional[HyperedgeListRequestOrder] + Sort direction: asc or desc + + filters : typing.Optional[typing.Dict[str, typing.Any]] + Filters constraining which items are returned. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[Hyperedge, HyperedgePage] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"graphs/{encode_path_param(graph_uuid)}/hyperedges/list", + method="POST", + params={ + "limit": limit, + "cursor": cursor, + "order_by": order_by, + "order": order, + }, + json={ + "filters": filters, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + HyperedgePage, + parse_obj_as( + type_=HyperedgePage, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + _get_next = lambda: self.list( + graph_uuid, + limit=limit, + cursor=_parsed_next, + order_by=order_by, + order=order, + filters=filters, + request_options=request_options, + ) + return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def get( + self, graph_uuid: str, hyperedge_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[Hyperedge]: + """ + Returns one hyperedge assembled from its member edges. The fact and the + validity timestamps are shared by every member and are reported on the + hyperedge; each member reports only its own name and endpoints. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + hyperedge_uuid : str + Hyperedge UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[Hyperedge] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"graphs/{encode_path_param(graph_uuid)}/hyperedges/{encode_path_param(hyperedge_uuid)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + Hyperedge, + parse_obj_as( + type_=Hyperedge, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def delete( + self, + graph_uuid: str, + hyperedge_uuid: str, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[AsyncResult]: + """ + Deletes every member edge of the hyperedge. After the task completes the + hyperedge and each of its members are gone. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + hyperedge_uuid : str + Hyperedge UUID + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AsyncResult] + Accepted + """ + _response = self._client_wrapper.httpx_client.request( + f"graphs/{encode_path_param(graph_uuid)}/hyperedges/{encode_path_param(hyperedge_uuid)}", + method="DELETE", + headers={ + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AsyncResult, + parse_obj_as( + type_=AsyncResult, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def update( + self, + graph_uuid: str, + hyperedge_uuid: str, + *, + fact: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[Hyperedge]: + """ + Updates the shared fact and writes it onto every member edge in one + all-or-nothing write: either every member carries the new fact or none + does. Only fact is accepted, because it is the only field the members + share. name belongs to each member edge, and membership changes use + create_edge and delete_edge. Updating fact on one member through + graph.edge.update cascades the same way. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + hyperedge_uuid : str + Hyperedge UUID + + fact : typing.Optional[str] + The natural-language fact, rewritten onto every member edge. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[Hyperedge] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"graphs/{encode_path_param(graph_uuid)}/hyperedges/{encode_path_param(hyperedge_uuid)}", + method="PATCH", + json={ + "fact": fact, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + Hyperedge, + parse_obj_as( + type_=Hyperedge, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def create_edge( + self, + graph_uuid: str, + hyperedge_uuid: str, + *, + name: str, + source_node: EdgeNodeRef, + target_node: EdgeNodeRef, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[AddHyperedgeEdgeResult]: + """ + Adds one member edge to an existing hyperedge. The new member inherits the + hyperedge's fact and timestamps and joins its episodes, so only its own + name and node pair are supplied. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + hyperedge_uuid : str + Hyperedge UUID + + name : str + The name of the new member edge, in upper snake case. + + source_node : EdgeNodeRef + The source node of the new member. + + target_node : EdgeNodeRef + The target node of the new member. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AddHyperedgeEdgeResult] + Accepted + """ + _response = self._client_wrapper.httpx_client.request( + f"graphs/{encode_path_param(graph_uuid)}/hyperedges/{encode_path_param(hyperedge_uuid)}/edges", + method="POST", + json={ + "name": name, + "source_node": convert_and_respect_annotation_metadata( + object_=source_node, annotation=EdgeNodeRef, direction="write" + ), + "target_node": convert_and_respect_annotation_metadata( + object_=target_node, annotation=EdgeNodeRef, direction="write" + ), + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AddHyperedgeEdgeResult, + parse_obj_as( + type_=AddHyperedgeEdgeResult, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def delete_edge( + self, + graph_uuid: str, + hyperedge_uuid: str, + edge_uuid: str, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[AsyncResult]: + """ + Removes one member edge from the hyperedge. The remaining members stay in + the hyperedge, and deleting the last member removes the hyperedge itself. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + hyperedge_uuid : str + Hyperedge UUID + + edge_uuid : str + Edge UUID + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[AsyncResult] + Accepted + """ + _response = self._client_wrapper.httpx_client.request( + f"graphs/{encode_path_param(graph_uuid)}/hyperedges/{encode_path_param(hyperedge_uuid)}/edges/{encode_path_param(edge_uuid)}", + method="DELETE", + headers={ + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AsyncResult, + parse_obj_as( + type_=AsyncResult, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + +class AsyncRawHyperedgeClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def add( + self, + graph_uuid: str, + *, + edges: typing.Sequence[HyperedgeInput], + fact: str, + attributes: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + expired_at: typing.Optional[str] = OMIT, + invalid_at: typing.Optional[str] = OMIT, + metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + valid_at: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[AddHyperedgeResult]: + """ + Creates one hyperedge: a fact that relates more than two nodes, written + onto one member edge per node pair. The member edges must span at least + three distinct nodes, since two nodes are a pair of edges rather than a + hyperedge; a single pair uses graph.edge.add. Zep assigns the hyperedge + identifier and every member edge identifier at accept time, and the + members become readable when the task completes. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + edges : typing.Sequence[HyperedgeInput] + The member edges to create. Each pair becomes one edge carrying the + shared fact. + + fact : str + The natural-language fact, written onto every member edge. + + attributes : typing.Optional[typing.Dict[str, typing.Any]] + Additional attributes to store on every member edge. + + expired_at : typing.Optional[str] + The time at which the fact was superseded or invalidated. + + invalid_at : typing.Optional[str] + The time at which the fact stopped being true. + + metadata : typing.Optional[typing.Dict[str, typing.Any]] + Metadata attached to the episode created for this hyperedge. + + valid_at : typing.Optional[str] + The time at which the fact became true. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AddHyperedgeResult] + Accepted + """ + _response = await self._client_wrapper.httpx_client.request( + f"graphs/{encode_path_param(graph_uuid)}/hyperedges", + method="POST", + json={ + "attributes": attributes, + "edges": convert_and_respect_annotation_metadata( + object_=edges, annotation=typing.Sequence[HyperedgeInput], direction="write" + ), + "expired_at": expired_at, + "fact": fact, + "invalid_at": invalid_at, + "metadata": metadata, + "valid_at": valid_at, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AddHyperedgeResult, + parse_obj_as( + type_=AddHyperedgeResult, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def list( + self, + graph_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + order_by: typing.Optional[HyperedgeListRequestOrderBy] = None, + order: typing.Optional[HyperedgeListRequestOrder] = None, + filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[Hyperedge, HyperedgePage]: + """ + Returns the graph's hyperedges. A hyperedge is listed while it has at + least one member edge. Supported filters are node_uuids, edge_uuids and + episode_uuids: a hyperedge matches a list when any of its members does, + and must match every list supplied. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + order_by : typing.Optional[HyperedgeListRequestOrderBy] + Sort key: uuid or created_at + + order : typing.Optional[HyperedgeListRequestOrder] + Sort direction: asc or desc + + filters : typing.Optional[typing.Dict[str, typing.Any]] + Filters constraining which items are returned. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[Hyperedge, HyperedgePage] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"graphs/{encode_path_param(graph_uuid)}/hyperedges/list", + method="POST", + params={ + "limit": limit, + "cursor": cursor, + "order_by": order_by, + "order": order, + }, + json={ + "filters": filters, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + HyperedgePage, + parse_obj_as( + type_=HyperedgePage, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + + async def _get_next(): + return await self.list( + graph_uuid, + limit=limit, + cursor=_parsed_next, + order_by=order_by, + order=order, + filters=filters, + request_options=request_options, + ) + + return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def get( + self, graph_uuid: str, hyperedge_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[Hyperedge]: + """ + Returns one hyperedge assembled from its member edges. The fact and the + validity timestamps are shared by every member and are reported on the + hyperedge; each member reports only its own name and endpoints. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + hyperedge_uuid : str + Hyperedge UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[Hyperedge] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"graphs/{encode_path_param(graph_uuid)}/hyperedges/{encode_path_param(hyperedge_uuid)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + Hyperedge, + parse_obj_as( + type_=Hyperedge, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def delete( + self, + graph_uuid: str, + hyperedge_uuid: str, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[AsyncResult]: + """ + Deletes every member edge of the hyperedge. After the task completes the + hyperedge and each of its members are gone. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + hyperedge_uuid : str + Hyperedge UUID + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AsyncResult] + Accepted + """ + _response = await self._client_wrapper.httpx_client.request( + f"graphs/{encode_path_param(graph_uuid)}/hyperedges/{encode_path_param(hyperedge_uuid)}", + method="DELETE", + headers={ + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AsyncResult, + parse_obj_as( + type_=AsyncResult, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def update( + self, + graph_uuid: str, + hyperedge_uuid: str, + *, + fact: typing.Optional[str] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[Hyperedge]: + """ + Updates the shared fact and writes it onto every member edge in one + all-or-nothing write: either every member carries the new fact or none + does. Only fact is accepted, because it is the only field the members + share. name belongs to each member edge, and membership changes use + create_edge and delete_edge. Updating fact on one member through + graph.edge.update cascades the same way. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + hyperedge_uuid : str + Hyperedge UUID + + fact : typing.Optional[str] + The natural-language fact, rewritten onto every member edge. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[Hyperedge] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"graphs/{encode_path_param(graph_uuid)}/hyperedges/{encode_path_param(hyperedge_uuid)}", + method="PATCH", + json={ + "fact": fact, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + Hyperedge, + parse_obj_as( + type_=Hyperedge, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 503: + raise ServiceUnavailableError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def create_edge( + self, + graph_uuid: str, + hyperedge_uuid: str, + *, + name: str, + source_node: EdgeNodeRef, + target_node: EdgeNodeRef, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[AddHyperedgeEdgeResult]: + """ + Adds one member edge to an existing hyperedge. The new member inherits the + hyperedge's fact and timestamps and joins its episodes, so only its own + name and node pair are supplied. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + hyperedge_uuid : str + Hyperedge UUID + + name : str + The name of the new member edge, in upper snake case. + + source_node : EdgeNodeRef + The source node of the new member. + + target_node : EdgeNodeRef + The target node of the new member. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AddHyperedgeEdgeResult] + Accepted + """ + _response = await self._client_wrapper.httpx_client.request( + f"graphs/{encode_path_param(graph_uuid)}/hyperedges/{encode_path_param(hyperedge_uuid)}/edges", + method="POST", + json={ + "name": name, + "source_node": convert_and_respect_annotation_metadata( + object_=source_node, annotation=EdgeNodeRef, direction="write" + ), + "target_node": convert_and_respect_annotation_metadata( + object_=target_node, annotation=EdgeNodeRef, direction="write" + ), + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AddHyperedgeEdgeResult, + parse_obj_as( + type_=AddHyperedgeEdgeResult, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def delete_edge( + self, + graph_uuid: str, + hyperedge_uuid: str, + edge_uuid: str, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[AsyncResult]: + """ + Removes one member edge from the hyperedge. The remaining members stay in + the hyperedge, and deleting the last member removes the hyperedge itself. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + hyperedge_uuid : str + Hyperedge UUID + + edge_uuid : str + Edge UUID + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[AsyncResult] + Accepted + """ + _response = await self._client_wrapper.httpx_client.request( + f"graphs/{encode_path_param(graph_uuid)}/hyperedges/{encode_path_param(hyperedge_uuid)}/edges/{encode_path_param(edge_uuid)}", + method="DELETE", + headers={ + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + AsyncResult, + parse_obj_as( + type_=AsyncResult, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) diff --git a/src/zep_cloud/graph/hyperedge/types/__init__.py b/src/zep_cloud/graph/hyperedge/types/__init__.py new file mode 100644 index 00000000..5e40917e --- /dev/null +++ b/src/zep_cloud/graph/hyperedge/types/__init__.py @@ -0,0 +1,38 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .hyperedge_list_request_order import HyperedgeListRequestOrder + from .hyperedge_list_request_order_by import HyperedgeListRequestOrderBy +_dynamic_imports: typing.Dict[str, str] = { + "HyperedgeListRequestOrder": ".hyperedge_list_request_order", + "HyperedgeListRequestOrderBy": ".hyperedge_list_request_order_by", +} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = ["HyperedgeListRequestOrder", "HyperedgeListRequestOrderBy"] diff --git a/src/zep_cloud/graph/hyperedge/types/hyperedge_list_request_order.py b/src/zep_cloud/graph/hyperedge/types/hyperedge_list_request_order.py new file mode 100644 index 00000000..38451398 --- /dev/null +++ b/src/zep_cloud/graph/hyperedge/types/hyperedge_list_request_order.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +HyperedgeListRequestOrder = typing.Union[typing.Literal["asc", "desc"], typing.Any] diff --git a/src/zep_cloud/graph/hyperedge/types/hyperedge_list_request_order_by.py b/src/zep_cloud/graph/hyperedge/types/hyperedge_list_request_order_by.py new file mode 100644 index 00000000..78526d13 --- /dev/null +++ b/src/zep_cloud/graph/hyperedge/types/hyperedge_list_request_order_by.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +HyperedgeListRequestOrderBy = typing.Union[typing.Literal["uuid", "created_at"], typing.Any] diff --git a/src/zep_cloud/graph/node/__init__.py b/src/zep_cloud/graph/node/__init__.py index 6c63ceb0..515cc4ca 100644 --- a/src/zep_cloud/graph/node/__init__.py +++ b/src/zep_cloud/graph/node/__init__.py @@ -6,8 +6,20 @@ from importlib import import_module if typing.TYPE_CHECKING: - from .types import V4NeighborsRequestDirection -_dynamic_imports: typing.Dict[str, str] = {"V4NeighborsRequestDirection": ".types"} + from .types import ( + NeighborsRequestDirection, + NodeListNeighborsRequestOrder, + NodeListNeighborsRequestOrderBy, + NodeListRequestOrder, + NodeListRequestOrderBy, + ) +_dynamic_imports: typing.Dict[str, str] = { + "NeighborsRequestDirection": ".types", + "NodeListNeighborsRequestOrder": ".types", + "NodeListNeighborsRequestOrderBy": ".types", + "NodeListRequestOrder": ".types", + "NodeListRequestOrderBy": ".types", +} def __getattr__(attr_name: str) -> typing.Any: @@ -31,4 +43,10 @@ def __dir__(): return sorted(lazy_attrs) -__all__ = ["V4NeighborsRequestDirection"] +__all__ = [ + "NeighborsRequestDirection", + "NodeListNeighborsRequestOrder", + "NodeListNeighborsRequestOrderBy", + "NodeListRequestOrder", + "NodeListRequestOrderBy", +] diff --git a/src/zep_cloud/graph/node/client.py b/src/zep_cloud/graph/node/client.py index c46151da..b3d8e96c 100644 --- a/src/zep_cloud/graph/node/client.py +++ b/src/zep_cloud/graph/node/client.py @@ -14,7 +14,11 @@ from ...types.node_page import NodePage from ...types.search_filters import SearchFilters from .raw_client import AsyncRawNodeClient, RawNodeClient -from .types.v4neighbors_request_direction import V4NeighborsRequestDirection +from .types.neighbors_request_direction import NeighborsRequestDirection +from .types.node_list_neighbors_request_order import NodeListNeighborsRequestOrder +from .types.node_list_neighbors_request_order_by import NodeListNeighborsRequestOrderBy +from .types.node_list_request_order import NodeListRequestOrder +from .types.node_list_request_order_by import NodeListRequestOrderBy # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -89,8 +93,9 @@ def list( *, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, + order_by: typing.Optional[NodeListRequestOrderBy] = None, + order: typing.Optional[NodeListRequestOrder] = None, filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Node, NodePage]: """ @@ -105,11 +110,15 @@ def list( cursor : typing.Optional[str] Opaque page cursor + order_by : typing.Optional[NodeListRequestOrderBy] + Sort key: uuid (default) or degree + + order : typing.Optional[NodeListRequestOrder] + Sort direction: asc or desc (default desc) + filters : typing.Optional[typing.Dict[str, typing.Any]] Filters constraining which items are returned. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -127,8 +136,6 @@ def list( ) response = client.graph.node.list( graph_uuid="graph_uuid", - limit=1, - cursor="cursor", ) for item in response: yield item @@ -140,8 +147,9 @@ def list( graph_uuid, limit=limit, cursor=cursor, + order_by=order_by, + order=order, filters=filters, - idempotency_key=idempotency_key, request_options=request_options, ) @@ -292,9 +300,10 @@ def list_neighbors( *, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, - direction: typing.Optional[V4NeighborsRequestDirection] = OMIT, + order_by: typing.Optional[NodeListNeighborsRequestOrderBy] = None, + order: typing.Optional[NodeListNeighborsRequestOrder] = None, + direction: typing.Optional[NeighborsRequestDirection] = OMIT, filters: typing.Optional[SearchFilters] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[NeighborEntry, NeighborPage]: """ @@ -312,14 +321,18 @@ def list_neighbors( cursor : typing.Optional[str] Opaque page cursor - direction : typing.Optional[V4NeighborsRequestDirection] + order_by : typing.Optional[NodeListNeighborsRequestOrderBy] + Sort field + + order : typing.Optional[NodeListNeighborsRequestOrder] + Sort direction: asc or desc + + direction : typing.Optional[NeighborsRequestDirection] The edge orientation to follow from the node: in, out, or both. filters : typing.Optional[SearchFilters] Filters constraining the connecting edges and the neighbor nodes. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -338,8 +351,6 @@ def list_neighbors( response = client.graph.node.list_neighbors( graph_uuid="graph_uuid", node_uuid="node_uuid", - limit=1, - cursor="cursor", ) for item in response: yield item @@ -352,9 +363,10 @@ def list_neighbors( node_uuid, limit=limit, cursor=cursor, + order_by=order_by, + order=order, direction=direction, filters=filters, - idempotency_key=idempotency_key, request_options=request_options, ) @@ -436,8 +448,9 @@ async def list( *, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, + order_by: typing.Optional[NodeListRequestOrderBy] = None, + order: typing.Optional[NodeListRequestOrder] = None, filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Node, NodePage]: """ @@ -452,11 +465,15 @@ async def list( cursor : typing.Optional[str] Opaque page cursor + order_by : typing.Optional[NodeListRequestOrderBy] + Sort key: uuid (default) or degree + + order : typing.Optional[NodeListRequestOrder] + Sort direction: asc or desc (default desc) + filters : typing.Optional[typing.Dict[str, typing.Any]] Filters constraining which items are returned. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -479,8 +496,6 @@ async def list( async def main() -> None: response = await client.graph.node.list( graph_uuid="graph_uuid", - limit=1, - cursor="cursor", ) async for item in response: yield item @@ -496,8 +511,9 @@ async def main() -> None: graph_uuid, limit=limit, cursor=cursor, + order_by=order_by, + order=order, filters=filters, - idempotency_key=idempotency_key, request_options=request_options, ) @@ -674,9 +690,10 @@ async def list_neighbors( *, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, - direction: typing.Optional[V4NeighborsRequestDirection] = OMIT, + order_by: typing.Optional[NodeListNeighborsRequestOrderBy] = None, + order: typing.Optional[NodeListNeighborsRequestOrder] = None, + direction: typing.Optional[NeighborsRequestDirection] = OMIT, filters: typing.Optional[SearchFilters] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[NeighborEntry, NeighborPage]: """ @@ -694,14 +711,18 @@ async def list_neighbors( cursor : typing.Optional[str] Opaque page cursor - direction : typing.Optional[V4NeighborsRequestDirection] + order_by : typing.Optional[NodeListNeighborsRequestOrderBy] + Sort field + + order : typing.Optional[NodeListNeighborsRequestOrder] + Sort direction: asc or desc + + direction : typing.Optional[NeighborsRequestDirection] The edge orientation to follow from the node: in, out, or both. filters : typing.Optional[SearchFilters] Filters constraining the connecting edges and the neighbor nodes. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -725,8 +746,6 @@ async def main() -> None: response = await client.graph.node.list_neighbors( graph_uuid="graph_uuid", node_uuid="node_uuid", - limit=1, - cursor="cursor", ) async for item in response: yield item @@ -743,8 +762,9 @@ async def main() -> None: node_uuid, limit=limit, cursor=cursor, + order_by=order_by, + order=order, direction=direction, filters=filters, - idempotency_key=idempotency_key, request_options=request_options, ) diff --git a/src/zep_cloud/graph/node/raw_client.py b/src/zep_cloud/graph/node/raw_client.py index c3bf3708..c61442ec 100644 --- a/src/zep_cloud/graph/node/raw_client.py +++ b/src/zep_cloud/graph/node/raw_client.py @@ -6,7 +6,8 @@ from ...core.api_error import ApiError as core_api_error_ApiError from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ...core.http_response import AsyncHttpResponse, HttpResponse -from ...core.jsonable_encoder import jsonable_encoder +from ...core.idempotency import generate_idempotency_key +from ...core.jsonable_encoder import encode_path_param from ...core.pagination import AsyncPager, SyncPager from ...core.parse_error import ParsingError from ...core.pydantic_utilities import parse_obj_as @@ -26,7 +27,11 @@ from ...types.node_input import NodeInput from ...types.node_page import NodePage from ...types.search_filters import SearchFilters -from .types.v4neighbors_request_direction import V4NeighborsRequestDirection +from .types.neighbors_request_direction import NeighborsRequestDirection +from .types.node_list_neighbors_request_order import NodeListNeighborsRequestOrder +from .types.node_list_neighbors_request_order_by import NodeListNeighborsRequestOrderBy +from .types.node_list_request_order import NodeListRequestOrder +from .types.node_list_request_order_by import NodeListRequestOrderBy from pydantic import ValidationError # this is used as the default value for optional parameters @@ -65,7 +70,7 @@ def add( Accepted """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/nodes", + f"graphs/{encode_path_param(graph_uuid)}/nodes", method="POST", json={ "nodes": convert_and_respect_annotation_metadata( @@ -74,7 +79,7 @@ def add( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -163,8 +168,9 @@ def list( *, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, + order_by: typing.Optional[NodeListRequestOrderBy] = None, + order: typing.Optional[NodeListRequestOrder] = None, filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Node, NodePage]: """ @@ -179,11 +185,15 @@ def list( cursor : typing.Optional[str] Opaque page cursor + order_by : typing.Optional[NodeListRequestOrderBy] + Sort key: uuid (default) or degree + + order : typing.Optional[NodeListRequestOrder] + Sort direction: asc or desc (default desc) + filters : typing.Optional[typing.Dict[str, typing.Any]] Filters constraining which items are returned. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -193,18 +203,20 @@ def list( OK """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/nodes/list", + f"graphs/{encode_path_param(graph_uuid)}/nodes/list", method="POST", params={ "limit": limit, "cursor": cursor, + "order_by": order_by, + "order": order, }, json={ "filters": filters, }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -225,8 +237,9 @@ def list( graph_uuid, limit=limit, cursor=_parsed_next, + order_by=order_by, + order=order, filters=filters, - idempotency_key=idempotency_key, request_options=request_options, ) return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) @@ -319,7 +332,7 @@ def get( OK """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/nodes/{jsonable_encoder(node_uuid)}", + f"graphs/{encode_path_param(graph_uuid)}/nodes/{encode_path_param(node_uuid)}", method="GET", request_options=request_options, ) @@ -429,10 +442,10 @@ def delete( Accepted """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/nodes/{jsonable_encoder(node_uuid)}", + f"graphs/{encode_path_param(graph_uuid)}/nodes/{encode_path_param(node_uuid)}", method="DELETE", headers={ - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, ) @@ -555,7 +568,7 @@ def update( OK """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/nodes/{jsonable_encoder(node_uuid)}", + f"graphs/{encode_path_param(graph_uuid)}/nodes/{encode_path_param(node_uuid)}", method="PATCH", json={ "attributes": attributes, @@ -564,7 +577,7 @@ def update( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -654,9 +667,10 @@ def list_neighbors( *, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, - direction: typing.Optional[V4NeighborsRequestDirection] = OMIT, + order_by: typing.Optional[NodeListNeighborsRequestOrderBy] = None, + order: typing.Optional[NodeListNeighborsRequestOrder] = None, + direction: typing.Optional[NeighborsRequestDirection] = OMIT, filters: typing.Optional[SearchFilters] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[NeighborEntry, NeighborPage]: """ @@ -674,14 +688,18 @@ def list_neighbors( cursor : typing.Optional[str] Opaque page cursor - direction : typing.Optional[V4NeighborsRequestDirection] + order_by : typing.Optional[NodeListNeighborsRequestOrderBy] + Sort field + + order : typing.Optional[NodeListNeighborsRequestOrder] + Sort direction: asc or desc + + direction : typing.Optional[NeighborsRequestDirection] The edge orientation to follow from the node: in, out, or both. filters : typing.Optional[SearchFilters] Filters constraining the connecting edges and the neighbor nodes. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -691,11 +709,13 @@ def list_neighbors( OK """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/nodes/{jsonable_encoder(node_uuid)}/neighbors", + f"graphs/{encode_path_param(graph_uuid)}/nodes/{encode_path_param(node_uuid)}/neighbors", method="POST", params={ "limit": limit, "cursor": cursor, + "order_by": order_by, + "order": order, }, json={ "direction": direction, @@ -705,7 +725,7 @@ def list_neighbors( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -727,9 +747,10 @@ def list_neighbors( node_uuid, limit=limit, cursor=_parsed_next, + order_by=order_by, + order=order, direction=direction, filters=filters, - idempotency_key=idempotency_key, request_options=request_options, ) return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) @@ -834,7 +855,7 @@ async def add( Accepted """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/nodes", + f"graphs/{encode_path_param(graph_uuid)}/nodes", method="POST", json={ "nodes": convert_and_respect_annotation_metadata( @@ -843,7 +864,7 @@ async def add( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -932,8 +953,9 @@ async def list( *, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, + order_by: typing.Optional[NodeListRequestOrderBy] = None, + order: typing.Optional[NodeListRequestOrder] = None, filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Node, NodePage]: """ @@ -948,11 +970,15 @@ async def list( cursor : typing.Optional[str] Opaque page cursor + order_by : typing.Optional[NodeListRequestOrderBy] + Sort key: uuid (default) or degree + + order : typing.Optional[NodeListRequestOrder] + Sort direction: asc or desc (default desc) + filters : typing.Optional[typing.Dict[str, typing.Any]] Filters constraining which items are returned. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -962,18 +988,20 @@ async def list( OK """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/nodes/list", + f"graphs/{encode_path_param(graph_uuid)}/nodes/list", method="POST", params={ "limit": limit, "cursor": cursor, + "order_by": order_by, + "order": order, }, json={ "filters": filters, }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -996,8 +1024,9 @@ async def _get_next(): graph_uuid, limit=limit, cursor=_parsed_next, + order_by=order_by, + order=order, filters=filters, - idempotency_key=idempotency_key, request_options=request_options, ) @@ -1091,7 +1120,7 @@ async def get( OK """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/nodes/{jsonable_encoder(node_uuid)}", + f"graphs/{encode_path_param(graph_uuid)}/nodes/{encode_path_param(node_uuid)}", method="GET", request_options=request_options, ) @@ -1201,10 +1230,10 @@ async def delete( Accepted """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/nodes/{jsonable_encoder(node_uuid)}", + f"graphs/{encode_path_param(graph_uuid)}/nodes/{encode_path_param(node_uuid)}", method="DELETE", headers={ - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, ) @@ -1327,7 +1356,7 @@ async def update( OK """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/nodes/{jsonable_encoder(node_uuid)}", + f"graphs/{encode_path_param(graph_uuid)}/nodes/{encode_path_param(node_uuid)}", method="PATCH", json={ "attributes": attributes, @@ -1336,7 +1365,7 @@ async def update( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -1426,9 +1455,10 @@ async def list_neighbors( *, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, - direction: typing.Optional[V4NeighborsRequestDirection] = OMIT, + order_by: typing.Optional[NodeListNeighborsRequestOrderBy] = None, + order: typing.Optional[NodeListNeighborsRequestOrder] = None, + direction: typing.Optional[NeighborsRequestDirection] = OMIT, filters: typing.Optional[SearchFilters] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[NeighborEntry, NeighborPage]: """ @@ -1446,14 +1476,18 @@ async def list_neighbors( cursor : typing.Optional[str] Opaque page cursor - direction : typing.Optional[V4NeighborsRequestDirection] + order_by : typing.Optional[NodeListNeighborsRequestOrderBy] + Sort field + + order : typing.Optional[NodeListNeighborsRequestOrder] + Sort direction: asc or desc + + direction : typing.Optional[NeighborsRequestDirection] The edge orientation to follow from the node: in, out, or both. filters : typing.Optional[SearchFilters] Filters constraining the connecting edges and the neighbor nodes. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1463,11 +1497,13 @@ async def list_neighbors( OK """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/nodes/{jsonable_encoder(node_uuid)}/neighbors", + f"graphs/{encode_path_param(graph_uuid)}/nodes/{encode_path_param(node_uuid)}/neighbors", method="POST", params={ "limit": limit, "cursor": cursor, + "order_by": order_by, + "order": order, }, json={ "direction": direction, @@ -1477,7 +1513,7 @@ async def list_neighbors( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -1501,9 +1537,10 @@ async def _get_next(): node_uuid, limit=limit, cursor=_parsed_next, + order_by=order_by, + order=order, direction=direction, filters=filters, - idempotency_key=idempotency_key, request_options=request_options, ) diff --git a/src/zep_cloud/graph/node/types/__init__.py b/src/zep_cloud/graph/node/types/__init__.py index 92034f44..4f298974 100644 --- a/src/zep_cloud/graph/node/types/__init__.py +++ b/src/zep_cloud/graph/node/types/__init__.py @@ -6,8 +6,18 @@ from importlib import import_module if typing.TYPE_CHECKING: - from .v4neighbors_request_direction import V4NeighborsRequestDirection -_dynamic_imports: typing.Dict[str, str] = {"V4NeighborsRequestDirection": ".v4neighbors_request_direction"} + from .neighbors_request_direction import NeighborsRequestDirection + from .node_list_neighbors_request_order import NodeListNeighborsRequestOrder + from .node_list_neighbors_request_order_by import NodeListNeighborsRequestOrderBy + from .node_list_request_order import NodeListRequestOrder + from .node_list_request_order_by import NodeListRequestOrderBy +_dynamic_imports: typing.Dict[str, str] = { + "NeighborsRequestDirection": ".neighbors_request_direction", + "NodeListNeighborsRequestOrder": ".node_list_neighbors_request_order", + "NodeListNeighborsRequestOrderBy": ".node_list_neighbors_request_order_by", + "NodeListRequestOrder": ".node_list_request_order", + "NodeListRequestOrderBy": ".node_list_request_order_by", +} def __getattr__(attr_name: str) -> typing.Any: @@ -31,4 +41,10 @@ def __dir__(): return sorted(lazy_attrs) -__all__ = ["V4NeighborsRequestDirection"] +__all__ = [ + "NeighborsRequestDirection", + "NodeListNeighborsRequestOrder", + "NodeListNeighborsRequestOrderBy", + "NodeListRequestOrder", + "NodeListRequestOrderBy", +] diff --git a/src/zep_cloud/graph/node/types/neighbors_request_direction.py b/src/zep_cloud/graph/node/types/neighbors_request_direction.py new file mode 100644 index 00000000..30dc39c7 --- /dev/null +++ b/src/zep_cloud/graph/node/types/neighbors_request_direction.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +NeighborsRequestDirection = typing.Union[typing.Literal["in", "out", "both"], typing.Any] diff --git a/src/zep_cloud/graph/node/types/node_list_neighbors_request_order.py b/src/zep_cloud/graph/node/types/node_list_neighbors_request_order.py new file mode 100644 index 00000000..04653307 --- /dev/null +++ b/src/zep_cloud/graph/node/types/node_list_neighbors_request_order.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +NodeListNeighborsRequestOrder = typing.Union[typing.Literal["asc", "desc"], typing.Any] diff --git a/src/zep_cloud/graph/node/types/node_list_neighbors_request_order_by.py b/src/zep_cloud/graph/node/types/node_list_neighbors_request_order_by.py new file mode 100644 index 00000000..9998b24c --- /dev/null +++ b/src/zep_cloud/graph/node/types/node_list_neighbors_request_order_by.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +NodeListNeighborsRequestOrderBy = typing.Union[typing.Literal["uuid", "created_at"], typing.Any] diff --git a/src/zep_cloud/graph/node/types/node_list_request_order.py b/src/zep_cloud/graph/node/types/node_list_request_order.py new file mode 100644 index 00000000..30411e42 --- /dev/null +++ b/src/zep_cloud/graph/node/types/node_list_request_order.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +NodeListRequestOrder = typing.Union[typing.Literal["asc", "desc"], typing.Any] diff --git a/src/zep_cloud/graph/node/types/node_list_request_order_by.py b/src/zep_cloud/graph/node/types/node_list_request_order_by.py new file mode 100644 index 00000000..1fa1186a --- /dev/null +++ b/src/zep_cloud/graph/node/types/node_list_request_order_by.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +NodeListRequestOrderBy = typing.Union[typing.Literal["uuid", "degree"], typing.Any] diff --git a/src/zep_cloud/graph/node/types/v4neighbors_request_direction.py b/src/zep_cloud/graph/node/types/v4neighbors_request_direction.py deleted file mode 100644 index 6d43f589..00000000 --- a/src/zep_cloud/graph/node/types/v4neighbors_request_direction.py +++ /dev/null @@ -1,5 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -V4NeighborsRequestDirection = typing.Union[typing.Literal["in", "out", "both"], typing.Any] diff --git a/src/zep_cloud/graph/observation/client.py b/src/zep_cloud/graph/observation/client.py index 068737a7..9f028cd0 100644 --- a/src/zep_cloud/graph/observation/client.py +++ b/src/zep_cloud/graph/observation/client.py @@ -35,7 +35,6 @@ def list( limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Observation, ObservationPage]: """ @@ -53,8 +52,6 @@ def list( filters : typing.Optional[typing.Dict[str, typing.Any]] Filters constraining which items are returned. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -72,8 +69,6 @@ def list( ) response = client.graph.observation.list( graph_uuid="graph_uuid", - limit=1, - cursor="cursor", ) for item in response: yield item @@ -82,12 +77,7 @@ def list( yield page """ return self._raw_client.list( - graph_uuid, - limit=limit, - cursor=cursor, - filters=filters, - idempotency_key=idempotency_key, - request_options=request_options, + graph_uuid, limit=limit, cursor=cursor, filters=filters, request_options=request_options ) def get( @@ -148,7 +138,6 @@ async def list( limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Observation, ObservationPage]: """ @@ -166,8 +155,6 @@ async def list( filters : typing.Optional[typing.Dict[str, typing.Any]] Filters constraining which items are returned. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -190,8 +177,6 @@ async def list( async def main() -> None: response = await client.graph.observation.list( graph_uuid="graph_uuid", - limit=1, - cursor="cursor", ) async for item in response: yield item @@ -204,12 +189,7 @@ async def main() -> None: asyncio.run(main()) """ return await self._raw_client.list( - graph_uuid, - limit=limit, - cursor=cursor, - filters=filters, - idempotency_key=idempotency_key, - request_options=request_options, + graph_uuid, limit=limit, cursor=cursor, filters=filters, request_options=request_options ) async def get( diff --git a/src/zep_cloud/graph/observation/raw_client.py b/src/zep_cloud/graph/observation/raw_client.py index 0d76c501..19c083e4 100644 --- a/src/zep_cloud/graph/observation/raw_client.py +++ b/src/zep_cloud/graph/observation/raw_client.py @@ -6,7 +6,8 @@ from ...core.api_error import ApiError as core_api_error_ApiError from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ...core.http_response import AsyncHttpResponse, HttpResponse -from ...core.jsonable_encoder import jsonable_encoder +from ...core.idempotency import generate_idempotency_key +from ...core.jsonable_encoder import encode_path_param from ...core.pagination import AsyncPager, SyncPager from ...core.parse_error import ParsingError from ...core.pydantic_utilities import parse_obj_as @@ -36,7 +37,6 @@ def list( limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Observation, ObservationPage]: """ @@ -54,8 +54,6 @@ def list( filters : typing.Optional[typing.Dict[str, typing.Any]] Filters constraining which items are returned. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -65,7 +63,7 @@ def list( OK """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/observations/list", + f"graphs/{encode_path_param(graph_uuid)}/observations/list", method="POST", params={ "limit": limit, @@ -76,7 +74,7 @@ def list( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -98,7 +96,6 @@ def list( limit=limit, cursor=_parsed_next, filters=filters, - idempotency_key=idempotency_key, request_options=request_options, ) return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) @@ -191,7 +188,7 @@ def get( OK """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/observations/{jsonable_encoder(observation_uuid)}", + f"graphs/{encode_path_param(graph_uuid)}/observations/{encode_path_param(observation_uuid)}", method="GET", request_options=request_options, ) @@ -285,7 +282,6 @@ async def list( limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Observation, ObservationPage]: """ @@ -303,8 +299,6 @@ async def list( filters : typing.Optional[typing.Dict[str, typing.Any]] Filters constraining which items are returned. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -314,7 +308,7 @@ async def list( OK """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/observations/list", + f"graphs/{encode_path_param(graph_uuid)}/observations/list", method="POST", params={ "limit": limit, @@ -325,7 +319,7 @@ async def list( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -349,7 +343,6 @@ async def _get_next(): limit=limit, cursor=_parsed_next, filters=filters, - idempotency_key=idempotency_key, request_options=request_options, ) @@ -443,7 +436,7 @@ async def get( OK """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/observations/{jsonable_encoder(observation_uuid)}", + f"graphs/{encode_path_param(graph_uuid)}/observations/{encode_path_param(observation_uuid)}", method="GET", request_options=request_options, ) diff --git a/src/zep_cloud/graph/raw_client.py b/src/zep_cloud/graph/raw_client.py index 22ebf730..2f4c9ecf 100644 --- a/src/zep_cloud/graph/raw_client.py +++ b/src/zep_cloud/graph/raw_client.py @@ -6,7 +6,8 @@ from ..core.api_error import ApiError as core_api_error_ApiError from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ..core.http_response import AsyncHttpResponse, HttpResponse -from ..core.jsonable_encoder import jsonable_encoder +from ..core.idempotency import generate_idempotency_key +from ..core.jsonable_encoder import encode_path_param from ..core.pagination import AsyncPager, SyncPager from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as @@ -19,7 +20,10 @@ from ..errors.unauthorized_error import UnauthorizedError from ..types.api_error import ApiError as types_api_error_ApiError from ..types.async_result import AsyncResult +from ..types.clone_graph_request import CloneGraphRequest from ..types.clone_graph_result import CloneGraphResult +from ..types.content_policy_event import ContentPolicyEvent +from ..types.content_policy_event_page import ContentPolicyEventPage from ..types.custom_instruction import CustomInstruction from ..types.edge import Edge from ..types.edge_page import EdgePage @@ -28,6 +32,8 @@ from ..types.episode import Episode from ..types.episode_page import EpisodePage from ..types.graph import Graph +from ..types.graph_content_policy import GraphContentPolicy +from ..types.graph_content_policy_request import GraphContentPolicyRequest from ..types.graph_context_response import GraphContextResponse from ..types.graph_delete_result import GraphDeleteResult from ..types.graph_page import GraphPage @@ -40,12 +46,14 @@ from ..types.observation_type import ObservationType from ..types.ontology import Ontology from ..types.search_filters import SearchFilters +from ..types.search_request_reranker import SearchRequestReranker from ..types.subgraph_response import SubgraphResponse from ..types.thread_summary import ThreadSummary from ..types.thread_summary_page import ThreadSummaryPage -from ..types.v4search_request_reranker import V4SearchRequestReranker -from .types.v4graph_context_request_recency_bias import V4GraphContextRequestRecencyBias -from .types.v4subgraph_request_direction import V4SubgraphRequestDirection +from .types.graph_context_request_recency_bias import GraphContextRequestRecencyBias +from .types.graph_list_request_order import GraphListRequestOrder +from .types.graph_list_request_order_by import GraphListRequestOrderBy +from .types.subgraph_request_direction import SubgraphRequestDirection from pydantic import ValidationError # this is used as the default value for optional parameters @@ -59,8 +67,8 @@ def __init__(self, *, client_wrapper: SyncClientWrapper): def create( self, *, + content_policy: typing.Optional[GraphContentPolicyRequest] = OMIT, description: typing.Optional[str] = OMIT, - graph_id: typing.Optional[str] = OMIT, name: typing.Optional[str] = OMIT, time_zone: typing.Optional[str] = OMIT, idempotency_key: typing.Optional[str] = None, @@ -69,12 +77,14 @@ def create( """ Parameters ---------- + content_policy : typing.Optional[GraphContentPolicyRequest] + Content policy additions for the graph. The graph binds the current + project content policy plus these additions, and the binding does not + change after creation. + description : typing.Optional[str] A description of the graph. - graph_id : typing.Optional[str] - An optional developer-assigned identifier for the graph. - name : typing.Optional[str] A display name for the graph. @@ -95,14 +105,16 @@ def create( "graphs", method="POST", json={ + "content_policy": convert_and_respect_annotation_metadata( + object_=content_policy, annotation=GraphContentPolicyRequest, direction="write" + ), "description": description, - "graph_id": graph_id, "name": name, "time_zone": time_zone, }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -190,10 +202,9 @@ def list( *, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, - order_by: typing.Optional[str] = None, - order: typing.Optional[str] = None, + order_by: typing.Optional[GraphListRequestOrderBy] = None, + order: typing.Optional[GraphListRequestOrder] = None, search: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Graph, GraphPage]: """ @@ -205,18 +216,16 @@ def list( cursor : typing.Optional[str] Opaque page cursor - order_by : typing.Optional[str] + order_by : typing.Optional[GraphListRequestOrderBy] Sort field - order : typing.Optional[str] + order : typing.Optional[GraphListRequestOrder] asc or desc search : typing.Optional[str] Filters results to graphs whose name, description, or graph ID contains this text. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -239,7 +248,7 @@ def list( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -262,7 +271,6 @@ def list( order_by=order_by, order=order, search=search, - idempotency_key=idempotency_key, request_options=request_options, ) return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) @@ -329,7 +337,6 @@ def lookup( graph_id: typing.Optional[str] = OMIT, thread_id: typing.Optional[str] = OMIT, user_id: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[Graph]: """ @@ -347,8 +354,6 @@ def lookup( The developer-assigned user ID to resolve to a UUID. Mutually exclusive with thread_id and graph_id. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -367,7 +372,7 @@ def lookup( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -444,7 +449,7 @@ def get(self, graph_uuid: str, *, request_options: typing.Optional[RequestOption OK """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}", + f"graphs/{encode_path_param(graph_uuid)}", method="GET", request_options=request_options, ) @@ -539,10 +544,10 @@ def delete( Accepted """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}", + f"graphs/{encode_path_param(graph_uuid)}", method="DELETE", headers={ - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, ) @@ -660,7 +665,7 @@ def update( OK """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}", + f"graphs/{encode_path_param(graph_uuid)}", method="PATCH", json={ "description": description, @@ -669,7 +674,7 @@ def update( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -756,7 +761,7 @@ def clone( self, graph_uuid: str, *, - target_graph_id: typing.Optional[str] = OMIT, + request: CloneGraphRequest, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[CloneGraphResult]: @@ -766,8 +771,7 @@ def clone( graph_uuid : str Graph UUID - target_graph_id : typing.Optional[str] - An optional name for the cloned graph. + request : CloneGraphRequest idempotency_key : typing.Optional[str] @@ -780,14 +784,12 @@ def clone( Accepted """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/clone", + f"graphs/{encode_path_param(graph_uuid)}/clone", method="POST", - json={ - "target_graph_id": target_graph_id, - }, + json=request, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -870,6 +872,225 @@ def clone( status_code=_response.status_code, headers=dict(_response.headers), body=_response_json ) + def get_content_policy( + self, graph_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[GraphContentPolicy]: + """ + Returns the content policy the graph bound at creation. The policy of a graph does not change after creation. A graph without a content policy returns revision 0 with no categories and no rules. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[GraphContentPolicy] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"graphs/{encode_path_param(graph_uuid)}/content-policy", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + GraphContentPolicy, + parse_obj_as( + type_=GraphContentPolicy, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def list_content_policy_events( + self, + graph_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[ContentPolicyEvent, ContentPolicyEventPage]: + """ + Lists the content policy decisions recorded for a graph, newest first. Each event carries identifiers only. A graph without a content policy returns an empty list. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + filters : typing.Optional[typing.Dict[str, typing.Any]] + Exact-match filters. Supported keys: episode_uuid and drop_reason. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[ContentPolicyEvent, ContentPolicyEventPage] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"graphs/{encode_path_param(graph_uuid)}/content-policy/events/list", + method="POST", + params={ + "limit": limit, + "cursor": cursor, + }, + json={ + "filters": filters, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + ContentPolicyEventPage, + parse_obj_as( + type_=ContentPolicyEventPage, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + _get_next = lambda: self.list_content_policy_events( + graph_uuid, + limit=limit, + cursor=_parsed_next, + filters=filters, + request_options=request_options, + ) + return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + def get_context( self, graph_uuid: str, @@ -878,9 +1099,8 @@ def get_context( filters: typing.Optional[SearchFilters] = OMIT, include_results: typing.Optional[bool] = OMIT, max_characters: typing.Optional[int] = OMIT, - recency_bias: typing.Optional[V4GraphContextRequestRecencyBias] = OMIT, + recency_bias: typing.Optional[GraphContextRequestRecencyBias] = OMIT, template_uuid: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[GraphContextResponse]: """ @@ -902,14 +1122,12 @@ def get_context( max_characters : typing.Optional[int] The maximum number of characters in the assembled context block. - recency_bias : typing.Optional[V4GraphContextRequestRecencyBias] + recency_bias : typing.Optional[GraphContextRequestRecencyBias] Adjusts result selection to favor more recent graph data. template_uuid : typing.Optional[str] The UUID of a context template used to render the context block. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -919,7 +1137,7 @@ def get_context( OK """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/context", + f"graphs/{encode_path_param(graph_uuid)}/context", method="POST", json={ "filters": convert_and_respect_annotation_metadata( @@ -933,7 +1151,7 @@ def get_context( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -1034,7 +1252,7 @@ def get_instructions( OK """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/instructions", + f"graphs/{encode_path_param(graph_uuid)}/instructions", method="GET", request_options=request_options, ) @@ -1128,7 +1346,7 @@ def set_instructions( OK """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/instructions", + f"graphs/{encode_path_param(graph_uuid)}/instructions", method="PUT", json={ "inherited": inherited, @@ -1138,7 +1356,7 @@ def set_instructions( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -1217,7 +1435,7 @@ def get_observation_steering( OK """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/observation-steering", + f"graphs/{encode_path_param(graph_uuid)}/observation-steering", method="GET", request_options=request_options, ) @@ -1316,7 +1534,7 @@ def set_observation_steering( OK """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/observation-steering", + f"graphs/{encode_path_param(graph_uuid)}/observation-steering", method="PUT", json={ "inherited": inherited, @@ -1327,7 +1545,7 @@ def set_observation_steering( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -1406,7 +1624,7 @@ def get_ontology( OK """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/ontology", + f"graphs/{encode_path_param(graph_uuid)}/ontology", method="GET", request_options=request_options, ) @@ -1471,6 +1689,7 @@ def set_ontology( graph_uuid: str, *, edge_types: typing.Optional[typing.Sequence[EdgeType]] = OMIT, + entity_type_hierarchy: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, entity_types: typing.Optional[typing.Sequence[EntityType]] = OMIT, inherited: typing.Optional[bool] = OMIT, idempotency_key: typing.Optional[str] = None, @@ -1485,6 +1704,9 @@ def set_ontology( edge_types : typing.Optional[typing.Sequence[EdgeType]] The edge types defined in the ontology in effect at this scope. + entity_type_hierarchy : typing.Optional[typing.Dict[str, typing.Any]] + The entity type hierarchy (spec ontology-1). Omitted when the ontology is flat. + entity_types : typing.Optional[typing.Sequence[EntityType]] The entity types defined in the ontology in effect at this scope. @@ -1503,12 +1725,13 @@ def set_ontology( OK """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/ontology", + f"graphs/{encode_path_param(graph_uuid)}/ontology", method="PUT", json={ "edge_types": convert_and_respect_annotation_metadata( object_=edge_types, annotation=typing.Sequence[EdgeType], direction="write" ), + "entity_type_hierarchy": entity_type_hierarchy, "entity_types": convert_and_respect_annotation_metadata( object_=entity_types, annotation=typing.Sequence[EntityType], direction="write" ), @@ -1516,7 +1739,7 @@ def set_ontology( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -1588,8 +1811,7 @@ def search_edges( center_node_uuid: typing.Optional[str] = OMIT, filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - reranker: typing.Optional[V4SearchRequestReranker] = OMIT, - idempotency_key: typing.Optional[str] = None, + reranker: typing.Optional[SearchRequestReranker] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Edge, EdgePage]: """ @@ -1621,11 +1843,9 @@ def search_edges( The diversity weighting used for maximal marginal relevance reranking. Required when reranker is mmr. - reranker : typing.Optional[V4SearchRequestReranker] + reranker : typing.Optional[SearchRequestReranker] The reranking strategy applied to retrieved results. Defaults to rrf. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1635,7 +1855,7 @@ def search_edges( OK """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/search/edges", + f"graphs/{encode_path_param(graph_uuid)}/search/edges", method="POST", params={ "limit": limit, @@ -1653,7 +1873,7 @@ def search_edges( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -1680,7 +1900,6 @@ def search_edges( filters=filters, mmr_lambda=mmr_lambda, reranker=reranker, - idempotency_key=idempotency_key, request_options=request_options, ) return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) @@ -1752,8 +1971,7 @@ def search_episodes( center_node_uuid: typing.Optional[str] = OMIT, filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - reranker: typing.Optional[V4SearchRequestReranker] = OMIT, - idempotency_key: typing.Optional[str] = None, + reranker: typing.Optional[SearchRequestReranker] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Episode, EpisodePage]: """ @@ -1785,11 +2003,9 @@ def search_episodes( The diversity weighting used for maximal marginal relevance reranking. Required when reranker is mmr. - reranker : typing.Optional[V4SearchRequestReranker] + reranker : typing.Optional[SearchRequestReranker] The reranking strategy applied to retrieved results. Defaults to rrf. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1799,7 +2015,7 @@ def search_episodes( OK """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/search/episodes", + f"graphs/{encode_path_param(graph_uuid)}/search/episodes", method="POST", params={ "limit": limit, @@ -1817,7 +2033,7 @@ def search_episodes( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -1844,7 +2060,6 @@ def search_episodes( filters=filters, mmr_lambda=mmr_lambda, reranker=reranker, - idempotency_key=idempotency_key, request_options=request_options, ) return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) @@ -1916,8 +2131,7 @@ def search_nodes( center_node_uuid: typing.Optional[str] = OMIT, filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - reranker: typing.Optional[V4SearchRequestReranker] = OMIT, - idempotency_key: typing.Optional[str] = None, + reranker: typing.Optional[SearchRequestReranker] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Node, NodePage]: """ @@ -1949,11 +2163,9 @@ def search_nodes( The diversity weighting used for maximal marginal relevance reranking. Required when reranker is mmr. - reranker : typing.Optional[V4SearchRequestReranker] + reranker : typing.Optional[SearchRequestReranker] The reranking strategy applied to retrieved results. Defaults to rrf. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1963,7 +2175,7 @@ def search_nodes( OK """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/search/nodes", + f"graphs/{encode_path_param(graph_uuid)}/search/nodes", method="POST", params={ "limit": limit, @@ -1981,7 +2193,7 @@ def search_nodes( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -2008,7 +2220,6 @@ def search_nodes( filters=filters, mmr_lambda=mmr_lambda, reranker=reranker, - idempotency_key=idempotency_key, request_options=request_options, ) return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) @@ -2080,8 +2291,7 @@ def search_observations( center_node_uuid: typing.Optional[str] = OMIT, filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - reranker: typing.Optional[V4SearchRequestReranker] = OMIT, - idempotency_key: typing.Optional[str] = None, + reranker: typing.Optional[SearchRequestReranker] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Observation, ObservationPage]: """ @@ -2113,11 +2323,9 @@ def search_observations( The diversity weighting used for maximal marginal relevance reranking. Required when reranker is mmr. - reranker : typing.Optional[V4SearchRequestReranker] + reranker : typing.Optional[SearchRequestReranker] The reranking strategy applied to retrieved results. Defaults to rrf. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -2127,7 +2335,7 @@ def search_observations( OK """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/search/observations", + f"graphs/{encode_path_param(graph_uuid)}/search/observations", method="POST", params={ "limit": limit, @@ -2145,7 +2353,7 @@ def search_observations( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -2172,7 +2380,6 @@ def search_observations( filters=filters, mmr_lambda=mmr_lambda, reranker=reranker, - idempotency_key=idempotency_key, request_options=request_options, ) return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) @@ -2244,8 +2451,7 @@ def search_thread_summaries( center_node_uuid: typing.Optional[str] = OMIT, filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - reranker: typing.Optional[V4SearchRequestReranker] = OMIT, - idempotency_key: typing.Optional[str] = None, + reranker: typing.Optional[SearchRequestReranker] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[ThreadSummary, ThreadSummaryPage]: """ @@ -2277,11 +2483,9 @@ def search_thread_summaries( The diversity weighting used for maximal marginal relevance reranking. Required when reranker is mmr. - reranker : typing.Optional[V4SearchRequestReranker] + reranker : typing.Optional[SearchRequestReranker] The reranking strategy applied to retrieved results. Defaults to rrf. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -2291,7 +2495,7 @@ def search_thread_summaries( OK """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/search/thread-summaries", + f"graphs/{encode_path_param(graph_uuid)}/search/thread-summaries", method="POST", params={ "limit": limit, @@ -2309,7 +2513,7 @@ def search_thread_summaries( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -2336,7 +2540,6 @@ def search_thread_summaries( filters=filters, mmr_lambda=mmr_lambda, reranker=reranker, - idempotency_key=idempotency_key, request_options=request_options, ) return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) @@ -2403,11 +2606,10 @@ def get_subgraph( *, seed_node_uuids: typing.Sequence[str], depth: typing.Optional[int] = OMIT, - direction: typing.Optional[V4SubgraphRequestDirection] = OMIT, + direction: typing.Optional[SubgraphRequestDirection] = OMIT, filters: typing.Optional[SearchFilters] = OMIT, max_edges: typing.Optional[int] = OMIT, max_nodes: typing.Optional[int] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[SubgraphResponse]: """ @@ -2422,7 +2624,7 @@ def get_subgraph( depth : typing.Optional[int] The maximum traversal depth from the seed nodes. Defaults to 1. - direction : typing.Optional[V4SubgraphRequestDirection] + direction : typing.Optional[SubgraphRequestDirection] The edge orientation to follow during expansion: in, out, or both. Defaults to both. @@ -2435,8 +2637,6 @@ def get_subgraph( max_nodes : typing.Optional[int] The maximum number of nodes in the response. Defaults to 100. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -2446,7 +2646,7 @@ def get_subgraph( OK """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/subgraph", + f"graphs/{encode_path_param(graph_uuid)}/subgraph", method="POST", json={ "depth": depth, @@ -2460,7 +2660,7 @@ def get_subgraph( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -2556,10 +2756,10 @@ def warm( Accepted """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/warm", + f"graphs/{encode_path_param(graph_uuid)}/warm", method="POST", headers={ - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, ) @@ -2649,8 +2849,8 @@ def __init__(self, *, client_wrapper: AsyncClientWrapper): async def create( self, *, + content_policy: typing.Optional[GraphContentPolicyRequest] = OMIT, description: typing.Optional[str] = OMIT, - graph_id: typing.Optional[str] = OMIT, name: typing.Optional[str] = OMIT, time_zone: typing.Optional[str] = OMIT, idempotency_key: typing.Optional[str] = None, @@ -2659,12 +2859,14 @@ async def create( """ Parameters ---------- + content_policy : typing.Optional[GraphContentPolicyRequest] + Content policy additions for the graph. The graph binds the current + project content policy plus these additions, and the binding does not + change after creation. + description : typing.Optional[str] A description of the graph. - graph_id : typing.Optional[str] - An optional developer-assigned identifier for the graph. - name : typing.Optional[str] A display name for the graph. @@ -2685,14 +2887,16 @@ async def create( "graphs", method="POST", json={ + "content_policy": convert_and_respect_annotation_metadata( + object_=content_policy, annotation=GraphContentPolicyRequest, direction="write" + ), "description": description, - "graph_id": graph_id, "name": name, "time_zone": time_zone, }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -2780,10 +2984,9 @@ async def list( *, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, - order_by: typing.Optional[str] = None, - order: typing.Optional[str] = None, + order_by: typing.Optional[GraphListRequestOrderBy] = None, + order: typing.Optional[GraphListRequestOrder] = None, search: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Graph, GraphPage]: """ @@ -2795,18 +2998,16 @@ async def list( cursor : typing.Optional[str] Opaque page cursor - order_by : typing.Optional[str] + order_by : typing.Optional[GraphListRequestOrderBy] Sort field - order : typing.Optional[str] + order : typing.Optional[GraphListRequestOrder] asc or desc search : typing.Optional[str] Filters results to graphs whose name, description, or graph ID contains this text. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -2829,7 +3030,7 @@ async def list( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -2854,7 +3055,6 @@ async def _get_next(): order_by=order_by, order=order, search=search, - idempotency_key=idempotency_key, request_options=request_options, ) @@ -2922,7 +3122,6 @@ async def lookup( graph_id: typing.Optional[str] = OMIT, thread_id: typing.Optional[str] = OMIT, user_id: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[Graph]: """ @@ -2940,8 +3139,6 @@ async def lookup( The developer-assigned user ID to resolve to a UUID. Mutually exclusive with thread_id and graph_id. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -2960,7 +3157,7 @@ async def lookup( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -3039,7 +3236,7 @@ async def get( OK """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}", + f"graphs/{encode_path_param(graph_uuid)}", method="GET", request_options=request_options, ) @@ -3134,10 +3331,10 @@ async def delete( Accepted """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}", + f"graphs/{encode_path_param(graph_uuid)}", method="DELETE", headers={ - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, ) @@ -3255,7 +3452,7 @@ async def update( OK """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}", + f"graphs/{encode_path_param(graph_uuid)}", method="PATCH", json={ "description": description, @@ -3264,7 +3461,7 @@ async def update( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -3351,7 +3548,7 @@ async def clone( self, graph_uuid: str, *, - target_graph_id: typing.Optional[str] = OMIT, + request: CloneGraphRequest, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[CloneGraphResult]: @@ -3361,8 +3558,7 @@ async def clone( graph_uuid : str Graph UUID - target_graph_id : typing.Optional[str] - An optional name for the cloned graph. + request : CloneGraphRequest idempotency_key : typing.Optional[str] @@ -3375,14 +3571,12 @@ async def clone( Accepted """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/clone", + f"graphs/{encode_path_param(graph_uuid)}/clone", method="POST", - json={ - "target_graph_id": target_graph_id, - }, + json=request, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -3465,6 +3659,228 @@ async def clone( status_code=_response.status_code, headers=dict(_response.headers), body=_response_json ) + async def get_content_policy( + self, graph_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[GraphContentPolicy]: + """ + Returns the content policy the graph bound at creation. The policy of a graph does not change after creation. A graph without a content policy returns revision 0 with no categories and no rules. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[GraphContentPolicy] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"graphs/{encode_path_param(graph_uuid)}/content-policy", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + GraphContentPolicy, + parse_obj_as( + type_=GraphContentPolicy, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def list_content_policy_events( + self, + graph_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[ContentPolicyEvent, ContentPolicyEventPage]: + """ + Lists the content policy decisions recorded for a graph, newest first. Each event carries identifiers only. A graph without a content policy returns an empty list. + + Parameters + ---------- + graph_uuid : str + Graph UUID + + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + filters : typing.Optional[typing.Dict[str, typing.Any]] + Exact-match filters. Supported keys: episode_uuid and drop_reason. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[ContentPolicyEvent, ContentPolicyEventPage] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"graphs/{encode_path_param(graph_uuid)}/content-policy/events/list", + method="POST", + params={ + "limit": limit, + "cursor": cursor, + }, + json={ + "filters": filters, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + ContentPolicyEventPage, + parse_obj_as( + type_=ContentPolicyEventPage, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + + async def _get_next(): + return await self.list_content_policy_events( + graph_uuid, + limit=limit, + cursor=_parsed_next, + filters=filters, + request_options=request_options, + ) + + return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + async def get_context( self, graph_uuid: str, @@ -3473,9 +3889,8 @@ async def get_context( filters: typing.Optional[SearchFilters] = OMIT, include_results: typing.Optional[bool] = OMIT, max_characters: typing.Optional[int] = OMIT, - recency_bias: typing.Optional[V4GraphContextRequestRecencyBias] = OMIT, + recency_bias: typing.Optional[GraphContextRequestRecencyBias] = OMIT, template_uuid: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[GraphContextResponse]: """ @@ -3497,14 +3912,12 @@ async def get_context( max_characters : typing.Optional[int] The maximum number of characters in the assembled context block. - recency_bias : typing.Optional[V4GraphContextRequestRecencyBias] + recency_bias : typing.Optional[GraphContextRequestRecencyBias] Adjusts result selection to favor more recent graph data. template_uuid : typing.Optional[str] The UUID of a context template used to render the context block. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -3514,7 +3927,7 @@ async def get_context( OK """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/context", + f"graphs/{encode_path_param(graph_uuid)}/context", method="POST", json={ "filters": convert_and_respect_annotation_metadata( @@ -3528,7 +3941,7 @@ async def get_context( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -3629,7 +4042,7 @@ async def get_instructions( OK """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/instructions", + f"graphs/{encode_path_param(graph_uuid)}/instructions", method="GET", request_options=request_options, ) @@ -3723,7 +4136,7 @@ async def set_instructions( OK """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/instructions", + f"graphs/{encode_path_param(graph_uuid)}/instructions", method="PUT", json={ "inherited": inherited, @@ -3733,7 +4146,7 @@ async def set_instructions( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -3812,7 +4225,7 @@ async def get_observation_steering( OK """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/observation-steering", + f"graphs/{encode_path_param(graph_uuid)}/observation-steering", method="GET", request_options=request_options, ) @@ -3911,7 +4324,7 @@ async def set_observation_steering( OK """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/observation-steering", + f"graphs/{encode_path_param(graph_uuid)}/observation-steering", method="PUT", json={ "inherited": inherited, @@ -3922,7 +4335,7 @@ async def set_observation_steering( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -4001,7 +4414,7 @@ async def get_ontology( OK """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/ontology", + f"graphs/{encode_path_param(graph_uuid)}/ontology", method="GET", request_options=request_options, ) @@ -4066,6 +4479,7 @@ async def set_ontology( graph_uuid: str, *, edge_types: typing.Optional[typing.Sequence[EdgeType]] = OMIT, + entity_type_hierarchy: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, entity_types: typing.Optional[typing.Sequence[EntityType]] = OMIT, inherited: typing.Optional[bool] = OMIT, idempotency_key: typing.Optional[str] = None, @@ -4080,6 +4494,9 @@ async def set_ontology( edge_types : typing.Optional[typing.Sequence[EdgeType]] The edge types defined in the ontology in effect at this scope. + entity_type_hierarchy : typing.Optional[typing.Dict[str, typing.Any]] + The entity type hierarchy (spec ontology-1). Omitted when the ontology is flat. + entity_types : typing.Optional[typing.Sequence[EntityType]] The entity types defined in the ontology in effect at this scope. @@ -4098,12 +4515,13 @@ async def set_ontology( OK """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/ontology", + f"graphs/{encode_path_param(graph_uuid)}/ontology", method="PUT", json={ "edge_types": convert_and_respect_annotation_metadata( object_=edge_types, annotation=typing.Sequence[EdgeType], direction="write" ), + "entity_type_hierarchy": entity_type_hierarchy, "entity_types": convert_and_respect_annotation_metadata( object_=entity_types, annotation=typing.Sequence[EntityType], direction="write" ), @@ -4111,7 +4529,7 @@ async def set_ontology( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -4183,8 +4601,7 @@ async def search_edges( center_node_uuid: typing.Optional[str] = OMIT, filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - reranker: typing.Optional[V4SearchRequestReranker] = OMIT, - idempotency_key: typing.Optional[str] = None, + reranker: typing.Optional[SearchRequestReranker] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Edge, EdgePage]: """ @@ -4216,11 +4633,9 @@ async def search_edges( The diversity weighting used for maximal marginal relevance reranking. Required when reranker is mmr. - reranker : typing.Optional[V4SearchRequestReranker] + reranker : typing.Optional[SearchRequestReranker] The reranking strategy applied to retrieved results. Defaults to rrf. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -4230,7 +4645,7 @@ async def search_edges( OK """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/search/edges", + f"graphs/{encode_path_param(graph_uuid)}/search/edges", method="POST", params={ "limit": limit, @@ -4248,7 +4663,7 @@ async def search_edges( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -4277,7 +4692,6 @@ async def _get_next(): filters=filters, mmr_lambda=mmr_lambda, reranker=reranker, - idempotency_key=idempotency_key, request_options=request_options, ) @@ -4350,8 +4764,7 @@ async def search_episodes( center_node_uuid: typing.Optional[str] = OMIT, filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - reranker: typing.Optional[V4SearchRequestReranker] = OMIT, - idempotency_key: typing.Optional[str] = None, + reranker: typing.Optional[SearchRequestReranker] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Episode, EpisodePage]: """ @@ -4383,11 +4796,9 @@ async def search_episodes( The diversity weighting used for maximal marginal relevance reranking. Required when reranker is mmr. - reranker : typing.Optional[V4SearchRequestReranker] + reranker : typing.Optional[SearchRequestReranker] The reranking strategy applied to retrieved results. Defaults to rrf. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -4397,7 +4808,7 @@ async def search_episodes( OK """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/search/episodes", + f"graphs/{encode_path_param(graph_uuid)}/search/episodes", method="POST", params={ "limit": limit, @@ -4415,7 +4826,7 @@ async def search_episodes( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -4444,7 +4855,6 @@ async def _get_next(): filters=filters, mmr_lambda=mmr_lambda, reranker=reranker, - idempotency_key=idempotency_key, request_options=request_options, ) @@ -4517,8 +4927,7 @@ async def search_nodes( center_node_uuid: typing.Optional[str] = OMIT, filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - reranker: typing.Optional[V4SearchRequestReranker] = OMIT, - idempotency_key: typing.Optional[str] = None, + reranker: typing.Optional[SearchRequestReranker] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Node, NodePage]: """ @@ -4550,11 +4959,9 @@ async def search_nodes( The diversity weighting used for maximal marginal relevance reranking. Required when reranker is mmr. - reranker : typing.Optional[V4SearchRequestReranker] + reranker : typing.Optional[SearchRequestReranker] The reranking strategy applied to retrieved results. Defaults to rrf. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -4564,7 +4971,7 @@ async def search_nodes( OK """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/search/nodes", + f"graphs/{encode_path_param(graph_uuid)}/search/nodes", method="POST", params={ "limit": limit, @@ -4582,7 +4989,7 @@ async def search_nodes( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -4611,7 +5018,6 @@ async def _get_next(): filters=filters, mmr_lambda=mmr_lambda, reranker=reranker, - idempotency_key=idempotency_key, request_options=request_options, ) @@ -4684,8 +5090,7 @@ async def search_observations( center_node_uuid: typing.Optional[str] = OMIT, filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - reranker: typing.Optional[V4SearchRequestReranker] = OMIT, - idempotency_key: typing.Optional[str] = None, + reranker: typing.Optional[SearchRequestReranker] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Observation, ObservationPage]: """ @@ -4717,11 +5122,9 @@ async def search_observations( The diversity weighting used for maximal marginal relevance reranking. Required when reranker is mmr. - reranker : typing.Optional[V4SearchRequestReranker] + reranker : typing.Optional[SearchRequestReranker] The reranking strategy applied to retrieved results. Defaults to rrf. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -4731,7 +5134,7 @@ async def search_observations( OK """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/search/observations", + f"graphs/{encode_path_param(graph_uuid)}/search/observations", method="POST", params={ "limit": limit, @@ -4749,7 +5152,7 @@ async def search_observations( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -4778,7 +5181,6 @@ async def _get_next(): filters=filters, mmr_lambda=mmr_lambda, reranker=reranker, - idempotency_key=idempotency_key, request_options=request_options, ) @@ -4851,8 +5253,7 @@ async def search_thread_summaries( center_node_uuid: typing.Optional[str] = OMIT, filters: typing.Optional[SearchFilters] = OMIT, mmr_lambda: typing.Optional[float] = OMIT, - reranker: typing.Optional[V4SearchRequestReranker] = OMIT, - idempotency_key: typing.Optional[str] = None, + reranker: typing.Optional[SearchRequestReranker] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[ThreadSummary, ThreadSummaryPage]: """ @@ -4884,11 +5285,9 @@ async def search_thread_summaries( The diversity weighting used for maximal marginal relevance reranking. Required when reranker is mmr. - reranker : typing.Optional[V4SearchRequestReranker] + reranker : typing.Optional[SearchRequestReranker] The reranking strategy applied to retrieved results. Defaults to rrf. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -4898,7 +5297,7 @@ async def search_thread_summaries( OK """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/search/thread-summaries", + f"graphs/{encode_path_param(graph_uuid)}/search/thread-summaries", method="POST", params={ "limit": limit, @@ -4916,7 +5315,7 @@ async def search_thread_summaries( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -4945,7 +5344,6 @@ async def _get_next(): filters=filters, mmr_lambda=mmr_lambda, reranker=reranker, - idempotency_key=idempotency_key, request_options=request_options, ) @@ -5013,11 +5411,10 @@ async def get_subgraph( *, seed_node_uuids: typing.Sequence[str], depth: typing.Optional[int] = OMIT, - direction: typing.Optional[V4SubgraphRequestDirection] = OMIT, + direction: typing.Optional[SubgraphRequestDirection] = OMIT, filters: typing.Optional[SearchFilters] = OMIT, max_edges: typing.Optional[int] = OMIT, max_nodes: typing.Optional[int] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[SubgraphResponse]: """ @@ -5032,7 +5429,7 @@ async def get_subgraph( depth : typing.Optional[int] The maximum traversal depth from the seed nodes. Defaults to 1. - direction : typing.Optional[V4SubgraphRequestDirection] + direction : typing.Optional[SubgraphRequestDirection] The edge orientation to follow during expansion: in, out, or both. Defaults to both. @@ -5045,8 +5442,6 @@ async def get_subgraph( max_nodes : typing.Optional[int] The maximum number of nodes in the response. Defaults to 100. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -5056,7 +5451,7 @@ async def get_subgraph( OK """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/subgraph", + f"graphs/{encode_path_param(graph_uuid)}/subgraph", method="POST", json={ "depth": depth, @@ -5070,7 +5465,7 @@ async def get_subgraph( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -5166,10 +5561,10 @@ async def warm( Accepted """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/warm", + f"graphs/{encode_path_param(graph_uuid)}/warm", method="POST", headers={ - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, ) diff --git a/src/zep_cloud/graph/thread_summary/client.py b/src/zep_cloud/graph/thread_summary/client.py index 3cca6737..2f445ecb 100644 --- a/src/zep_cloud/graph/thread_summary/client.py +++ b/src/zep_cloud/graph/thread_summary/client.py @@ -35,7 +35,6 @@ def list( limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[ThreadSummary, ThreadSummaryPage]: """ @@ -53,8 +52,6 @@ def list( filters : typing.Optional[typing.Dict[str, typing.Any]] Filters constraining which items are returned. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -72,8 +69,6 @@ def list( ) response = client.graph.thread_summary.list( graph_uuid="graph_uuid", - limit=1, - cursor="cursor", ) for item in response: yield item @@ -82,12 +77,7 @@ def list( yield page """ return self._raw_client.list( - graph_uuid, - limit=limit, - cursor=cursor, - filters=filters, - idempotency_key=idempotency_key, - request_options=request_options, + graph_uuid, limit=limit, cursor=cursor, filters=filters, request_options=request_options ) @@ -113,7 +103,6 @@ async def list( limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[ThreadSummary, ThreadSummaryPage]: """ @@ -131,8 +120,6 @@ async def list( filters : typing.Optional[typing.Dict[str, typing.Any]] Filters constraining which items are returned. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -155,8 +142,6 @@ async def list( async def main() -> None: response = await client.graph.thread_summary.list( graph_uuid="graph_uuid", - limit=1, - cursor="cursor", ) async for item in response: yield item @@ -169,10 +154,5 @@ async def main() -> None: asyncio.run(main()) """ return await self._raw_client.list( - graph_uuid, - limit=limit, - cursor=cursor, - filters=filters, - idempotency_key=idempotency_key, - request_options=request_options, + graph_uuid, limit=limit, cursor=cursor, filters=filters, request_options=request_options ) diff --git a/src/zep_cloud/graph/thread_summary/raw_client.py b/src/zep_cloud/graph/thread_summary/raw_client.py index ef650ac3..74ec97dc 100644 --- a/src/zep_cloud/graph/thread_summary/raw_client.py +++ b/src/zep_cloud/graph/thread_summary/raw_client.py @@ -5,7 +5,8 @@ from ...core.api_error import ApiError as core_api_error_ApiError from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper -from ...core.jsonable_encoder import jsonable_encoder +from ...core.idempotency import generate_idempotency_key +from ...core.jsonable_encoder import encode_path_param from ...core.pagination import AsyncPager, SyncPager from ...core.parse_error import ParsingError from ...core.pydantic_utilities import parse_obj_as @@ -35,7 +36,6 @@ def list( limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[ThreadSummary, ThreadSummaryPage]: """ @@ -53,8 +53,6 @@ def list( filters : typing.Optional[typing.Dict[str, typing.Any]] Filters constraining which items are returned. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -64,7 +62,7 @@ def list( OK """ _response = self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/thread-summaries/list", + f"graphs/{encode_path_param(graph_uuid)}/thread-summaries/list", method="POST", params={ "limit": limit, @@ -75,7 +73,7 @@ def list( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -97,7 +95,6 @@ def list( limit=limit, cursor=_parsed_next, filters=filters, - idempotency_key=idempotency_key, request_options=request_options, ) return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) @@ -181,7 +178,6 @@ async def list( limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, filters: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[ThreadSummary, ThreadSummaryPage]: """ @@ -199,8 +195,6 @@ async def list( filters : typing.Optional[typing.Dict[str, typing.Any]] Filters constraining which items are returned. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -210,7 +204,7 @@ async def list( OK """ _response = await self._client_wrapper.httpx_client.request( - f"graphs/{jsonable_encoder(graph_uuid)}/thread-summaries/list", + f"graphs/{encode_path_param(graph_uuid)}/thread-summaries/list", method="POST", params={ "limit": limit, @@ -221,7 +215,7 @@ async def list( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -245,7 +239,6 @@ async def _get_next(): limit=limit, cursor=_parsed_next, filters=filters, - idempotency_key=idempotency_key, request_options=request_options, ) diff --git a/src/zep_cloud/graph/types/__init__.py b/src/zep_cloud/graph/types/__init__.py index 9b446df3..a6aca73a 100644 --- a/src/zep_cloud/graph/types/__init__.py +++ b/src/zep_cloud/graph/types/__init__.py @@ -6,11 +6,15 @@ from importlib import import_module if typing.TYPE_CHECKING: - from .v4graph_context_request_recency_bias import V4GraphContextRequestRecencyBias - from .v4subgraph_request_direction import V4SubgraphRequestDirection + from .graph_context_request_recency_bias import GraphContextRequestRecencyBias + from .graph_list_request_order import GraphListRequestOrder + from .graph_list_request_order_by import GraphListRequestOrderBy + from .subgraph_request_direction import SubgraphRequestDirection _dynamic_imports: typing.Dict[str, str] = { - "V4GraphContextRequestRecencyBias": ".v4graph_context_request_recency_bias", - "V4SubgraphRequestDirection": ".v4subgraph_request_direction", + "GraphContextRequestRecencyBias": ".graph_context_request_recency_bias", + "GraphListRequestOrder": ".graph_list_request_order", + "GraphListRequestOrderBy": ".graph_list_request_order_by", + "SubgraphRequestDirection": ".subgraph_request_direction", } @@ -35,4 +39,9 @@ def __dir__(): return sorted(lazy_attrs) -__all__ = ["V4GraphContextRequestRecencyBias", "V4SubgraphRequestDirection"] +__all__ = [ + "GraphContextRequestRecencyBias", + "GraphListRequestOrder", + "GraphListRequestOrderBy", + "SubgraphRequestDirection", +] diff --git a/src/zep_cloud/graph/types/graph_context_request_recency_bias.py b/src/zep_cloud/graph/types/graph_context_request_recency_bias.py new file mode 100644 index 00000000..54fd263e --- /dev/null +++ b/src/zep_cloud/graph/types/graph_context_request_recency_bias.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +GraphContextRequestRecencyBias = typing.Union[typing.Literal["off", "mild", "strong"], typing.Any] diff --git a/src/zep_cloud/graph/types/graph_list_request_order.py b/src/zep_cloud/graph/types/graph_list_request_order.py new file mode 100644 index 00000000..e2c966f7 --- /dev/null +++ b/src/zep_cloud/graph/types/graph_list_request_order.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +GraphListRequestOrder = typing.Union[typing.Literal["asc", "desc"], typing.Any] diff --git a/src/zep_cloud/graph/types/graph_list_request_order_by.py b/src/zep_cloud/graph/types/graph_list_request_order_by.py new file mode 100644 index 00000000..af7b3552 --- /dev/null +++ b/src/zep_cloud/graph/types/graph_list_request_order_by.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +GraphListRequestOrderBy = typing.Union[typing.Literal["created_at", "name", "uuid"], typing.Any] diff --git a/src/zep_cloud/graph/types/subgraph_request_direction.py b/src/zep_cloud/graph/types/subgraph_request_direction.py new file mode 100644 index 00000000..b1c6cfc4 --- /dev/null +++ b/src/zep_cloud/graph/types/subgraph_request_direction.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +SubgraphRequestDirection = typing.Union[typing.Literal["in", "out", "both"], typing.Any] diff --git a/src/zep_cloud/graph/types/v4graph_context_request_recency_bias.py b/src/zep_cloud/graph/types/v4graph_context_request_recency_bias.py deleted file mode 100644 index ac1a67b5..00000000 --- a/src/zep_cloud/graph/types/v4graph_context_request_recency_bias.py +++ /dev/null @@ -1,5 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -V4GraphContextRequestRecencyBias = typing.Union[typing.Literal["off", "mild", "strong"], typing.Any] diff --git a/src/zep_cloud/graph/types/v4subgraph_request_direction.py b/src/zep_cloud/graph/types/v4subgraph_request_direction.py deleted file mode 100644 index ac84fb19..00000000 --- a/src/zep_cloud/graph/types/v4subgraph_request_direction.py +++ /dev/null @@ -1,5 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -V4SubgraphRequestDirection = typing.Union[typing.Literal["in", "out", "both"], typing.Any] diff --git a/src/zep_cloud/lookup/client.py b/src/zep_cloud/lookup/client.py index b9a11ce7..ab8ca1d2 100644 --- a/src/zep_cloud/lookup/client.py +++ b/src/zep_cloud/lookup/client.py @@ -32,7 +32,6 @@ def batch( graphs: typing.Optional[typing.Sequence[str]] = OMIT, threads: typing.Optional[typing.Sequence[str]] = OMIT, users: typing.Optional[typing.Sequence[str]] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> LookupBatchResponse: """ @@ -47,8 +46,6 @@ def batch( users : typing.Optional[typing.Sequence[str]] Developer-assigned user IDs to resolve to UUIDs. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -66,13 +63,7 @@ def batch( ) client.lookup.batch() """ - _response = self._raw_client.batch( - graphs=graphs, - threads=threads, - users=users, - idempotency_key=idempotency_key, - request_options=request_options, - ) + _response = self._raw_client.batch(graphs=graphs, threads=threads, users=users, request_options=request_options) return _response.data @@ -97,7 +88,6 @@ async def batch( graphs: typing.Optional[typing.Sequence[str]] = OMIT, threads: typing.Optional[typing.Sequence[str]] = OMIT, users: typing.Optional[typing.Sequence[str]] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> LookupBatchResponse: """ @@ -112,8 +102,6 @@ async def batch( users : typing.Optional[typing.Sequence[str]] Developer-assigned user IDs to resolve to UUIDs. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -140,10 +128,6 @@ async def main() -> None: asyncio.run(main()) """ _response = await self._raw_client.batch( - graphs=graphs, - threads=threads, - users=users, - idempotency_key=idempotency_key, - request_options=request_options, + graphs=graphs, threads=threads, users=users, request_options=request_options ) return _response.data diff --git a/src/zep_cloud/lookup/raw_client.py b/src/zep_cloud/lookup/raw_client.py index 05de7f5c..9842c654 100644 --- a/src/zep_cloud/lookup/raw_client.py +++ b/src/zep_cloud/lookup/raw_client.py @@ -6,6 +6,7 @@ from ..core.api_error import ApiError as core_api_error_ApiError from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ..core.http_response import AsyncHttpResponse, HttpResponse +from ..core.idempotency import generate_idempotency_key from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as from ..core.request_options import RequestOptions @@ -30,7 +31,6 @@ def batch( graphs: typing.Optional[typing.Sequence[str]] = OMIT, threads: typing.Optional[typing.Sequence[str]] = OMIT, users: typing.Optional[typing.Sequence[str]] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[LookupBatchResponse]: """ @@ -45,8 +45,6 @@ def batch( users : typing.Optional[typing.Sequence[str]] Developer-assigned user IDs to resolve to UUIDs. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -65,7 +63,7 @@ def batch( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -137,7 +135,6 @@ async def batch( graphs: typing.Optional[typing.Sequence[str]] = OMIT, threads: typing.Optional[typing.Sequence[str]] = OMIT, users: typing.Optional[typing.Sequence[str]] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[LookupBatchResponse]: """ @@ -152,8 +149,6 @@ async def batch( users : typing.Optional[typing.Sequence[str]] Developer-assigned user IDs to resolve to UUIDs. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -172,7 +167,7 @@ async def batch( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, diff --git a/src/zep_cloud/project/client.py b/src/zep_cloud/project/client.py index bb2e0771..eef704ef 100644 --- a/src/zep_cloud/project/client.py +++ b/src/zep_cloud/project/client.py @@ -3,7 +3,12 @@ import typing from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.pagination import AsyncPager, SyncPager from ..core.request_options import RequestOptions +from ..types.content_policy import ContentPolicy +from ..types.content_policy_category_request import ContentPolicyCategoryRequest +from ..types.content_policy_revision_page import ContentPolicyRevisionPage +from ..types.content_policy_rule_request import ContentPolicyRuleRequest from ..types.custom_instruction import CustomInstruction from ..types.edge_type import EdgeType from ..types.entity_type import EntityType @@ -63,6 +68,7 @@ def update( self, *, default_time_zone: typing.Optional[str] = OMIT, + include_policy_violating_episodes: typing.Optional[bool] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> Project: @@ -73,6 +79,10 @@ def update( The project's IANA fallback time zone. Set to null to clear the existing value. + include_policy_violating_episodes : typing.Optional[bool] + When true, episode reads on graphs with a content policy include the + episodes that violated the policy. + idempotency_key : typing.Optional[str] request_options : typing.Optional[RequestOptions] @@ -93,8 +103,156 @@ def update( client.project.update() """ _response = self._raw_client.update( - default_time_zone=default_time_zone, idempotency_key=idempotency_key, request_options=request_options + default_time_zone=default_time_zone, + include_policy_violating_episodes=include_policy_violating_episodes, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + def get_content_policy(self, *, request_options: typing.Optional[RequestOptions] = None) -> ContentPolicy: + """ + Returns the current content policy revision of the project. A new graph binds this revision at creation. + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ContentPolicy + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.project.get_content_policy() + """ + _response = self._raw_client.get_content_policy(request_options=request_options) + return _response.data + + def set_content_policy( + self, + *, + categories: typing.Optional[typing.Sequence[ContentPolicyCategoryRequest]] = OMIT, + rules: typing.Optional[typing.Sequence[ContentPolicyRuleRequest]] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> ContentPolicy: + """ + Replaces the project content policy and creates a new immutable revision. Graphs that already exist keep the revision they bound. An empty policy (no categories and no rules) removes the content policy for new graphs. + + Parameters + ---------- + categories : typing.Optional[typing.Sequence[ContentPolicyCategoryRequest]] + The categories of the policy. Maximum 16. An empty list with no rules + means no content policy. + + rules : typing.Optional[typing.Sequence[ContentPolicyRuleRequest]] + The rules of the policy. Maximum 32. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ContentPolicy + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.project.set_content_policy() + """ + _response = self._raw_client.set_content_policy( + categories=categories, rules=rules, idempotency_key=idempotency_key, request_options=request_options + ) + return _response.data + + def list_content_policy_revisions( + self, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[ContentPolicy, ContentPolicyRevisionPage]: + """ + Lists every revision of the project content policy, newest first, including revision 0. + + Parameters + ---------- + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[ContentPolicy, ContentPolicyRevisionPage] + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + response = client.project.list_content_policy_revisions() + for item in response: + yield item + # alternatively, you can paginate page-by-page + for page in response.iter_pages(): + yield page + """ + return self._raw_client.list_content_policy_revisions( + limit=limit, cursor=cursor, request_options=request_options + ) + + def get_content_policy_revision( + self, revision_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> ContentPolicy: + """ + Parameters + ---------- + revision_uuid : str + Revision UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ContentPolicy + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", ) + client.project.get_content_policy_revision( + revision_uuid="revision_uuid", + ) + """ + _response = self._raw_client.get_content_policy_revision(revision_uuid, request_options=request_options) return _response.data def get_instructions(self, *, request_options: typing.Optional[RequestOptions] = None) -> Instructions: @@ -273,17 +431,23 @@ def set_ontology( self, *, edge_types: typing.Optional[typing.Sequence[EdgeType]] = OMIT, + entity_type_hierarchy: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, entity_types: typing.Optional[typing.Sequence[EntityType]] = OMIT, inherited: typing.Optional[bool] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> Ontology: """ + Replaces the entity types and the edge types that the project uses. + Parameters ---------- edge_types : typing.Optional[typing.Sequence[EdgeType]] The edge types defined in the ontology in effect at this scope. + entity_type_hierarchy : typing.Optional[typing.Dict[str, typing.Any]] + The entity type hierarchy (spec ontology-1). Omitted when the ontology is flat. + entity_types : typing.Optional[typing.Sequence[EntityType]] The entity types defined in the ontology in effect at this scope. @@ -312,6 +476,7 @@ def set_ontology( """ _response = self._raw_client.set_ontology( edge_types=edge_types, + entity_type_hierarchy=entity_type_hierarchy, entity_types=entity_types, inherited=inherited, idempotency_key=idempotency_key, @@ -443,6 +608,7 @@ async def update( self, *, default_time_zone: typing.Optional[str] = OMIT, + include_policy_violating_episodes: typing.Optional[bool] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> Project: @@ -453,6 +619,10 @@ async def update( The project's IANA fallback time zone. Set to null to clear the existing value. + include_policy_violating_episodes : typing.Optional[bool] + When true, episode reads on graphs with a content policy include the + episodes that violated the policy. + idempotency_key : typing.Optional[str] request_options : typing.Optional[RequestOptions] @@ -481,8 +651,189 @@ async def main() -> None: asyncio.run(main()) """ _response = await self._raw_client.update( - default_time_zone=default_time_zone, idempotency_key=idempotency_key, request_options=request_options + default_time_zone=default_time_zone, + include_policy_violating_episodes=include_policy_violating_episodes, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + async def get_content_policy(self, *, request_options: typing.Optional[RequestOptions] = None) -> ContentPolicy: + """ + Returns the current content policy revision of the project. A new graph binds this revision at creation. + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ContentPolicy + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.project.get_content_policy() + + + asyncio.run(main()) + """ + _response = await self._raw_client.get_content_policy(request_options=request_options) + return _response.data + + async def set_content_policy( + self, + *, + categories: typing.Optional[typing.Sequence[ContentPolicyCategoryRequest]] = OMIT, + rules: typing.Optional[typing.Sequence[ContentPolicyRuleRequest]] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> ContentPolicy: + """ + Replaces the project content policy and creates a new immutable revision. Graphs that already exist keep the revision they bound. An empty policy (no categories and no rules) removes the content policy for new graphs. + + Parameters + ---------- + categories : typing.Optional[typing.Sequence[ContentPolicyCategoryRequest]] + The categories of the policy. Maximum 16. An empty list with no rules + means no content policy. + + rules : typing.Optional[typing.Sequence[ContentPolicyRuleRequest]] + The rules of the policy. Maximum 32. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ContentPolicy + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.project.set_content_policy() + + + asyncio.run(main()) + """ + _response = await self._raw_client.set_content_policy( + categories=categories, rules=rules, idempotency_key=idempotency_key, request_options=request_options + ) + return _response.data + + async def list_content_policy_revisions( + self, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[ContentPolicy, ContentPolicyRevisionPage]: + """ + Lists every revision of the project content policy, newest first, including revision 0. + + Parameters + ---------- + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[ContentPolicy, ContentPolicyRevisionPage] + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + response = await client.project.list_content_policy_revisions() + async for item in response: + yield item + + # alternatively, you can paginate page-by-page + async for page in response.iter_pages(): + yield page + + + asyncio.run(main()) + """ + return await self._raw_client.list_content_policy_revisions( + limit=limit, cursor=cursor, request_options=request_options ) + + async def get_content_policy_revision( + self, revision_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> ContentPolicy: + """ + Parameters + ---------- + revision_uuid : str + Revision UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ContentPolicy + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.project.get_content_policy_revision( + revision_uuid="revision_uuid", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get_content_policy_revision(revision_uuid, request_options=request_options) return _response.data async def get_instructions(self, *, request_options: typing.Optional[RequestOptions] = None) -> Instructions: @@ -701,17 +1052,23 @@ async def set_ontology( self, *, edge_types: typing.Optional[typing.Sequence[EdgeType]] = OMIT, + entity_type_hierarchy: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, entity_types: typing.Optional[typing.Sequence[EntityType]] = OMIT, inherited: typing.Optional[bool] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> Ontology: """ + Replaces the entity types and the edge types that the project uses. + Parameters ---------- edge_types : typing.Optional[typing.Sequence[EdgeType]] The edge types defined in the ontology in effect at this scope. + entity_type_hierarchy : typing.Optional[typing.Dict[str, typing.Any]] + The entity type hierarchy (spec ontology-1). Omitted when the ontology is flat. + entity_types : typing.Optional[typing.Sequence[EntityType]] The entity types defined in the ontology in effect at this scope. @@ -748,6 +1105,7 @@ async def main() -> None: """ _response = await self._raw_client.set_ontology( edge_types=edge_types, + entity_type_hierarchy=entity_type_hierarchy, entity_types=entity_types, inherited=inherited, idempotency_key=idempotency_key, diff --git a/src/zep_cloud/project/raw_client.py b/src/zep_cloud/project/raw_client.py index c0eef778..332fcbf1 100644 --- a/src/zep_cloud/project/raw_client.py +++ b/src/zep_cloud/project/raw_client.py @@ -6,15 +6,23 @@ from ..core.api_error import ApiError as core_api_error_ApiError from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ..core.http_response import AsyncHttpResponse, HttpResponse +from ..core.idempotency import generate_idempotency_key +from ..core.jsonable_encoder import encode_path_param +from ..core.pagination import AsyncPager, SyncPager from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as from ..core.request_options import RequestOptions from ..core.serialization import convert_and_respect_annotation_metadata from ..errors.bad_request_error import BadRequestError from ..errors.conflict_error import ConflictError +from ..errors.forbidden_error import ForbiddenError from ..errors.not_found_error import NotFoundError from ..errors.unauthorized_error import UnauthorizedError from ..types.api_error import ApiError as types_api_error_ApiError +from ..types.content_policy import ContentPolicy +from ..types.content_policy_category_request import ContentPolicyCategoryRequest +from ..types.content_policy_revision_page import ContentPolicyRevisionPage +from ..types.content_policy_rule_request import ContentPolicyRuleRequest from ..types.custom_instruction import CustomInstruction from ..types.edge_type import EdgeType from ..types.entity_type import EntityType @@ -112,6 +120,7 @@ def update( self, *, default_time_zone: typing.Optional[str] = OMIT, + include_policy_violating_episodes: typing.Optional[bool] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[Project]: @@ -122,6 +131,10 @@ def update( The project's IANA fallback time zone. Set to null to clear the existing value. + include_policy_violating_episodes : typing.Optional[bool] + When true, episode reads on graphs with a content policy include the + episodes that violated the policy. + idempotency_key : typing.Optional[str] request_options : typing.Optional[RequestOptions] @@ -137,10 +150,11 @@ def update( method="PATCH", json={ "default_time_zone": default_time_zone, + "include_policy_violating_episodes": include_policy_violating_episodes, }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -212,10 +226,12 @@ def update( status_code=_response.status_code, headers=dict(_response.headers), body=_response_json ) - def get_instructions( + def get_content_policy( self, *, request_options: typing.Optional[RequestOptions] = None - ) -> HttpResponse[Instructions]: + ) -> HttpResponse[ContentPolicy]: """ + Returns the current content policy revision of the project. A new graph binds this revision at creation. + Parameters ---------- request_options : typing.Optional[RequestOptions] @@ -223,20 +239,732 @@ def get_instructions( Returns ------- - HttpResponse[Instructions] + HttpResponse[ContentPolicy] OK """ _response = self._client_wrapper.httpx_client.request( - "project/instructions", + "project/content-policy", method="GET", request_options=request_options, ) try: if 200 <= _response.status_code < 300: _data = typing.cast( - Instructions, + ContentPolicy, + parse_obj_as( + type_=ContentPolicy, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def set_content_policy( + self, + *, + categories: typing.Optional[typing.Sequence[ContentPolicyCategoryRequest]] = OMIT, + rules: typing.Optional[typing.Sequence[ContentPolicyRuleRequest]] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[ContentPolicy]: + """ + Replaces the project content policy and creates a new immutable revision. Graphs that already exist keep the revision they bound. An empty policy (no categories and no rules) removes the content policy for new graphs. + + Parameters + ---------- + categories : typing.Optional[typing.Sequence[ContentPolicyCategoryRequest]] + The categories of the policy. Maximum 16. An empty list with no rules + means no content policy. + + rules : typing.Optional[typing.Sequence[ContentPolicyRuleRequest]] + The rules of the policy. Maximum 32. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[ContentPolicy] + OK + """ + _response = self._client_wrapper.httpx_client.request( + "project/content-policy", + method="PUT", + json={ + "categories": convert_and_respect_annotation_metadata( + object_=categories, annotation=typing.Sequence[ContentPolicyCategoryRequest], direction="write" + ), + "rules": convert_and_respect_annotation_metadata( + object_=rules, annotation=typing.Sequence[ContentPolicyRuleRequest], direction="write" + ), + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ContentPolicy, + parse_obj_as( + type_=ContentPolicy, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def list_content_policy_revisions( + self, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[ContentPolicy, ContentPolicyRevisionPage]: + """ + Lists every revision of the project content policy, newest first, including revision 0. + + Parameters + ---------- + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[ContentPolicy, ContentPolicyRevisionPage] + OK + """ + _response = self._client_wrapper.httpx_client.request( + "project/content-policy/revisions", + method="GET", + params={ + "limit": limit, + "cursor": cursor, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + ContentPolicyRevisionPage, + parse_obj_as( + type_=ContentPolicyRevisionPage, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + _get_next = lambda: self.list_content_policy_revisions( + limit=limit, + cursor=_parsed_next, + request_options=request_options, + ) + return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def get_content_policy_revision( + self, revision_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[ContentPolicy]: + """ + Parameters + ---------- + revision_uuid : str + Revision UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[ContentPolicy] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"project/content-policy/revisions/{encode_path_param(revision_uuid)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ContentPolicy, + parse_obj_as( + type_=ContentPolicy, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def get_instructions( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[Instructions]: + """ + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[Instructions] + OK + """ + _response = self._client_wrapper.httpx_client.request( + "project/instructions", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + Instructions, + parse_obj_as( + type_=Instructions, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def set_instructions( + self, + *, + inherited: typing.Optional[bool] = OMIT, + instructions: typing.Optional[typing.Sequence[CustomInstruction]] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[Instructions]: + """ + Parameters + ---------- + inherited : typing.Optional[bool] + Whether this is the project's default value rather than an override set on + this graph. + + instructions : typing.Optional[typing.Sequence[CustomInstruction]] + The custom extraction instructions in effect at this scope, each with a + name and text. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[Instructions] + OK + """ + _response = self._client_wrapper.httpx_client.request( + "project/instructions", + method="PUT", + json={ + "inherited": inherited, + "instructions": convert_and_respect_annotation_metadata( + object_=instructions, annotation=typing.Sequence[CustomInstruction], direction="write" + ), + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + Instructions, + parse_obj_as( + type_=Instructions, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def get_observation_steering( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[ObservationSteering]: + """ + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[ObservationSteering] + OK + """ + _response = self._client_wrapper.httpx_client.request( + "project/observation-steering", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ObservationSteering, + parse_obj_as( + type_=ObservationSteering, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def set_observation_steering( + self, + *, + inherited: typing.Optional[bool] = OMIT, + instruction: typing.Optional[str] = OMIT, + types: typing.Optional[typing.Sequence[ObservationType]] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[ObservationSteering]: + """ + Parameters + ---------- + inherited : typing.Optional[bool] + Whether this is the project's default value rather than an override set on + this graph. + + instruction : typing.Optional[str] + The natural-language instruction steering how observations are generated + at this scope. + + types : typing.Optional[typing.Sequence[ObservationType]] + The named observation types, each with a description, that generation + should steer toward at this scope. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[ObservationSteering] + OK + """ + _response = self._client_wrapper.httpx_client.request( + "project/observation-steering", + method="PUT", + json={ + "inherited": inherited, + "instruction": instruction, + "types": convert_and_respect_annotation_metadata( + object_=types, annotation=typing.Sequence[ObservationType], direction="write" + ), + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ObservationSteering, + parse_obj_as( + type_=ObservationSteering, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def get_ontology(self, *, request_options: typing.Optional[RequestOptions] = None) -> HttpResponse[Ontology]: + """ + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[Ontology] + OK + """ + _response = self._client_wrapper.httpx_client.request( + "project/ontology", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + Ontology, parse_obj_as( - type_=Instructions, # type: ignore + type_=Ontology, # type: ignore object_=_response.json(), ), ) @@ -287,25 +1015,34 @@ def get_instructions( status_code=_response.status_code, headers=dict(_response.headers), body=_response_json ) - def set_instructions( + def set_ontology( self, *, + edge_types: typing.Optional[typing.Sequence[EdgeType]] = OMIT, + entity_type_hierarchy: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + entity_types: typing.Optional[typing.Sequence[EntityType]] = OMIT, inherited: typing.Optional[bool] = OMIT, - instructions: typing.Optional[typing.Sequence[CustomInstruction]] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, - ) -> HttpResponse[Instructions]: + ) -> HttpResponse[Ontology]: """ + Replaces the entity types and the edge types that the project uses. + Parameters ---------- + edge_types : typing.Optional[typing.Sequence[EdgeType]] + The edge types defined in the ontology in effect at this scope. + + entity_type_hierarchy : typing.Optional[typing.Dict[str, typing.Any]] + The entity type hierarchy (spec ontology-1). Omitted when the ontology is flat. + + entity_types : typing.Optional[typing.Sequence[EntityType]] + The entity types defined in the ontology in effect at this scope. + inherited : typing.Optional[bool] Whether this is the project's default value rather than an override set on this graph. - instructions : typing.Optional[typing.Sequence[CustomInstruction]] - The custom extraction instructions in effect at this scope, each with a - name and text. - idempotency_key : typing.Optional[str] request_options : typing.Optional[RequestOptions] @@ -313,21 +1050,25 @@ def set_instructions( Returns ------- - HttpResponse[Instructions] + HttpResponse[Ontology] OK """ _response = self._client_wrapper.httpx_client.request( - "project/instructions", + "project/ontology", method="PUT", json={ - "inherited": inherited, - "instructions": convert_and_respect_annotation_metadata( - object_=instructions, annotation=typing.Sequence[CustomInstruction], direction="write" + "edge_types": convert_and_respect_annotation_metadata( + object_=edge_types, annotation=typing.Sequence[EdgeType], direction="write" + ), + "entity_type_hierarchy": entity_type_hierarchy, + "entity_types": convert_and_respect_annotation_metadata( + object_=entity_types, annotation=typing.Sequence[EntityType], direction="write" ), + "inherited": inherited, }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -335,9 +1076,9 @@ def set_instructions( try: if 200 <= _response.status_code < 300: _data = typing.cast( - Instructions, + Ontology, parse_obj_as( - type_=Instructions, # type: ignore + type_=Ontology, # type: ignore object_=_response.json(), ), ) @@ -388,9 +1129,9 @@ def set_instructions( status_code=_response.status_code, headers=dict(_response.headers), body=_response_json ) - def get_observation_steering( + def get_user_summary_instructions( self, *, request_options: typing.Optional[RequestOptions] = None - ) -> HttpResponse[ObservationSteering]: + ) -> HttpResponse[UserSummaryInstructions]: """ Parameters ---------- @@ -399,20 +1140,20 @@ def get_observation_steering( Returns ------- - HttpResponse[ObservationSteering] + HttpResponse[UserSummaryInstructions] OK """ _response = self._client_wrapper.httpx_client.request( - "project/observation-steering", + "project/user-summary-instructions", method="GET", request_options=request_options, ) try: if 200 <= _response.status_code < 300: _data = typing.cast( - ObservationSteering, + UserSummaryInstructions, parse_obj_as( - type_=ObservationSteering, # type: ignore + type_=UserSummaryInstructions, # type: ignore object_=_response.json(), ), ) @@ -463,15 +1204,14 @@ def get_observation_steering( status_code=_response.status_code, headers=dict(_response.headers), body=_response_json ) - def set_observation_steering( + def set_user_summary_instructions( self, *, inherited: typing.Optional[bool] = OMIT, - instruction: typing.Optional[str] = OMIT, - types: typing.Optional[typing.Sequence[ObservationType]] = OMIT, + instructions: typing.Optional[typing.Sequence[UserInstruction]] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, - ) -> HttpResponse[ObservationSteering]: + ) -> HttpResponse[UserSummaryInstructions]: """ Parameters ---------- @@ -479,13 +1219,9 @@ def set_observation_steering( Whether this is the project's default value rather than an override set on this graph. - instruction : typing.Optional[str] - The natural-language instruction steering how observations are generated - at this scope. - - types : typing.Optional[typing.Sequence[ObservationType]] - The named observation types, each with a description, that generation - should steer toward at this scope. + instructions : typing.Optional[typing.Sequence[UserInstruction]] + The custom instructions used when generating a user's summary at this + scope, each with a name and text. idempotency_key : typing.Optional[str] @@ -494,22 +1230,21 @@ def set_observation_steering( Returns ------- - HttpResponse[ObservationSteering] + HttpResponse[UserSummaryInstructions] OK """ _response = self._client_wrapper.httpx_client.request( - "project/observation-steering", + "project/user-summary-instructions", method="PUT", json={ "inherited": inherited, - "instruction": instruction, - "types": convert_and_respect_annotation_metadata( - object_=types, annotation=typing.Sequence[ObservationType], direction="write" + "instructions": convert_and_respect_annotation_metadata( + object_=instructions, annotation=typing.Sequence[UserInstruction], direction="write" ), }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -517,9 +1252,9 @@ def set_observation_steering( try: if 200 <= _response.status_code < 300: _data = typing.cast( - ObservationSteering, + UserSummaryInstructions, parse_obj_as( - type_=ObservationSteering, # type: ignore + type_=UserSummaryInstructions, # type: ignore object_=_response.json(), ), ) @@ -570,7 +1305,12 @@ def set_observation_steering( status_code=_response.status_code, headers=dict(_response.headers), body=_response_json ) - def get_ontology(self, *, request_options: typing.Optional[RequestOptions] = None) -> HttpResponse[Ontology]: + +class AsyncRawProjectClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def get(self, *, request_options: typing.Optional[RequestOptions] = None) -> AsyncHttpResponse[Project]: """ Parameters ---------- @@ -579,24 +1319,24 @@ def get_ontology(self, *, request_options: typing.Optional[RequestOptions] = Non Returns ------- - HttpResponse[Ontology] + AsyncHttpResponse[Project] OK """ - _response = self._client_wrapper.httpx_client.request( - "project/ontology", + _response = await self._client_wrapper.httpx_client.request( + "project", method="GET", request_options=request_options, ) try: if 200 <= _response.status_code < 300: _data = typing.cast( - Ontology, + Project, parse_obj_as( - type_=Ontology, # type: ignore + type_=Project, # type: ignore object_=_response.json(), ), ) - return HttpResponse(response=_response, data=_data) + return AsyncHttpResponse(response=_response, data=_data) if _response.status_code == 400: raise BadRequestError( headers=dict(_response.headers), @@ -643,27 +1383,24 @@ def get_ontology(self, *, request_options: typing.Optional[RequestOptions] = Non status_code=_response.status_code, headers=dict(_response.headers), body=_response_json ) - def set_ontology( + async def update( self, *, - edge_types: typing.Optional[typing.Sequence[EdgeType]] = OMIT, - entity_types: typing.Optional[typing.Sequence[EntityType]] = OMIT, - inherited: typing.Optional[bool] = OMIT, + default_time_zone: typing.Optional[str] = OMIT, + include_policy_violating_episodes: typing.Optional[bool] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, - ) -> HttpResponse[Ontology]: + ) -> AsyncHttpResponse[Project]: """ Parameters ---------- - edge_types : typing.Optional[typing.Sequence[EdgeType]] - The edge types defined in the ontology in effect at this scope. - - entity_types : typing.Optional[typing.Sequence[EntityType]] - The entity types defined in the ontology in effect at this scope. + default_time_zone : typing.Optional[str] + The project's IANA fallback time zone. Set to null to clear the existing + value. - inherited : typing.Optional[bool] - Whether this is the project's default value rather than an override set on - this graph. + include_policy_violating_episodes : typing.Optional[bool] + When true, episode reads on graphs with a content policy include the + episodes that violated the policy. idempotency_key : typing.Optional[str] @@ -672,24 +1409,19 @@ def set_ontology( Returns ------- - HttpResponse[Ontology] + AsyncHttpResponse[Project] OK """ - _response = self._client_wrapper.httpx_client.request( - "project/ontology", - method="PUT", + _response = await self._client_wrapper.httpx_client.request( + "project", + method="PATCH", json={ - "edge_types": convert_and_respect_annotation_metadata( - object_=edge_types, annotation=typing.Sequence[EdgeType], direction="write" - ), - "entity_types": convert_and_respect_annotation_metadata( - object_=entity_types, annotation=typing.Sequence[EntityType], direction="write" - ), - "inherited": inherited, + "default_time_zone": default_time_zone, + "include_policy_violating_episodes": include_policy_violating_episodes, }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -697,13 +1429,13 @@ def set_ontology( try: if 200 <= _response.status_code < 300: _data = typing.cast( - Ontology, + Project, parse_obj_as( - type_=Ontology, # type: ignore + type_=Project, # type: ignore object_=_response.json(), ), ) - return HttpResponse(response=_response, data=_data) + return AsyncHttpResponse(response=_response, data=_data) if _response.status_code == 400: raise BadRequestError( headers=dict(_response.headers), @@ -737,6 +1469,17 @@ def set_ontology( ), ), ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) _response_json = _response.json() except JSONDecodeError: raise core_api_error_ApiError( @@ -750,10 +1493,12 @@ def set_ontology( status_code=_response.status_code, headers=dict(_response.headers), body=_response_json ) - def get_user_summary_instructions( + async def get_content_policy( self, *, request_options: typing.Optional[RequestOptions] = None - ) -> HttpResponse[UserSummaryInstructions]: + ) -> AsyncHttpResponse[ContentPolicy]: """ + Returns the current content policy revision of the project. A new graph binds this revision at creation. + Parameters ---------- request_options : typing.Optional[RequestOptions] @@ -761,35 +1506,24 @@ def get_user_summary_instructions( Returns ------- - HttpResponse[UserSummaryInstructions] + AsyncHttpResponse[ContentPolicy] OK """ - _response = self._client_wrapper.httpx_client.request( - "project/user-summary-instructions", + _response = await self._client_wrapper.httpx_client.request( + "project/content-policy", method="GET", request_options=request_options, ) try: if 200 <= _response.status_code < 300: _data = typing.cast( - UserSummaryInstructions, + ContentPolicy, parse_obj_as( - type_=UserSummaryInstructions, # type: ignore + type_=ContentPolicy, # type: ignore object_=_response.json(), ), ) - return HttpResponse(response=_response, data=_data) - if _response.status_code == 400: - raise BadRequestError( - headers=dict(_response.headers), - body=typing.cast( - types_api_error_ApiError, - parse_obj_as( - type_=types_api_error_ApiError, # type: ignore - object_=_response.json(), - ), - ), - ) + return AsyncHttpResponse(response=_response, data=_data) if _response.status_code == 401: raise UnauthorizedError( headers=dict(_response.headers), @@ -801,8 +1535,8 @@ def get_user_summary_instructions( ), ), ) - if _response.status_code == 404: - raise NotFoundError( + if _response.status_code == 403: + raise ForbiddenError( headers=dict(_response.headers), body=typing.cast( types_api_error_ApiError, @@ -825,24 +1559,25 @@ def get_user_summary_instructions( status_code=_response.status_code, headers=dict(_response.headers), body=_response_json ) - def set_user_summary_instructions( + async def set_content_policy( self, *, - inherited: typing.Optional[bool] = OMIT, - instructions: typing.Optional[typing.Sequence[UserInstruction]] = OMIT, + categories: typing.Optional[typing.Sequence[ContentPolicyCategoryRequest]] = OMIT, + rules: typing.Optional[typing.Sequence[ContentPolicyRuleRequest]] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, - ) -> HttpResponse[UserSummaryInstructions]: + ) -> AsyncHttpResponse[ContentPolicy]: """ + Replaces the project content policy and creates a new immutable revision. Graphs that already exist keep the revision they bound. An empty policy (no categories and no rules) removes the content policy for new graphs. + Parameters ---------- - inherited : typing.Optional[bool] - Whether this is the project's default value rather than an override set on - this graph. + categories : typing.Optional[typing.Sequence[ContentPolicyCategoryRequest]] + The categories of the policy. Maximum 16. An empty list with no rules + means no content policy. - instructions : typing.Optional[typing.Sequence[UserInstruction]] - The custom instructions used when generating a user's summary at this - scope, each with a name and text. + rules : typing.Optional[typing.Sequence[ContentPolicyRuleRequest]] + The rules of the policy. Maximum 32. idempotency_key : typing.Optional[str] @@ -851,21 +1586,23 @@ def set_user_summary_instructions( Returns ------- - HttpResponse[UserSummaryInstructions] + AsyncHttpResponse[ContentPolicy] OK """ - _response = self._client_wrapper.httpx_client.request( - "project/user-summary-instructions", + _response = await self._client_wrapper.httpx_client.request( + "project/content-policy", method="PUT", json={ - "inherited": inherited, - "instructions": convert_and_respect_annotation_metadata( - object_=instructions, annotation=typing.Sequence[UserInstruction], direction="write" + "categories": convert_and_respect_annotation_metadata( + object_=categories, annotation=typing.Sequence[ContentPolicyCategoryRequest], direction="write" + ), + "rules": convert_and_respect_annotation_metadata( + object_=rules, annotation=typing.Sequence[ContentPolicyRuleRequest], direction="write" ), }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -873,13 +1610,13 @@ def set_user_summary_instructions( try: if 200 <= _response.status_code < 300: _data = typing.cast( - UserSummaryInstructions, + ContentPolicy, parse_obj_as( - type_=UserSummaryInstructions, # type: ignore + type_=ContentPolicy, # type: ignore object_=_response.json(), ), ) - return HttpResponse(response=_response, data=_data) + return AsyncHttpResponse(response=_response, data=_data) if _response.status_code == 400: raise BadRequestError( headers=dict(_response.headers), @@ -902,8 +1639,8 @@ def set_user_summary_instructions( ), ), ) - if _response.status_code == 404: - raise NotFoundError( + if _response.status_code == 403: + raise ForbiddenError( headers=dict(_response.headers), body=typing.cast( types_api_error_ApiError, @@ -926,38 +1663,62 @@ def set_user_summary_instructions( status_code=_response.status_code, headers=dict(_response.headers), body=_response_json ) - -class AsyncRawProjectClient: - def __init__(self, *, client_wrapper: AsyncClientWrapper): - self._client_wrapper = client_wrapper - - async def get(self, *, request_options: typing.Optional[RequestOptions] = None) -> AsyncHttpResponse[Project]: + async def list_content_policy_revisions( + self, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[ContentPolicy, ContentPolicyRevisionPage]: """ + Lists every revision of the project content policy, newest first, including revision 0. + Parameters ---------- + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - AsyncHttpResponse[Project] + AsyncPager[ContentPolicy, ContentPolicyRevisionPage] OK """ _response = await self._client_wrapper.httpx_client.request( - "project", + "project/content-policy/revisions", method="GET", + params={ + "limit": limit, + "cursor": cursor, + }, request_options=request_options, ) try: if 200 <= _response.status_code < 300: - _data = typing.cast( - Project, + _parsed_response = typing.cast( + ContentPolicyRevisionPage, parse_obj_as( - type_=Project, # type: ignore + type_=ContentPolicyRevisionPage, # type: ignore object_=_response.json(), ), ) - return AsyncHttpResponse(response=_response, data=_data) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + + async def _get_next(): + return await self.list_content_policy_revisions( + limit=limit, + cursor=_parsed_next, + request_options=request_options, + ) + + return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) if _response.status_code == 400: raise BadRequestError( headers=dict(_response.headers), @@ -980,8 +1741,8 @@ async def get(self, *, request_options: typing.Optional[RequestOptions] = None) ), ), ) - if _response.status_code == 404: - raise NotFoundError( + if _response.status_code == 403: + raise ForbiddenError( headers=dict(_response.headers), body=typing.cast( types_api_error_ApiError, @@ -1004,49 +1765,34 @@ async def get(self, *, request_options: typing.Optional[RequestOptions] = None) status_code=_response.status_code, headers=dict(_response.headers), body=_response_json ) - async def update( - self, - *, - default_time_zone: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, - request_options: typing.Optional[RequestOptions] = None, - ) -> AsyncHttpResponse[Project]: + async def get_content_policy_revision( + self, revision_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[ContentPolicy]: """ Parameters ---------- - default_time_zone : typing.Optional[str] - The project's IANA fallback time zone. Set to null to clear the existing - value. - - idempotency_key : typing.Optional[str] + revision_uuid : str + Revision UUID request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - AsyncHttpResponse[Project] + AsyncHttpResponse[ContentPolicy] OK """ _response = await self._client_wrapper.httpx_client.request( - "project", - method="PATCH", - json={ - "default_time_zone": default_time_zone, - }, - headers={ - "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, - }, + f"project/content-policy/revisions/{encode_path_param(revision_uuid)}", + method="GET", request_options=request_options, - omit=OMIT, ) try: if 200 <= _response.status_code < 300: _data = typing.cast( - Project, + ContentPolicy, parse_obj_as( - type_=Project, # type: ignore + type_=ContentPolicy, # type: ignore object_=_response.json(), ), ) @@ -1073,8 +1819,8 @@ async def update( ), ), ) - if _response.status_code == 404: - raise NotFoundError( + if _response.status_code == 403: + raise ForbiddenError( headers=dict(_response.headers), body=typing.cast( types_api_error_ApiError, @@ -1084,8 +1830,8 @@ async def update( ), ), ) - if _response.status_code == 409: - raise ConflictError( + if _response.status_code == 404: + raise NotFoundError( headers=dict(_response.headers), body=typing.cast( types_api_error_ApiError, @@ -1223,7 +1969,7 @@ async def set_instructions( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -1405,7 +2151,7 @@ async def set_observation_steering( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -1545,17 +2291,23 @@ async def set_ontology( self, *, edge_types: typing.Optional[typing.Sequence[EdgeType]] = OMIT, + entity_type_hierarchy: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, entity_types: typing.Optional[typing.Sequence[EntityType]] = OMIT, inherited: typing.Optional[bool] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[Ontology]: """ + Replaces the entity types and the edge types that the project uses. + Parameters ---------- edge_types : typing.Optional[typing.Sequence[EdgeType]] The edge types defined in the ontology in effect at this scope. + entity_type_hierarchy : typing.Optional[typing.Dict[str, typing.Any]] + The entity type hierarchy (spec ontology-1). Omitted when the ontology is flat. + entity_types : typing.Optional[typing.Sequence[EntityType]] The entity types defined in the ontology in effect at this scope. @@ -1580,6 +2332,7 @@ async def set_ontology( "edge_types": convert_and_respect_annotation_metadata( object_=edge_types, annotation=typing.Sequence[EdgeType], direction="write" ), + "entity_type_hierarchy": entity_type_hierarchy, "entity_types": convert_and_respect_annotation_metadata( object_=entity_types, annotation=typing.Sequence[EntityType], direction="write" ), @@ -1587,7 +2340,7 @@ async def set_ontology( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -1763,7 +2516,7 @@ async def set_user_summary_instructions( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, diff --git a/src/zep_cloud/task/client.py b/src/zep_cloud/task/client.py index 6900d8dd..7384be13 100644 --- a/src/zep_cloud/task/client.py +++ b/src/zep_cloud/task/client.py @@ -56,10 +56,7 @@ def list( client = Zep( api_key="YOUR_API_KEY", ) - response = client.task.list( - limit=1, - cursor="cursor", - ) + response = client.task.list() for item in response: yield item # alternatively, you can paginate page-by-page @@ -149,10 +146,7 @@ async def list( async def main() -> None: - response = await client.task.list( - limit=1, - cursor="cursor", - ) + response = await client.task.list() async for item in response: yield item diff --git a/src/zep_cloud/task/raw_client.py b/src/zep_cloud/task/raw_client.py index 6a40ba70..2b5aa800 100644 --- a/src/zep_cloud/task/raw_client.py +++ b/src/zep_cloud/task/raw_client.py @@ -6,7 +6,7 @@ from ..core.api_error import ApiError as core_api_error_ApiError from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ..core.http_response import AsyncHttpResponse, HttpResponse -from ..core.jsonable_encoder import jsonable_encoder +from ..core.jsonable_encoder import encode_path_param from ..core.pagination import AsyncPager, SyncPager from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as @@ -137,7 +137,7 @@ def get(self, task_uuid: str, *, request_options: typing.Optional[RequestOptions OK """ _response = self._client_wrapper.httpx_client.request( - f"tasks/{jsonable_encoder(task_uuid)}", + f"tasks/{encode_path_param(task_uuid)}", method="GET", request_options=request_options, ) @@ -320,7 +320,7 @@ async def get( OK """ _response = await self._client_wrapper.httpx_client.request( - f"tasks/{jsonable_encoder(task_uuid)}", + f"tasks/{encode_path_param(task_uuid)}", method="GET", request_options=request_options, ) diff --git a/src/zep_cloud/thread/__init__.py b/src/zep_cloud/thread/__init__.py index d917233f..7b10a6b5 100644 --- a/src/zep_cloud/thread/__init__.py +++ b/src/zep_cloud/thread/__init__.py @@ -6,8 +6,14 @@ from importlib import import_module if typing.TYPE_CHECKING: + from .types import ThreadListMessagesRequestOrder, ThreadListRequestOrder, ThreadListRequestOrderBy from . import message -_dynamic_imports: typing.Dict[str, str] = {"message": ".message"} +_dynamic_imports: typing.Dict[str, str] = { + "ThreadListMessagesRequestOrder": ".types", + "ThreadListRequestOrder": ".types", + "ThreadListRequestOrderBy": ".types", + "message": ".message", +} def __getattr__(attr_name: str) -> typing.Any: @@ -31,4 +37,4 @@ def __dir__(): return sorted(lazy_attrs) -__all__ = ["message"] +__all__ = ["ThreadListMessagesRequestOrder", "ThreadListRequestOrder", "ThreadListRequestOrderBy", "message"] diff --git a/src/zep_cloud/thread/client.py b/src/zep_cloud/thread/client.py index f3107992..136b430d 100644 --- a/src/zep_cloud/thread/client.py +++ b/src/zep_cloud/thread/client.py @@ -19,6 +19,9 @@ from ..types.thread_page import ThreadPage from ..types.thread_summary import ThreadSummary from .raw_client import AsyncRawThreadClient, RawThreadClient +from .types.thread_list_messages_request_order import ThreadListMessagesRequestOrder +from .types.thread_list_request_order import ThreadListRequestOrder +from .types.thread_list_request_order_by import ThreadListRequestOrderBy if typing.TYPE_CHECKING: from .message.client import AsyncMessageClient, MessageClient @@ -48,8 +51,8 @@ def list( *, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, - order_by: typing.Optional[str] = None, - order: typing.Optional[str] = None, + order_by: typing.Optional[ThreadListRequestOrderBy] = None, + order: typing.Optional[ThreadListRequestOrder] = None, user_uuid: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Thread, ThreadPage]: @@ -62,10 +65,10 @@ def list( cursor : typing.Optional[str] Opaque page cursor - order_by : typing.Optional[str] + order_by : typing.Optional[ThreadListRequestOrderBy] Sort field - order : typing.Optional[str] + order : typing.Optional[ThreadListRequestOrder] asc or desc user_uuid : typing.Optional[str] @@ -86,13 +89,7 @@ def list( client = Zep( api_key="YOUR_API_KEY", ) - response = client.thread.list( - limit=1, - cursor="cursor", - order_by="order_by", - order="order", - user_uuid="user_uuid", - ) + response = client.thread.list() for item in response: yield item # alternatively, you can paginate page-by-page @@ -112,7 +109,6 @@ def create( self, *, user_uuid: str, - thread_id: typing.Optional[str] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> Thread: @@ -122,9 +118,6 @@ def create( user_uuid : str The UUID of the user this thread belongs to. - thread_id : typing.Optional[str] - An optional developer-assigned identifier for the thread. - idempotency_key : typing.Optional[str] request_options : typing.Optional[RequestOptions] @@ -147,7 +140,7 @@ def create( ) """ _response = self._raw_client.create( - user_uuid=user_uuid, thread_id=thread_id, idempotency_key=idempotency_key, request_options=request_options + user_uuid=user_uuid, idempotency_key=idempotency_key, request_options=request_options ) return _response.data @@ -157,7 +150,6 @@ def lookup( graph_id: typing.Optional[str] = OMIT, thread_id: typing.Optional[str] = OMIT, user_id: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> Thread: """ @@ -175,8 +167,6 @@ def lookup( The developer-assigned user ID to resolve to a UUID. Mutually exclusive with thread_id and graph_id. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -195,11 +185,7 @@ def lookup( client.thread.lookup() """ _response = self._raw_client.lookup( - graph_id=graph_id, - thread_id=thread_id, - user_id=user_id, - idempotency_key=idempotency_key, - request_options=request_options, + graph_id=graph_id, thread_id=thread_id, user_id=user_id, request_options=request_options ) return _response.data @@ -304,7 +290,6 @@ def get_context( ) client.thread.get_context( thread_uuid="thread_uuid", - template_uuid="template_uuid", ) """ _response = self._raw_client.get_context( @@ -349,8 +334,6 @@ def list_episodes( ) response = client.thread.list_episodes( thread_uuid="thread_uuid", - limit=1, - cursor="cursor", ) for item in response: yield item @@ -366,6 +349,8 @@ def list_messages( *, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, + order_by: typing.Optional[typing.Literal["created_at"]] = None, + order: typing.Optional[ThreadListMessagesRequestOrder] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Message, MessagePage]: """ @@ -380,6 +365,12 @@ def list_messages( cursor : typing.Optional[str] Opaque page cursor + order_by : typing.Optional[typing.Literal["created_at"]] + Sort field + + order : typing.Optional[ThreadListMessagesRequestOrder] + Sort direction: asc or desc + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -397,8 +388,6 @@ def list_messages( ) response = client.thread.list_messages( thread_uuid="thread_uuid", - limit=1, - cursor="cursor", ) for item in response: yield item @@ -406,7 +395,9 @@ def list_messages( for page in response.iter_pages(): yield page """ - return self._raw_client.list_messages(thread_uuid, limit=limit, cursor=cursor, request_options=request_options) + return self._raw_client.list_messages( + thread_uuid, limit=limit, cursor=cursor, order_by=order_by, order=order, request_options=request_options + ) def add_messages( self, @@ -535,8 +526,8 @@ async def list( *, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, - order_by: typing.Optional[str] = None, - order: typing.Optional[str] = None, + order_by: typing.Optional[ThreadListRequestOrderBy] = None, + order: typing.Optional[ThreadListRequestOrder] = None, user_uuid: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Thread, ThreadPage]: @@ -549,10 +540,10 @@ async def list( cursor : typing.Optional[str] Opaque page cursor - order_by : typing.Optional[str] + order_by : typing.Optional[ThreadListRequestOrderBy] Sort field - order : typing.Optional[str] + order : typing.Optional[ThreadListRequestOrder] asc or desc user_uuid : typing.Optional[str] @@ -578,13 +569,7 @@ async def list( async def main() -> None: - response = await client.thread.list( - limit=1, - cursor="cursor", - order_by="order_by", - order="order", - user_uuid="user_uuid", - ) + response = await client.thread.list() async for item in response: yield item @@ -608,7 +593,6 @@ async def create( self, *, user_uuid: str, - thread_id: typing.Optional[str] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> Thread: @@ -618,9 +602,6 @@ async def create( user_uuid : str The UUID of the user this thread belongs to. - thread_id : typing.Optional[str] - An optional developer-assigned identifier for the thread. - idempotency_key : typing.Optional[str] request_options : typing.Optional[RequestOptions] @@ -651,7 +632,7 @@ async def main() -> None: asyncio.run(main()) """ _response = await self._raw_client.create( - user_uuid=user_uuid, thread_id=thread_id, idempotency_key=idempotency_key, request_options=request_options + user_uuid=user_uuid, idempotency_key=idempotency_key, request_options=request_options ) return _response.data @@ -661,7 +642,6 @@ async def lookup( graph_id: typing.Optional[str] = OMIT, thread_id: typing.Optional[str] = OMIT, user_id: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> Thread: """ @@ -679,8 +659,6 @@ async def lookup( The developer-assigned user ID to resolve to a UUID. Mutually exclusive with thread_id and graph_id. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -707,11 +685,7 @@ async def main() -> None: asyncio.run(main()) """ _response = await self._raw_client.lookup( - graph_id=graph_id, - thread_id=thread_id, - user_id=user_id, - idempotency_key=idempotency_key, - request_options=request_options, + graph_id=graph_id, thread_id=thread_id, user_id=user_id, request_options=request_options ) return _response.data @@ -837,7 +811,6 @@ async def get_context( async def main() -> None: await client.thread.get_context( thread_uuid="thread_uuid", - template_uuid="template_uuid", ) @@ -890,8 +863,6 @@ async def list_episodes( async def main() -> None: response = await client.thread.list_episodes( thread_uuid="thread_uuid", - limit=1, - cursor="cursor", ) async for item in response: yield item @@ -913,6 +884,8 @@ async def list_messages( *, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, + order_by: typing.Optional[typing.Literal["created_at"]] = None, + order: typing.Optional[ThreadListMessagesRequestOrder] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Message, MessagePage]: """ @@ -927,6 +900,12 @@ async def list_messages( cursor : typing.Optional[str] Opaque page cursor + order_by : typing.Optional[typing.Literal["created_at"]] + Sort field + + order : typing.Optional[ThreadListMessagesRequestOrder] + Sort direction: asc or desc + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -949,8 +928,6 @@ async def list_messages( async def main() -> None: response = await client.thread.list_messages( thread_uuid="thread_uuid", - limit=1, - cursor="cursor", ) async for item in response: yield item @@ -963,7 +940,7 @@ async def main() -> None: asyncio.run(main()) """ return await self._raw_client.list_messages( - thread_uuid, limit=limit, cursor=cursor, request_options=request_options + thread_uuid, limit=limit, cursor=cursor, order_by=order_by, order=order, request_options=request_options ) async def add_messages( diff --git a/src/zep_cloud/thread/message/client.py b/src/zep_cloud/thread/message/client.py index bc1b36da..eb090bab 100644 --- a/src/zep_cloud/thread/message/client.py +++ b/src/zep_cloud/thread/message/client.py @@ -80,7 +80,7 @@ def update( Message UUID metadata : typing.Optional[typing.Dict[str, typing.Any]] - Metadata to merge onto the message; a key set to null is removed. + Metadata to merge onto the message; a key set to null is removed. Max 10 keys after the merge. Values must be strings, numbers, booleans, or arrays of scalars. idempotency_key : typing.Optional[str] @@ -191,7 +191,7 @@ async def update( Message UUID metadata : typing.Optional[typing.Dict[str, typing.Any]] - Metadata to merge onto the message; a key set to null is removed. + Metadata to merge onto the message; a key set to null is removed. Max 10 keys after the merge. Values must be strings, numbers, booleans, or arrays of scalars. idempotency_key : typing.Optional[str] diff --git a/src/zep_cloud/thread/message/raw_client.py b/src/zep_cloud/thread/message/raw_client.py index 516a28b2..88a176dd 100644 --- a/src/zep_cloud/thread/message/raw_client.py +++ b/src/zep_cloud/thread/message/raw_client.py @@ -6,7 +6,8 @@ from ...core.api_error import ApiError as core_api_error_ApiError from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ...core.http_response import AsyncHttpResponse, HttpResponse -from ...core.jsonable_encoder import jsonable_encoder +from ...core.idempotency import generate_idempotency_key +from ...core.jsonable_encoder import encode_path_param from ...core.parse_error import ParsingError from ...core.pydantic_utilities import parse_obj_as from ...core.request_options import RequestOptions @@ -47,7 +48,7 @@ def get( OK """ _response = self._client_wrapper.httpx_client.request( - f"threads/{jsonable_encoder(thread_uuid)}/messages/{jsonable_encoder(message_uuid)}", + f"threads/{encode_path_param(thread_uuid)}/messages/{encode_path_param(message_uuid)}", method="GET", request_options=request_options, ) @@ -126,7 +127,7 @@ def update( Message UUID metadata : typing.Optional[typing.Dict[str, typing.Any]] - Metadata to merge onto the message; a key set to null is removed. + Metadata to merge onto the message; a key set to null is removed. Max 10 keys after the merge. Values must be strings, numbers, booleans, or arrays of scalars. idempotency_key : typing.Optional[str] @@ -139,14 +140,14 @@ def update( OK """ _response = self._client_wrapper.httpx_client.request( - f"threads/{jsonable_encoder(thread_uuid)}/messages/{jsonable_encoder(message_uuid)}", + f"threads/{encode_path_param(thread_uuid)}/messages/{encode_path_param(message_uuid)}", method="PATCH", json={ "metadata": metadata, }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -244,7 +245,7 @@ async def get( OK """ _response = await self._client_wrapper.httpx_client.request( - f"threads/{jsonable_encoder(thread_uuid)}/messages/{jsonable_encoder(message_uuid)}", + f"threads/{encode_path_param(thread_uuid)}/messages/{encode_path_param(message_uuid)}", method="GET", request_options=request_options, ) @@ -323,7 +324,7 @@ async def update( Message UUID metadata : typing.Optional[typing.Dict[str, typing.Any]] - Metadata to merge onto the message; a key set to null is removed. + Metadata to merge onto the message; a key set to null is removed. Max 10 keys after the merge. Values must be strings, numbers, booleans, or arrays of scalars. idempotency_key : typing.Optional[str] @@ -336,14 +337,14 @@ async def update( OK """ _response = await self._client_wrapper.httpx_client.request( - f"threads/{jsonable_encoder(thread_uuid)}/messages/{jsonable_encoder(message_uuid)}", + f"threads/{encode_path_param(thread_uuid)}/messages/{encode_path_param(message_uuid)}", method="PATCH", json={ "metadata": metadata, }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, diff --git a/src/zep_cloud/thread/raw_client.py b/src/zep_cloud/thread/raw_client.py index 0c93ef76..0f3e97e3 100644 --- a/src/zep_cloud/thread/raw_client.py +++ b/src/zep_cloud/thread/raw_client.py @@ -6,7 +6,8 @@ from ..core.api_error import ApiError as core_api_error_ApiError from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ..core.http_response import AsyncHttpResponse, HttpResponse -from ..core.jsonable_encoder import jsonable_encoder +from ..core.idempotency import generate_idempotency_key +from ..core.jsonable_encoder import encode_path_param from ..core.pagination import AsyncPager, SyncPager from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as @@ -29,6 +30,9 @@ from ..types.thread_delete_result import ThreadDeleteResult from ..types.thread_page import ThreadPage from ..types.thread_summary import ThreadSummary +from .types.thread_list_messages_request_order import ThreadListMessagesRequestOrder +from .types.thread_list_request_order import ThreadListRequestOrder +from .types.thread_list_request_order_by import ThreadListRequestOrderBy from pydantic import ValidationError # this is used as the default value for optional parameters @@ -44,8 +48,8 @@ def list( *, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, - order_by: typing.Optional[str] = None, - order: typing.Optional[str] = None, + order_by: typing.Optional[ThreadListRequestOrderBy] = None, + order: typing.Optional[ThreadListRequestOrder] = None, user_uuid: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Thread, ThreadPage]: @@ -58,10 +62,10 @@ def list( cursor : typing.Optional[str] Opaque page cursor - order_by : typing.Optional[str] + order_by : typing.Optional[ThreadListRequestOrderBy] Sort field - order : typing.Optional[str] + order : typing.Optional[ThreadListRequestOrder] asc or desc user_uuid : typing.Optional[str] @@ -158,7 +162,6 @@ def create( self, *, user_uuid: str, - thread_id: typing.Optional[str] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[Thread]: @@ -168,9 +171,6 @@ def create( user_uuid : str The UUID of the user this thread belongs to. - thread_id : typing.Optional[str] - An optional developer-assigned identifier for the thread. - idempotency_key : typing.Optional[str] request_options : typing.Optional[RequestOptions] @@ -185,12 +185,11 @@ def create( "threads", method="POST", json={ - "thread_id": thread_id, "user_uuid": user_uuid, }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -268,7 +267,6 @@ def lookup( graph_id: typing.Optional[str] = OMIT, thread_id: typing.Optional[str] = OMIT, user_id: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[Thread]: """ @@ -286,8 +284,6 @@ def lookup( The developer-assigned user ID to resolve to a UUID. Mutually exclusive with thread_id and graph_id. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -306,7 +302,7 @@ def lookup( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -383,7 +379,7 @@ def get(self, thread_uuid: str, *, request_options: typing.Optional[RequestOptio OK """ _response = self._client_wrapper.httpx_client.request( - f"threads/{jsonable_encoder(thread_uuid)}", + f"threads/{encode_path_param(thread_uuid)}", method="GET", request_options=request_options, ) @@ -467,10 +463,10 @@ def delete( Accepted """ _response = self._client_wrapper.httpx_client.request( - f"threads/{jsonable_encoder(thread_uuid)}", + f"threads/{encode_path_param(thread_uuid)}", method="DELETE", headers={ - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, ) @@ -566,7 +562,7 @@ def get_context( OK """ _response = self._client_wrapper.httpx_client.request( - f"threads/{jsonable_encoder(thread_uuid)}/context", + f"threads/{encode_path_param(thread_uuid)}/context", method="GET", params={ "template_uuid": template_uuid, @@ -669,7 +665,7 @@ def list_episodes( OK """ _response = self._client_wrapper.httpx_client.request( - f"threads/{jsonable_encoder(thread_uuid)}/episodes", + f"threads/{encode_path_param(thread_uuid)}/episodes", method="GET", params={ "limit": limit, @@ -770,6 +766,8 @@ def list_messages( *, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, + order_by: typing.Optional[typing.Literal["created_at"]] = None, + order: typing.Optional[ThreadListMessagesRequestOrder] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Message, MessagePage]: """ @@ -784,6 +782,12 @@ def list_messages( cursor : typing.Optional[str] Opaque page cursor + order_by : typing.Optional[typing.Literal["created_at"]] + Sort field + + order : typing.Optional[ThreadListMessagesRequestOrder] + Sort direction: asc or desc + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -793,11 +797,13 @@ def list_messages( OK """ _response = self._client_wrapper.httpx_client.request( - f"threads/{jsonable_encoder(thread_uuid)}/messages", + f"threads/{encode_path_param(thread_uuid)}/messages", method="GET", params={ "limit": limit, "cursor": cursor, + "order_by": order_by, + "order": order, }, request_options=request_options, ) @@ -817,6 +823,8 @@ def list_messages( thread_uuid, limit=limit, cursor=_parsed_next, + order_by=order_by, + order=order, request_options=request_options, ) return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) @@ -909,7 +917,7 @@ def add_messages( Accepted """ _response = self._client_wrapper.httpx_client.request( - f"threads/{jsonable_encoder(thread_uuid)}/messages", + f"threads/{encode_path_param(thread_uuid)}/messages", method="POST", json={ "ignore_roles": ignore_roles, @@ -921,7 +929,7 @@ def add_messages( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -1011,7 +1019,7 @@ def get_summary( OK """ _response = self._client_wrapper.httpx_client.request( - f"threads/{jsonable_encoder(thread_uuid)}/summary", + f"threads/{encode_path_param(thread_uuid)}/summary", method="GET", request_options=request_options, ) @@ -1092,8 +1100,8 @@ async def list( *, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, - order_by: typing.Optional[str] = None, - order: typing.Optional[str] = None, + order_by: typing.Optional[ThreadListRequestOrderBy] = None, + order: typing.Optional[ThreadListRequestOrder] = None, user_uuid: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Thread, ThreadPage]: @@ -1106,10 +1114,10 @@ async def list( cursor : typing.Optional[str] Opaque page cursor - order_by : typing.Optional[str] + order_by : typing.Optional[ThreadListRequestOrderBy] Sort field - order : typing.Optional[str] + order : typing.Optional[ThreadListRequestOrder] asc or desc user_uuid : typing.Optional[str] @@ -1209,7 +1217,6 @@ async def create( self, *, user_uuid: str, - thread_id: typing.Optional[str] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[Thread]: @@ -1219,9 +1226,6 @@ async def create( user_uuid : str The UUID of the user this thread belongs to. - thread_id : typing.Optional[str] - An optional developer-assigned identifier for the thread. - idempotency_key : typing.Optional[str] request_options : typing.Optional[RequestOptions] @@ -1236,12 +1240,11 @@ async def create( "threads", method="POST", json={ - "thread_id": thread_id, "user_uuid": user_uuid, }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -1319,7 +1322,6 @@ async def lookup( graph_id: typing.Optional[str] = OMIT, thread_id: typing.Optional[str] = OMIT, user_id: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[Thread]: """ @@ -1337,8 +1339,6 @@ async def lookup( The developer-assigned user ID to resolve to a UUID. Mutually exclusive with thread_id and graph_id. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1357,7 +1357,7 @@ async def lookup( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -1436,7 +1436,7 @@ async def get( OK """ _response = await self._client_wrapper.httpx_client.request( - f"threads/{jsonable_encoder(thread_uuid)}", + f"threads/{encode_path_param(thread_uuid)}", method="GET", request_options=request_options, ) @@ -1520,10 +1520,10 @@ async def delete( Accepted """ _response = await self._client_wrapper.httpx_client.request( - f"threads/{jsonable_encoder(thread_uuid)}", + f"threads/{encode_path_param(thread_uuid)}", method="DELETE", headers={ - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, ) @@ -1619,7 +1619,7 @@ async def get_context( OK """ _response = await self._client_wrapper.httpx_client.request( - f"threads/{jsonable_encoder(thread_uuid)}/context", + f"threads/{encode_path_param(thread_uuid)}/context", method="GET", params={ "template_uuid": template_uuid, @@ -1722,7 +1722,7 @@ async def list_episodes( OK """ _response = await self._client_wrapper.httpx_client.request( - f"threads/{jsonable_encoder(thread_uuid)}/episodes", + f"threads/{encode_path_param(thread_uuid)}/episodes", method="GET", params={ "limit": limit, @@ -1826,6 +1826,8 @@ async def list_messages( *, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, + order_by: typing.Optional[typing.Literal["created_at"]] = None, + order: typing.Optional[ThreadListMessagesRequestOrder] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Message, MessagePage]: """ @@ -1840,6 +1842,12 @@ async def list_messages( cursor : typing.Optional[str] Opaque page cursor + order_by : typing.Optional[typing.Literal["created_at"]] + Sort field + + order : typing.Optional[ThreadListMessagesRequestOrder] + Sort direction: asc or desc + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1849,11 +1857,13 @@ async def list_messages( OK """ _response = await self._client_wrapper.httpx_client.request( - f"threads/{jsonable_encoder(thread_uuid)}/messages", + f"threads/{encode_path_param(thread_uuid)}/messages", method="GET", params={ "limit": limit, "cursor": cursor, + "order_by": order_by, + "order": order, }, request_options=request_options, ) @@ -1875,6 +1885,8 @@ async def _get_next(): thread_uuid, limit=limit, cursor=_parsed_next, + order_by=order_by, + order=order, request_options=request_options, ) @@ -1968,7 +1980,7 @@ async def add_messages( Accepted """ _response = await self._client_wrapper.httpx_client.request( - f"threads/{jsonable_encoder(thread_uuid)}/messages", + f"threads/{encode_path_param(thread_uuid)}/messages", method="POST", json={ "ignore_roles": ignore_roles, @@ -1980,7 +1992,7 @@ async def add_messages( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -2070,7 +2082,7 @@ async def get_summary( OK """ _response = await self._client_wrapper.httpx_client.request( - f"threads/{jsonable_encoder(thread_uuid)}/summary", + f"threads/{encode_path_param(thread_uuid)}/summary", method="GET", request_options=request_options, ) diff --git a/src/zep_cloud/thread/types/__init__.py b/src/zep_cloud/thread/types/__init__.py new file mode 100644 index 00000000..4ad5877a --- /dev/null +++ b/src/zep_cloud/thread/types/__init__.py @@ -0,0 +1,40 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .thread_list_messages_request_order import ThreadListMessagesRequestOrder + from .thread_list_request_order import ThreadListRequestOrder + from .thread_list_request_order_by import ThreadListRequestOrderBy +_dynamic_imports: typing.Dict[str, str] = { + "ThreadListMessagesRequestOrder": ".thread_list_messages_request_order", + "ThreadListRequestOrder": ".thread_list_request_order", + "ThreadListRequestOrderBy": ".thread_list_request_order_by", +} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = ["ThreadListMessagesRequestOrder", "ThreadListRequestOrder", "ThreadListRequestOrderBy"] diff --git a/src/zep_cloud/thread/types/thread_list_messages_request_order.py b/src/zep_cloud/thread/types/thread_list_messages_request_order.py new file mode 100644 index 00000000..9490cbd7 --- /dev/null +++ b/src/zep_cloud/thread/types/thread_list_messages_request_order.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +ThreadListMessagesRequestOrder = typing.Union[typing.Literal["asc", "desc"], typing.Any] diff --git a/src/zep_cloud/thread/types/thread_list_request_order.py b/src/zep_cloud/thread/types/thread_list_request_order.py new file mode 100644 index 00000000..69b54f19 --- /dev/null +++ b/src/zep_cloud/thread/types/thread_list_request_order.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +ThreadListRequestOrder = typing.Union[typing.Literal["asc", "desc"], typing.Any] diff --git a/src/zep_cloud/thread/types/thread_list_request_order_by.py b/src/zep_cloud/thread/types/thread_list_request_order_by.py new file mode 100644 index 00000000..4c4eb541 --- /dev/null +++ b/src/zep_cloud/thread/types/thread_list_request_order_by.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +ThreadListRequestOrderBy = typing.Union[typing.Literal["created_at", "updated_at", "uuid"], typing.Any] diff --git a/src/zep_cloud/trace_connection/__init__.py b/src/zep_cloud/trace_connection/__init__.py new file mode 100644 index 00000000..7afeda57 --- /dev/null +++ b/src/zep_cloud/trace_connection/__init__.py @@ -0,0 +1,34 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from . import project, trace +_dynamic_imports: typing.Dict[str, str] = {"project": ".project", "trace": ".trace"} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = ["project", "trace"] diff --git a/src/zep_cloud/trace_connection/client.py b/src/zep_cloud/trace_connection/client.py new file mode 100644 index 00000000..97889f74 --- /dev/null +++ b/src/zep_cloud/trace_connection/client.py @@ -0,0 +1,715 @@ +# This file was auto-generated by Fern from our API Definition. + +from __future__ import annotations + +import typing + +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.pagination import AsyncPager, SyncPager +from ..core.request_options import RequestOptions +from ..types.trace_connection import TraceConnection +from ..types.trace_connection_page import TraceConnectionPage +from .raw_client import AsyncRawTraceConnectionClient, RawTraceConnectionClient + +if typing.TYPE_CHECKING: + from .project.client import AsyncProjectClient, ProjectClient + from .trace.client import AsyncTraceClient, TraceClient +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class TraceConnectionClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawTraceConnectionClient(client_wrapper=client_wrapper) + self._client_wrapper = client_wrapper + self._project: typing.Optional[ProjectClient] = None + self._trace: typing.Optional[TraceClient] = None + + @property + def with_raw_response(self) -> RawTraceConnectionClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawTraceConnectionClient + """ + return self._raw_client + + def list( + self, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[TraceConnection, TraceConnectionPage]: + """ + List trace connections in the current Zep project. + + Parameters + ---------- + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[TraceConnection, TraceConnectionPage] + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + response = client.trace_connection.list() + for item in response: + yield item + # alternatively, you can paginate page-by-page + for page in response.iter_pages(): + yield page + """ + return self._raw_client.list(limit=limit, cursor=cursor, request_options=request_options) + + def create( + self, + *, + api_url: typing.Optional[str] = OMIT, + credential: typing.Optional[str] = OMIT, + name: typing.Optional[str] = OMIT, + provider: typing.Optional[str] = OMIT, + requests_per_minute: typing.Optional[int] = OMIT, + retention_days: typing.Optional[int] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> TraceConnection: + """ + Verify the provider credential before Zep stores it. Example request: `{"name":"Support traces","provider":"braintrust","credential":"secret","requests_per_minute":10}`. + + Parameters + ---------- + api_url : typing.Optional[str] + APIURL is an optional custom provider endpoint. + + credential : typing.Optional[str] + Credential is the write-only provider credential. + + name : typing.Optional[str] + Name is the connection name. + + provider : typing.Optional[str] + Provider is the provider name. + + requests_per_minute : typing.Optional[int] + RequestsPerMinute is the provider request rate limit. + + retention_days : typing.Optional[int] + RetentionDays is an optional provider retention window. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + TraceConnection + Created + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.trace_connection.create() + """ + _response = self._raw_client.create( + api_url=api_url, + credential=credential, + name=name, + provider=provider, + requests_per_minute=requests_per_minute, + retention_days=retention_days, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + def get(self, connection_uuid: str, *, request_options: typing.Optional[RequestOptions] = None) -> TraceConnection: + """ + Read one trace connection. The response includes a credential hint and never includes the credential. + + Parameters + ---------- + connection_uuid : str + Trace connection UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + TraceConnection + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.trace_connection.get( + connection_uuid="connection_uuid", + ) + """ + _response = self._raw_client.get(connection_uuid, request_options=request_options) + return _response.data + + def delete( + self, + connection_uuid: str, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> None: + """ + Delete a trace connection that no active trajectory import uses. + + Parameters + ---------- + connection_uuid : str + Trace connection UUID + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + None + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.trace_connection.delete( + connection_uuid="connection_uuid", + ) + """ + _response = self._raw_client.delete( + connection_uuid, idempotency_key=idempotency_key, request_options=request_options + ) + return _response.data + + def update( + self, + connection_uuid: str, + *, + api_url: typing.Optional[str] = OMIT, + credential: typing.Optional[str] = OMIT, + name: typing.Optional[str] = OMIT, + requests_per_minute: typing.Optional[int] = OMIT, + retention_days: typing.Optional[int] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> TraceConnection: + """ + Verify changed provider settings before Zep stores them. Example request: `{"credential":"new-secret","requests_per_minute":20}`. + + Parameters + ---------- + connection_uuid : str + Trace connection UUID + + api_url : typing.Optional[str] + APIURL is the new custom provider endpoint, when supplied. + + credential : typing.Optional[str] + Credential is the new write-only provider credential, when supplied. + + name : typing.Optional[str] + Name is the new connection name, when supplied. + + requests_per_minute : typing.Optional[int] + RequestsPerMinute is the new provider request rate limit, when supplied. + + retention_days : typing.Optional[int] + RetentionDays is the new provider retention window, when supplied. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + TraceConnection + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.trace_connection.update( + connection_uuid="connection_uuid", + ) + """ + _response = self._raw_client.update( + connection_uuid, + api_url=api_url, + credential=credential, + name=name, + requests_per_minute=requests_per_minute, + retention_days=retention_days, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + def verify( + self, + connection_uuid: str, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> TraceConnection: + """ + Check the provider credential and update the connection status. + + Parameters + ---------- + connection_uuid : str + Trace connection UUID + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + TraceConnection + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.trace_connection.verify( + connection_uuid="connection_uuid", + ) + """ + _response = self._raw_client.verify( + connection_uuid, idempotency_key=idempotency_key, request_options=request_options + ) + return _response.data + + @property + def project(self): + if self._project is None: + from .project.client import ProjectClient # noqa: E402 + + self._project = ProjectClient(client_wrapper=self._client_wrapper) + return self._project + + @property + def trace(self): + if self._trace is None: + from .trace.client import TraceClient # noqa: E402 + + self._trace = TraceClient(client_wrapper=self._client_wrapper) + return self._trace + + +class AsyncTraceConnectionClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawTraceConnectionClient(client_wrapper=client_wrapper) + self._client_wrapper = client_wrapper + self._project: typing.Optional[AsyncProjectClient] = None + self._trace: typing.Optional[AsyncTraceClient] = None + + @property + def with_raw_response(self) -> AsyncRawTraceConnectionClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawTraceConnectionClient + """ + return self._raw_client + + async def list( + self, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[TraceConnection, TraceConnectionPage]: + """ + List trace connections in the current Zep project. + + Parameters + ---------- + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[TraceConnection, TraceConnectionPage] + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + response = await client.trace_connection.list() + async for item in response: + yield item + + # alternatively, you can paginate page-by-page + async for page in response.iter_pages(): + yield page + + + asyncio.run(main()) + """ + return await self._raw_client.list(limit=limit, cursor=cursor, request_options=request_options) + + async def create( + self, + *, + api_url: typing.Optional[str] = OMIT, + credential: typing.Optional[str] = OMIT, + name: typing.Optional[str] = OMIT, + provider: typing.Optional[str] = OMIT, + requests_per_minute: typing.Optional[int] = OMIT, + retention_days: typing.Optional[int] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> TraceConnection: + """ + Verify the provider credential before Zep stores it. Example request: `{"name":"Support traces","provider":"braintrust","credential":"secret","requests_per_minute":10}`. + + Parameters + ---------- + api_url : typing.Optional[str] + APIURL is an optional custom provider endpoint. + + credential : typing.Optional[str] + Credential is the write-only provider credential. + + name : typing.Optional[str] + Name is the connection name. + + provider : typing.Optional[str] + Provider is the provider name. + + requests_per_minute : typing.Optional[int] + RequestsPerMinute is the provider request rate limit. + + retention_days : typing.Optional[int] + RetentionDays is an optional provider retention window. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + TraceConnection + Created + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.trace_connection.create() + + + asyncio.run(main()) + """ + _response = await self._raw_client.create( + api_url=api_url, + credential=credential, + name=name, + provider=provider, + requests_per_minute=requests_per_minute, + retention_days=retention_days, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + async def get( + self, connection_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> TraceConnection: + """ + Read one trace connection. The response includes a credential hint and never includes the credential. + + Parameters + ---------- + connection_uuid : str + Trace connection UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + TraceConnection + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.trace_connection.get( + connection_uuid="connection_uuid", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get(connection_uuid, request_options=request_options) + return _response.data + + async def delete( + self, + connection_uuid: str, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> None: + """ + Delete a trace connection that no active trajectory import uses. + + Parameters + ---------- + connection_uuid : str + Trace connection UUID + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + None + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.trace_connection.delete( + connection_uuid="connection_uuid", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.delete( + connection_uuid, idempotency_key=idempotency_key, request_options=request_options + ) + return _response.data + + async def update( + self, + connection_uuid: str, + *, + api_url: typing.Optional[str] = OMIT, + credential: typing.Optional[str] = OMIT, + name: typing.Optional[str] = OMIT, + requests_per_minute: typing.Optional[int] = OMIT, + retention_days: typing.Optional[int] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> TraceConnection: + """ + Verify changed provider settings before Zep stores them. Example request: `{"credential":"new-secret","requests_per_minute":20}`. + + Parameters + ---------- + connection_uuid : str + Trace connection UUID + + api_url : typing.Optional[str] + APIURL is the new custom provider endpoint, when supplied. + + credential : typing.Optional[str] + Credential is the new write-only provider credential, when supplied. + + name : typing.Optional[str] + Name is the new connection name, when supplied. + + requests_per_minute : typing.Optional[int] + RequestsPerMinute is the new provider request rate limit, when supplied. + + retention_days : typing.Optional[int] + RetentionDays is the new provider retention window, when supplied. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + TraceConnection + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.trace_connection.update( + connection_uuid="connection_uuid", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.update( + connection_uuid, + api_url=api_url, + credential=credential, + name=name, + requests_per_minute=requests_per_minute, + retention_days=retention_days, + idempotency_key=idempotency_key, + request_options=request_options, + ) + return _response.data + + async def verify( + self, + connection_uuid: str, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> TraceConnection: + """ + Check the provider credential and update the connection status. + + Parameters + ---------- + connection_uuid : str + Trace connection UUID + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + TraceConnection + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.trace_connection.verify( + connection_uuid="connection_uuid", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.verify( + connection_uuid, idempotency_key=idempotency_key, request_options=request_options + ) + return _response.data + + @property + def project(self): + if self._project is None: + from .project.client import AsyncProjectClient # noqa: E402 + + self._project = AsyncProjectClient(client_wrapper=self._client_wrapper) + return self._project + + @property + def trace(self): + if self._trace is None: + from .trace.client import AsyncTraceClient # noqa: E402 + + self._trace = AsyncTraceClient(client_wrapper=self._client_wrapper) + return self._trace diff --git a/src/zep_cloud/trace_connection/project/__init__.py b/src/zep_cloud/trace_connection/project/__init__.py new file mode 100644 index 00000000..5cde0202 --- /dev/null +++ b/src/zep_cloud/trace_connection/project/__init__.py @@ -0,0 +1,4 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + diff --git a/src/zep_cloud/trace_connection/project/client.py b/src/zep_cloud/trace_connection/project/client.py new file mode 100644 index 00000000..b26019a2 --- /dev/null +++ b/src/zep_cloud/trace_connection/project/client.py @@ -0,0 +1,147 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ...core.pagination import AsyncPager, SyncPager +from ...core.request_options import RequestOptions +from ...types.trace_provider_project import TraceProviderProject +from ...types.trace_provider_project_page import TraceProviderProjectPage +from .raw_client import AsyncRawProjectClient, RawProjectClient + + +class ProjectClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawProjectClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawProjectClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawProjectClient + """ + return self._raw_client + + def list( + self, + connection_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[TraceProviderProject, TraceProviderProjectPage]: + """ + List provider projects with the `limit` and `cursor` query parameters. + + Parameters + ---------- + connection_uuid : str + Trace connection UUID + + limit : typing.Optional[int] + Page size from 1 to 100; default 50 + + cursor : typing.Optional[str] + Provider page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[TraceProviderProject, TraceProviderProjectPage] + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + response = client.trace_connection.project.list( + connection_uuid="connection_uuid", + ) + for item in response: + yield item + # alternatively, you can paginate page-by-page + for page in response.iter_pages(): + yield page + """ + return self._raw_client.list(connection_uuid, limit=limit, cursor=cursor, request_options=request_options) + + +class AsyncProjectClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawProjectClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawProjectClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawProjectClient + """ + return self._raw_client + + async def list( + self, + connection_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[TraceProviderProject, TraceProviderProjectPage]: + """ + List provider projects with the `limit` and `cursor` query parameters. + + Parameters + ---------- + connection_uuid : str + Trace connection UUID + + limit : typing.Optional[int] + Page size from 1 to 100; default 50 + + cursor : typing.Optional[str] + Provider page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[TraceProviderProject, TraceProviderProjectPage] + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + response = await client.trace_connection.project.list( + connection_uuid="connection_uuid", + ) + async for item in response: + yield item + + # alternatively, you can paginate page-by-page + async for page in response.iter_pages(): + yield page + + + asyncio.run(main()) + """ + return await self._raw_client.list(connection_uuid, limit=limit, cursor=cursor, request_options=request_options) diff --git a/src/zep_cloud/trace_connection/project/raw_client.py b/src/zep_cloud/trace_connection/project/raw_client.py new file mode 100644 index 00000000..237530e1 --- /dev/null +++ b/src/zep_cloud/trace_connection/project/raw_client.py @@ -0,0 +1,263 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ...core.api_error import ApiError as core_api_error_ApiError +from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ...core.jsonable_encoder import encode_path_param +from ...core.pagination import AsyncPager, SyncPager +from ...core.parse_error import ParsingError +from ...core.pydantic_utilities import parse_obj_as +from ...core.request_options import RequestOptions +from ...errors.bad_request_error import BadRequestError +from ...errors.forbidden_error import ForbiddenError +from ...errors.not_found_error import NotFoundError +from ...errors.unauthorized_error import UnauthorizedError +from ...types.api_error import ApiError as types_api_error_ApiError +from ...types.trace_provider_project import TraceProviderProject +from ...types.trace_provider_project_page import TraceProviderProjectPage +from pydantic import ValidationError + + +class RawProjectClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def list( + self, + connection_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[TraceProviderProject, TraceProviderProjectPage]: + """ + List provider projects with the `limit` and `cursor` query parameters. + + Parameters + ---------- + connection_uuid : str + Trace connection UUID + + limit : typing.Optional[int] + Page size from 1 to 100; default 50 + + cursor : typing.Optional[str] + Provider page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[TraceProviderProject, TraceProviderProjectPage] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"trace-connections/{encode_path_param(connection_uuid)}/projects", + method="GET", + params={ + "limit": limit, + "cursor": cursor, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + TraceProviderProjectPage, + parse_obj_as( + type_=TraceProviderProjectPage, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + _get_next = lambda: self.list( + connection_uuid, + limit=limit, + cursor=_parsed_next, + request_options=request_options, + ) + return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + +class AsyncRawProjectClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def list( + self, + connection_uuid: str, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[TraceProviderProject, TraceProviderProjectPage]: + """ + List provider projects with the `limit` and `cursor` query parameters. + + Parameters + ---------- + connection_uuid : str + Trace connection UUID + + limit : typing.Optional[int] + Page size from 1 to 100; default 50 + + cursor : typing.Optional[str] + Provider page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[TraceProviderProject, TraceProviderProjectPage] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"trace-connections/{encode_path_param(connection_uuid)}/projects", + method="GET", + params={ + "limit": limit, + "cursor": cursor, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + TraceProviderProjectPage, + parse_obj_as( + type_=TraceProviderProjectPage, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + + async def _get_next(): + return await self.list( + connection_uuid, + limit=limit, + cursor=_parsed_next, + request_options=request_options, + ) + + return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) diff --git a/src/zep_cloud/trace_connection/raw_client.py b/src/zep_cloud/trace_connection/raw_client.py new file mode 100644 index 00000000..8d3a0350 --- /dev/null +++ b/src/zep_cloud/trace_connection/raw_client.py @@ -0,0 +1,1344 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ..core.api_error import ApiError as core_api_error_ApiError +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.http_response import AsyncHttpResponse, HttpResponse +from ..core.idempotency import generate_idempotency_key +from ..core.jsonable_encoder import encode_path_param +from ..core.pagination import AsyncPager, SyncPager +from ..core.parse_error import ParsingError +from ..core.pydantic_utilities import parse_obj_as +from ..core.request_options import RequestOptions +from ..errors.bad_request_error import BadRequestError +from ..errors.conflict_error import ConflictError +from ..errors.forbidden_error import ForbiddenError +from ..errors.not_found_error import NotFoundError +from ..errors.unauthorized_error import UnauthorizedError +from ..errors.unprocessable_entity_error import UnprocessableEntityError +from ..types.api_error import ApiError as types_api_error_ApiError +from ..types.trace_connection import TraceConnection +from ..types.trace_connection_page import TraceConnectionPage +from pydantic import ValidationError + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class RawTraceConnectionClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def list( + self, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[TraceConnection, TraceConnectionPage]: + """ + List trace connections in the current Zep project. + + Parameters + ---------- + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[TraceConnection, TraceConnectionPage] + OK + """ + _response = self._client_wrapper.httpx_client.request( + "trace-connections", + method="GET", + params={ + "limit": limit, + "cursor": cursor, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + TraceConnectionPage, + parse_obj_as( + type_=TraceConnectionPage, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + _get_next = lambda: self.list( + limit=limit, + cursor=_parsed_next, + request_options=request_options, + ) + return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def create( + self, + *, + api_url: typing.Optional[str] = OMIT, + credential: typing.Optional[str] = OMIT, + name: typing.Optional[str] = OMIT, + provider: typing.Optional[str] = OMIT, + requests_per_minute: typing.Optional[int] = OMIT, + retention_days: typing.Optional[int] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[TraceConnection]: + """ + Verify the provider credential before Zep stores it. Example request: `{"name":"Support traces","provider":"braintrust","credential":"secret","requests_per_minute":10}`. + + Parameters + ---------- + api_url : typing.Optional[str] + APIURL is an optional custom provider endpoint. + + credential : typing.Optional[str] + Credential is the write-only provider credential. + + name : typing.Optional[str] + Name is the connection name. + + provider : typing.Optional[str] + Provider is the provider name. + + requests_per_minute : typing.Optional[int] + RequestsPerMinute is the provider request rate limit. + + retention_days : typing.Optional[int] + RetentionDays is an optional provider retention window. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[TraceConnection] + Created + """ + _response = self._client_wrapper.httpx_client.request( + "trace-connections", + method="POST", + json={ + "api_url": api_url, + "credential": credential, + "name": name, + "provider": provider, + "requests_per_minute": requests_per_minute, + "retention_days": retention_days, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + TraceConnection, + parse_obj_as( + type_=TraceConnection, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def get( + self, connection_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[TraceConnection]: + """ + Read one trace connection. The response includes a credential hint and never includes the credential. + + Parameters + ---------- + connection_uuid : str + Trace connection UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[TraceConnection] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"trace-connections/{encode_path_param(connection_uuid)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + TraceConnection, + parse_obj_as( + type_=TraceConnection, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def delete( + self, + connection_uuid: str, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[None]: + """ + Delete a trace connection that no active trajectory import uses. + + Parameters + ---------- + connection_uuid : str + Trace connection UUID + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[None] + """ + _response = self._client_wrapper.httpx_client.request( + f"trace-connections/{encode_path_param(connection_uuid)}", + method="DELETE", + headers={ + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return HttpResponse(response=_response, data=None) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def update( + self, + connection_uuid: str, + *, + api_url: typing.Optional[str] = OMIT, + credential: typing.Optional[str] = OMIT, + name: typing.Optional[str] = OMIT, + requests_per_minute: typing.Optional[int] = OMIT, + retention_days: typing.Optional[int] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[TraceConnection]: + """ + Verify changed provider settings before Zep stores them. Example request: `{"credential":"new-secret","requests_per_minute":20}`. + + Parameters + ---------- + connection_uuid : str + Trace connection UUID + + api_url : typing.Optional[str] + APIURL is the new custom provider endpoint, when supplied. + + credential : typing.Optional[str] + Credential is the new write-only provider credential, when supplied. + + name : typing.Optional[str] + Name is the new connection name, when supplied. + + requests_per_minute : typing.Optional[int] + RequestsPerMinute is the new provider request rate limit, when supplied. + + retention_days : typing.Optional[int] + RetentionDays is the new provider retention window, when supplied. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[TraceConnection] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"trace-connections/{encode_path_param(connection_uuid)}", + method="PATCH", + json={ + "api_url": api_url, + "credential": credential, + "name": name, + "requests_per_minute": requests_per_minute, + "retention_days": retention_days, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + TraceConnection, + parse_obj_as( + type_=TraceConnection, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def verify( + self, + connection_uuid: str, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[TraceConnection]: + """ + Check the provider credential and update the connection status. + + Parameters + ---------- + connection_uuid : str + Trace connection UUID + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[TraceConnection] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"trace-connections/{encode_path_param(connection_uuid)}/verify", + method="POST", + headers={ + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + TraceConnection, + parse_obj_as( + type_=TraceConnection, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + +class AsyncRawTraceConnectionClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def list( + self, + *, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[TraceConnection, TraceConnectionPage]: + """ + List trace connections in the current Zep project. + + Parameters + ---------- + limit : typing.Optional[int] + Page size + + cursor : typing.Optional[str] + Opaque page cursor + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[TraceConnection, TraceConnectionPage] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + "trace-connections", + method="GET", + params={ + "limit": limit, + "cursor": cursor, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + TraceConnectionPage, + parse_obj_as( + type_=TraceConnectionPage, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + + async def _get_next(): + return await self.list( + limit=limit, + cursor=_parsed_next, + request_options=request_options, + ) + + return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def create( + self, + *, + api_url: typing.Optional[str] = OMIT, + credential: typing.Optional[str] = OMIT, + name: typing.Optional[str] = OMIT, + provider: typing.Optional[str] = OMIT, + requests_per_minute: typing.Optional[int] = OMIT, + retention_days: typing.Optional[int] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[TraceConnection]: + """ + Verify the provider credential before Zep stores it. Example request: `{"name":"Support traces","provider":"braintrust","credential":"secret","requests_per_minute":10}`. + + Parameters + ---------- + api_url : typing.Optional[str] + APIURL is an optional custom provider endpoint. + + credential : typing.Optional[str] + Credential is the write-only provider credential. + + name : typing.Optional[str] + Name is the connection name. + + provider : typing.Optional[str] + Provider is the provider name. + + requests_per_minute : typing.Optional[int] + RequestsPerMinute is the provider request rate limit. + + retention_days : typing.Optional[int] + RetentionDays is an optional provider retention window. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[TraceConnection] + Created + """ + _response = await self._client_wrapper.httpx_client.request( + "trace-connections", + method="POST", + json={ + "api_url": api_url, + "credential": credential, + "name": name, + "provider": provider, + "requests_per_minute": requests_per_minute, + "retention_days": retention_days, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + TraceConnection, + parse_obj_as( + type_=TraceConnection, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def get( + self, connection_uuid: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[TraceConnection]: + """ + Read one trace connection. The response includes a credential hint and never includes the credential. + + Parameters + ---------- + connection_uuid : str + Trace connection UUID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[TraceConnection] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"trace-connections/{encode_path_param(connection_uuid)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + TraceConnection, + parse_obj_as( + type_=TraceConnection, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def delete( + self, + connection_uuid: str, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[None]: + """ + Delete a trace connection that no active trajectory import uses. + + Parameters + ---------- + connection_uuid : str + Trace connection UUID + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[None] + """ + _response = await self._client_wrapper.httpx_client.request( + f"trace-connections/{encode_path_param(connection_uuid)}", + method="DELETE", + headers={ + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return AsyncHttpResponse(response=_response, data=None) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def update( + self, + connection_uuid: str, + *, + api_url: typing.Optional[str] = OMIT, + credential: typing.Optional[str] = OMIT, + name: typing.Optional[str] = OMIT, + requests_per_minute: typing.Optional[int] = OMIT, + retention_days: typing.Optional[int] = OMIT, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[TraceConnection]: + """ + Verify changed provider settings before Zep stores them. Example request: `{"credential":"new-secret","requests_per_minute":20}`. + + Parameters + ---------- + connection_uuid : str + Trace connection UUID + + api_url : typing.Optional[str] + APIURL is the new custom provider endpoint, when supplied. + + credential : typing.Optional[str] + Credential is the new write-only provider credential, when supplied. + + name : typing.Optional[str] + Name is the new connection name, when supplied. + + requests_per_minute : typing.Optional[int] + RequestsPerMinute is the new provider request rate limit, when supplied. + + retention_days : typing.Optional[int] + RetentionDays is the new provider retention window, when supplied. + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[TraceConnection] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"trace-connections/{encode_path_param(connection_uuid)}", + method="PATCH", + json={ + "api_url": api_url, + "credential": credential, + "name": name, + "requests_per_minute": requests_per_minute, + "retention_days": retention_days, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + TraceConnection, + parse_obj_as( + type_=TraceConnection, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def verify( + self, + connection_uuid: str, + *, + idempotency_key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[TraceConnection]: + """ + Check the provider credential and update the connection status. + + Parameters + ---------- + connection_uuid : str + Trace connection UUID + + idempotency_key : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[TraceConnection] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"trace-connections/{encode_path_param(connection_uuid)}/verify", + method="POST", + headers={ + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + TraceConnection, + parse_obj_as( + type_=TraceConnection, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) diff --git a/src/zep_cloud/trace_connection/trace/__init__.py b/src/zep_cloud/trace_connection/trace/__init__.py new file mode 100644 index 00000000..5cde0202 --- /dev/null +++ b/src/zep_cloud/trace_connection/trace/__init__.py @@ -0,0 +1,4 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + diff --git a/src/zep_cloud/trace_connection/trace/client.py b/src/zep_cloud/trace_connection/trace/client.py new file mode 100644 index 00000000..dc8ac6b3 --- /dev/null +++ b/src/zep_cloud/trace_connection/trace/client.py @@ -0,0 +1,305 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ...core.pagination import AsyncPager, SyncPager +from ...core.request_options import RequestOptions +from ...types.source_trace_page import SourceTracePage +from ...types.source_trace_response import SourceTraceResponse +from ...types.source_trace_summary import SourceTraceSummary +from ...types.trace_filter import TraceFilter +from ...types.trajectory_mapping import TrajectoryMapping +from .raw_client import AsyncRawTraceClient, RawTraceClient + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class TraceClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawTraceClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawTraceClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawTraceClient + """ + return self._raw_client + + def get( + self, + connection_uuid: str, + *, + provider_project_id: str, + trace_id: str, + mapping: typing.Optional[TrajectoryMapping] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> SourceTraceResponse: + """ + Read one trace and optionally preview a mapping. Example body: `{"provider_project_id":"project_123","trace_id":"trace-123","mapping":{"task_family":{"source":"fixed","value":"support"}}}`. + + Parameters + ---------- + connection_uuid : str + Trace connection UUID + + provider_project_id : str + ProviderProjectID is the provider project identifier. + + trace_id : str + TraceID is the provider trace identifier. + + mapping : typing.Optional[TrajectoryMapping] + Mapping is an optional mapping preview configuration. Example: {"task_family":{"source":"fixed","value":"support"}}. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SourceTraceResponse + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + client.trace_connection.trace.get( + connection_uuid="connection_uuid", + provider_project_id="project_123", + trace_id="trace_123", + ) + """ + _response = self._raw_client.get( + connection_uuid, + provider_project_id=provider_project_id, + trace_id=trace_id, + mapping=mapping, + request_options=request_options, + ) + return _response.data + + def list( + self, + connection_uuid: str, + *, + provider_project_id: str, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + filter: typing.Optional[TraceFilter] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[SourceTraceSummary, SourceTracePage]: + """ + Filter provider traces. Example body: `{"provider_project_id":"project_123","filter":{"started_after":"2026-01-01T00:00:00Z"}}`. + + Parameters + ---------- + connection_uuid : str + Trace connection UUID + + provider_project_id : str + ProviderProjectID is the provider project identifier. + + limit : typing.Optional[int] + Page size from 1 to 100; default 25 + + cursor : typing.Optional[str] + Opaque page cursor + + filter : typing.Optional[TraceFilter] + Filter contains provider trace filters. Example: {"started_after":"2026-01-01T00:00:00Z"}. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[SourceTraceSummary, SourceTracePage] + OK + + Examples + -------- + from zep_cloud import Zep + + client = Zep( + api_key="YOUR_API_KEY", + ) + response = client.trace_connection.trace.list( + connection_uuid="connection_uuid", + provider_project_id="project_123", + ) + for item in response: + yield item + # alternatively, you can paginate page-by-page + for page in response.iter_pages(): + yield page + """ + return self._raw_client.list( + connection_uuid, + provider_project_id=provider_project_id, + limit=limit, + cursor=cursor, + filter=filter, + request_options=request_options, + ) + + +class AsyncTraceClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawTraceClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawTraceClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawTraceClient + """ + return self._raw_client + + async def get( + self, + connection_uuid: str, + *, + provider_project_id: str, + trace_id: str, + mapping: typing.Optional[TrajectoryMapping] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> SourceTraceResponse: + """ + Read one trace and optionally preview a mapping. Example body: `{"provider_project_id":"project_123","trace_id":"trace-123","mapping":{"task_family":{"source":"fixed","value":"support"}}}`. + + Parameters + ---------- + connection_uuid : str + Trace connection UUID + + provider_project_id : str + ProviderProjectID is the provider project identifier. + + trace_id : str + TraceID is the provider trace identifier. + + mapping : typing.Optional[TrajectoryMapping] + Mapping is an optional mapping preview configuration. Example: {"task_family":{"source":"fixed","value":"support"}}. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SourceTraceResponse + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.trace_connection.trace.get( + connection_uuid="connection_uuid", + provider_project_id="project_123", + trace_id="trace_123", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get( + connection_uuid, + provider_project_id=provider_project_id, + trace_id=trace_id, + mapping=mapping, + request_options=request_options, + ) + return _response.data + + async def list( + self, + connection_uuid: str, + *, + provider_project_id: str, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + filter: typing.Optional[TraceFilter] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[SourceTraceSummary, SourceTracePage]: + """ + Filter provider traces. Example body: `{"provider_project_id":"project_123","filter":{"started_after":"2026-01-01T00:00:00Z"}}`. + + Parameters + ---------- + connection_uuid : str + Trace connection UUID + + provider_project_id : str + ProviderProjectID is the provider project identifier. + + limit : typing.Optional[int] + Page size from 1 to 100; default 25 + + cursor : typing.Optional[str] + Opaque page cursor + + filter : typing.Optional[TraceFilter] + Filter contains provider trace filters. Example: {"started_after":"2026-01-01T00:00:00Z"}. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[SourceTraceSummary, SourceTracePage] + OK + + Examples + -------- + import asyncio + + from zep_cloud import AsyncZep + + client = AsyncZep( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + response = await client.trace_connection.trace.list( + connection_uuid="connection_uuid", + provider_project_id="project_123", + ) + async for item in response: + yield item + + # alternatively, you can paginate page-by-page + async for page in response.iter_pages(): + yield page + + + asyncio.run(main()) + """ + return await self._raw_client.list( + connection_uuid, + provider_project_id=provider_project_id, + limit=limit, + cursor=cursor, + filter=filter, + request_options=request_options, + ) diff --git a/src/zep_cloud/trace_connection/trace/raw_client.py b/src/zep_cloud/trace_connection/trace/raw_client.py new file mode 100644 index 00000000..f4736e64 --- /dev/null +++ b/src/zep_cloud/trace_connection/trace/raw_client.py @@ -0,0 +1,595 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ...core.api_error import ApiError as core_api_error_ApiError +from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ...core.http_response import AsyncHttpResponse, HttpResponse +from ...core.idempotency import generate_idempotency_key +from ...core.jsonable_encoder import encode_path_param +from ...core.pagination import AsyncPager, SyncPager +from ...core.parse_error import ParsingError +from ...core.pydantic_utilities import parse_obj_as +from ...core.request_options import RequestOptions +from ...core.serialization import convert_and_respect_annotation_metadata +from ...errors.bad_gateway_error import BadGatewayError +from ...errors.bad_request_error import BadRequestError +from ...errors.forbidden_error import ForbiddenError +from ...errors.not_found_error import NotFoundError +from ...errors.unauthorized_error import UnauthorizedError +from ...types.api_error import ApiError as types_api_error_ApiError +from ...types.source_trace_page import SourceTracePage +from ...types.source_trace_response import SourceTraceResponse +from ...types.source_trace_summary import SourceTraceSummary +from ...types.trace_filter import TraceFilter +from ...types.trajectory_mapping import TrajectoryMapping +from pydantic import ValidationError + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class RawTraceClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def get( + self, + connection_uuid: str, + *, + provider_project_id: str, + trace_id: str, + mapping: typing.Optional[TrajectoryMapping] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[SourceTraceResponse]: + """ + Read one trace and optionally preview a mapping. Example body: `{"provider_project_id":"project_123","trace_id":"trace-123","mapping":{"task_family":{"source":"fixed","value":"support"}}}`. + + Parameters + ---------- + connection_uuid : str + Trace connection UUID + + provider_project_id : str + ProviderProjectID is the provider project identifier. + + trace_id : str + TraceID is the provider trace identifier. + + mapping : typing.Optional[TrajectoryMapping] + Mapping is an optional mapping preview configuration. Example: {"task_family":{"source":"fixed","value":"support"}}. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[SourceTraceResponse] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"trace-connections/{encode_path_param(connection_uuid)}/traces/get", + method="POST", + json={ + "mapping": convert_and_respect_annotation_metadata( + object_=mapping, annotation=TrajectoryMapping, direction="write" + ), + "provider_project_id": provider_project_id, + "trace_id": trace_id, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + SourceTraceResponse, + parse_obj_as( + type_=SourceTraceResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 502: + raise BadGatewayError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + def list( + self, + connection_uuid: str, + *, + provider_project_id: str, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + filter: typing.Optional[TraceFilter] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[SourceTraceSummary, SourceTracePage]: + """ + Filter provider traces. Example body: `{"provider_project_id":"project_123","filter":{"started_after":"2026-01-01T00:00:00Z"}}`. + + Parameters + ---------- + connection_uuid : str + Trace connection UUID + + provider_project_id : str + ProviderProjectID is the provider project identifier. + + limit : typing.Optional[int] + Page size from 1 to 100; default 25 + + cursor : typing.Optional[str] + Opaque page cursor + + filter : typing.Optional[TraceFilter] + Filter contains provider trace filters. Example: {"started_after":"2026-01-01T00:00:00Z"}. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[SourceTraceSummary, SourceTracePage] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"trace-connections/{encode_path_param(connection_uuid)}/traces/list", + method="POST", + params={ + "limit": limit, + "cursor": cursor, + }, + json={ + "filter": convert_and_respect_annotation_metadata( + object_=filter, annotation=TraceFilter, direction="write" + ), + "provider_project_id": provider_project_id, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + SourceTracePage, + parse_obj_as( + type_=SourceTracePage, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + _get_next = lambda: self.list( + connection_uuid, + provider_project_id=provider_project_id, + limit=limit, + cursor=_parsed_next, + filter=filter, + request_options=request_options, + ) + return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 502: + raise BadGatewayError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + +class AsyncRawTraceClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def get( + self, + connection_uuid: str, + *, + provider_project_id: str, + trace_id: str, + mapping: typing.Optional[TrajectoryMapping] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[SourceTraceResponse]: + """ + Read one trace and optionally preview a mapping. Example body: `{"provider_project_id":"project_123","trace_id":"trace-123","mapping":{"task_family":{"source":"fixed","value":"support"}}}`. + + Parameters + ---------- + connection_uuid : str + Trace connection UUID + + provider_project_id : str + ProviderProjectID is the provider project identifier. + + trace_id : str + TraceID is the provider trace identifier. + + mapping : typing.Optional[TrajectoryMapping] + Mapping is an optional mapping preview configuration. Example: {"task_family":{"source":"fixed","value":"support"}}. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[SourceTraceResponse] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"trace-connections/{encode_path_param(connection_uuid)}/traces/get", + method="POST", + json={ + "mapping": convert_and_respect_annotation_metadata( + object_=mapping, annotation=TrajectoryMapping, direction="write" + ), + "provider_project_id": provider_project_id, + "trace_id": trace_id, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + SourceTraceResponse, + parse_obj_as( + type_=SourceTraceResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 502: + raise BadGatewayError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + + async def list( + self, + connection_uuid: str, + *, + provider_project_id: str, + limit: typing.Optional[int] = None, + cursor: typing.Optional[str] = None, + filter: typing.Optional[TraceFilter] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[SourceTraceSummary, SourceTracePage]: + """ + Filter provider traces. Example body: `{"provider_project_id":"project_123","filter":{"started_after":"2026-01-01T00:00:00Z"}}`. + + Parameters + ---------- + connection_uuid : str + Trace connection UUID + + provider_project_id : str + ProviderProjectID is the provider project identifier. + + limit : typing.Optional[int] + Page size from 1 to 100; default 25 + + cursor : typing.Optional[str] + Opaque page cursor + + filter : typing.Optional[TraceFilter] + Filter contains provider trace filters. Example: {"started_after":"2026-01-01T00:00:00Z"}. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[SourceTraceSummary, SourceTracePage] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"trace-connections/{encode_path_param(connection_uuid)}/traces/list", + method="POST", + params={ + "limit": limit, + "cursor": cursor, + }, + json={ + "filter": convert_and_respect_annotation_metadata( + object_=filter, annotation=TraceFilter, direction="write" + ), + "provider_project_id": provider_project_id, + }, + headers={ + "content-type": "application/json", + "Idempotency-Key": generate_idempotency_key(), + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + SourceTracePage, + parse_obj_as( + type_=SourceTracePage, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.items + _parsed_next = _parsed_response.next_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + + async def _get_next(): + return await self.list( + connection_uuid, + provider_project_id=provider_project_id, + limit=limit, + cursor=_parsed_next, + filter=filter, + request_options=request_options, + ) + + return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 502: + raise BadGatewayError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) diff --git a/src/zep_cloud/types/__init__.py b/src/zep_cloud/types/__init__.py index 690e4c16..61bd7238 100644 --- a/src/zep_cloud/types/__init__.py +++ b/src/zep_cloud/types/__init__.py @@ -6,26 +6,127 @@ from importlib import import_module if typing.TYPE_CHECKING: - from .add_edge_result import AddEdgeResult + from .add_agent_skill_use_outcome_request import AddAgentSkillUseOutcomeRequest + from .add_agent_skill_use_outcome_request_outcome import AddAgentSkillUseOutcomeRequestOutcome + from .add_edges_result import AddEdgesResult from .add_episode_result import AddEpisodeResult + from .add_hyperedge_edge_result import AddHyperedgeEdgeResult + from .add_hyperedge_result import AddHyperedgeResult from .add_message import AddMessage from .add_messages_result import AddMessagesResult from .add_nodes_result import AddNodesResult from .added_edge import AddedEdge + from .added_hyperedge import AddedHyperedge + from .added_hyperedge_edge import AddedHyperedgeEdge from .added_node import AddedNode + from .agent import Agent + from .agent_breaking_change import AgentBreakingChange + from .agent_context import AgentContext + from .agent_context_evidence_counts import AgentContextEvidenceCounts + from .agent_context_partial_source import AgentContextPartialSource + from .agent_context_resource import AgentContextResource + from .agent_context_skill_snapshot import AgentContextSkillSnapshot + from .agent_context_skipped_skill import AgentContextSkippedSkill + from .agent_delete_result import AgentDeleteResult + from .agent_learning_state import AgentLearningState + from .agent_literal_policy import AgentLiteralPolicy + from .agent_literal_policy_classes import AgentLiteralPolicyClasses + from .agent_literal_policy_values import AgentLiteralPolicyValues + from .agent_memory_evaluation_policy import AgentMemoryEvaluationPolicy + from .agent_memory_evaluation_requirement import AgentMemoryEvaluationRequirement + from .agent_memory_settings import AgentMemorySettings + from .agent_memory_settings_approval import AgentMemorySettingsApproval + from .agent_memory_settings_compilation_mode import AgentMemorySettingsCompilationMode + from .agent_page import AgentPage + from .agent_skill import AgentSkill + from .agent_skill_admission_decision import AgentSkillAdmissionDecision + from .agent_skill_candidate import AgentSkillCandidate + from .agent_skill_candidate_base_version import AgentSkillCandidateBaseVersion + from .agent_skill_candidate_evaluation import AgentSkillCandidateEvaluation + from .agent_skill_candidate_evidence import AgentSkillCandidateEvidence + from .agent_skill_candidate_review import AgentSkillCandidateReview + from .agent_skill_candidate_review_result import AgentSkillCandidateReviewResult + from .agent_skill_candidate_review_summary import AgentSkillCandidateReviewSummary + from .agent_skill_compilation_outcome import AgentSkillCompilationOutcome + from .agent_skill_compilation_outcome_rejection_class import AgentSkillCompilationOutcomeRejectionClass + from .agent_skill_evaluation import AgentSkillEvaluation + from .agent_skill_evidence import AgentSkillEvidence + from .agent_skill_publication_lineage import AgentSkillPublicationLineage + from .agent_skill_relationship import AgentSkillRelationship + from .agent_skill_search_hit import AgentSkillSearchHit + from .agent_skill_search_hit_maturity import AgentSkillSearchHitMaturity + from .agent_skill_search_response import AgentSkillSearchResponse + from .agent_skill_use import AgentSkillUse + from .agent_skill_use_outcome import AgentSkillUseOutcome + from .agent_skill_version import AgentSkillVersion + from .agent_skill_version_comparison import AgentSkillVersionComparison + from .agent_split_plan import AgentSplitPlan + from .agent_split_plan_destination import AgentSplitPlanDestination + from .agent_split_plan_destination_request import AgentSplitPlanDestinationRequest + from .agent_split_plan_skill_reference import AgentSplitPlanSkillReference + from .agent_split_plan_skill_selection_request import AgentSplitPlanSkillSelectionRequest + from .agent_split_plan_source import AgentSplitPlanSource + from .agent_status import AgentStatus + from .agent_trajectory import AgentTrajectory + from .agent_trajectory_close_verifier import AgentTrajectoryCloseVerifier + from .agent_trajectory_event import AgentTrajectoryEvent + from .agent_trajectory_event_context import AgentTrajectoryEventContext + from .agent_trajectory_event_page import AgentTrajectoryEventPage + from .agent_trajectory_event_processing_state import AgentTrajectoryEventProcessingState + from .agent_trajectory_event_source import AgentTrajectoryEventSource + from .agent_trajectory_event_source_copy_mode import AgentTrajectoryEventSourceCopyMode + from .agent_trajectory_event_source_retention_mode import AgentTrajectoryEventSourceRetentionMode + from .agent_trajectory_event_type import AgentTrajectoryEventType + from .agent_trajectory_finalization_result import AgentTrajectoryFinalizationResult + from .agent_trajectory_internal import AgentTrajectoryInternal + from .agent_trajectory_lifecycle import AgentTrajectoryLifecycle + from .agent_trajectory_outcome import AgentTrajectoryOutcome + from .agent_trajectory_page import AgentTrajectoryPage + from .agent_trajectory_processing_state import AgentTrajectoryProcessingState + from .agent_trajectory_resource_ref import AgentTrajectoryResourceRef + from .agent_trajectory_sequence_range import AgentTrajectorySequenceRange + from .agent_trajectory_source import AgentTrajectorySource + from .agent_trajectory_source_deletion_result import AgentTrajectorySourceDeletionResult + from .agent_trajectory_summary_creation_reason import AgentTrajectorySummaryCreationReason + from .agent_trajectory_summary_omission_reason import AgentTrajectorySummaryOmissionReason + from .agent_trajectory_summary_omitted_range import AgentTrajectorySummaryOmittedRange + from .agent_trajectory_summary_page import AgentTrajectorySummaryPage + from .agent_trajectory_summary_version import AgentTrajectorySummaryVersion + from .agent_trajectory_verification import AgentTrajectoryVerification + from .agent_verification_strength import AgentVerificationStrength + from .agent_verifier import AgentVerifier + from .agent_verifier_assertion_outcome import AgentVerifierAssertionOutcome + from .agent_verifier_evidence_invalidation_result import AgentVerifierEvidenceInvalidationResult + from .agent_verifier_principal import AgentVerifierPrincipal + from .agent_verifier_principal_binding import AgentVerifierPrincipalBinding + from .agent_verifier_principal_binding_input import AgentVerifierPrincipalBindingInput + from .agent_verifier_status import AgentVerifierStatus from .api_error import ApiError from .artifact_list_request import ArtifactListRequest from .async_result import AsyncResult from .batch import Batch from .batch_item import BatchItem from .batch_item_input import BatchItemInput + from .batch_item_input_data_type import BatchItemInputDataType + from .batch_item_input_role import BatchItemInputRole + from .batch_item_input_type import BatchItemInputType from .batch_item_kind import BatchItemKind from .batch_item_page import BatchItemPage from .batch_item_status import BatchItemStatus from .batch_items_response import BatchItemsResponse from .batch_page import BatchPage + from .clone_graph_request import CloneGraphRequest from .clone_graph_result import CloneGraphResult - from .comparison_operator import ComparisonOperator + from .content_policy import ContentPolicy + from .content_policy_category import ContentPolicyCategory + from .content_policy_category_request import ContentPolicyCategoryRequest + from .content_policy_event import ContentPolicyEvent + from .content_policy_event_artifact_kind import ContentPolicyEventArtifactKind + from .content_policy_event_drop_reason import ContentPolicyEventDropReason + from .content_policy_event_page import ContentPolicyEventPage + from .content_policy_revision_page import ContentPolicyRevisionPage + from .content_policy_rule import ContentPolicyRule + from .content_policy_rule_request import ContentPolicyRuleRequest from .context_edge import ContextEdge from .context_episode import ContextEpisode from .context_node import ContextNode @@ -34,12 +135,23 @@ from .context_template import ContextTemplate from .context_template_page import ContextTemplatePage from .context_thread_summary import ContextThreadSummary + from .create_agent_request import CreateAgentRequest from .create_context_template_request import CreateContextTemplateRequest from .custom_instruction import CustomInstruction from .date_filter import DateFilter + from .date_filter_field import DateFilterField + from .date_filter_group import DateFilterGroup + from .date_filter_operator import DateFilterOperator + from .date_filters import DateFilters + from .debug_log_entry import DebugLogEntry + from .debug_log_level import DebugLogLevel + from .debug_log_status import DebugLogStatus + from .debug_logging_enablement import DebugLoggingEnablement + from .delete_agent_trajectory_request import DeleteAgentTrajectoryRequest from .document_summary import DocumentSummary from .document_summary_page import DocumentSummaryPage from .edge import Edge + from .edge_input import EdgeInput from .edge_node_ref import EdgeNodeRef from .edge_page import EdgePage from .edge_source_target import EdgeSourceTarget @@ -48,15 +160,37 @@ from .entity_property_type import EntityPropertyType from .entity_type import EntityType from .episode import Episode - from .episode_metadata_filter import EpisodeMetadataFilter + from .episode_content_policy import EpisodeContentPolicy + from .episode_content_policy_status import EpisodeContentPolicyStatus + from .episode_debug_log import EpisodeDebugLog from .episode_page import EpisodePage from .error_body import ErrorBody from .graph import Graph + from .graph_content_policy import GraphContentPolicy + from .graph_content_policy_request import GraphContentPolicyRequest from .graph_context_response import GraphContextResponse from .graph_data_type import GraphDataType from .graph_delete_result import GraphDeleteResult from .graph_page import GraphPage - from .graphiti_metadata_filter_group_type import GraphitiMetadataFilterGroupType + from .hyperedge import Hyperedge + from .hyperedge_edge import HyperedgeEdge + from .hyperedge_input import HyperedgeInput + from .hyperedge_page import HyperedgePage + from .imported_trajectory_reference import ImportedTrajectoryReference + from .ingestion_trace import IngestionTrace + from .ingestion_trace_edge import IngestionTraceEdge + from .ingestion_trace_edge_invalidation import IngestionTraceEdgeInvalidation + from .ingestion_trace_edge_reference import IngestionTraceEdgeReference + from .ingestion_trace_entity_type import IngestionTraceEntityType + from .ingestion_trace_episode import IngestionTraceEpisode + from .ingestion_trace_input import IngestionTraceInput + from .ingestion_trace_node import IngestionTraceNode + from .ingestion_trace_node_duplicate import IngestionTraceNodeDuplicate + from .ingestion_trace_node_resolution import IngestionTraceNodeResolution + from .ingestion_trace_output import IngestionTraceOutput + from .ingestion_trace_page import IngestionTracePage + from .ingestion_trace_status import IngestionTraceStatus + from .ingestion_trace_step import IngestionTraceStep from .instructions import Instructions from .lookup_batch_response import LookupBatchResponse from .lookup_item import LookupItem @@ -64,27 +198,60 @@ from .membership_mutation_result import MembershipMutationResult from .message import Message from .message_page import MessagePage + from .metadata_filter import MetadataFilter from .metadata_filter_group import MetadataFilterGroup + from .metadata_filter_group_type import MetadataFilterGroupType + from .metadata_filter_operator import MetadataFilterOperator + from .metadata_filter_value import MetadataFilterValue + from .metadata_filter_value_three_item import MetadataFilterValueThreeItem from .mutate_members_request import MutateMembersRequest from .neighbor_entry import NeighborEntry from .neighbor_page import NeighborPage from .node import Node from .node_input import NodeInput from .node_page import NodePage + from .objective_mapping_rule import ObjectiveMappingRule + from .objective_mapping_rule_source import ObjectiveMappingRuleSource from .observation import Observation from .observation_page import ObservationPage from .observation_steering import ObservationSteering from .observation_type import ObservationType from .ontology import Ontology + from .outcome_mapping_rule import OutcomeMappingRule + from .outcome_mapping_rule_rule import OutcomeMappingRuleRule + from .pagev4agent_skill_candidate_review_summary import Pagev4AgentSkillCandidateReviewSummary + from .pagev4agent_skill_compilation_outcome import Pagev4AgentSkillCompilationOutcome + from .pagev4agent_skill_evidence import Pagev4AgentSkillEvidence + from .pagev4agent_skill_relationship import Pagev4AgentSkillRelationship + from .pagev4agent_skill_search_hit import Pagev4AgentSkillSearchHit + from .pagev4agent_skill_version import Pagev4AgentSkillVersion + from .pagev4agent_verifier import Pagev4AgentVerifier from .process_batch_result import ProcessBatchResult from .project import Project from .property_filter import PropertyFilter + from .property_filter_operator import PropertyFilterOperator + from .property_filter_value import PropertyFilterValue + from .property_filter_value_three_item import PropertyFilterValueThreeItem from .role_type import RoleType from .search_filters import SearchFilters from .search_list_request import SearchListRequest from .search_request import SearchRequest + from .search_request_reranker import SearchRequestReranker + from .skill_definition import SkillDefinition + from .skill_definition_section import SkillDefinitionSection + from .skill_failure import SkillFailure + from .skill_procedure_step import SkillProcedureStep + from .skill_relation import SkillRelation + from .skill_resource import SkillResource + from .source_span import SourceSpan + from .source_trace import SourceTrace + from .source_trace_page import SourceTracePage + from .source_trace_response import SourceTraceResponse + from .source_trace_summary import SourceTraceSummary from .subgraph_response import SubgraphResponse from .task import Task + from .task_family_mapping_rule import TaskFamilyMappingRule + from .task_family_mapping_rule_source import TaskFamilyMappingRuleSource from .task_page import TaskPage from .task_progress import TaskProgress from .thread import Thread @@ -93,6 +260,32 @@ from .thread_page import ThreadPage from .thread_summary import ThreadSummary from .thread_summary_page import ThreadSummaryPage + from .trace_connection import TraceConnection + from .trace_connection_page import TraceConnectionPage + from .trace_connection_settings import TraceConnectionSettings + from .trace_filter import TraceFilter + from .trace_preview import TracePreview + from .trace_provider_project import TraceProviderProject + from .trace_provider_project_page import TraceProviderProjectPage + from .trace_score_range import TraceScoreRange + from .trajectory_content_mapping import TrajectoryContentMapping + from .trajectory_import import TrajectoryImport + from .trajectory_import_page import TrajectoryImportPage + from .trajectory_import_pause_reason import TrajectoryImportPauseReason + from .trajectory_import_run import TrajectoryImportRun + from .trajectory_import_run_item import TrajectoryImportRunItem + from .trajectory_import_run_item_page import TrajectoryImportRunItemPage + from .trajectory_import_run_page import TrajectoryImportRunPage + from .trajectory_import_run_reference import TrajectoryImportRunReference + from .trajectory_import_run_reference_status import TrajectoryImportRunReferenceStatus + from .trajectory_import_run_reference_trigger import TrajectoryImportRunReferenceTrigger + from .trajectory_import_schedule import TrajectoryImportSchedule + from .trajectory_import_selection import TrajectoryImportSelection + from .trajectory_mapping import TrajectoryMapping + from .trajectory_mapping_include_outcomes_item import TrajectoryMappingIncludeOutcomesItem + from .trajectory_mapping_result import TrajectoryMappingResult + from .trajectory_mapping_result_outcome import TrajectoryMappingResultOutcome + from .trajectory_mapping_result_outcome_rule import TrajectoryMappingResultOutcomeRule from .user import User from .user_delete_result import UserDeleteResult from .user_group import UserGroup @@ -100,31 +293,128 @@ from .user_instruction import UserInstruction from .user_page import UserPage from .user_summary_instructions import UserSummaryInstructions - from .v4batch_item_input_data_type import V4BatchItemInputDataType - from .v4batch_item_input_role import V4BatchItemInputRole - from .v4batch_item_input_type import V4BatchItemInputType - from .v4search_request_reranker import V4SearchRequestReranker _dynamic_imports: typing.Dict[str, str] = { - "AddEdgeResult": ".add_edge_result", + "AddAgentSkillUseOutcomeRequest": ".add_agent_skill_use_outcome_request", + "AddAgentSkillUseOutcomeRequestOutcome": ".add_agent_skill_use_outcome_request_outcome", + "AddEdgesResult": ".add_edges_result", "AddEpisodeResult": ".add_episode_result", + "AddHyperedgeEdgeResult": ".add_hyperedge_edge_result", + "AddHyperedgeResult": ".add_hyperedge_result", "AddMessage": ".add_message", "AddMessagesResult": ".add_messages_result", "AddNodesResult": ".add_nodes_result", "AddedEdge": ".added_edge", + "AddedHyperedge": ".added_hyperedge", + "AddedHyperedgeEdge": ".added_hyperedge_edge", "AddedNode": ".added_node", + "Agent": ".agent", + "AgentBreakingChange": ".agent_breaking_change", + "AgentContext": ".agent_context", + "AgentContextEvidenceCounts": ".agent_context_evidence_counts", + "AgentContextPartialSource": ".agent_context_partial_source", + "AgentContextResource": ".agent_context_resource", + "AgentContextSkillSnapshot": ".agent_context_skill_snapshot", + "AgentContextSkippedSkill": ".agent_context_skipped_skill", + "AgentDeleteResult": ".agent_delete_result", + "AgentLearningState": ".agent_learning_state", + "AgentLiteralPolicy": ".agent_literal_policy", + "AgentLiteralPolicyClasses": ".agent_literal_policy_classes", + "AgentLiteralPolicyValues": ".agent_literal_policy_values", + "AgentMemoryEvaluationPolicy": ".agent_memory_evaluation_policy", + "AgentMemoryEvaluationRequirement": ".agent_memory_evaluation_requirement", + "AgentMemorySettings": ".agent_memory_settings", + "AgentMemorySettingsApproval": ".agent_memory_settings_approval", + "AgentMemorySettingsCompilationMode": ".agent_memory_settings_compilation_mode", + "AgentPage": ".agent_page", + "AgentSkill": ".agent_skill", + "AgentSkillAdmissionDecision": ".agent_skill_admission_decision", + "AgentSkillCandidate": ".agent_skill_candidate", + "AgentSkillCandidateBaseVersion": ".agent_skill_candidate_base_version", + "AgentSkillCandidateEvaluation": ".agent_skill_candidate_evaluation", + "AgentSkillCandidateEvidence": ".agent_skill_candidate_evidence", + "AgentSkillCandidateReview": ".agent_skill_candidate_review", + "AgentSkillCandidateReviewResult": ".agent_skill_candidate_review_result", + "AgentSkillCandidateReviewSummary": ".agent_skill_candidate_review_summary", + "AgentSkillCompilationOutcome": ".agent_skill_compilation_outcome", + "AgentSkillCompilationOutcomeRejectionClass": ".agent_skill_compilation_outcome_rejection_class", + "AgentSkillEvaluation": ".agent_skill_evaluation", + "AgentSkillEvidence": ".agent_skill_evidence", + "AgentSkillPublicationLineage": ".agent_skill_publication_lineage", + "AgentSkillRelationship": ".agent_skill_relationship", + "AgentSkillSearchHit": ".agent_skill_search_hit", + "AgentSkillSearchHitMaturity": ".agent_skill_search_hit_maturity", + "AgentSkillSearchResponse": ".agent_skill_search_response", + "AgentSkillUse": ".agent_skill_use", + "AgentSkillUseOutcome": ".agent_skill_use_outcome", + "AgentSkillVersion": ".agent_skill_version", + "AgentSkillVersionComparison": ".agent_skill_version_comparison", + "AgentSplitPlan": ".agent_split_plan", + "AgentSplitPlanDestination": ".agent_split_plan_destination", + "AgentSplitPlanDestinationRequest": ".agent_split_plan_destination_request", + "AgentSplitPlanSkillReference": ".agent_split_plan_skill_reference", + "AgentSplitPlanSkillSelectionRequest": ".agent_split_plan_skill_selection_request", + "AgentSplitPlanSource": ".agent_split_plan_source", + "AgentStatus": ".agent_status", + "AgentTrajectory": ".agent_trajectory", + "AgentTrajectoryCloseVerifier": ".agent_trajectory_close_verifier", + "AgentTrajectoryEvent": ".agent_trajectory_event", + "AgentTrajectoryEventContext": ".agent_trajectory_event_context", + "AgentTrajectoryEventPage": ".agent_trajectory_event_page", + "AgentTrajectoryEventProcessingState": ".agent_trajectory_event_processing_state", + "AgentTrajectoryEventSource": ".agent_trajectory_event_source", + "AgentTrajectoryEventSourceCopyMode": ".agent_trajectory_event_source_copy_mode", + "AgentTrajectoryEventSourceRetentionMode": ".agent_trajectory_event_source_retention_mode", + "AgentTrajectoryEventType": ".agent_trajectory_event_type", + "AgentTrajectoryFinalizationResult": ".agent_trajectory_finalization_result", + "AgentTrajectoryInternal": ".agent_trajectory_internal", + "AgentTrajectoryLifecycle": ".agent_trajectory_lifecycle", + "AgentTrajectoryOutcome": ".agent_trajectory_outcome", + "AgentTrajectoryPage": ".agent_trajectory_page", + "AgentTrajectoryProcessingState": ".agent_trajectory_processing_state", + "AgentTrajectoryResourceRef": ".agent_trajectory_resource_ref", + "AgentTrajectorySequenceRange": ".agent_trajectory_sequence_range", + "AgentTrajectorySource": ".agent_trajectory_source", + "AgentTrajectorySourceDeletionResult": ".agent_trajectory_source_deletion_result", + "AgentTrajectorySummaryCreationReason": ".agent_trajectory_summary_creation_reason", + "AgentTrajectorySummaryOmissionReason": ".agent_trajectory_summary_omission_reason", + "AgentTrajectorySummaryOmittedRange": ".agent_trajectory_summary_omitted_range", + "AgentTrajectorySummaryPage": ".agent_trajectory_summary_page", + "AgentTrajectorySummaryVersion": ".agent_trajectory_summary_version", + "AgentTrajectoryVerification": ".agent_trajectory_verification", + "AgentVerificationStrength": ".agent_verification_strength", + "AgentVerifier": ".agent_verifier", + "AgentVerifierAssertionOutcome": ".agent_verifier_assertion_outcome", + "AgentVerifierEvidenceInvalidationResult": ".agent_verifier_evidence_invalidation_result", + "AgentVerifierPrincipal": ".agent_verifier_principal", + "AgentVerifierPrincipalBinding": ".agent_verifier_principal_binding", + "AgentVerifierPrincipalBindingInput": ".agent_verifier_principal_binding_input", + "AgentVerifierStatus": ".agent_verifier_status", "ApiError": ".api_error", "ArtifactListRequest": ".artifact_list_request", "AsyncResult": ".async_result", "Batch": ".batch", "BatchItem": ".batch_item", "BatchItemInput": ".batch_item_input", + "BatchItemInputDataType": ".batch_item_input_data_type", + "BatchItemInputRole": ".batch_item_input_role", + "BatchItemInputType": ".batch_item_input_type", "BatchItemKind": ".batch_item_kind", "BatchItemPage": ".batch_item_page", "BatchItemStatus": ".batch_item_status", "BatchItemsResponse": ".batch_items_response", "BatchPage": ".batch_page", + "CloneGraphRequest": ".clone_graph_request", "CloneGraphResult": ".clone_graph_result", - "ComparisonOperator": ".comparison_operator", + "ContentPolicy": ".content_policy", + "ContentPolicyCategory": ".content_policy_category", + "ContentPolicyCategoryRequest": ".content_policy_category_request", + "ContentPolicyEvent": ".content_policy_event", + "ContentPolicyEventArtifactKind": ".content_policy_event_artifact_kind", + "ContentPolicyEventDropReason": ".content_policy_event_drop_reason", + "ContentPolicyEventPage": ".content_policy_event_page", + "ContentPolicyRevisionPage": ".content_policy_revision_page", + "ContentPolicyRule": ".content_policy_rule", + "ContentPolicyRuleRequest": ".content_policy_rule_request", "ContextEdge": ".context_edge", "ContextEpisode": ".context_episode", "ContextNode": ".context_node", @@ -133,12 +423,23 @@ "ContextTemplate": ".context_template", "ContextTemplatePage": ".context_template_page", "ContextThreadSummary": ".context_thread_summary", + "CreateAgentRequest": ".create_agent_request", "CreateContextTemplateRequest": ".create_context_template_request", "CustomInstruction": ".custom_instruction", "DateFilter": ".date_filter", + "DateFilterField": ".date_filter_field", + "DateFilterGroup": ".date_filter_group", + "DateFilterOperator": ".date_filter_operator", + "DateFilters": ".date_filters", + "DebugLogEntry": ".debug_log_entry", + "DebugLogLevel": ".debug_log_level", + "DebugLogStatus": ".debug_log_status", + "DebugLoggingEnablement": ".debug_logging_enablement", + "DeleteAgentTrajectoryRequest": ".delete_agent_trajectory_request", "DocumentSummary": ".document_summary", "DocumentSummaryPage": ".document_summary_page", "Edge": ".edge", + "EdgeInput": ".edge_input", "EdgeNodeRef": ".edge_node_ref", "EdgePage": ".edge_page", "EdgeSourceTarget": ".edge_source_target", @@ -147,15 +448,37 @@ "EntityPropertyType": ".entity_property_type", "EntityType": ".entity_type", "Episode": ".episode", - "EpisodeMetadataFilter": ".episode_metadata_filter", + "EpisodeContentPolicy": ".episode_content_policy", + "EpisodeContentPolicyStatus": ".episode_content_policy_status", + "EpisodeDebugLog": ".episode_debug_log", "EpisodePage": ".episode_page", "ErrorBody": ".error_body", "Graph": ".graph", + "GraphContentPolicy": ".graph_content_policy", + "GraphContentPolicyRequest": ".graph_content_policy_request", "GraphContextResponse": ".graph_context_response", "GraphDataType": ".graph_data_type", "GraphDeleteResult": ".graph_delete_result", "GraphPage": ".graph_page", - "GraphitiMetadataFilterGroupType": ".graphiti_metadata_filter_group_type", + "Hyperedge": ".hyperedge", + "HyperedgeEdge": ".hyperedge_edge", + "HyperedgeInput": ".hyperedge_input", + "HyperedgePage": ".hyperedge_page", + "ImportedTrajectoryReference": ".imported_trajectory_reference", + "IngestionTrace": ".ingestion_trace", + "IngestionTraceEdge": ".ingestion_trace_edge", + "IngestionTraceEdgeInvalidation": ".ingestion_trace_edge_invalidation", + "IngestionTraceEdgeReference": ".ingestion_trace_edge_reference", + "IngestionTraceEntityType": ".ingestion_trace_entity_type", + "IngestionTraceEpisode": ".ingestion_trace_episode", + "IngestionTraceInput": ".ingestion_trace_input", + "IngestionTraceNode": ".ingestion_trace_node", + "IngestionTraceNodeDuplicate": ".ingestion_trace_node_duplicate", + "IngestionTraceNodeResolution": ".ingestion_trace_node_resolution", + "IngestionTraceOutput": ".ingestion_trace_output", + "IngestionTracePage": ".ingestion_trace_page", + "IngestionTraceStatus": ".ingestion_trace_status", + "IngestionTraceStep": ".ingestion_trace_step", "Instructions": ".instructions", "LookupBatchResponse": ".lookup_batch_response", "LookupItem": ".lookup_item", @@ -163,27 +486,60 @@ "MembershipMutationResult": ".membership_mutation_result", "Message": ".message", "MessagePage": ".message_page", + "MetadataFilter": ".metadata_filter", "MetadataFilterGroup": ".metadata_filter_group", + "MetadataFilterGroupType": ".metadata_filter_group_type", + "MetadataFilterOperator": ".metadata_filter_operator", + "MetadataFilterValue": ".metadata_filter_value", + "MetadataFilterValueThreeItem": ".metadata_filter_value_three_item", "MutateMembersRequest": ".mutate_members_request", "NeighborEntry": ".neighbor_entry", "NeighborPage": ".neighbor_page", "Node": ".node", "NodeInput": ".node_input", "NodePage": ".node_page", + "ObjectiveMappingRule": ".objective_mapping_rule", + "ObjectiveMappingRuleSource": ".objective_mapping_rule_source", "Observation": ".observation", "ObservationPage": ".observation_page", "ObservationSteering": ".observation_steering", "ObservationType": ".observation_type", "Ontology": ".ontology", + "OutcomeMappingRule": ".outcome_mapping_rule", + "OutcomeMappingRuleRule": ".outcome_mapping_rule_rule", + "Pagev4AgentSkillCandidateReviewSummary": ".pagev4agent_skill_candidate_review_summary", + "Pagev4AgentSkillCompilationOutcome": ".pagev4agent_skill_compilation_outcome", + "Pagev4AgentSkillEvidence": ".pagev4agent_skill_evidence", + "Pagev4AgentSkillRelationship": ".pagev4agent_skill_relationship", + "Pagev4AgentSkillSearchHit": ".pagev4agent_skill_search_hit", + "Pagev4AgentSkillVersion": ".pagev4agent_skill_version", + "Pagev4AgentVerifier": ".pagev4agent_verifier", "ProcessBatchResult": ".process_batch_result", "Project": ".project", "PropertyFilter": ".property_filter", + "PropertyFilterOperator": ".property_filter_operator", + "PropertyFilterValue": ".property_filter_value", + "PropertyFilterValueThreeItem": ".property_filter_value_three_item", "RoleType": ".role_type", "SearchFilters": ".search_filters", "SearchListRequest": ".search_list_request", "SearchRequest": ".search_request", + "SearchRequestReranker": ".search_request_reranker", + "SkillDefinition": ".skill_definition", + "SkillDefinitionSection": ".skill_definition_section", + "SkillFailure": ".skill_failure", + "SkillProcedureStep": ".skill_procedure_step", + "SkillRelation": ".skill_relation", + "SkillResource": ".skill_resource", + "SourceSpan": ".source_span", + "SourceTrace": ".source_trace", + "SourceTracePage": ".source_trace_page", + "SourceTraceResponse": ".source_trace_response", + "SourceTraceSummary": ".source_trace_summary", "SubgraphResponse": ".subgraph_response", "Task": ".task", + "TaskFamilyMappingRule": ".task_family_mapping_rule", + "TaskFamilyMappingRuleSource": ".task_family_mapping_rule_source", "TaskPage": ".task_page", "TaskProgress": ".task_progress", "Thread": ".thread", @@ -192,6 +548,32 @@ "ThreadPage": ".thread_page", "ThreadSummary": ".thread_summary", "ThreadSummaryPage": ".thread_summary_page", + "TraceConnection": ".trace_connection", + "TraceConnectionPage": ".trace_connection_page", + "TraceConnectionSettings": ".trace_connection_settings", + "TraceFilter": ".trace_filter", + "TracePreview": ".trace_preview", + "TraceProviderProject": ".trace_provider_project", + "TraceProviderProjectPage": ".trace_provider_project_page", + "TraceScoreRange": ".trace_score_range", + "TrajectoryContentMapping": ".trajectory_content_mapping", + "TrajectoryImport": ".trajectory_import", + "TrajectoryImportPage": ".trajectory_import_page", + "TrajectoryImportPauseReason": ".trajectory_import_pause_reason", + "TrajectoryImportRun": ".trajectory_import_run", + "TrajectoryImportRunItem": ".trajectory_import_run_item", + "TrajectoryImportRunItemPage": ".trajectory_import_run_item_page", + "TrajectoryImportRunPage": ".trajectory_import_run_page", + "TrajectoryImportRunReference": ".trajectory_import_run_reference", + "TrajectoryImportRunReferenceStatus": ".trajectory_import_run_reference_status", + "TrajectoryImportRunReferenceTrigger": ".trajectory_import_run_reference_trigger", + "TrajectoryImportSchedule": ".trajectory_import_schedule", + "TrajectoryImportSelection": ".trajectory_import_selection", + "TrajectoryMapping": ".trajectory_mapping", + "TrajectoryMappingIncludeOutcomesItem": ".trajectory_mapping_include_outcomes_item", + "TrajectoryMappingResult": ".trajectory_mapping_result", + "TrajectoryMappingResultOutcome": ".trajectory_mapping_result_outcome", + "TrajectoryMappingResultOutcomeRule": ".trajectory_mapping_result_outcome_rule", "User": ".user", "UserDeleteResult": ".user_delete_result", "UserGroup": ".user_group", @@ -199,10 +581,6 @@ "UserInstruction": ".user_instruction", "UserPage": ".user_page", "UserSummaryInstructions": ".user_summary_instructions", - "V4BatchItemInputDataType": ".v4batch_item_input_data_type", - "V4BatchItemInputRole": ".v4batch_item_input_role", - "V4BatchItemInputType": ".v4batch_item_input_type", - "V4SearchRequestReranker": ".v4search_request_reranker", } @@ -228,26 +606,127 @@ def __dir__(): __all__ = [ - "AddEdgeResult", + "AddAgentSkillUseOutcomeRequest", + "AddAgentSkillUseOutcomeRequestOutcome", + "AddEdgesResult", "AddEpisodeResult", + "AddHyperedgeEdgeResult", + "AddHyperedgeResult", "AddMessage", "AddMessagesResult", "AddNodesResult", "AddedEdge", + "AddedHyperedge", + "AddedHyperedgeEdge", "AddedNode", + "Agent", + "AgentBreakingChange", + "AgentContext", + "AgentContextEvidenceCounts", + "AgentContextPartialSource", + "AgentContextResource", + "AgentContextSkillSnapshot", + "AgentContextSkippedSkill", + "AgentDeleteResult", + "AgentLearningState", + "AgentLiteralPolicy", + "AgentLiteralPolicyClasses", + "AgentLiteralPolicyValues", + "AgentMemoryEvaluationPolicy", + "AgentMemoryEvaluationRequirement", + "AgentMemorySettings", + "AgentMemorySettingsApproval", + "AgentMemorySettingsCompilationMode", + "AgentPage", + "AgentSkill", + "AgentSkillAdmissionDecision", + "AgentSkillCandidate", + "AgentSkillCandidateBaseVersion", + "AgentSkillCandidateEvaluation", + "AgentSkillCandidateEvidence", + "AgentSkillCandidateReview", + "AgentSkillCandidateReviewResult", + "AgentSkillCandidateReviewSummary", + "AgentSkillCompilationOutcome", + "AgentSkillCompilationOutcomeRejectionClass", + "AgentSkillEvaluation", + "AgentSkillEvidence", + "AgentSkillPublicationLineage", + "AgentSkillRelationship", + "AgentSkillSearchHit", + "AgentSkillSearchHitMaturity", + "AgentSkillSearchResponse", + "AgentSkillUse", + "AgentSkillUseOutcome", + "AgentSkillVersion", + "AgentSkillVersionComparison", + "AgentSplitPlan", + "AgentSplitPlanDestination", + "AgentSplitPlanDestinationRequest", + "AgentSplitPlanSkillReference", + "AgentSplitPlanSkillSelectionRequest", + "AgentSplitPlanSource", + "AgentStatus", + "AgentTrajectory", + "AgentTrajectoryCloseVerifier", + "AgentTrajectoryEvent", + "AgentTrajectoryEventContext", + "AgentTrajectoryEventPage", + "AgentTrajectoryEventProcessingState", + "AgentTrajectoryEventSource", + "AgentTrajectoryEventSourceCopyMode", + "AgentTrajectoryEventSourceRetentionMode", + "AgentTrajectoryEventType", + "AgentTrajectoryFinalizationResult", + "AgentTrajectoryInternal", + "AgentTrajectoryLifecycle", + "AgentTrajectoryOutcome", + "AgentTrajectoryPage", + "AgentTrajectoryProcessingState", + "AgentTrajectoryResourceRef", + "AgentTrajectorySequenceRange", + "AgentTrajectorySource", + "AgentTrajectorySourceDeletionResult", + "AgentTrajectorySummaryCreationReason", + "AgentTrajectorySummaryOmissionReason", + "AgentTrajectorySummaryOmittedRange", + "AgentTrajectorySummaryPage", + "AgentTrajectorySummaryVersion", + "AgentTrajectoryVerification", + "AgentVerificationStrength", + "AgentVerifier", + "AgentVerifierAssertionOutcome", + "AgentVerifierEvidenceInvalidationResult", + "AgentVerifierPrincipal", + "AgentVerifierPrincipalBinding", + "AgentVerifierPrincipalBindingInput", + "AgentVerifierStatus", "ApiError", "ArtifactListRequest", "AsyncResult", "Batch", "BatchItem", "BatchItemInput", + "BatchItemInputDataType", + "BatchItemInputRole", + "BatchItemInputType", "BatchItemKind", "BatchItemPage", "BatchItemStatus", "BatchItemsResponse", "BatchPage", + "CloneGraphRequest", "CloneGraphResult", - "ComparisonOperator", + "ContentPolicy", + "ContentPolicyCategory", + "ContentPolicyCategoryRequest", + "ContentPolicyEvent", + "ContentPolicyEventArtifactKind", + "ContentPolicyEventDropReason", + "ContentPolicyEventPage", + "ContentPolicyRevisionPage", + "ContentPolicyRule", + "ContentPolicyRuleRequest", "ContextEdge", "ContextEpisode", "ContextNode", @@ -256,12 +735,23 @@ def __dir__(): "ContextTemplate", "ContextTemplatePage", "ContextThreadSummary", + "CreateAgentRequest", "CreateContextTemplateRequest", "CustomInstruction", "DateFilter", + "DateFilterField", + "DateFilterGroup", + "DateFilterOperator", + "DateFilters", + "DebugLogEntry", + "DebugLogLevel", + "DebugLogStatus", + "DebugLoggingEnablement", + "DeleteAgentTrajectoryRequest", "DocumentSummary", "DocumentSummaryPage", "Edge", + "EdgeInput", "EdgeNodeRef", "EdgePage", "EdgeSourceTarget", @@ -270,15 +760,37 @@ def __dir__(): "EntityPropertyType", "EntityType", "Episode", - "EpisodeMetadataFilter", + "EpisodeContentPolicy", + "EpisodeContentPolicyStatus", + "EpisodeDebugLog", "EpisodePage", "ErrorBody", "Graph", + "GraphContentPolicy", + "GraphContentPolicyRequest", "GraphContextResponse", "GraphDataType", "GraphDeleteResult", "GraphPage", - "GraphitiMetadataFilterGroupType", + "Hyperedge", + "HyperedgeEdge", + "HyperedgeInput", + "HyperedgePage", + "ImportedTrajectoryReference", + "IngestionTrace", + "IngestionTraceEdge", + "IngestionTraceEdgeInvalidation", + "IngestionTraceEdgeReference", + "IngestionTraceEntityType", + "IngestionTraceEpisode", + "IngestionTraceInput", + "IngestionTraceNode", + "IngestionTraceNodeDuplicate", + "IngestionTraceNodeResolution", + "IngestionTraceOutput", + "IngestionTracePage", + "IngestionTraceStatus", + "IngestionTraceStep", "Instructions", "LookupBatchResponse", "LookupItem", @@ -286,27 +798,60 @@ def __dir__(): "MembershipMutationResult", "Message", "MessagePage", + "MetadataFilter", "MetadataFilterGroup", + "MetadataFilterGroupType", + "MetadataFilterOperator", + "MetadataFilterValue", + "MetadataFilterValueThreeItem", "MutateMembersRequest", "NeighborEntry", "NeighborPage", "Node", "NodeInput", "NodePage", + "ObjectiveMappingRule", + "ObjectiveMappingRuleSource", "Observation", "ObservationPage", "ObservationSteering", "ObservationType", "Ontology", + "OutcomeMappingRule", + "OutcomeMappingRuleRule", + "Pagev4AgentSkillCandidateReviewSummary", + "Pagev4AgentSkillCompilationOutcome", + "Pagev4AgentSkillEvidence", + "Pagev4AgentSkillRelationship", + "Pagev4AgentSkillSearchHit", + "Pagev4AgentSkillVersion", + "Pagev4AgentVerifier", "ProcessBatchResult", "Project", "PropertyFilter", + "PropertyFilterOperator", + "PropertyFilterValue", + "PropertyFilterValueThreeItem", "RoleType", "SearchFilters", "SearchListRequest", "SearchRequest", + "SearchRequestReranker", + "SkillDefinition", + "SkillDefinitionSection", + "SkillFailure", + "SkillProcedureStep", + "SkillRelation", + "SkillResource", + "SourceSpan", + "SourceTrace", + "SourceTracePage", + "SourceTraceResponse", + "SourceTraceSummary", "SubgraphResponse", "Task", + "TaskFamilyMappingRule", + "TaskFamilyMappingRuleSource", "TaskPage", "TaskProgress", "Thread", @@ -315,6 +860,32 @@ def __dir__(): "ThreadPage", "ThreadSummary", "ThreadSummaryPage", + "TraceConnection", + "TraceConnectionPage", + "TraceConnectionSettings", + "TraceFilter", + "TracePreview", + "TraceProviderProject", + "TraceProviderProjectPage", + "TraceScoreRange", + "TrajectoryContentMapping", + "TrajectoryImport", + "TrajectoryImportPage", + "TrajectoryImportPauseReason", + "TrajectoryImportRun", + "TrajectoryImportRunItem", + "TrajectoryImportRunItemPage", + "TrajectoryImportRunPage", + "TrajectoryImportRunReference", + "TrajectoryImportRunReferenceStatus", + "TrajectoryImportRunReferenceTrigger", + "TrajectoryImportSchedule", + "TrajectoryImportSelection", + "TrajectoryMapping", + "TrajectoryMappingIncludeOutcomesItem", + "TrajectoryMappingResult", + "TrajectoryMappingResultOutcome", + "TrajectoryMappingResultOutcomeRule", "User", "UserDeleteResult", "UserGroup", @@ -322,8 +893,4 @@ def __dir__(): "UserInstruction", "UserPage", "UserSummaryInstructions", - "V4BatchItemInputDataType", - "V4BatchItemInputRole", - "V4BatchItemInputType", - "V4SearchRequestReranker", ] diff --git a/src/zep_cloud/types/add_agent_skill_use_outcome_request.py b/src/zep_cloud/types/add_agent_skill_use_outcome_request.py new file mode 100644 index 00000000..85aefad5 --- /dev/null +++ b/src/zep_cloud/types/add_agent_skill_use_outcome_request.py @@ -0,0 +1,20 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .add_agent_skill_use_outcome_request_outcome import AddAgentSkillUseOutcomeRequestOutcome + + +class AddAgentSkillUseOutcomeRequest(UniversalBaseModel): + outcome: AddAgentSkillUseOutcomeRequestOutcome + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/add_agent_skill_use_outcome_request_outcome.py b/src/zep_cloud/types/add_agent_skill_use_outcome_request_outcome.py new file mode 100644 index 00000000..0fdbf974 --- /dev/null +++ b/src/zep_cloud/types/add_agent_skill_use_outcome_request_outcome.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +AddAgentSkillUseOutcomeRequestOutcome = typing.Union[ + typing.Literal["succeeded", "failed", "partial", "abandoned", "unknown"], typing.Any +] diff --git a/src/zep_cloud/types/add_edges_result.py b/src/zep_cloud/types/add_edges_result.py new file mode 100644 index 00000000..4186ed87 --- /dev/null +++ b/src/zep_cloud/types/add_edges_result.py @@ -0,0 +1,29 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .added_edge import AddedEdge +from .task import Task + + +class AddEdgesResult(UniversalBaseModel): + edges: typing.Optional[typing.List[AddedEdge]] = pydantic.Field(default=None) + """ + The accept-time acknowledgements in request order. + """ + + task: typing.Optional[Task] = pydantic.Field(default=None) + """ + The asynchronous task that tracks edge creation and indexing. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/add_edge_result.py b/src/zep_cloud/types/add_hyperedge_edge_result.py similarity index 70% rename from src/zep_cloud/types/add_edge_result.py rename to src/zep_cloud/types/add_hyperedge_edge_result.py index eda0788f..d4047dc6 100644 --- a/src/zep_cloud/types/add_edge_result.py +++ b/src/zep_cloud/types/add_hyperedge_edge_result.py @@ -8,17 +8,16 @@ from .task import Task -class AddEdgeResult(UniversalBaseModel): +class AddHyperedgeEdgeResult(UniversalBaseModel): edge: typing.Optional[AddedEdge] = pydantic.Field(default=None) """ - An accept-time acknowledgement of the fact you submitted, carrying the - identifier and fields you supplied rather than the full edge resource - returned by later reads. + An accept-time acknowledgement of the member edge, carrying the + identifier Zep assigned and the hyperedge's shared fields. """ task: typing.Optional[Task] = pydantic.Field(default=None) """ - The asynchronous task that tracks the edge's extraction and indexing. + The asynchronous task that tracks writing the member edge. """ if IS_PYDANTIC_V2: diff --git a/src/zep_cloud/types/add_hyperedge_result.py b/src/zep_cloud/types/add_hyperedge_result.py new file mode 100644 index 00000000..13ea1ef9 --- /dev/null +++ b/src/zep_cloud/types/add_hyperedge_result.py @@ -0,0 +1,29 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .added_hyperedge import AddedHyperedge +from .task import Task + + +class AddHyperedgeResult(UniversalBaseModel): + hyperedge: typing.Optional[AddedHyperedge] = pydantic.Field(default=None) + """ + An accept-time acknowledgement of the hyperedge you submitted. + """ + + task: typing.Optional[Task] = pydantic.Field(default=None) + """ + The asynchronous task that tracks writing the member edges. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/add_message.py b/src/zep_cloud/types/add_message.py index 497b7481..5c823494 100644 --- a/src/zep_cloud/types/add_message.py +++ b/src/zep_cloud/types/add_message.py @@ -15,9 +15,15 @@ class AddMessage(UniversalBaseModel): The content of the message. """ + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The message's reference time, used for temporal reasoning rather than + ingestion time. Defaults to the ingestion time. + """ + metadata: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) """ - Custom metadata to store with the message. + Custom metadata to store with the message. Max 10 keys. Values must be strings, numbers, booleans, or arrays of scalars. """ name: typing.Optional[str] = pydantic.Field(default=None) @@ -39,6 +45,10 @@ class AddMessage(UniversalBaseModel): description="Reserved for future use. Message identifiers are always server-assigned,\nso this field must be left unset.", ), ] = None + """ + Reserved for future use. Message identifiers are always server-assigned, + so this field must be left unset. + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/zep_cloud/types/added_edge.py b/src/zep_cloud/types/added_edge.py index 7e06ac37..7840807a 100644 --- a/src/zep_cloud/types/added_edge.py +++ b/src/zep_cloud/types/added_edge.py @@ -45,16 +45,34 @@ class AddedEdge(UniversalBaseModel): The source node fields you supplied when creating this edge. """ + source_node_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The source node UUID is set when deduplicate is false. It is the UUID you + supplied, or the UUID Zep assigned to a node that the request creates. + When deduplicate is true, read the endpoint from the task result. + """ + target_node: typing.Optional[EdgeNodeRef] = pydantic.Field(default=None) """ The target node fields you supplied when creating this edge. """ + target_node_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The target node UUID is set when deduplicate is false. It is the UUID you + supplied, or the UUID Zep assigned to a node that the request creates. + When deduplicate is true, read the endpoint from the task result. + """ + uuid_: typing_extensions.Annotated[ typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid", description="The unique identifier assigned to the edge."), ] = None + """ + The unique identifier assigned to the edge. + """ + valid_at: typing.Optional[str] = pydantic.Field(default=None) """ The time from which the fact is considered true. diff --git a/src/zep_cloud/types/added_hyperedge.py b/src/zep_cloud/types/added_hyperedge.py new file mode 100644 index 00000000..12167d06 --- /dev/null +++ b/src/zep_cloud/types/added_hyperedge.py @@ -0,0 +1,64 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .added_hyperedge_edge import AddedHyperedgeEdge + + +class AddedHyperedge(UniversalBaseModel): + attributes: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + The attributes you supplied for every member edge. + """ + + edges: typing.Optional[typing.List[AddedHyperedgeEdge]] = pydantic.Field(default=None) + """ + The member edges, each with its assigned identifier. + """ + + expired_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the fact was superseded or removed. + """ + + fact: typing.Optional[str] = pydantic.Field(default=None) + """ + The natural-language fact you submitted. + """ + + invalid_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time at which the fact stopped being true. + """ + + metadata: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + The episode metadata you supplied. + """ + + uuid_: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="The unique identifier assigned to the hyperedge."), + ] = None + """ + The unique identifier assigned to the hyperedge. + """ + + valid_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time from which the fact is considered true. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/added_hyperedge_edge.py b/src/zep_cloud/types/added_hyperedge_edge.py new file mode 100644 index 00000000..1f045b94 --- /dev/null +++ b/src/zep_cloud/types/added_hyperedge_edge.py @@ -0,0 +1,44 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .edge_node_ref import EdgeNodeRef + + +class AddedHyperedgeEdge(UniversalBaseModel): + name: typing.Optional[str] = pydantic.Field(default=None) + """ + The name of the member edge you supplied. + """ + + source_node: typing.Optional[EdgeNodeRef] = pydantic.Field(default=None) + """ + The source node fields you supplied for this member. + """ + + target_node: typing.Optional[EdgeNodeRef] = pydantic.Field(default=None) + """ + The target node fields you supplied for this member. + """ + + uuid_: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="The unique identifier assigned to this member edge."), + ] = None + """ + The unique identifier assigned to this member edge. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/added_node.py b/src/zep_cloud/types/added_node.py index 8d972bfe..b20e379e 100644 --- a/src/zep_cloud/types/added_node.py +++ b/src/zep_cloud/types/added_node.py @@ -44,6 +44,9 @@ class AddedNode(UniversalBaseModel): FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid", description="The node UUID, assigned by Zep."), ] = None + """ + The node UUID, assigned by Zep. + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/zep_cloud/types/agent.py b/src/zep_cloud/types/agent.py new file mode 100644 index 00000000..89f99e7d --- /dev/null +++ b/src/zep_cloud/types/agent.py @@ -0,0 +1,90 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .agent_memory_settings import AgentMemorySettings +from .agent_status import AgentStatus + + +class Agent(UniversalBaseModel): + agent_id: typing.Optional[str] = pydantic.Field(default=None) + """ + The developer-assigned Agent identifier, unique within the project. + """ + + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the Agent was created. + """ + + deployment_id: typing.Optional[str] = pydantic.Field(default=None) + """ + The customer deployment this Agent represents. + """ + + description: typing.Optional[str] = pydantic.Field(default=None) + """ + A human-readable description of the Agent. + """ + + memory_settings: typing.Optional[AgentMemorySettings] = pydantic.Field(default=None) + """ + Agent Memory capture, compilation, and promotion settings. + """ + + metadata: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Developer metadata used to organize and filter Agents. + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + The Agent's display name. + """ + + revision: typing.Optional[int] = pydantic.Field(default=None) + """ + The revision required by the next update or delete request. + """ + + security_domain: typing.Optional[str] = pydantic.Field(default=None) + """ + The immutable boundary within which Skills may be synthesized. + """ + + status: typing.Optional[AgentStatus] = pydantic.Field(default=None) + """ + The current lifecycle status. + """ + + updated_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the Agent was last updated. + """ + + uuid_: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="The stable identifier of the Agent."), + ] = None + """ + The stable identifier of the Agent. + """ + + version: typing.Optional[str] = pydantic.Field(default=None) + """ + The customer deployment version this Agent represents. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_breaking_change.py b/src/zep_cloud/types/agent_breaking_change.py new file mode 100644 index 00000000..fd12f02b --- /dev/null +++ b/src/zep_cloud/types/agent_breaking_change.py @@ -0,0 +1,31 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata + + +class AgentBreakingChange(UniversalBaseModel): + affected_skill_count: typing.Optional[int] = None + agent_uuid: typing.Optional[str] = None + revision: typing.Optional[int] = pydantic.Field(default=None) + """ + The Agent revision produced by this declaration, stable on replay. + """ + + uuid_: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + ] = None + version: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_context.py b/src/zep_cloud/types/agent_context.py new file mode 100644 index 00000000..740f2aa0 --- /dev/null +++ b/src/zep_cloud/types/agent_context.py @@ -0,0 +1,30 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .agent_context_partial_source import AgentContextPartialSource +from .agent_context_skill_snapshot import AgentContextSkillSnapshot +from .agent_context_skipped_skill import AgentContextSkippedSkill + + +class AgentContext(UniversalBaseModel): + context: typing.Optional[str] = None + objective: typing.Optional[str] = None + partial_sources: typing.Optional[typing.List[AgentContextPartialSource]] = None + request_id: typing.Optional[str] = None + skipped: typing.Optional[typing.List[AgentContextSkippedSkill]] = None + snapshot: typing.Optional[typing.List[AgentContextSkillSnapshot]] = None + task_family: typing.Optional[str] = None + trajectory_uuid: typing.Optional[str] = None + truncated: typing.Optional[bool] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_context_evidence_counts.py b/src/zep_cloud/types/agent_context_evidence_counts.py new file mode 100644 index 00000000..c882bb3a --- /dev/null +++ b/src/zep_cloud/types/agent_context_evidence_counts.py @@ -0,0 +1,21 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class AgentContextEvidenceCounts(UniversalBaseModel): + contradicting: typing.Optional[int] = None + neutral: typing.Optional[int] = None + supporting: typing.Optional[int] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_context_partial_source.py b/src/zep_cloud/types/agent_context_partial_source.py new file mode 100644 index 00000000..56d4ccbc --- /dev/null +++ b/src/zep_cloud/types/agent_context_partial_source.py @@ -0,0 +1,21 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class AgentContextPartialSource(UniversalBaseModel): + reason: typing.Optional[str] = None + source: typing.Optional[str] = None + task_uuid: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_context_resource.py b/src/zep_cloud/types/agent_context_resource.py new file mode 100644 index 00000000..21747abe --- /dev/null +++ b/src/zep_cloud/types/agent_context_resource.py @@ -0,0 +1,20 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class AgentContextResource(UniversalBaseModel): + name: str + version: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_context_skill_snapshot.py b/src/zep_cloud/types/agent_context_skill_snapshot.py new file mode 100644 index 00000000..939b69c5 --- /dev/null +++ b/src/zep_cloud/types/agent_context_skill_snapshot.py @@ -0,0 +1,25 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .agent_context_evidence_counts import AgentContextEvidenceCounts + + +class AgentContextSkillSnapshot(UniversalBaseModel): + artifact_sha256: typing.Optional[str] = None + evidence_citations: typing.Optional[typing.List[str]] = None + evidence_counts: typing.Optional[AgentContextEvidenceCounts] = None + rank: typing.Optional[int] = None + skill_uuid: typing.Optional[str] = None + version: typing.Optional[int] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_context_skipped_skill.py b/src/zep_cloud/types/agent_context_skipped_skill.py new file mode 100644 index 00000000..3c219ef3 --- /dev/null +++ b/src/zep_cloud/types/agent_context_skipped_skill.py @@ -0,0 +1,21 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class AgentContextSkippedSkill(UniversalBaseModel): + reason: typing.Optional[str] = None + skill_uuid: typing.Optional[str] = None + version: typing.Optional[int] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_delete_result.py b/src/zep_cloud/types/agent_delete_result.py new file mode 100644 index 00000000..a9e73440 --- /dev/null +++ b/src/zep_cloud/types/agent_delete_result.py @@ -0,0 +1,23 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .task import Task + + +class AgentDeleteResult(UniversalBaseModel): + task: typing.Optional[Task] = pydantic.Field(default=None) + """ + The asynchronous task that tracks the Agent's deletion. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_learning_state.py b/src/zep_cloud/types/agent_learning_state.py new file mode 100644 index 00000000..06b784c4 --- /dev/null +++ b/src/zep_cloud/types/agent_learning_state.py @@ -0,0 +1,35 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class AgentLearningState(UniversalBaseModel): + approval: typing.Optional[str] = pydantic.Field(default=None) + """ + Approval is the approval mode of the Agent: manual or auto. The default is auto. + """ + + compilation_mode: typing.Optional[str] = None + compilation_pending: typing.Optional[bool] = pydantic.Field(default=None) + """ + CompilationPending is true while a learning run for the task family + waits to start or runs. Skills from that run are not yet available. + """ + + eligible_trajectory_count: typing.Optional[int] = None + minimum_attempt_families: typing.Optional[int] = None + next_step: typing.Optional[str] = None + required_evaluations: typing.Optional[typing.List[str]] = None + task_family: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_literal_policy.py b/src/zep_cloud/types/agent_literal_policy.py new file mode 100644 index 00000000..e1a36568 --- /dev/null +++ b/src/zep_cloud/types/agent_literal_policy.py @@ -0,0 +1,59 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .agent_literal_policy_classes import AgentLiteralPolicyClasses +from .agent_literal_policy_values import AgentLiteralPolicyValues + + +class AgentLiteralPolicy(UniversalBaseModel): + allowlisted_classes: typing.Optional[AgentLiteralPolicyClasses] = pydantic.Field(default=None) + """ + Typed classes that the policy may preserve. + """ + + allowlisted_values: typing.Optional[AgentLiteralPolicyValues] = pydantic.Field(default=None) + """ + Exact reusable values that the policy may preserve when applicability matches. + """ + + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time this explicit revision was created. Omitted for revision zero. + """ + + created_by_principal_id: typing.Optional[str] = pydantic.Field(default=None) + """ + The principal identifier that created this explicit revision. Empty for revision zero. + """ + + created_by_principal_type: typing.Optional[str] = pydantic.Field(default=None) + """ + The principal type that created this explicit revision. Empty for revision zero. + """ + + default: typing.Optional[str] = pydantic.Field(default=None) + """ + The remediation for literals that are not explicitly allowed. + """ + + digest: typing.Optional[str] = pydantic.Field(default=None) + """ + SHA-256 of the canonical policy JSON. + """ + + revision: typing.Optional[int] = pydantic.Field(default=None) + """ + The immutable policy revision. Revision zero is the built-in strict default. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_literal_policy_classes.py b/src/zep_cloud/types/agent_literal_policy_classes.py new file mode 100644 index 00000000..5835a64d --- /dev/null +++ b/src/zep_cloud/types/agent_literal_policy_classes.py @@ -0,0 +1,27 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class AgentLiteralPolicyClasses(UniversalBaseModel): + environments: typing.List[str] = pydantic.Field() + """ + Reusable environment literal classes. + """ + + tools: typing.List[str] = pydantic.Field() + """ + Reusable tool literal classes. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_literal_policy_values.py b/src/zep_cloud/types/agent_literal_policy_values.py new file mode 100644 index 00000000..35745693 --- /dev/null +++ b/src/zep_cloud/types/agent_literal_policy_values.py @@ -0,0 +1,27 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class AgentLiteralPolicyValues(UniversalBaseModel): + environments: typing.List[str] = pydantic.Field() + """ + Exact reusable values eligible for a permitted environment literal class. + """ + + tools: typing.List[str] = pydantic.Field() + """ + Exact reusable values eligible for a permitted tool literal class. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_memory_evaluation_policy.py b/src/zep_cloud/types/agent_memory_evaluation_policy.py new file mode 100644 index 00000000..83914406 --- /dev/null +++ b/src/zep_cloud/types/agent_memory_evaluation_policy.py @@ -0,0 +1,21 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .agent_memory_evaluation_requirement import AgentMemoryEvaluationRequirement + + +class AgentMemoryEvaluationPolicy(UniversalBaseModel): + requirements: typing.List[AgentMemoryEvaluationRequirement] + task_family: str + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_memory_evaluation_requirement.py b/src/zep_cloud/types/agent_memory_evaluation_requirement.py new file mode 100644 index 00000000..36db8c89 --- /dev/null +++ b/src/zep_cloud/types/agent_memory_evaluation_requirement.py @@ -0,0 +1,23 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class AgentMemoryEvaluationRequirement(UniversalBaseModel): + controlled: typing.Optional[bool] = None + environment: typing.Optional[str] = None + evaluated_by: str + evaluator_version: str + result: str + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_memory_settings.py b/src/zep_cloud/types/agent_memory_settings.py new file mode 100644 index 00000000..ef09a9f5 --- /dev/null +++ b/src/zep_cloud/types/agent_memory_settings.py @@ -0,0 +1,48 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .agent_memory_evaluation_policy import AgentMemoryEvaluationPolicy +from .agent_memory_settings_approval import AgentMemorySettingsApproval +from .agent_memory_settings_compilation_mode import AgentMemorySettingsCompilationMode + + +class AgentMemorySettings(UniversalBaseModel): + admission_evaluation_requirements: typing.Optional[typing.List[AgentMemoryEvaluationPolicy]] = None + approval: typing.Optional[AgentMemorySettingsApproval] = None + approval_minimum_attempt_families: typing.Optional[int] = None + approval_required_tools: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + ApprovalRequiredTools lists the tool names that need a member approval in + auto approval. A generated Skill that uses one of these tools waits for a + member. The default is an empty list. + """ + + auto_approval_task_families: typing.Optional[typing.List[str]] = None + compilation_mode: typing.Optional[AgentMemorySettingsCompilationMode] = None + provisional_expiry_days: typing.Optional[int] = pydantic.Field(default=None) + """ + ProvisionalExpiryDays is the period after which Zep retires a provisional + Skill that no application used. When it is not set, provisional Skills do + not expire. + """ + + provisional_skill_limit: typing.Optional[int] = pydantic.Field(default=None) + """ + ProvisionalSkillLimit is the maximum count of provisional Skills in one + task family. Over the limit, a new provisional Skill waits for a member. + When it is not set, no limit applies. + """ + + retention_days: typing.Optional[int] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_memory_settings_approval.py b/src/zep_cloud/types/agent_memory_settings_approval.py new file mode 100644 index 00000000..a83e2a06 --- /dev/null +++ b/src/zep_cloud/types/agent_memory_settings_approval.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +AgentMemorySettingsApproval = typing.Union[typing.Literal["manual", "auto"], typing.Any] diff --git a/src/zep_cloud/types/agent_memory_settings_compilation_mode.py b/src/zep_cloud/types/agent_memory_settings_compilation_mode.py new file mode 100644 index 00000000..88799dc5 --- /dev/null +++ b/src/zep_cloud/types/agent_memory_settings_compilation_mode.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +AgentMemorySettingsCompilationMode = typing.Union[typing.Literal["scheduled", "manual", "on_close"], typing.Any] diff --git a/src/zep_cloud/types/agent_page.py b/src/zep_cloud/types/agent_page.py new file mode 100644 index 00000000..939d8fc6 --- /dev/null +++ b/src/zep_cloud/types/agent_page.py @@ -0,0 +1,34 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .agent import Agent + + +class AgentPage(UniversalBaseModel): + items: typing.Optional[typing.List[Agent]] = pydantic.Field(default=None) + """ + The Agents on this page. + """ + + next_cursor: typing.Optional[str] = pydantic.Field(default=None) + """ + Opaque cursor for retrieving the next page, present only when more results + are available. + """ + + total_size: typing.Optional[int] = pydantic.Field(default=None) + """ + The total number of Agents matching the filters and authorization scope. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_skill.py b/src/zep_cloud/types/agent_skill.py new file mode 100644 index 00000000..fb8b61d5 --- /dev/null +++ b/src/zep_cloud/types/agent_skill.py @@ -0,0 +1,34 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata + + +class AgentSkill(UniversalBaseModel): + agent_versions: typing.Optional[typing.List[str]] = None + created_at: typing.Optional[str] = None + current_version: typing.Optional[int] = None + kind: typing.Optional[str] = None + package_name: typing.Optional[str] = None + searchable: typing.Optional[bool] = None + skill_id: typing.Optional[str] = None + status: typing.Optional[str] = None + task_family: typing.Optional[str] = None + unavailable_reason: typing.Optional[str] = None + updated_at: typing.Optional[str] = None + uuid_: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + ] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_skill_admission_decision.py b/src/zep_cloud/types/agent_skill_admission_decision.py new file mode 100644 index 00000000..7cd21340 --- /dev/null +++ b/src/zep_cloud/types/agent_skill_admission_decision.py @@ -0,0 +1,24 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class AgentSkillAdmissionDecision(UniversalBaseModel): + created_at: typing.Optional[str] = None + decision: typing.Optional[str] = None + mode: typing.Optional[str] = None + reason_code: typing.Optional[str] = None + skill_version: typing.Optional[int] = None + supporting_attempt_families: typing.Optional[int] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_skill_candidate.py b/src/zep_cloud/types/agent_skill_candidate.py new file mode 100644 index 00000000..59aece17 --- /dev/null +++ b/src/zep_cloud/types/agent_skill_candidate.py @@ -0,0 +1,37 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .agent_skill_candidate_base_version import AgentSkillCandidateBaseVersion +from .agent_skill_candidate_evidence import AgentSkillCandidateEvidence + + +class AgentSkillCandidate(UniversalBaseModel): + agent_versions: typing.Optional[typing.List[str]] = None + base_versions: typing.Optional[typing.List[AgentSkillCandidateBaseVersion]] = None + confidence: typing.Optional[float] = None + decision: typing.Optional[str] = None + description: typing.Optional[str] = None + do_not_use_when: typing.Optional[typing.List[str]] = None + evidence: typing.Optional[typing.List[AgentSkillCandidateEvidence]] = None + kind: typing.Optional[str] = None + markdown: typing.Optional[str] = None + name: typing.Optional[str] = None + package_name: typing.Optional[str] = None + task_family: typing.Optional[str] = None + uuid_: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + ] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_skill_candidate_base_version.py b/src/zep_cloud/types/agent_skill_candidate_base_version.py new file mode 100644 index 00000000..c07535c4 --- /dev/null +++ b/src/zep_cloud/types/agent_skill_candidate_base_version.py @@ -0,0 +1,25 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class AgentSkillCandidateBaseVersion(UniversalBaseModel): + agent_versions: typing.Optional[typing.List[str]] = None + description: typing.Optional[str] = None + do_not_use_when: typing.Optional[typing.List[str]] = None + markdown: typing.Optional[str] = None + name: typing.Optional[str] = None + skill_uuid: typing.Optional[str] = None + version: typing.Optional[int] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_skill_candidate_evaluation.py b/src/zep_cloud/types/agent_skill_candidate_evaluation.py new file mode 100644 index 00000000..994223ae --- /dev/null +++ b/src/zep_cloud/types/agent_skill_candidate_evaluation.py @@ -0,0 +1,34 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata + + +class AgentSkillCandidateEvaluation(UniversalBaseModel): + candidate_uuid: typing.Optional[str] = None + controlled_test: typing.Optional[bool] = None + created_at: typing.Optional[str] = None + environment: typing.Optional[str] = None + evaluated_by: typing.Optional[str] = None + evaluator_version: typing.Optional[str] = None + evidence_reference: typing.Optional[str] = None + metrics: typing.Optional[typing.Dict[str, float]] = None + review_uuid: typing.Optional[str] = None + revision: typing.Optional[int] = None + uuid_: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + ] = None + verdict: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_skill_candidate_evidence.py b/src/zep_cloud/types/agent_skill_candidate_evidence.py new file mode 100644 index 00000000..40df094d --- /dev/null +++ b/src/zep_cloud/types/agent_skill_candidate_evidence.py @@ -0,0 +1,29 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class AgentSkillCandidateEvidence(UniversalBaseModel): + imported_provider: typing.Optional[str] = pydantic.Field(default=None) + """ + ImportedProvider is the provider of the source import, when this Trajectory was imported. + """ + + occurred_at: typing.Optional[str] = None + outcome: typing.Optional[str] = None + polarity: typing.Optional[str] = None + source_kind: typing.Optional[str] = None + trajectory_uuid: typing.Optional[str] = None + verification: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_skill_candidate_review.py b/src/zep_cloud/types/agent_skill_candidate_review.py new file mode 100644 index 00000000..09371977 --- /dev/null +++ b/src/zep_cloud/types/agent_skill_candidate_review.py @@ -0,0 +1,39 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .agent_skill_candidate import AgentSkillCandidate +from .agent_skill_candidate_review_result import AgentSkillCandidateReviewResult + + +class AgentSkillCandidateReview(UniversalBaseModel): + candidate_count: typing.Optional[int] = None + candidates: typing.Optional[typing.List[AgentSkillCandidate]] = None + created_at: typing.Optional[str] = None + import_review_required: typing.Optional[bool] = pydantic.Field(default=None) + """ + ImportReviewRequired reports whether any evidence import requires approval. + """ + + reason_code: typing.Optional[str] = None + results: typing.Optional[typing.List[AgentSkillCandidateReviewResult]] = None + reviewed_at: typing.Optional[str] = None + revision: typing.Optional[int] = None + status: typing.Optional[str] = None + task_family: typing.Optional[str] = None + uuid_: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + ] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_skill_candidate_review_result.py b/src/zep_cloud/types/agent_skill_candidate_review_result.py new file mode 100644 index 00000000..683addc3 --- /dev/null +++ b/src/zep_cloud/types/agent_skill_candidate_review_result.py @@ -0,0 +1,28 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .agent_skill_candidate_base_version import AgentSkillCandidateBaseVersion + + +class AgentSkillCandidateReviewResult(UniversalBaseModel): + base_versions: typing.Optional[typing.List[AgentSkillCandidateBaseVersion]] = None + candidate_uuids: typing.Optional[typing.List[str]] = None + decision: typing.Optional[str] = None + target_skill_uuids: typing.Optional[typing.List[str]] = None + uuid_: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + ] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_skill_candidate_review_summary.py b/src/zep_cloud/types/agent_skill_candidate_review_summary.py new file mode 100644 index 00000000..e537a18d --- /dev/null +++ b/src/zep_cloud/types/agent_skill_candidate_review_summary.py @@ -0,0 +1,30 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata + + +class AgentSkillCandidateReviewSummary(UniversalBaseModel): + candidate_count: typing.Optional[int] = None + created_at: typing.Optional[str] = None + reason_code: typing.Optional[str] = None + reviewed_at: typing.Optional[str] = None + revision: typing.Optional[int] = None + status: typing.Optional[str] = None + task_family: typing.Optional[str] = None + uuid_: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + ] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_skill_compilation_outcome.py b/src/zep_cloud/types/agent_skill_compilation_outcome.py new file mode 100644 index 00000000..0cd13383 --- /dev/null +++ b/src/zep_cloud/types/agent_skill_compilation_outcome.py @@ -0,0 +1,43 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .agent_skill_compilation_outcome_rejection_class import AgentSkillCompilationOutcomeRejectionClass + + +class AgentSkillCompilationOutcome(UniversalBaseModel): + agent_uuid: typing.Optional[str] = None + attempts: typing.Optional[int] = None + candidate_count: typing.Optional[int] = None + compilation_identity: typing.Optional[str] = None + compilation_window_uuid: typing.Optional[str] = None + created_at: typing.Optional[str] = None + decision: typing.Optional[str] = None + proposal_count: typing.Optional[int] = None + reason_text: typing.Optional[str] = None + rejected_add_count: typing.Optional[int] = pydantic.Field(default=None) + """ + RejectedAddCount is the count of add proposals that the Reflector, + the proposal scanner, or the Curator rejected in this compilation. + """ + + rejection_class: typing.Optional[AgentSkillCompilationOutcomeRejectionClass] = None + stage: typing.Optional[str] = None + task_family: typing.Optional[str] = None + trajectory_count: typing.Optional[int] = None + uuid_: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + ] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_skill_compilation_outcome_rejection_class.py b/src/zep_cloud/types/agent_skill_compilation_outcome_rejection_class.py new file mode 100644 index 00000000..08c50166 --- /dev/null +++ b/src/zep_cloud/types/agent_skill_compilation_outcome_rejection_class.py @@ -0,0 +1,18 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +AgentSkillCompilationOutcomeRejectionClass = typing.Union[ + typing.Literal[ + "no_eligible_trajectories", + "reflector_invalid_output", + "applicability_ungrounded", + "corroboration_insufficient", + "scanner_rejected", + "curator_rejected", + "curator_attempts_exhausted", + "prompt_budget_exceeded", + "provider_error", + ], + typing.Any, +] diff --git a/src/zep_cloud/types/agent_skill_evaluation.py b/src/zep_cloud/types/agent_skill_evaluation.py new file mode 100644 index 00000000..0972a3ad --- /dev/null +++ b/src/zep_cloud/types/agent_skill_evaluation.py @@ -0,0 +1,35 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata + + +class AgentSkillEvaluation(UniversalBaseModel): + controlled_test: typing.Optional[bool] = None + created_at: typing.Optional[str] = None + environment: typing.Optional[str] = None + evaluated_by: typing.Optional[str] = None + evaluator_version: typing.Optional[str] = None + evidence_reference: typing.Optional[str] = None + metrics: typing.Optional[typing.Dict[str, float]] = None + skill_uuid: typing.Optional[str] = None + skill_version: typing.Optional[int] = None + trajectory_uuid: typing.Optional[str] = None + use_uuid: typing.Optional[str] = None + uuid_: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + ] = None + verdict: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_skill_evidence.py b/src/zep_cloud/types/agent_skill_evidence.py new file mode 100644 index 00000000..a1a20631 --- /dev/null +++ b/src/zep_cloud/types/agent_skill_evidence.py @@ -0,0 +1,27 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class AgentSkillEvidence(UniversalBaseModel): + assertion_uuid: typing.Optional[str] = None + created_at: typing.Optional[str] = None + occurred_at: typing.Optional[str] = None + polarity: typing.Optional[str] = None + source_kind: typing.Optional[str] = None + summary_version_uuid: typing.Optional[str] = None + trajectory_event_uuid: typing.Optional[str] = None + trajectory_uuid: typing.Optional[str] = None + verification: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_skill_publication_lineage.py b/src/zep_cloud/types/agent_skill_publication_lineage.py new file mode 100644 index 00000000..c4b38e36 --- /dev/null +++ b/src/zep_cloud/types/agent_skill_publication_lineage.py @@ -0,0 +1,67 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class AgentSkillPublicationLineage(UniversalBaseModel): + destination_agent_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The destination Agent UUID. + """ + + destination_skill_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The destination Skill UUID. + """ + + destination_version_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The destination version UUID. + """ + + policy_revision: typing.Optional[int] = pydantic.Field(default=None) + """ + The policy revision that allowed automatic publication. + """ + + policy_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The policy UUID that allowed automatic publication. + """ + + publication_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The publication UUID. + """ + + source_agent_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The source Agent UUID. + """ + + source_skill_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The source Skill UUID. + """ + + source_version: typing.Optional[int] = pydantic.Field(default=None) + """ + The source version number. + """ + + source_version_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The source version UUID. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_skill_relationship.py b/src/zep_cloud/types/agent_skill_relationship.py new file mode 100644 index 00000000..c2797bad --- /dev/null +++ b/src/zep_cloud/types/agent_skill_relationship.py @@ -0,0 +1,33 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class AgentSkillRelationship(UniversalBaseModel): + application_state: typing.Optional[str] = None + kind: typing.Optional[str] = None + related_package_name: typing.Optional[str] = None + related_skill_kind: typing.Optional[str] = None + related_skill_name: typing.Optional[str] = None + related_skill_task_family: typing.Optional[str] = None + related_skill_uuid: typing.Optional[str] = None + related_skill_version: typing.Optional[int] = None + related_version_constraint: typing.Optional[str] = None + resource_name: typing.Optional[str] = None + resource_version_constraint: typing.Optional[str] = None + trajectory_outcome: typing.Optional[str] = None + trajectory_task_family: typing.Optional[str] = None + trajectory_uuid: typing.Optional[str] = None + trajectory_verification: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_skill_search_hit.py b/src/zep_cloud/types/agent_skill_search_hit.py new file mode 100644 index 00000000..3c31b1f3 --- /dev/null +++ b/src/zep_cloud/types/agent_skill_search_hit.py @@ -0,0 +1,62 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .agent_skill_search_hit_maturity import AgentSkillSearchHitMaturity + + +class AgentSkillSearchHit(UniversalBaseModel): + agent_versions: typing.Optional[typing.List[str]] = None + description: typing.Optional[str] = None + environments: typing.Optional[typing.List[str]] = None + kind: typing.Optional[str] = None + markdown: typing.Optional[str] = None + maturity: typing.Optional[AgentSkillSearchHitMaturity] = pydantic.Field(default=None) + """ + Maturity is the trust tier of the Skill: provisional (one source attempt + family), corroborated (two or more), established (a Trust of 0.6 or + more from verified applications), or authored (no compiled source). + """ + + name: typing.Optional[str] = None + package_name: typing.Optional[str] = None + self_contained: typing.Optional[bool] = None + skill_id: typing.Optional[str] = None + source_attempt_families: typing.Optional[int] = pydantic.Field(default=None) + """ + SourceAttemptFamilies is the count of distinct, successful, verified + attempt families that support the current version. + """ + + task_family: typing.Optional[str] = None + tools: typing.Optional[typing.List[str]] = None + trust: typing.Optional[float] = pydantic.Field(default=None) + """ + Trust is the lower bound of the 95% Wilson score interval for the + success rate of strongly verified applications of the Skill. It is 0 + when the Skill has no verified application. + """ + + uuid_: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + ] = None + verified_applications: typing.Optional[int] = pydantic.Field(default=None) + """ + VerifiedApplications is the count of strongly verified applications + that end in success or failure. + """ + + version: typing.Optional[int] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_skill_search_hit_maturity.py b/src/zep_cloud/types/agent_skill_search_hit_maturity.py new file mode 100644 index 00000000..583a04c0 --- /dev/null +++ b/src/zep_cloud/types/agent_skill_search_hit_maturity.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +AgentSkillSearchHitMaturity = typing.Union[ + typing.Literal["provisional", "corroborated", "established", "authored"], typing.Any +] diff --git a/src/zep_cloud/types/agent_skill_search_response.py b/src/zep_cloud/types/agent_skill_search_response.py new file mode 100644 index 00000000..ccec48a5 --- /dev/null +++ b/src/zep_cloud/types/agent_skill_search_response.py @@ -0,0 +1,22 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .agent_skill_search_hit import AgentSkillSearchHit + + +class AgentSkillSearchResponse(UniversalBaseModel): + items: typing.Optional[typing.List[AgentSkillSearchHit]] = None + next_cursor: typing.Optional[str] = None + search_id: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_skill_use.py b/src/zep_cloud/types/agent_skill_use.py new file mode 100644 index 00000000..66cdb92c --- /dev/null +++ b/src/zep_cloud/types/agent_skill_use.py @@ -0,0 +1,32 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .agent_skill_use_outcome import AgentSkillUseOutcome + + +class AgentSkillUse(UniversalBaseModel): + agent_version: typing.Optional[str] = None + created_at: typing.Optional[str] = None + outcome: typing.Optional[AgentSkillUseOutcome] = None + reason_code: typing.Optional[str] = None + skill_uuid: typing.Optional[str] = None + skill_version: typing.Optional[int] = None + trajectory_uuid: typing.Optional[str] = None + usage: typing.Optional[str] = None + uuid_: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + ] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_skill_use_outcome.py b/src/zep_cloud/types/agent_skill_use_outcome.py new file mode 100644 index 00000000..8141867c --- /dev/null +++ b/src/zep_cloud/types/agent_skill_use_outcome.py @@ -0,0 +1,29 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata + + +class AgentSkillUseOutcome(UniversalBaseModel): + assertion_uuid: typing.Optional[str] = None + created_at: typing.Optional[str] = None + outcome: typing.Optional[str] = None + trajectory_uuid: typing.Optional[str] = None + use_uuid: typing.Optional[str] = None + uuid_: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + ] = None + verification: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_skill_version.py b/src/zep_cloud/types/agent_skill_version.py new file mode 100644 index 00000000..d6633c3f --- /dev/null +++ b/src/zep_cloud/types/agent_skill_version.py @@ -0,0 +1,30 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .skill_definition import SkillDefinition + + +class AgentSkillVersion(UniversalBaseModel): + contract: typing.Optional[typing.Dict[str, typing.Any]] = None + created_at: typing.Optional[str] = None + definition: typing.Optional[SkillDefinition] = None + markdown: typing.Optional[str] = pydantic.Field(default=None) + """ + Markdown is the agent view of the Skill unless the request selects + `markdown_format=full`. + """ + + self_contained: typing.Optional[bool] = None + version: typing.Optional[int] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_skill_version_comparison.py b/src/zep_cloud/types/agent_skill_version_comparison.py new file mode 100644 index 00000000..5bb389d1 --- /dev/null +++ b/src/zep_cloud/types/agent_skill_version_comparison.py @@ -0,0 +1,26 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .agent_skill_version import AgentSkillVersion + + +class AgentSkillVersionComparison(UniversalBaseModel): + changed_fields: typing.Optional[typing.List[str]] = None + from_: typing_extensions.Annotated[ + typing.Optional[AgentSkillVersion], FieldMetadata(alias="from"), pydantic.Field(alias="from") + ] = None + to: typing.Optional[AgentSkillVersion] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_split_plan.py b/src/zep_cloud/types/agent_split_plan.py new file mode 100644 index 00000000..bfee69f1 --- /dev/null +++ b/src/zep_cloud/types/agent_split_plan.py @@ -0,0 +1,31 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .agent_split_plan_destination import AgentSplitPlanDestination +from .agent_split_plan_source import AgentSplitPlanSource + + +class AgentSplitPlan(UniversalBaseModel): + authorizes_agent_creation: typing.Optional[bool] = None + authorizes_publication: typing.Optional[bool] = None + creates_resources: typing.Optional[bool] = pydantic.Field(default=None) + """ + A split plan is not human approval and grants no authority for later commands. + """ + + destinations: typing.Optional[typing.List[AgentSplitPlanDestination]] = None + rationale: typing.Optional[str] = None + review_acknowledged: typing.Optional[bool] = None + source: typing.Optional[AgentSplitPlanSource] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_split_plan_destination.py b/src/zep_cloud/types/agent_split_plan_destination.py new file mode 100644 index 00000000..ea5a2a4d --- /dev/null +++ b/src/zep_cloud/types/agent_split_plan_destination.py @@ -0,0 +1,22 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .agent_split_plan_skill_reference import AgentSplitPlanSkillReference +from .create_agent_request import CreateAgentRequest + + +class AgentSplitPlanDestination(UniversalBaseModel): + agent: typing.Optional[CreateAgentRequest] = None + skills: typing.Optional[typing.List[AgentSplitPlanSkillReference]] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_split_plan_destination_request.py b/src/zep_cloud/types/agent_split_plan_destination_request.py new file mode 100644 index 00000000..d8adbec3 --- /dev/null +++ b/src/zep_cloud/types/agent_split_plan_destination_request.py @@ -0,0 +1,22 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .agent_split_plan_skill_selection_request import AgentSplitPlanSkillSelectionRequest +from .create_agent_request import CreateAgentRequest + + +class AgentSplitPlanDestinationRequest(UniversalBaseModel): + agent: CreateAgentRequest + skills: typing.List[AgentSplitPlanSkillSelectionRequest] + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_split_plan_skill_reference.py b/src/zep_cloud/types/agent_split_plan_skill_reference.py new file mode 100644 index 00000000..c5ee19f9 --- /dev/null +++ b/src/zep_cloud/types/agent_split_plan_skill_reference.py @@ -0,0 +1,24 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class AgentSplitPlanSkillReference(UniversalBaseModel): + package_name: typing.Optional[str] = None + skill_id: typing.Optional[str] = None + skill_uuid: typing.Optional[str] = None + skill_version_uuid: typing.Optional[str] = None + status: typing.Optional[str] = None + version: typing.Optional[int] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_split_plan_skill_selection_request.py b/src/zep_cloud/types/agent_split_plan_skill_selection_request.py new file mode 100644 index 00000000..024b2129 --- /dev/null +++ b/src/zep_cloud/types/agent_split_plan_skill_selection_request.py @@ -0,0 +1,21 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class AgentSplitPlanSkillSelectionRequest(UniversalBaseModel): + skill_uuid: str + skill_version_uuid: str + version: int + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_split_plan_source.py b/src/zep_cloud/types/agent_split_plan_source.py new file mode 100644 index 00000000..2104f76b --- /dev/null +++ b/src/zep_cloud/types/agent_split_plan_source.py @@ -0,0 +1,20 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class AgentSplitPlanSource(UniversalBaseModel): + agent_uuid: typing.Optional[str] = None + revision: typing.Optional[int] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_status.py b/src/zep_cloud/types/agent_status.py new file mode 100644 index 00000000..7220fae5 --- /dev/null +++ b/src/zep_cloud/types/agent_status.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +AgentStatus = typing.Union[typing.Literal["active", "deleting", "deletion_failed"], typing.Any] diff --git a/src/zep_cloud/types/agent_trajectory.py b/src/zep_cloud/types/agent_trajectory.py new file mode 100644 index 00000000..b276e8dc --- /dev/null +++ b/src/zep_cloud/types/agent_trajectory.py @@ -0,0 +1,128 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .agent_trajectory_internal import AgentTrajectoryInternal +from .agent_trajectory_lifecycle import AgentTrajectoryLifecycle +from .agent_trajectory_outcome import AgentTrajectoryOutcome +from .agent_trajectory_source import AgentTrajectorySource +from .agent_trajectory_verification import AgentTrajectoryVerification + + +class AgentTrajectory(UniversalBaseModel): + abandoned_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the Trajectory was abandoned. + """ + + agent_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The owning Agent UUID. + """ + + attempt_family_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The stable retry-family identity shared with declared child attempts. + """ + + closed_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the Trajectory closed. + """ + + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the Trajectory was created. + """ + + internal: typing.Optional[AgentTrajectoryInternal] = pydantic.Field(default=None) + """ + Server-owned fields that are not part of the top-level capture contract. + """ + + learn_from: typing.Optional[bool] = pydantic.Field(default=None) + """ + Whether eligible evidence may participate in learning. + """ + + learn_from_reason: typing.Optional[str] = pydantic.Field(default=None) + """ + Why the Trajectory is not eligible for learning. + """ + + metadata: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Developer metadata used for exact containment filters. + """ + + objective: typing.Optional[str] = pydantic.Field(default=None) + """ + The task-instance objective captured for this attempt. + """ + + outcome: typing.Optional[AgentTrajectoryOutcome] = pydantic.Field(default=None) + """ + The caller-owned task outcome. + """ + + parent_trajectory_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The parent attempt when this Trajectory is a retry. + """ + + revision: typing.Optional[int] = pydantic.Field(default=None) + """ + The revision required by the next update or lifecycle command. + """ + + source: typing.Optional[AgentTrajectorySource] = pydantic.Field(default=None) + """ + The source record for an imported Trajectory. + """ + + status: typing.Optional[AgentTrajectoryLifecycle] = pydantic.Field(default=None) + """ + The current lifecycle state. + """ + + task_family: typing.Optional[str] = pydantic.Field(default=None) + """ + The optional opaque task-family classification slug. + """ + + trajectory_id: typing.Optional[str] = pydantic.Field(default=None) + """ + The optional customer-assigned identifier, unique within the Agent. + """ + + updated_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the Trajectory was last updated. + """ + + uuid_: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="The stable Trajectory UUID."), + ] = None + """ + The stable Trajectory UUID. + """ + + verification: typing.Optional[AgentTrajectoryVerification] = pydantic.Field(default=None) + """ + The strength of the accepted outcome verification. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_trajectory_close_verifier.py b/src/zep_cloud/types/agent_trajectory_close_verifier.py new file mode 100644 index 00000000..47e02f88 --- /dev/null +++ b/src/zep_cloud/types/agent_trajectory_close_verifier.py @@ -0,0 +1,28 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .agent_verifier_assertion_outcome import AgentVerifierAssertionOutcome + + +class AgentTrajectoryCloseVerifier(UniversalBaseModel): + assertion_id: typing.Optional[str] = None + class_: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="class"), pydantic.Field(alias="class") + ] = None + evidence_reference: typing.Optional[str] = None + outcome: typing.Optional[AgentVerifierAssertionOutcome] = None + verifier_id: str + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_trajectory_event.py b/src/zep_cloud/types/agent_trajectory_event.py new file mode 100644 index 00000000..ea5c2146 --- /dev/null +++ b/src/zep_cloud/types/agent_trajectory_event.py @@ -0,0 +1,42 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .agent_trajectory_event_context import AgentTrajectoryEventContext +from .agent_trajectory_event_processing_state import AgentTrajectoryEventProcessingState +from .agent_trajectory_event_source import AgentTrajectoryEventSource +from .agent_trajectory_event_type import AgentTrajectoryEventType + + +class AgentTrajectoryEvent(UniversalBaseModel): + agent_uuid: typing.Optional[str] = None + content: typing.Optional[str] = None + context: typing.Optional[AgentTrajectoryEventContext] = None + created_at: typing.Optional[str] = None + event_id: typing.Optional[str] = None + event_type: typing.Optional[AgentTrajectoryEventType] = None + failed_at: typing.Optional[str] = None + metadata: typing.Optional[typing.Dict[str, typing.Any]] = None + occurred_at: typing.Optional[str] = None + processed_at: typing.Optional[str] = None + processing_state: typing.Optional[AgentTrajectoryEventProcessingState] = None + sequence: typing.Optional[int] = None + sources: typing.Optional[typing.List[AgentTrajectoryEventSource]] = None + trajectory_uuid: typing.Optional[str] = None + updated_at: typing.Optional[str] = None + uuid_: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + ] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_trajectory_event_context.py b/src/zep_cloud/types/agent_trajectory_event_context.py new file mode 100644 index 00000000..514b4aa0 --- /dev/null +++ b/src/zep_cloud/types/agent_trajectory_event_context.py @@ -0,0 +1,24 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .agent_trajectory_resource_ref import AgentTrajectoryResourceRef + + +class AgentTrajectoryEventContext(UniversalBaseModel): + artifacts: typing.Optional[typing.List[AgentTrajectoryResourceRef]] = None + environments: typing.Optional[typing.List[AgentTrajectoryResourceRef]] = None + model: typing.Optional[AgentTrajectoryResourceRef] = None + tools: typing.Optional[typing.List[AgentTrajectoryResourceRef]] = None + verification: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_trajectory_event_page.py b/src/zep_cloud/types/agent_trajectory_event_page.py new file mode 100644 index 00000000..8fd37686 --- /dev/null +++ b/src/zep_cloud/types/agent_trajectory_event_page.py @@ -0,0 +1,22 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .agent_trajectory_event import AgentTrajectoryEvent + + +class AgentTrajectoryEventPage(UniversalBaseModel): + items: typing.Optional[typing.List[AgentTrajectoryEvent]] = None + next_cursor: typing.Optional[str] = None + total_size: typing.Optional[int] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_trajectory_event_processing_state.py b/src/zep_cloud/types/agent_trajectory_event_processing_state.py new file mode 100644 index 00000000..cf0fe0d0 --- /dev/null +++ b/src/zep_cloud/types/agent_trajectory_event_processing_state.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +AgentTrajectoryEventProcessingState = typing.Union[ + typing.Literal["pending", "processing", "processed", "failed"], typing.Any +] diff --git a/src/zep_cloud/types/agent_trajectory_event_source.py b/src/zep_cloud/types/agent_trajectory_event_source.py new file mode 100644 index 00000000..8b304c96 --- /dev/null +++ b/src/zep_cloud/types/agent_trajectory_event_source.py @@ -0,0 +1,26 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .agent_trajectory_event_source_copy_mode import AgentTrajectoryEventSourceCopyMode +from .agent_trajectory_event_source_retention_mode import AgentTrajectoryEventSourceRetentionMode + + +class AgentTrajectoryEventSource(UniversalBaseModel): + copy_mode: typing.Optional[AgentTrajectoryEventSourceCopyMode] = None + kind: str + retention_mode: typing.Optional[AgentTrajectoryEventSourceRetentionMode] = None + uuid_: typing_extensions.Annotated[str, FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid")] + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_trajectory_event_source_copy_mode.py b/src/zep_cloud/types/agent_trajectory_event_source_copy_mode.py new file mode 100644 index 00000000..d1286632 --- /dev/null +++ b/src/zep_cloud/types/agent_trajectory_event_source_copy_mode.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +AgentTrajectoryEventSourceCopyMode = typing.Union[typing.Literal["reference", "copied"], typing.Any] diff --git a/src/zep_cloud/types/agent_trajectory_event_source_retention_mode.py b/src/zep_cloud/types/agent_trajectory_event_source_retention_mode.py new file mode 100644 index 00000000..35887874 --- /dev/null +++ b/src/zep_cloud/types/agent_trajectory_event_source_retention_mode.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +AgentTrajectoryEventSourceRetentionMode = typing.Union[typing.Literal["delete_with_source", "keep"], typing.Any] diff --git a/src/zep_cloud/types/agent_trajectory_event_type.py b/src/zep_cloud/types/agent_trajectory_event_type.py new file mode 100644 index 00000000..78e42f2e --- /dev/null +++ b/src/zep_cloud/types/agent_trajectory_event_type.py @@ -0,0 +1,20 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +AgentTrajectoryEventType = typing.Union[ + typing.Literal[ + "input_reference", + "observation", + "decision", + "tool_call", + "tool_result", + "artifact", + "checkpoint", + "feedback", + "correction", + "reflection", + "verification", + ], + typing.Any, +] diff --git a/src/zep_cloud/types/agent_trajectory_finalization_result.py b/src/zep_cloud/types/agent_trajectory_finalization_result.py new file mode 100644 index 00000000..fbdcd8ab --- /dev/null +++ b/src/zep_cloud/types/agent_trajectory_finalization_result.py @@ -0,0 +1,22 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .agent_trajectory import AgentTrajectory +from .task import Task + + +class AgentTrajectoryFinalizationResult(UniversalBaseModel): + task: typing.Optional[Task] = None + trajectory: typing.Optional[AgentTrajectory] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_trajectory_internal.py b/src/zep_cloud/types/agent_trajectory_internal.py new file mode 100644 index 00000000..9534cc8e --- /dev/null +++ b/src/zep_cloud/types/agent_trajectory_internal.py @@ -0,0 +1,25 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .agent_trajectory_processing_state import AgentTrajectoryProcessingState + + +class AgentTrajectoryInternal(UniversalBaseModel): + assertion_uuid: typing.Optional[str] = None + closing_sequence: typing.Optional[int] = None + current_summary_version: typing.Optional[int] = None + last_task_uuid: typing.Optional[str] = None + next_sequence: typing.Optional[int] = None + processing_state: typing.Optional[AgentTrajectoryProcessingState] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_trajectory_lifecycle.py b/src/zep_cloud/types/agent_trajectory_lifecycle.py new file mode 100644 index 00000000..c8278d5e --- /dev/null +++ b/src/zep_cloud/types/agent_trajectory_lifecycle.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +AgentTrajectoryLifecycle = typing.Union[typing.Literal["open", "closing", "closed", "abandoned", "deleted"], typing.Any] diff --git a/src/zep_cloud/types/agent_trajectory_outcome.py b/src/zep_cloud/types/agent_trajectory_outcome.py new file mode 100644 index 00000000..21eb637a --- /dev/null +++ b/src/zep_cloud/types/agent_trajectory_outcome.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +AgentTrajectoryOutcome = typing.Union[ + typing.Literal["succeeded", "failed", "partial", "abandoned", "unknown"], typing.Any +] diff --git a/src/zep_cloud/types/agent_trajectory_page.py b/src/zep_cloud/types/agent_trajectory_page.py new file mode 100644 index 00000000..61289f39 --- /dev/null +++ b/src/zep_cloud/types/agent_trajectory_page.py @@ -0,0 +1,33 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .agent_trajectory import AgentTrajectory + + +class AgentTrajectoryPage(UniversalBaseModel): + items: typing.Optional[typing.List[AgentTrajectory]] = pydantic.Field(default=None) + """ + The Trajectories on this page. + """ + + next_cursor: typing.Optional[str] = pydantic.Field(default=None) + """ + Opaque cursor for retrieving the next page, present only when more results are available. + """ + + total_size: typing.Optional[int] = pydantic.Field(default=None) + """ + The total number of Trajectories matching the filters within the owning Agent. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_trajectory_processing_state.py b/src/zep_cloud/types/agent_trajectory_processing_state.py new file mode 100644 index 00000000..2169df9d --- /dev/null +++ b/src/zep_cloud/types/agent_trajectory_processing_state.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +AgentTrajectoryProcessingState = typing.Union[typing.Literal["idle", "pending", "processing", "failed"], typing.Any] diff --git a/src/zep_cloud/types/agent_trajectory_resource_ref.py b/src/zep_cloud/types/agent_trajectory_resource_ref.py new file mode 100644 index 00000000..8aa5b7ec --- /dev/null +++ b/src/zep_cloud/types/agent_trajectory_resource_ref.py @@ -0,0 +1,20 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class AgentTrajectoryResourceRef(UniversalBaseModel): + name: str + version: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_trajectory_sequence_range.py b/src/zep_cloud/types/agent_trajectory_sequence_range.py new file mode 100644 index 00000000..4cf9aed7 --- /dev/null +++ b/src/zep_cloud/types/agent_trajectory_sequence_range.py @@ -0,0 +1,20 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class AgentTrajectorySequenceRange(UniversalBaseModel): + first: int + last: int + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_trajectory_source.py b/src/zep_cloud/types/agent_trajectory_source.py new file mode 100644 index 00000000..ab5e32f5 --- /dev/null +++ b/src/zep_cloud/types/agent_trajectory_source.py @@ -0,0 +1,36 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class AgentTrajectorySource(UniversalBaseModel): + connection_uuid: typing.Optional[str] = None + import_uuid: typing.Optional[str] = None + imported_at: typing.Optional[str] = None + kind: typing.Optional[typing.Literal["trace_import"]] = None + provider: typing.Optional[str] = None + provider_project_id: typing.Optional[str] = None + run_uuid: typing.Optional[str] = None + scores: typing.Optional[typing.Dict[str, typing.Any]] = None + source_changed: typing.Optional[bool] = pydantic.Field(default=None) + """ + SourceChanged reports whether the provider trace changed after import. + """ + + source_revision: typing.Optional[str] = None + source_url: typing.Optional[str] = None + trace_ended_at: typing.Optional[str] = None + trace_id: typing.Optional[str] = None + trace_started_at: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_trajectory_source_deletion_result.py b/src/zep_cloud/types/agent_trajectory_source_deletion_result.py new file mode 100644 index 00000000..b4c76874 --- /dev/null +++ b/src/zep_cloud/types/agent_trajectory_source_deletion_result.py @@ -0,0 +1,25 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .agent_trajectory import AgentTrajectory +from .task import Task + + +class AgentTrajectorySourceDeletionResult(UniversalBaseModel): + affected_skills: typing.Optional[int] = None + deletion_uuid: typing.Optional[str] = None + skill_repair_task: typing.Optional[Task] = None + summary_repair_task: typing.Optional[Task] = None + trajectory: typing.Optional[AgentTrajectory] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_trajectory_summary_creation_reason.py b/src/zep_cloud/types/agent_trajectory_summary_creation_reason.py new file mode 100644 index 00000000..7f9e8892 --- /dev/null +++ b/src/zep_cloud/types/agent_trajectory_summary_creation_reason.py @@ -0,0 +1,8 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +AgentTrajectorySummaryCreationReason = typing.Union[ + typing.Literal["close", "abandon", "revision", "task_family_correction", "evidence_deletion", "policy_change"], + typing.Any, +] diff --git a/src/zep_cloud/types/agent_trajectory_summary_omission_reason.py b/src/zep_cloud/types/agent_trajectory_summary_omission_reason.py new file mode 100644 index 00000000..464ae894 --- /dev/null +++ b/src/zep_cloud/types/agent_trajectory_summary_omission_reason.py @@ -0,0 +1,10 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +AgentTrajectorySummaryOmissionReason = typing.Union[ + typing.Literal[ + "narrower_authorization_boundary", "acknowledged_gap", "abandoned_gap", "processing_failed", "source_deleted" + ], + typing.Any, +] diff --git a/src/zep_cloud/types/agent_trajectory_summary_omitted_range.py b/src/zep_cloud/types/agent_trajectory_summary_omitted_range.py new file mode 100644 index 00000000..bf57b588 --- /dev/null +++ b/src/zep_cloud/types/agent_trajectory_summary_omitted_range.py @@ -0,0 +1,22 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .agent_trajectory_summary_omission_reason import AgentTrajectorySummaryOmissionReason + + +class AgentTrajectorySummaryOmittedRange(UniversalBaseModel): + first_sequence: typing.Optional[int] = None + last_sequence: typing.Optional[int] = None + reason: typing.Optional[AgentTrajectorySummaryOmissionReason] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_trajectory_summary_page.py b/src/zep_cloud/types/agent_trajectory_summary_page.py new file mode 100644 index 00000000..2b6aacc5 --- /dev/null +++ b/src/zep_cloud/types/agent_trajectory_summary_page.py @@ -0,0 +1,22 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .agent_trajectory_summary_version import AgentTrajectorySummaryVersion + + +class AgentTrajectorySummaryPage(UniversalBaseModel): + items: typing.Optional[typing.List[AgentTrajectorySummaryVersion]] = None + next_cursor: typing.Optional[str] = None + total_size: typing.Optional[int] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_trajectory_summary_version.py b/src/zep_cloud/types/agent_trajectory_summary_version.py new file mode 100644 index 00000000..806d4f12 --- /dev/null +++ b/src/zep_cloud/types/agent_trajectory_summary_version.py @@ -0,0 +1,43 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .agent_trajectory_outcome import AgentTrajectoryOutcome +from .agent_trajectory_summary_creation_reason import AgentTrajectorySummaryCreationReason +from .agent_trajectory_summary_omitted_range import AgentTrajectorySummaryOmittedRange +from .agent_trajectory_verification import AgentTrajectoryVerification + + +class AgentTrajectorySummaryVersion(UniversalBaseModel): + agent_uuid: typing.Optional[str] = None + assertion_uuid: typing.Optional[str] = None + created_at: typing.Optional[str] = None + creation_reason: typing.Optional[AgentTrajectorySummaryCreationReason] = None + first_occurred_at: typing.Optional[str] = None + first_sequence: typing.Optional[int] = None + last_occurred_at: typing.Optional[str] = None + last_sequence: typing.Optional[int] = None + omitted_sequence_ranges: typing.Optional[typing.List[AgentTrajectorySummaryOmittedRange]] = None + outcome: typing.Optional[AgentTrajectoryOutcome] = None + parent_version_uuid: typing.Optional[str] = None + structured_summary: typing.Optional[typing.Dict[str, typing.Any]] = None + text: typing.Optional[str] = None + trajectory_uuid: typing.Optional[str] = None + uuid_: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + ] = None + verification: typing.Optional[AgentTrajectoryVerification] = None + version: typing.Optional[int] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_trajectory_verification.py b/src/zep_cloud/types/agent_trajectory_verification.py new file mode 100644 index 00000000..f63a95d6 --- /dev/null +++ b/src/zep_cloud/types/agent_trajectory_verification.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +AgentTrajectoryVerification = typing.Union[typing.Literal["none", "agent", "tool", "customer", "external"], typing.Any] diff --git a/src/zep_cloud/types/agent_verification_strength.py b/src/zep_cloud/types/agent_verification_strength.py new file mode 100644 index 00000000..b70d691b --- /dev/null +++ b/src/zep_cloud/types/agent_verification_strength.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +AgentVerificationStrength = typing.Union[ + typing.Literal["tool_verified", "customer_verified", "externally_verified"], typing.Any +] diff --git a/src/zep_cloud/types/agent_verifier.py b/src/zep_cloud/types/agent_verifier.py new file mode 100644 index 00000000..c2b22a21 --- /dev/null +++ b/src/zep_cloud/types/agent_verifier.py @@ -0,0 +1,101 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .agent_verification_strength import AgentVerificationStrength +from .agent_verifier_principal import AgentVerifierPrincipal +from .agent_verifier_principal_binding import AgentVerifierPrincipalBinding +from .agent_verifier_status import AgentVerifierStatus + + +class AgentVerifier(UniversalBaseModel): + agent_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The owning Agent UUID. + """ + + capabilities: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Structured capabilities reported by the verifier integration. + """ + + class_: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="class"), + pydantic.Field(alias="class", description="The immutable verifier class."), + ] = None + """ + The immutable verifier class. + """ + + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the registration was created. + """ + + created_by: typing.Optional[AgentVerifierPrincipal] = pydantic.Field(default=None) + """ + The authenticated principal that created this registration. + """ + + metadata: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Developer metadata used to organize the registration. + """ + + permitted_strengths: typing.Optional[typing.List[AgentVerificationStrength]] = pydantic.Field(default=None) + """ + Verification strengths this registration may assert. + """ + + principal_bindings: typing.Optional[typing.List[AgentVerifierPrincipalBinding]] = pydantic.Field(default=None) + """ + Exact authenticated principals permitted to submit verifier assertions. + """ + + revision: typing.Optional[int] = pydantic.Field(default=None) + """ + The revision required by the next update or revoke request. + """ + + revoked_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the registration was revoked. + """ + + status: typing.Optional[AgentVerifierStatus] = pydantic.Field(default=None) + """ + The registration lifecycle status. + """ + + updated_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the registration was last updated. + """ + + uuid_: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="The stable verifier registration UUID."), + ] = None + """ + The stable verifier registration UUID. + """ + + verifier_id: typing.Optional[str] = pydantic.Field(default=None) + """ + The developer-assigned verifier identifier, unique within the Agent. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_verifier_assertion_outcome.py b/src/zep_cloud/types/agent_verifier_assertion_outcome.py new file mode 100644 index 00000000..0061c6f9 --- /dev/null +++ b/src/zep_cloud/types/agent_verifier_assertion_outcome.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +AgentVerifierAssertionOutcome = typing.Union[ + typing.Literal["succeeded", "failed", "partial", "abandoned", "unknown"], typing.Any +] diff --git a/src/zep_cloud/types/agent_verifier_evidence_invalidation_result.py b/src/zep_cloud/types/agent_verifier_evidence_invalidation_result.py new file mode 100644 index 00000000..690a92b9 --- /dev/null +++ b/src/zep_cloud/types/agent_verifier_evidence_invalidation_result.py @@ -0,0 +1,33 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .agent_verifier_principal import AgentVerifierPrincipal +from .task import Task + + +class AgentVerifierEvidenceInvalidationResult(UniversalBaseModel): + affected_skill_uuids: typing.Optional[typing.List[str]] = None + agent_uuid: typing.Optional[str] = None + created_at: typing.Optional[str] = None + created_by: typing.Optional[AgentVerifierPrincipal] = None + reason: typing.Optional[str] = None + task: typing.Optional[Task] = None + uuid_: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid") + ] = None + verifier_revisions: typing.Optional[typing.List[int]] = None + verifier_uuid: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_verifier_principal.py b/src/zep_cloud/types/agent_verifier_principal.py new file mode 100644 index 00000000..110d15f7 --- /dev/null +++ b/src/zep_cloud/types/agent_verifier_principal.py @@ -0,0 +1,27 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class AgentVerifierPrincipal(UniversalBaseModel): + principal_id: str = pydantic.Field() + """ + The exact principal identifier. Wildcards are not supported. + """ + + principal_type: str = pydantic.Field() + """ + The authenticated principal type: member, project-api-key, service, or mcp_user. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_verifier_principal_binding.py b/src/zep_cloud/types/agent_verifier_principal_binding.py new file mode 100644 index 00000000..fde5a96f --- /dev/null +++ b/src/zep_cloud/types/agent_verifier_principal_binding.py @@ -0,0 +1,38 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .agent_verification_strength import AgentVerificationStrength + + +class AgentVerifierPrincipalBinding(UniversalBaseModel): + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the binding was created. + """ + + effective_strength: typing.Optional[AgentVerificationStrength] = pydantic.Field(default=None) + """ + The verification strength assigned to this principal binding. + """ + + principal_id: typing.Optional[str] = pydantic.Field(default=None) + """ + The exact principal identifier bound to this verifier. + """ + + principal_type: typing.Optional[str] = pydantic.Field(default=None) + """ + The authenticated principal type bound to this verifier. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_verifier_principal_binding_input.py b/src/zep_cloud/types/agent_verifier_principal_binding_input.py new file mode 100644 index 00000000..9f60ca22 --- /dev/null +++ b/src/zep_cloud/types/agent_verifier_principal_binding_input.py @@ -0,0 +1,33 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .agent_verification_strength import AgentVerificationStrength + + +class AgentVerifierPrincipalBindingInput(UniversalBaseModel): + effective_strength: AgentVerificationStrength = pydantic.Field() + """ + The verification strength assigned to this principal binding. + """ + + principal_id: str = pydantic.Field() + """ + The exact principal identifier. Wildcards are not supported. + """ + + principal_type: str = pydantic.Field() + """ + The authenticated principal type: member, project-api-key, service, or mcp_user. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/agent_verifier_status.py b/src/zep_cloud/types/agent_verifier_status.py new file mode 100644 index 00000000..94fb52b5 --- /dev/null +++ b/src/zep_cloud/types/agent_verifier_status.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +AgentVerifierStatus = typing.Union[typing.Literal["active", "revoked"], typing.Any] diff --git a/src/zep_cloud/types/batch.py b/src/zep_cloud/types/batch.py index 5185d2c6..ce9ab404 100644 --- a/src/zep_cloud/types/batch.py +++ b/src/zep_cloud/types/batch.py @@ -42,6 +42,9 @@ class Batch(UniversalBaseModel): FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid", description="The unique identifier of the batch."), ] = None + """ + The unique identifier of the batch. + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/zep_cloud/types/batch_item.py b/src/zep_cloud/types/batch_item.py index 0673fb5d..8a966b72 100644 --- a/src/zep_cloud/types/batch_item.py +++ b/src/zep_cloud/types/batch_item.py @@ -8,9 +8,16 @@ from ..core.serialization import FieldMetadata from .batch_item_kind import BatchItemKind from .batch_item_status import BatchItemStatus +from .episode_content_policy import EpisodeContentPolicy class BatchItem(UniversalBaseModel): + content_policy: typing.Optional[EpisodeContentPolicy] = pydantic.Field(default=None) + """ + The content policy state of the item's episode, present only on a graph + with a bound content policy rule and only once the item is processed. + """ + created_at: typing.Optional[str] = pydantic.Field(default=None) """ The time the item was appended to the batch. @@ -58,6 +65,9 @@ class BatchItem(UniversalBaseModel): FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid", description="The unique identifier of the batch item."), ] = None + """ + The unique identifier of the batch item. + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/zep_cloud/types/batch_item_input.py b/src/zep_cloud/types/batch_item_input.py index e67bea5c..e9c37ac4 100644 --- a/src/zep_cloud/types/batch_item_input.py +++ b/src/zep_cloud/types/batch_item_input.py @@ -4,9 +4,9 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -from .v4batch_item_input_data_type import V4BatchItemInputDataType -from .v4batch_item_input_role import V4BatchItemInputRole -from .v4batch_item_input_type import V4BatchItemInputType +from .batch_item_input_data_type import BatchItemInputDataType +from .batch_item_input_role import BatchItemInputRole +from .batch_item_input_type import BatchItemInputType class BatchItemInput(UniversalBaseModel): @@ -15,12 +15,18 @@ class BatchItemInput(UniversalBaseModel): The message content, for a thread_message item. """ + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The item's reference time, used for temporal reasoning rather than + ingestion time. Applies to both graph_episode and thread_message items. + """ + data: typing.Optional[str] = pydantic.Field(default=None) """ The episode content, for a graph_episode item. """ - data_type: typing.Optional[V4BatchItemInputDataType] = pydantic.Field(default=None) + data_type: typing.Optional[BatchItemInputDataType] = pydantic.Field(default=None) """ The data format of the episode: text, json, or message. """ @@ -37,7 +43,7 @@ class BatchItemInput(UniversalBaseModel): metadata: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) """ - Metadata to store on the item. + Metadata to store on the item. Max 10 keys. Values must be strings, numbers, booleans, or arrays of scalars. """ name: typing.Optional[str] = pydantic.Field(default=None) @@ -45,7 +51,7 @@ class BatchItemInput(UniversalBaseModel): A customizable name for the sender of the message. """ - role: typing.Optional[V4BatchItemInputRole] = pydantic.Field(default=None) + role: typing.Optional[BatchItemInputRole] = pydantic.Field(default=None) """ The role of the message's sender, for a thread_message item. """ @@ -60,7 +66,7 @@ class BatchItemInput(UniversalBaseModel): The thread this message is added to, for a thread_message item. """ - type: V4BatchItemInputType = pydantic.Field() + type: BatchItemInputType = pydantic.Field() """ The kind of item: graph_episode or thread_message. """ diff --git a/src/zep_cloud/types/batch_item_input_data_type.py b/src/zep_cloud/types/batch_item_input_data_type.py new file mode 100644 index 00000000..01c1e753 --- /dev/null +++ b/src/zep_cloud/types/batch_item_input_data_type.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +BatchItemInputDataType = typing.Union[typing.Literal["text", "json", "message"], typing.Any] diff --git a/src/zep_cloud/types/batch_item_input_role.py b/src/zep_cloud/types/batch_item_input_role.py new file mode 100644 index 00000000..16b22220 --- /dev/null +++ b/src/zep_cloud/types/batch_item_input_role.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +BatchItemInputRole = typing.Union[typing.Literal["system", "assistant", "user", "function", "tool"], typing.Any] diff --git a/src/zep_cloud/types/batch_item_input_type.py b/src/zep_cloud/types/batch_item_input_type.py new file mode 100644 index 00000000..a5f0a3ff --- /dev/null +++ b/src/zep_cloud/types/batch_item_input_type.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +BatchItemInputType = typing.Union[typing.Literal["graph_episode", "thread_message"], typing.Any] diff --git a/src/zep_cloud/types/clone_graph_request.py b/src/zep_cloud/types/clone_graph_request.py new file mode 100644 index 00000000..1af8f9ef --- /dev/null +++ b/src/zep_cloud/types/clone_graph_request.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +CloneGraphRequest = typing.Dict[str, typing.Any] diff --git a/src/zep_cloud/types/comparison_operator.py b/src/zep_cloud/types/comparison_operator.py deleted file mode 100644 index 8e1df62e..00000000 --- a/src/zep_cloud/types/comparison_operator.py +++ /dev/null @@ -1,7 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -ComparisonOperator = typing.Union[ - typing.Literal["=", "<>", ">", "<", ">=", "<=", "IS NULL", "is_null", "IS NOT NULL", "CONTAINS"], typing.Any -] diff --git a/src/zep_cloud/types/content_policy.py b/src/zep_cloud/types/content_policy.py new file mode 100644 index 00000000..889d0ba9 --- /dev/null +++ b/src/zep_cloud/types/content_policy.py @@ -0,0 +1,54 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .content_policy_category import ContentPolicyCategory +from .content_policy_rule import ContentPolicyRule + + +class ContentPolicy(UniversalBaseModel): + categories: typing.Optional[typing.List[ContentPolicyCategory]] = pydantic.Field(default=None) + """ + The categories of the policy. + """ + + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + When this policy set was created. + """ + + revision: typing.Optional[int] = pydantic.Field(default=None) + """ + The project revision number. 0 is the empty policy of a new project. + """ + + rules: typing.Optional[typing.List[ContentPolicyRule]] = pydantic.Field(default=None) + """ + The rules of the policy. + """ + + uuid_: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field( + alias="uuid", + description="The identifier of this policy set. A project revision and every graph\nthat binds it without additions share one uuid.", + ), + ] = None + """ + The identifier of this policy set. A project revision and every graph + that binds it without additions share one uuid. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/episode_metadata_filter.py b/src/zep_cloud/types/content_policy_category.py similarity index 51% rename from src/zep_cloud/types/episode_metadata_filter.py rename to src/zep_cloud/types/content_policy_category.py index d3c15798..af7c7fd8 100644 --- a/src/zep_cloud/types/episode_metadata_filter.py +++ b/src/zep_cloud/types/content_policy_category.py @@ -4,23 +4,23 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -from .comparison_operator import ComparisonOperator -class EpisodeMetadataFilter(UniversalBaseModel): - comparison_operator: ComparisonOperator = pydantic.Field() +class ContentPolicyCategory(UniversalBaseModel): + description: typing.Optional[str] = pydantic.Field(default=None) """ - Comparison operator: =, <>, >, <, >=, <=, IS NULL, IS NOT NULL, IN, CONTAINS + What the category covers. """ - property_name: str = pydantic.Field() + id: typing.Optional[str] = pydantic.Field(default=None) """ - Metadata key to filter on + The server-assigned identifier of the category. Stable across revisions + while the key is unchanged. """ - property_value: typing.Optional[typing.Any] = pydantic.Field(default=None) + key: typing.Optional[str] = pydantic.Field(default=None) """ - Value to compare against. Not required for IS NULL / IS NOT NULL operators. + The stable key of the category. """ if IS_PYDANTIC_V2: diff --git a/src/zep_cloud/types/content_policy_category_request.py b/src/zep_cloud/types/content_policy_category_request.py new file mode 100644 index 00000000..1e9195dc --- /dev/null +++ b/src/zep_cloud/types/content_policy_category_request.py @@ -0,0 +1,28 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class ContentPolicyCategoryRequest(UniversalBaseModel): + description: typing.Optional[str] = pydantic.Field(default=None) + """ + What the category covers, in plain language. Maximum 500 characters. + """ + + key: typing.Optional[str] = pydantic.Field(default=None) + """ + A stable key for the category, unique within the policy. Lowercase + letters, digits, and underscores; 2 to 64 characters. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/content_policy_event.py b/src/zep_cloud/types/content_policy_event.py new file mode 100644 index 00000000..3381518d --- /dev/null +++ b/src/zep_cloud/types/content_policy_event.py @@ -0,0 +1,61 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .content_policy_event_artifact_kind import ContentPolicyEventArtifactKind +from .content_policy_event_drop_reason import ContentPolicyEventDropReason + + +class ContentPolicyEvent(UniversalBaseModel): + artifact_kind: typing.Optional[ContentPolicyEventArtifactKind] = pydantic.Field(default=None) + """ + The kind of artifact the decision applied to. episode marks the + episode-level record that carries every matched category. + """ + + category_keys: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + The keys of the categories with a matched rule. + """ + + decided_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time of the decision. + """ + + drop_reason: typing.Optional[ContentPolicyEventDropReason] = pydantic.Field(default=None) + """ + Why the artifact was dropped: match, indeterminate, oversize, or + dependent. + """ + + episode_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The episode the decision belongs to. + """ + + id: typing.Optional[str] = pydantic.Field(default=None) + """ + The opaque identifier of the event. + """ + + revision: typing.Optional[int] = pydantic.Field(default=None) + """ + The project revision number of the policy the graph bound. + """ + + rule_ids: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + The identifiers of the rules that matched. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/content_policy_event_artifact_kind.py b/src/zep_cloud/types/content_policy_event_artifact_kind.py new file mode 100644 index 00000000..c4eccda9 --- /dev/null +++ b/src/zep_cloud/types/content_policy_event_artifact_kind.py @@ -0,0 +1,17 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +ContentPolicyEventArtifactKind = typing.Union[ + typing.Literal[ + "entity", + "entity_attribute", + "entity_summary", + "edge", + "thread_summary", + "document_summary", + "observation", + "episode", + ], + typing.Any, +] diff --git a/src/zep_cloud/types/content_policy_event_drop_reason.py b/src/zep_cloud/types/content_policy_event_drop_reason.py new file mode 100644 index 00000000..b23b0ba2 --- /dev/null +++ b/src/zep_cloud/types/content_policy_event_drop_reason.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +ContentPolicyEventDropReason = typing.Union[ + typing.Literal["match", "indeterminate", "oversize", "dependent"], typing.Any +] diff --git a/src/zep_cloud/types/content_policy_event_page.py b/src/zep_cloud/types/content_policy_event_page.py new file mode 100644 index 00000000..2dd73674 --- /dev/null +++ b/src/zep_cloud/types/content_policy_event_page.py @@ -0,0 +1,34 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .content_policy_event import ContentPolicyEvent + + +class ContentPolicyEventPage(UniversalBaseModel): + items: typing.Optional[typing.List[ContentPolicyEvent]] = pydantic.Field(default=None) + """ + The events on this page, newest first. + """ + + next_cursor: typing.Optional[str] = pydantic.Field(default=None) + """ + The cursor to pass as the next request's cursor to fetch the following + page; absent when no further pages remain. + """ + + total_size: typing.Optional[int] = pydantic.Field(default=None) + """ + The total number of events that match the filters. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/content_policy_revision_page.py b/src/zep_cloud/types/content_policy_revision_page.py new file mode 100644 index 00000000..efd46c83 --- /dev/null +++ b/src/zep_cloud/types/content_policy_revision_page.py @@ -0,0 +1,34 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .content_policy import ContentPolicy + + +class ContentPolicyRevisionPage(UniversalBaseModel): + items: typing.Optional[typing.List[ContentPolicy]] = pydantic.Field(default=None) + """ + The revisions on this page, newest first. + """ + + next_cursor: typing.Optional[str] = pydantic.Field(default=None) + """ + The cursor to pass as the next request's cursor to fetch the following + page; absent when no further pages remain. + """ + + total_size: typing.Optional[int] = pydantic.Field(default=None) + """ + The total number of revisions, including revision 0. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/content_policy_rule.py b/src/zep_cloud/types/content_policy_rule.py new file mode 100644 index 00000000..e7c2a3f1 --- /dev/null +++ b/src/zep_cloud/types/content_policy_rule.py @@ -0,0 +1,43 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class ContentPolicyRule(UniversalBaseModel): + category_key: typing.Optional[str] = pydantic.Field(default=None) + """ + The key of the category this rule belongs to. + """ + + description: typing.Optional[str] = pydantic.Field(default=None) + """ + The content this rule prohibits. + """ + + id: typing.Optional[str] = pydantic.Field(default=None) + """ + The server-assigned identifier of the rule. Stable across revisions while + the category key and description are unchanged. + """ + + permitted_examples: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + Examples of similar content the rule permits. + """ + + prohibited_examples: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + Examples of content the rule prohibits. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/content_policy_rule_request.py b/src/zep_cloud/types/content_policy_rule_request.py new file mode 100644 index 00000000..89f64471 --- /dev/null +++ b/src/zep_cloud/types/content_policy_rule_request.py @@ -0,0 +1,41 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class ContentPolicyRuleRequest(UniversalBaseModel): + category_key: typing.Optional[str] = pydantic.Field(default=None) + """ + The key of the category this rule belongs to. The category must be in + the same policy. + """ + + description: typing.Optional[str] = pydantic.Field(default=None) + """ + The content this rule prohibits, in plain language. Maximum 1000 + characters. + """ + + permitted_examples: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + Examples of similar content the rule permits. 0 to 8 items, each at most + 500 characters. + """ + + prohibited_examples: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + Examples of content the rule prohibits. 1 to 8 items, each at most 500 + characters. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/context_edge.py b/src/zep_cloud/types/context_edge.py index b6abe458..7b8e20e4 100644 --- a/src/zep_cloud/types/context_edge.py +++ b/src/zep_cloud/types/context_edge.py @@ -39,6 +39,12 @@ class ContextEdge(UniversalBaseModel): The unique identifier of the graph this edge belongs to. """ + hyperedge_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier of the hyperedge this edge is a member of. Omitted + when the edge is not part of a hyperedge. + """ + invalid_at: typing.Optional[str] = pydantic.Field(default=None) """ The time at which the fact stopped being true. @@ -116,6 +122,10 @@ class ContextEdge(UniversalBaseModel): FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid", description="The unique identifier of the edge."), ] = None + """ + The unique identifier of the edge. + """ + valid_at: typing.Optional[str] = pydantic.Field(default=None) """ The time from which the fact is considered true. diff --git a/src/zep_cloud/types/context_episode.py b/src/zep_cloud/types/context_episode.py index f56676ea..aca02c46 100644 --- a/src/zep_cloud/types/context_episode.py +++ b/src/zep_cloud/types/context_episode.py @@ -6,6 +6,7 @@ import typing_extensions from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel from ..core.serialization import FieldMetadata +from .episode_content_policy import EpisodeContentPolicy from .graph_data_type import GraphDataType from .role_type import RoleType @@ -16,6 +17,12 @@ class ContextEpisode(UniversalBaseModel): The raw content of the episode. """ + content_policy: typing.Optional[EpisodeContentPolicy] = pydantic.Field(default=None) + """ + The content policy state of the episode, present only on a graph with a + bound content policy rule. + """ + created_at: typing.Optional[str] = pydantic.Field(default=None) """ The time the episode was created. @@ -94,6 +101,10 @@ class ContextEpisode(UniversalBaseModel): FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid", description="The unique identifier of the episode."), ] = None + """ + The unique identifier of the episode. + """ + valid_at: typing.Optional[str] = pydantic.Field(default=None) """ The time the episode's content became true or was observed, used for diff --git a/src/zep_cloud/types/context_node.py b/src/zep_cloud/types/context_node.py index 5aaced05..c4cc9fcb 100644 --- a/src/zep_cloud/types/context_node.py +++ b/src/zep_cloud/types/context_node.py @@ -19,6 +19,27 @@ class ContextNode(UniversalBaseModel): The time the node was created. """ + degree: typing.Optional[int] = pydantic.Field(default=None) + """ + The count of live entity edges that touch this node, in both directions. + Present only when the list request orders by `degree`. + """ + + episode_uuids: typing.List[str] = pydantic.Field() + """ + The UUIDs of the live episodes that mention this node, newest first. The + list is complete when `episode_uuids_truncated` is false. The list holds + the newest 100 when the node has more than 100 source episodes; list + episodes with the `mentioned_node_uuids` filter to read them all. + """ + + episode_uuids_truncated: bool = pydantic.Field() + """ + True when the node has more than 100 source episodes, so `episode_uuids` + holds only the newest 100, or when provenance is unavailable. False means + `episode_uuids` is the complete set. + """ + graph_uuid: typing.Optional[str] = pydantic.Field(default=None) """ The unique identifier of the graph this node belongs to. @@ -63,6 +84,9 @@ class ContextNode(UniversalBaseModel): FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid", description="The node UUID, assigned by Zep."), ] = None + """ + The node UUID, assigned by Zep. + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/zep_cloud/types/context_observation.py b/src/zep_cloud/types/context_observation.py index f90c9685..2e9cf1c4 100644 --- a/src/zep_cloud/types/context_observation.py +++ b/src/zep_cloud/types/context_observation.py @@ -68,6 +68,9 @@ class ContextObservation(UniversalBaseModel): FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid", description="The unique identifier of the observation, assigned by Zep."), ] = None + """ + The unique identifier of the observation, assigned by Zep. + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/zep_cloud/types/context_template.py b/src/zep_cloud/types/context_template.py index eef45951..c9e30673 100644 --- a/src/zep_cloud/types/context_template.py +++ b/src/zep_cloud/types/context_template.py @@ -29,6 +29,9 @@ class ContextTemplate(UniversalBaseModel): FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid", description="The unique identifier of the context template."), ] = None + """ + The unique identifier of the context template. + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/zep_cloud/types/context_thread_summary.py b/src/zep_cloud/types/context_thread_summary.py index 08c469cd..c3c5277f 100644 --- a/src/zep_cloud/types/context_thread_summary.py +++ b/src/zep_cloud/types/context_thread_summary.py @@ -59,6 +59,9 @@ class ContextThreadSummary(UniversalBaseModel): FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid", description="The unique identifier of the thread summary."), ] = None + """ + The unique identifier of the thread summary. + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/zep_cloud/types/create_agent_request.py b/src/zep_cloud/types/create_agent_request.py new file mode 100644 index 00000000..6a6b3bc9 --- /dev/null +++ b/src/zep_cloud/types/create_agent_request.py @@ -0,0 +1,58 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .agent_memory_settings import AgentMemorySettings + + +class CreateAgentRequest(UniversalBaseModel): + agent_id: str = pydantic.Field() + """ + The developer-assigned Agent identifier, unique within the project. + """ + + deployment_id: typing.Optional[str] = pydantic.Field(default=None) + """ + The customer deployment this Agent represents. + """ + + description: typing.Optional[str] = pydantic.Field(default=None) + """ + A human-readable description of the Agent. + """ + + memory_settings: typing.Optional[AgentMemorySettings] = pydantic.Field(default=None) + """ + Agent Memory capture, compilation, and promotion settings. + """ + + metadata: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Developer metadata used to organize and filter Agents. + """ + + name: str = pydantic.Field() + """ + The Agent's display name. + """ + + security_domain: str = pydantic.Field() + """ + The immutable boundary within which Skills may be synthesized. 1 to 200 characters of lowercase letters, digits, and the characters : . - _ + """ + + version: typing.Optional[str] = pydantic.Field(default=None) + """ + The customer deployment version this Agent represents. If you omit it, the version is "default". + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/date_filter.py b/src/zep_cloud/types/date_filter.py index 19ab4222..a9e7cf1d 100644 --- a/src/zep_cloud/types/date_filter.py +++ b/src/zep_cloud/types/date_filter.py @@ -1,22 +1,28 @@ # This file was auto-generated by Fern from our API Definition. +import datetime as dt import typing import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -from .comparison_operator import ComparisonOperator +from .date_filter_field import DateFilterField +from .date_filter_operator import DateFilterOperator class DateFilter(UniversalBaseModel): - comparison_operator: ComparisonOperator = pydantic.Field() + field: typing.Optional[DateFilterField] = pydantic.Field(default=None) """ - Comparison operator for date filter + The temporal field to compare. """ - date: typing.Optional[str] = pydantic.Field(default=None) + operator: typing.Optional[DateFilterOperator] = pydantic.Field(default=None) """ - Date to filter on. Required for non-null operators (`=`, `<>`, `>`, `<`, `>=`, `<=`). - Should be omitted for IS NULL (or is_null) and IS NOT NULL operators. + The lowercase comparison operator. + """ + + value: typing.Optional[dt.datetime] = pydantic.Field(default=None) + """ + The RFC 3339 timestamp. Omit this field for null operators. """ if IS_PYDANTIC_V2: diff --git a/src/zep_cloud/types/date_filter_field.py b/src/zep_cloud/types/date_filter_field.py new file mode 100644 index 00000000..4370528c --- /dev/null +++ b/src/zep_cloud/types/date_filter_field.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +DateFilterField = typing.Union[typing.Literal["created_at", "valid_at", "invalid_at", "expired_at"], typing.Any] diff --git a/src/zep_cloud/types/date_filter_group.py b/src/zep_cloud/types/date_filter_group.py new file mode 100644 index 00000000..f53408ef --- /dev/null +++ b/src/zep_cloud/types/date_filter_group.py @@ -0,0 +1,23 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .date_filter import DateFilter + + +class DateFilterGroup(UniversalBaseModel): + all_of: typing.Optional[typing.List[DateFilter]] = pydantic.Field(default=None) + """ + All conditions in the group must match. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/date_filter_operator.py b/src/zep_cloud/types/date_filter_operator.py new file mode 100644 index 00000000..3e1667df --- /dev/null +++ b/src/zep_cloud/types/date_filter_operator.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +DateFilterOperator = typing.Union[ + typing.Literal["eq", "ne", "gt", "lt", "gte", "lte", "is_null", "is_not_null"], typing.Any +] diff --git a/src/zep_cloud/types/date_filters.py b/src/zep_cloud/types/date_filters.py new file mode 100644 index 00000000..1e805ab7 --- /dev/null +++ b/src/zep_cloud/types/date_filters.py @@ -0,0 +1,23 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .date_filter_group import DateFilterGroup + + +class DateFilters(UniversalBaseModel): + any_of: typing.Optional[typing.List[DateFilterGroup]] = pydantic.Field(default=None) + """ + Each group is combined with OR logic. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/debug_log_entry.py b/src/zep_cloud/types/debug_log_entry.py new file mode 100644 index 00000000..52ee3a4a --- /dev/null +++ b/src/zep_cloud/types/debug_log_entry.py @@ -0,0 +1,33 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .debug_log_level import DebugLogLevel + + +class DebugLogEntry(UniversalBaseModel): + level: typing.Optional[DebugLogLevel] = pydantic.Field(default=None) + """ + The severity of the entry. + """ + + logged_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the entry was written. + """ + + message: typing.Optional[str] = pydantic.Field(default=None) + """ + The log message. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/debug_log_level.py b/src/zep_cloud/types/debug_log_level.py new file mode 100644 index 00000000..6623752f --- /dev/null +++ b/src/zep_cloud/types/debug_log_level.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +DebugLogLevel = typing.Union[typing.Literal["debug", "info", "warning", "error"], typing.Any] diff --git a/src/zep_cloud/types/debug_log_status.py b/src/zep_cloud/types/debug_log_status.py new file mode 100644 index 00000000..901a02f3 --- /dev/null +++ b/src/zep_cloud/types/debug_log_status.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +DebugLogStatus = typing.Union[typing.Literal["running", "completed", "error"], typing.Any] diff --git a/src/zep_cloud/types/debug_logging_enablement.py b/src/zep_cloud/types/debug_logging_enablement.py new file mode 100644 index 00000000..73275e8a --- /dev/null +++ b/src/zep_cloud/types/debug_logging_enablement.py @@ -0,0 +1,28 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class DebugLoggingEnablement(UniversalBaseModel): + duration_seconds: typing.Optional[int] = pydantic.Field(default=None) + """ + The number of seconds that debug logging stays enabled. + """ + + ingestion_trace_enabled: typing.Optional[bool] = pydantic.Field(default=None) + """ + Tells if ingestion tracing was also enabled. Ingestion tracing is + available on the Flex, Flex Plus, and Enterprise plans. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/delete_agent_trajectory_request.py b/src/zep_cloud/types/delete_agent_trajectory_request.py new file mode 100644 index 00000000..018ac6e1 --- /dev/null +++ b/src/zep_cloud/types/delete_agent_trajectory_request.py @@ -0,0 +1,19 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class DeleteAgentTrajectoryRequest(UniversalBaseModel): + expected_revision: int + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/document_summary.py b/src/zep_cloud/types/document_summary.py index 715059e4..4ab0d5a7 100644 --- a/src/zep_cloud/types/document_summary.py +++ b/src/zep_cloud/types/document_summary.py @@ -39,6 +39,9 @@ class DocumentSummary(UniversalBaseModel): FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid", description="The unique identifier of the document summary."), ] = None + """ + The unique identifier of the document summary. + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/zep_cloud/types/edge.py b/src/zep_cloud/types/edge.py index a6bc4937..6bf557c3 100644 --- a/src/zep_cloud/types/edge.py +++ b/src/zep_cloud/types/edge.py @@ -39,6 +39,12 @@ class Edge(UniversalBaseModel): The unique identifier of the graph this edge belongs to. """ + hyperedge_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier of the hyperedge this edge is a member of. Omitted + when the edge is not part of a hyperedge. + """ + invalid_at: typing.Optional[str] = pydantic.Field(default=None) """ The time at which the fact stopped being true. @@ -110,6 +116,10 @@ class Edge(UniversalBaseModel): FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid", description="The unique identifier of the edge."), ] = None + """ + The unique identifier of the edge. + """ + valid_at: typing.Optional[str] = pydantic.Field(default=None) """ The time from which the fact is considered true. diff --git a/src/zep_cloud/types/edge_input.py b/src/zep_cloud/types/edge_input.py new file mode 100644 index 00000000..83eeaa43 --- /dev/null +++ b/src/zep_cloud/types/edge_input.py @@ -0,0 +1,66 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .edge_node_ref import EdgeNodeRef + + +class EdgeInput(UniversalBaseModel): + attributes: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Additional attributes to store on the edge. + """ + + expired_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time at which the fact was superseded or invalidated. + """ + + fact: str = pydantic.Field() + """ + The fact text describing the relationship between the source and target + nodes. + """ + + fact_name: str = pydantic.Field() + """ + The name of the edge, in upper snake case, for example RELATES_TO. + """ + + invalid_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time at which the fact stopped being true. + """ + + metadata: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Metadata attached to the episode created for this edge. + """ + + source_node: EdgeNodeRef = pydantic.Field() + """ + The source node. A name creates a node without deduplication, or matches + an existing node by name first when deduplication is enabled. + """ + + target_node: EdgeNodeRef = pydantic.Field() + """ + The target node. A name creates a node without deduplication, or matches + an existing node by name first when deduplication is enabled. + """ + + valid_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time at which the fact became true. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/edge_node_ref.py b/src/zep_cloud/types/edge_node_ref.py index e409c420..d465a4b7 100644 --- a/src/zep_cloud/types/edge_node_ref.py +++ b/src/zep_cloud/types/edge_node_ref.py @@ -21,7 +21,7 @@ class EdgeNodeRef(UniversalBaseModel): name: typing.Optional[str] = pydantic.Field(default=None) """ - The name of the node to create or match. + The name of the node to create, or to match when deduplication is enabled. """ summary: typing.Optional[str] = pydantic.Field(default=None) @@ -34,6 +34,9 @@ class EdgeNodeRef(UniversalBaseModel): FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid", description="The unique identifier of an existing node to attach the edge to."), ] = None + """ + The unique identifier of an existing node to attach the edge to. + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/zep_cloud/types/episode.py b/src/zep_cloud/types/episode.py index 4933eba2..2c28d61c 100644 --- a/src/zep_cloud/types/episode.py +++ b/src/zep_cloud/types/episode.py @@ -6,6 +6,7 @@ import typing_extensions from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel from ..core.serialization import FieldMetadata +from .episode_content_policy import EpisodeContentPolicy from .graph_data_type import GraphDataType from .role_type import RoleType @@ -16,6 +17,12 @@ class Episode(UniversalBaseModel): The raw content of the episode. """ + content_policy: typing.Optional[EpisodeContentPolicy] = pydantic.Field(default=None) + """ + The content policy state of the episode, present only on a graph with a + bound content policy rule. + """ + created_at: typing.Optional[str] = pydantic.Field(default=None) """ The time the episode was created. @@ -88,6 +95,10 @@ class Episode(UniversalBaseModel): FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid", description="The unique identifier of the episode."), ] = None + """ + The unique identifier of the episode. + """ + valid_at: typing.Optional[str] = pydantic.Field(default=None) """ The time the episode's content became true or was observed, used for diff --git a/src/zep_cloud/types/episode_content_policy.py b/src/zep_cloud/types/episode_content_policy.py new file mode 100644 index 00000000..32471791 --- /dev/null +++ b/src/zep_cloud/types/episode_content_policy.py @@ -0,0 +1,51 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .episode_content_policy_status import EpisodeContentPolicyStatus + + +class EpisodeContentPolicy(UniversalBaseModel): + category_keys: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + The keys of the categories with a matched rule. + """ + + dropped_count: typing.Optional[int] = pydantic.Field(default=None) + """ + The number of derived candidates that were dropped. + """ + + retained_count: typing.Optional[int] = pydantic.Field(default=None) + """ + The number of derived candidates that were published to the graph. + """ + + revision: typing.Optional[int] = pydantic.Field(default=None) + """ + The project revision number of the policy the graph bound. + """ + + status: typing.Optional[EpisodeContentPolicyStatus] = pydantic.Field(default=None) + """ + The evaluation status. pending means the evaluation has not finished, + complete means every candidate was evaluated and the graph batch was + written, and failed means ingestion retries were exhausted. + """ + + violated: typing.Optional[bool] = pydantic.Field(default=None) + """ + Whether at least one derived candidate matched a rule. Once true, it + stays true. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/episode_content_policy_status.py b/src/zep_cloud/types/episode_content_policy_status.py new file mode 100644 index 00000000..19aa06f9 --- /dev/null +++ b/src/zep_cloud/types/episode_content_policy_status.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +EpisodeContentPolicyStatus = typing.Union[typing.Literal["pending", "complete", "failed"], typing.Any] diff --git a/src/zep_cloud/types/episode_debug_log.py b/src/zep_cloud/types/episode_debug_log.py new file mode 100644 index 00000000..9e584393 --- /dev/null +++ b/src/zep_cloud/types/episode_debug_log.py @@ -0,0 +1,44 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .debug_log_entry import DebugLogEntry +from .debug_log_status import DebugLogStatus + + +class EpisodeDebugLog(UniversalBaseModel): + completed_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the ingestion workflow completed, present only after completion. + """ + + entries: typing.Optional[typing.List[DebugLogEntry]] = pydantic.Field(default=None) + """ + The log entries, oldest first. + """ + + error: typing.Optional[str] = pydantic.Field(default=None) + """ + The error message, present only when the status is error. + """ + + started_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the ingestion workflow started. + """ + + status: typing.Optional[DebugLogStatus] = pydantic.Field(default=None) + """ + The state of the ingestion workflow. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/graph.py b/src/zep_cloud/types/graph.py index 78a2321e..a939d525 100644 --- a/src/zep_cloud/types/graph.py +++ b/src/zep_cloud/types/graph.py @@ -57,6 +57,9 @@ class Graph(UniversalBaseModel): FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid", description="The unique identifier of the graph."), ] = None + """ + The unique identifier of the graph. + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/zep_cloud/types/graph_content_policy.py b/src/zep_cloud/types/graph_content_policy.py new file mode 100644 index 00000000..7ae2b2ba --- /dev/null +++ b/src/zep_cloud/types/graph_content_policy.py @@ -0,0 +1,65 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .content_policy_category import ContentPolicyCategory +from .content_policy_rule import ContentPolicyRule + + +class GraphContentPolicy(UniversalBaseModel): + bound_at: typing.Optional[str] = pydantic.Field(default=None) + """ + When the graph bound the policy. + """ + + categories: typing.Optional[typing.List[ContentPolicyCategory]] = pydantic.Field(default=None) + """ + The categories of the policy. + """ + + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + When this policy set was created. + """ + + project_revision: typing.Optional[int] = pydantic.Field(default=None) + """ + The project revision number this graph bound at creation. It always + equals revision. + """ + + revision: typing.Optional[int] = pydantic.Field(default=None) + """ + The project revision number. 0 is the empty policy of a new project. + """ + + rules: typing.Optional[typing.List[ContentPolicyRule]] = pydantic.Field(default=None) + """ + The rules of the policy. + """ + + uuid_: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field( + alias="uuid", + description="The identifier of this policy set. A project revision and every graph\nthat binds it without additions share one uuid.", + ), + ] = None + """ + The identifier of this policy set. A project revision and every graph + that binds it without additions share one uuid. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/graph_content_policy_request.py b/src/zep_cloud/types/graph_content_policy_request.py new file mode 100644 index 00000000..6bde3587 --- /dev/null +++ b/src/zep_cloud/types/graph_content_policy_request.py @@ -0,0 +1,37 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .content_policy_category_request import ContentPolicyCategoryRequest +from .content_policy_rule_request import ContentPolicyRuleRequest + + +class GraphContentPolicyRequest(UniversalBaseModel): + categories: typing.Optional[typing.List[ContentPolicyCategoryRequest]] = pydantic.Field(default=None) + """ + Categories to add for this graph. A key that the project policy already + has is ignored. + """ + + project_revision: typing.Optional[int] = pydantic.Field(default=None) + """ + When set, the create fails with content_policy_revision_stale unless this + is the current project revision. + """ + + rules: typing.Optional[typing.List[ContentPolicyRuleRequest]] = pydantic.Field(default=None) + """ + Rules to add for this graph. A rule that the project policy already has, + with the same category key and description, is ignored. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/graph_context_response.py b/src/zep_cloud/types/graph_context_response.py index 1a66ccf0..36ed982d 100644 --- a/src/zep_cloud/types/graph_context_response.py +++ b/src/zep_cloud/types/graph_context_response.py @@ -10,14 +10,15 @@ class GraphContextResponse(UniversalBaseModel): context: typing.Optional[str] = pydantic.Field(default=None) """ - The assembled context block of facts, entities, and episodes, ready to - insert into a system prompt. + The assembled context block of facts, entities, observations, and thread + summaries. Pass it through the model provider's untrusted-data channel. """ results: typing.Optional[ContextResults] = pydantic.Field(default=None) """ The individual edges, nodes, episodes, observations, and thread summaries - selected to build the context. Present only when requested. + selected to build the context. Episodes are always empty because context + assembly does not select episodes. Present only when requested. """ truncated: typing.Optional[bool] = pydantic.Field(default=None) diff --git a/src/zep_cloud/types/graphiti_metadata_filter_group_type.py b/src/zep_cloud/types/graphiti_metadata_filter_group_type.py deleted file mode 100644 index c788e943..00000000 --- a/src/zep_cloud/types/graphiti_metadata_filter_group_type.py +++ /dev/null @@ -1,5 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -GraphitiMetadataFilterGroupType = typing.Union[typing.Literal["and", "or"], typing.Any] diff --git a/src/zep_cloud/types/hyperedge.py b/src/zep_cloud/types/hyperedge.py new file mode 100644 index 00000000..781d817e --- /dev/null +++ b/src/zep_cloud/types/hyperedge.py @@ -0,0 +1,66 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .hyperedge_edge import HyperedgeEdge + + +class Hyperedge(UniversalBaseModel): + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the hyperedge was created. Every member edge shares this value. + """ + + edges: typing.Optional[typing.List[HyperedgeEdge]] = pydantic.Field(default=None) + """ + The member edges, ordered by uuid. Each carries only its own identity and + endpoints; the shared fact and timestamps are on the hyperedge. + """ + + expired_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the fact was superseded or removed. + """ + + fact: typing.Optional[str] = pydantic.Field(default=None) + """ + The natural-language fact this hyperedge represents. Every member edge + carries the same fact. + """ + + graph_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier of the graph this hyperedge belongs to. + """ + + invalid_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time at which the fact stopped being true. + """ + + uuid_: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="The unique identifier of the hyperedge."), + ] = None + """ + The unique identifier of the hyperedge. + """ + + valid_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time from which the fact is considered true. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/hyperedge_edge.py b/src/zep_cloud/types/hyperedge_edge.py new file mode 100644 index 00000000..2f0305f9 --- /dev/null +++ b/src/zep_cloud/types/hyperedge_edge.py @@ -0,0 +1,43 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata + + +class HyperedgeEdge(UniversalBaseModel): + name: typing.Optional[str] = pydantic.Field(default=None) + """ + The name of the member edge, in upper snake case, for example FOUNDED. + """ + + source_node_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier of the member edge's source node. + """ + + target_node_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier of the member edge's target node. + """ + + uuid_: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="The unique identifier of the member edge."), + ] = None + """ + The unique identifier of the member edge. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/hyperedge_input.py b/src/zep_cloud/types/hyperedge_input.py new file mode 100644 index 00000000..e36d9744 --- /dev/null +++ b/src/zep_cloud/types/hyperedge_input.py @@ -0,0 +1,35 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .edge_node_ref import EdgeNodeRef + + +class HyperedgeInput(UniversalBaseModel): + name: str = pydantic.Field() + """ + The name of the member edge, in upper snake case, for example FOUNDED. + """ + + source_node: EdgeNodeRef = pydantic.Field() + """ + The source node of this member, referenced by uuid or created or matched + by name. + """ + + target_node: EdgeNodeRef = pydantic.Field() + """ + The target node of this member, referenced by uuid or created or matched + by name. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/hyperedge_page.py b/src/zep_cloud/types/hyperedge_page.py new file mode 100644 index 00000000..3b7815da --- /dev/null +++ b/src/zep_cloud/types/hyperedge_page.py @@ -0,0 +1,21 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .hyperedge import Hyperedge + + +class HyperedgePage(UniversalBaseModel): + items: typing.Optional[typing.List[Hyperedge]] = None + next_cursor: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/imported_trajectory_reference.py b/src/zep_cloud/types/imported_trajectory_reference.py new file mode 100644 index 00000000..7b3d5bba --- /dev/null +++ b/src/zep_cloud/types/imported_trajectory_reference.py @@ -0,0 +1,32 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class ImportedTrajectoryReference(UniversalBaseModel): + agent_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + AgentUUID is the visible Agent identifier. + """ + + import_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + ImportUUID is the active import owner identifier. + """ + + trajectory_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + TrajectoryUUID is the imported Trajectory identifier. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/ingestion_trace.py b/src/zep_cloud/types/ingestion_trace.py new file mode 100644 index 00000000..89520530 --- /dev/null +++ b/src/zep_cloud/types/ingestion_trace.py @@ -0,0 +1,62 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .ingestion_trace_input import IngestionTraceInput +from .ingestion_trace_output import IngestionTraceOutput +from .ingestion_trace_status import IngestionTraceStatus +from .ingestion_trace_step import IngestionTraceStep + + +class IngestionTrace(UniversalBaseModel): + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the trace was recorded. + """ + + error: typing.Optional[str] = pydantic.Field(default=None) + """ + The error message, present only when the status is failed. + """ + + input: typing.Optional[IngestionTraceInput] = pydantic.Field(default=None) + """ + The input of the step. + """ + + output: typing.Optional[IngestionTraceOutput] = pydantic.Field(default=None) + """ + The output of the step, with an explanation on each entry that has one. + """ + + status: typing.Optional[IngestionTraceStatus] = pydantic.Field(default=None) + """ + Tells if the explanations of the step were recorded. + """ + + step: typing.Optional[IngestionTraceStep] = pydantic.Field(default=None) + """ + The ingestion step that the trace records. + """ + + uuid_: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="The unique identifier of the trace."), + ] = None + """ + The unique identifier of the trace. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/ingestion_trace_edge.py b/src/zep_cloud/types/ingestion_trace_edge.py new file mode 100644 index 00000000..bda1c1cf --- /dev/null +++ b/src/zep_cloud/types/ingestion_trace_edge.py @@ -0,0 +1,84 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata + + +class IngestionTraceEdge(UniversalBaseModel): + attributes: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Additional attributes of the edge, as defined by its edge type. + """ + + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the edge was created. + """ + + episode_uuids: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + The episodes that the edge was derived from. + """ + + expired_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the edge was superseded. + """ + + explanation: typing.Optional[str] = pydantic.Field(default=None) + """ + The explanation of the decision of the step for this edge. Present only + on output entries that have an explanation. + """ + + fact: typing.Optional[str] = pydantic.Field(default=None) + """ + The natural-language fact that the edge represents. + """ + + invalid_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time at which the fact stopped being true. + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + The name of the edge, in upper snake case. + """ + + source_node_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier of the source node of the edge. + """ + + target_node_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier of the target node of the edge. + """ + + uuid_: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="The unique identifier of the edge."), + ] = None + """ + The unique identifier of the edge. + """ + + valid_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time from which the fact is true. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/ingestion_trace_edge_invalidation.py b/src/zep_cloud/types/ingestion_trace_edge_invalidation.py new file mode 100644 index 00000000..7350062f --- /dev/null +++ b/src/zep_cloud/types/ingestion_trace_edge_invalidation.py @@ -0,0 +1,28 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .ingestion_trace_edge_reference import IngestionTraceEdgeReference + + +class IngestionTraceEdgeInvalidation(UniversalBaseModel): + invalidated_edge_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier of the invalidated edge. + """ + + invalidating_edges: typing.Optional[typing.List[IngestionTraceEdgeReference]] = pydantic.Field(default=None) + """ + The resolved edges that invalidated the edge. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/ingestion_trace_edge_reference.py b/src/zep_cloud/types/ingestion_trace_edge_reference.py new file mode 100644 index 00000000..9e3bbb08 --- /dev/null +++ b/src/zep_cloud/types/ingestion_trace_edge_reference.py @@ -0,0 +1,33 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata + + +class IngestionTraceEdgeReference(UniversalBaseModel): + explanation: typing.Optional[str] = pydantic.Field(default=None) + """ + The explanation of the decision, when the step recorded one. + """ + + uuid_: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="The unique identifier of the edge."), + ] = None + """ + The unique identifier of the edge. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/ingestion_trace_entity_type.py b/src/zep_cloud/types/ingestion_trace_entity_type.py new file mode 100644 index 00000000..4a141678 --- /dev/null +++ b/src/zep_cloud/types/ingestion_trace_entity_type.py @@ -0,0 +1,44 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .entity_property import EntityProperty + + +class IngestionTraceEntityType(UniversalBaseModel): + description: typing.Optional[str] = pydantic.Field(default=None) + """ + A description of the entity type, used to guide extraction. + """ + + identity_properties: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + The property names that determine whether two nodes of this type are the + same entity. + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + The name of the entity type. + """ + + parent: typing.Optional[str] = pydantic.Field(default=None) + """ + The name of the parent entity type. Absent for a top-level type. + """ + + properties: typing.Optional[typing.List[EntityProperty]] = pydantic.Field(default=None) + """ + The custom properties defined on nodes of this type. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/ingestion_trace_episode.py b/src/zep_cloud/types/ingestion_trace_episode.py new file mode 100644 index 00000000..63b6ee22 --- /dev/null +++ b/src/zep_cloud/types/ingestion_trace_episode.py @@ -0,0 +1,43 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata + + +class IngestionTraceEpisode(UniversalBaseModel): + content: typing.Optional[str] = pydantic.Field(default=None) + """ + The content of the episode. + """ + + source: typing.Optional[str] = pydantic.Field(default=None) + """ + The source type of the episode, for example message, text, or json. + """ + + uuid_: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="The unique identifier of the episode."), + ] = None + """ + The unique identifier of the episode. + """ + + valid_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time at which the episode occurred. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/ingestion_trace_input.py b/src/zep_cloud/types/ingestion_trace_input.py new file mode 100644 index 00000000..77b37e71 --- /dev/null +++ b/src/zep_cloud/types/ingestion_trace_input.py @@ -0,0 +1,89 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .edge_type import EdgeType +from .ingestion_trace_edge import IngestionTraceEdge +from .ingestion_trace_entity_type import IngestionTraceEntityType +from .ingestion_trace_episode import IngestionTraceEpisode +from .ingestion_trace_node import IngestionTraceNode + + +class IngestionTraceInput(UniversalBaseModel): + candidate_edges: typing.Optional[typing.List[IngestionTraceEdge]] = pydantic.Field(default=None) + """ + The existing edges that the step compared with the extracted edges. + Present for resolve_edges and empty for + the other steps. + """ + + candidate_nodes: typing.Optional[typing.List[IngestionTraceNode]] = pydantic.Field(default=None) + """ + The existing nodes that the step compared with the extracted nodes. + Present for resolve_nodes and empty for + the other steps. + """ + + custom_instructions: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + The custom extraction instructions in effect for the episode. + """ + + edge_types: typing.Optional[typing.List[EdgeType]] = pydantic.Field(default=None) + """ + The custom edge types in effect for the episode. + """ + + entity_types: typing.Optional[typing.List[IngestionTraceEntityType]] = pydantic.Field(default=None) + """ + The custom entity types in effect for the episode. + """ + + episode_content: typing.Optional[str] = pydantic.Field(default=None) + """ + The content of the episode that the step processed. + """ + + episodes: typing.Optional[typing.List[IngestionTraceEpisode]] = pydantic.Field(default=None) + """ + The episodes that the step processed together. + """ + + extracted_edges: typing.Optional[typing.List[IngestionTraceEdge]] = pydantic.Field(default=None) + """ + The extracted edges that the step resolved. Present for resolve_edges and empty for + the other steps. + """ + + extracted_nodes: typing.Optional[typing.List[IngestionTraceNode]] = pydantic.Field(default=None) + """ + The extracted nodes that the step resolved. Present for resolve_nodes and empty for + the other steps. + """ + + ignore_default_ontology: typing.Optional[bool] = pydantic.Field(default=None) + """ + Tells if the default ontology was ignored. + """ + + previous_episodes: typing.Optional[typing.List[IngestionTraceEpisode]] = pydantic.Field(default=None) + """ + The previous episodes that the step used as context. + """ + + resolved_nodes: typing.Optional[typing.List[IngestionTraceNode]] = pydantic.Field(default=None) + """ + The resolved nodes that the extracted edges connect. Present for resolve_edges and empty for + the other steps. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/ingestion_trace_node.py b/src/zep_cloud/types/ingestion_trace_node.py new file mode 100644 index 00000000..82f912f8 --- /dev/null +++ b/src/zep_cloud/types/ingestion_trace_node.py @@ -0,0 +1,65 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata + + +class IngestionTraceNode(UniversalBaseModel): + attributes: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Additional attributes of the node, as defined by its entity type. + """ + + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + The time the node was created. + """ + + episode_indexes: typing.Optional[typing.List[int]] = pydantic.Field(default=None) + """ + The positions in the input episodes of the episodes that the node was + extracted from. Present on the extracted nodes of combined_extraction. + """ + + explanation: typing.Optional[str] = pydantic.Field(default=None) + """ + The explanation of the decision of the step for this node. Present only + on output entries that have an explanation. + """ + + labels: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + The entity type labels of the node. + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + The name of the entity that the node represents. + """ + + summary: typing.Optional[str] = pydantic.Field(default=None) + """ + The summary of the entity that the node represents. + """ + + uuid_: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="The unique identifier of the node."), + ] = None + """ + The unique identifier of the node. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/ingestion_trace_node_duplicate.py b/src/zep_cloud/types/ingestion_trace_node_duplicate.py new file mode 100644 index 00000000..cb593499 --- /dev/null +++ b/src/zep_cloud/types/ingestion_trace_node_duplicate.py @@ -0,0 +1,28 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .ingestion_trace_node import IngestionTraceNode + + +class IngestionTraceNodeDuplicate(UniversalBaseModel): + existing_node: typing.Optional[IngestionTraceNode] = pydantic.Field(default=None) + """ + The existing node that the extracted node duplicates. + """ + + extracted_node: typing.Optional[IngestionTraceNode] = pydantic.Field(default=None) + """ + The extracted node. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/ingestion_trace_node_resolution.py b/src/zep_cloud/types/ingestion_trace_node_resolution.py new file mode 100644 index 00000000..84c7b28e --- /dev/null +++ b/src/zep_cloud/types/ingestion_trace_node_resolution.py @@ -0,0 +1,32 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class IngestionTraceNodeResolution(UniversalBaseModel): + explanation: typing.Optional[str] = pydantic.Field(default=None) + """ + The explanation of the decision, when the step recorded one. + """ + + extracted_node_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier of the extracted node. + """ + + resolved_node_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier of the resolved node. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/ingestion_trace_output.py b/src/zep_cloud/types/ingestion_trace_output.py new file mode 100644 index 00000000..4cedc27c --- /dev/null +++ b/src/zep_cloud/types/ingestion_trace_output.py @@ -0,0 +1,71 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .ingestion_trace_edge import IngestionTraceEdge +from .ingestion_trace_edge_invalidation import IngestionTraceEdgeInvalidation +from .ingestion_trace_node import IngestionTraceNode +from .ingestion_trace_node_duplicate import IngestionTraceNodeDuplicate +from .ingestion_trace_node_resolution import IngestionTraceNodeResolution + + +class IngestionTraceOutput(UniversalBaseModel): + edge_invalidations: typing.Optional[typing.List[IngestionTraceEdgeInvalidation]] = pydantic.Field(default=None) + """ + The existing edges that the resolved edges invalidated. Present for resolve_edges and empty for + the other steps. + """ + + edges: typing.Optional[typing.List[IngestionTraceEdge]] = pydantic.Field(default=None) + """ + The resolved edges. Present for resolve_edges and empty for + the other steps. + """ + + extracted_edges: typing.Optional[typing.List[IngestionTraceEdge]] = pydantic.Field(default=None) + """ + The edges that the step extracted. Present for combined_extraction and + empty for the other steps. + """ + + extracted_nodes: typing.Optional[typing.List[IngestionTraceNode]] = pydantic.Field(default=None) + """ + The nodes that the step extracted. Present for combined_extraction and + empty for the other steps. + """ + + new_edges: typing.Optional[typing.List[IngestionTraceEdge]] = pydantic.Field(default=None) + """ + The resolved edges that are new to the graph. Present for resolve_edges and empty for + the other steps. + """ + + node_duplicates: typing.Optional[typing.List[IngestionTraceNodeDuplicate]] = pydantic.Field(default=None) + """ + The extracted nodes that the step found to be duplicates of existing + nodes. Present for resolve_nodes and empty for + the other steps. + """ + + node_resolutions: typing.Optional[typing.List[IngestionTraceNodeResolution]] = pydantic.Field(default=None) + """ + The resolved node of each extracted node. Present for resolve_nodes and empty for + the other steps. + """ + + nodes: typing.Optional[typing.List[IngestionTraceNode]] = pydantic.Field(default=None) + """ + The resolved nodes. Present for resolve_nodes and empty for + the other steps. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/ingestion_trace_page.py b/src/zep_cloud/types/ingestion_trace_page.py new file mode 100644 index 00000000..d6ee3fb2 --- /dev/null +++ b/src/zep_cloud/types/ingestion_trace_page.py @@ -0,0 +1,29 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .ingestion_trace import IngestionTrace + + +class IngestionTracePage(UniversalBaseModel): + items: typing.Optional[typing.List[IngestionTrace]] = pydantic.Field(default=None) + """ + The ingestion traces on this page. + """ + + next_cursor: typing.Optional[str] = pydantic.Field(default=None) + """ + The cursor to pass as the next request's cursor to fetch the following + page; absent when no further pages remain. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/ingestion_trace_status.py b/src/zep_cloud/types/ingestion_trace_status.py new file mode 100644 index 00000000..8409b248 --- /dev/null +++ b/src/zep_cloud/types/ingestion_trace_status.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +IngestionTraceStatus = typing.Union[typing.Literal["recorded", "failed"], typing.Any] diff --git a/src/zep_cloud/types/ingestion_trace_step.py b/src/zep_cloud/types/ingestion_trace_step.py new file mode 100644 index 00000000..5d854e6f --- /dev/null +++ b/src/zep_cloud/types/ingestion_trace_step.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +IngestionTraceStep = typing.Union[typing.Literal["combined_extraction", "resolve_nodes", "resolve_edges"], typing.Any] diff --git a/src/zep_cloud/types/lookup_item.py b/src/zep_cloud/types/lookup_item.py index cb642343..8606ed81 100644 --- a/src/zep_cloud/types/lookup_item.py +++ b/src/zep_cloud/types/lookup_item.py @@ -29,6 +29,9 @@ class LookupItem(UniversalBaseModel): FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid", description="The resource's unique identifier; present only when found is true."), ] = None + """ + The resource's unique identifier; present only when found is true. + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/zep_cloud/types/message.py b/src/zep_cloud/types/message.py index 92ff273a..04f70bfc 100644 --- a/src/zep_cloud/types/message.py +++ b/src/zep_cloud/types/message.py @@ -52,6 +52,9 @@ class Message(UniversalBaseModel): FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid", description="The unique identifier of the message."), ] = None + """ + The unique identifier of the message. + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/zep_cloud/types/metadata_filter.py b/src/zep_cloud/types/metadata_filter.py new file mode 100644 index 00000000..a6611e6e --- /dev/null +++ b/src/zep_cloud/types/metadata_filter.py @@ -0,0 +1,34 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .metadata_filter_operator import MetadataFilterOperator +from .metadata_filter_value import MetadataFilterValue + + +class MetadataFilter(UniversalBaseModel): + operator: typing.Optional[MetadataFilterOperator] = pydantic.Field(default=None) + """ + The lowercase comparison operator. + """ + + property_name: typing.Optional[str] = pydantic.Field(default=None) + """ + The metadata property name to compare. + """ + + value: typing.Optional[MetadataFilterValue] = pydantic.Field(default=None) + """ + The comparison value. Use an array for in, a non-empty string for contains, and omit the field for null operators. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/metadata_filter_group.py b/src/zep_cloud/types/metadata_filter_group.py index 4c662e35..3a232d31 100644 --- a/src/zep_cloud/types/metadata_filter_group.py +++ b/src/zep_cloud/types/metadata_filter_group.py @@ -6,24 +6,24 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel, update_forward_refs -from .episode_metadata_filter import EpisodeMetadataFilter -from .graphiti_metadata_filter_group_type import GraphitiMetadataFilterGroupType +from .metadata_filter import MetadataFilter +from .metadata_filter_group_type import MetadataFilterGroupType class MetadataFilterGroup(UniversalBaseModel): - filters: typing.Optional[typing.List[EpisodeMetadataFilter]] = pydantic.Field(default=None) + filters: typing.Optional[typing.List[MetadataFilter]] = pydantic.Field(default=None) """ - Leaf filters (predicates on metadata key-value pairs) + The metadata predicates in this group. """ groups: typing.Optional[typing.List["MetadataFilterGroup"]] = pydantic.Field(default=None) """ - Nested sub-groups for composing complex boolean expressions + The nested metadata groups in this group. """ - type: GraphitiMetadataFilterGroupType = pydantic.Field() + type: typing.Optional[MetadataFilterGroupType] = pydantic.Field(default=None) """ - Logical operator: "and" or "or" + The logical operator for this group. """ if IS_PYDANTIC_V2: diff --git a/src/zep_cloud/types/metadata_filter_group_type.py b/src/zep_cloud/types/metadata_filter_group_type.py new file mode 100644 index 00000000..ddf1b594 --- /dev/null +++ b/src/zep_cloud/types/metadata_filter_group_type.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +MetadataFilterGroupType = typing.Union[typing.Literal["and", "or"], typing.Any] diff --git a/src/zep_cloud/types/metadata_filter_operator.py b/src/zep_cloud/types/metadata_filter_operator.py new file mode 100644 index 00000000..c24bc28f --- /dev/null +++ b/src/zep_cloud/types/metadata_filter_operator.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +MetadataFilterOperator = typing.Union[ + typing.Literal["eq", "ne", "gt", "lt", "gte", "lte", "in", "contains", "is_null", "is_not_null"], typing.Any +] diff --git a/src/zep_cloud/types/metadata_filter_value.py b/src/zep_cloud/types/metadata_filter_value.py new file mode 100644 index 00000000..9a537732 --- /dev/null +++ b/src/zep_cloud/types/metadata_filter_value.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from .metadata_filter_value_three_item import MetadataFilterValueThreeItem + +MetadataFilterValue = typing.Union[str, float, bool, typing.List[MetadataFilterValueThreeItem]] diff --git a/src/zep_cloud/types/metadata_filter_value_three_item.py b/src/zep_cloud/types/metadata_filter_value_three_item.py new file mode 100644 index 00000000..7027653a --- /dev/null +++ b/src/zep_cloud/types/metadata_filter_value_three_item.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +MetadataFilterValueThreeItem = typing.Union[str, float, bool] diff --git a/src/zep_cloud/types/node.py b/src/zep_cloud/types/node.py index ca63fc56..f2dba08f 100644 --- a/src/zep_cloud/types/node.py +++ b/src/zep_cloud/types/node.py @@ -19,6 +19,27 @@ class Node(UniversalBaseModel): The time the node was created. """ + degree: typing.Optional[int] = pydantic.Field(default=None) + """ + The count of live entity edges that touch this node, in both directions. + Present only when the list request orders by `degree`. + """ + + episode_uuids: typing.List[str] = pydantic.Field() + """ + The UUIDs of the live episodes that mention this node, newest first. The + list is complete when `episode_uuids_truncated` is false. The list holds + the newest 100 when the node has more than 100 source episodes; list + episodes with the `mentioned_node_uuids` filter to read them all. + """ + + episode_uuids_truncated: bool = pydantic.Field() + """ + True when the node has more than 100 source episodes, so `episode_uuids` + holds only the newest 100, or when provenance is unavailable. False means + `episode_uuids` is the complete set. + """ + graph_uuid: typing.Optional[str] = pydantic.Field(default=None) """ The unique identifier of the graph this node belongs to. @@ -57,6 +78,9 @@ class Node(UniversalBaseModel): FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid", description="The node UUID, assigned by Zep."), ] = None + """ + The node UUID, assigned by Zep. + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/zep_cloud/types/objective_mapping_rule.py b/src/zep_cloud/types/objective_mapping_rule.py new file mode 100644 index 00000000..0cd8dc3f --- /dev/null +++ b/src/zep_cloud/types/objective_mapping_rule.py @@ -0,0 +1,28 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .objective_mapping_rule_source import ObjectiveMappingRuleSource + + +class ObjectiveMappingRule(UniversalBaseModel): + key: typing.Optional[str] = pydantic.Field(default=None) + """ + Key is the root metadata key to read. + """ + + source: typing.Optional[ObjectiveMappingRuleSource] = pydantic.Field(default=None) + """ + Source selects the objective source. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/objective_mapping_rule_source.py b/src/zep_cloud/types/objective_mapping_rule_source.py new file mode 100644 index 00000000..07a8997a --- /dev/null +++ b/src/zep_cloud/types/objective_mapping_rule_source.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +ObjectiveMappingRuleSource = typing.Union[typing.Literal["first_user_message", "root_input", "metadata"], typing.Any] diff --git a/src/zep_cloud/types/observation.py b/src/zep_cloud/types/observation.py index 052a268b..9ccd587a 100644 --- a/src/zep_cloud/types/observation.py +++ b/src/zep_cloud/types/observation.py @@ -62,6 +62,9 @@ class Observation(UniversalBaseModel): FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid", description="The unique identifier of the observation, assigned by Zep."), ] = None + """ + The unique identifier of the observation, assigned by Zep. + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/zep_cloud/types/ontology.py b/src/zep_cloud/types/ontology.py index 385f5723..d85f12e9 100644 --- a/src/zep_cloud/types/ontology.py +++ b/src/zep_cloud/types/ontology.py @@ -14,6 +14,11 @@ class Ontology(UniversalBaseModel): The edge types defined in the ontology in effect at this scope. """ + entity_type_hierarchy: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + The entity type hierarchy (spec ontology-1). Omitted when the ontology is flat. + """ + entity_types: typing.Optional[typing.List[EntityType]] = pydantic.Field(default=None) """ The entity types defined in the ontology in effect at this scope. diff --git a/src/zep_cloud/types/outcome_mapping_rule.py b/src/zep_cloud/types/outcome_mapping_rule.py new file mode 100644 index 00000000..26fbc89a --- /dev/null +++ b/src/zep_cloud/types/outcome_mapping_rule.py @@ -0,0 +1,48 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .outcome_mapping_rule_rule import OutcomeMappingRuleRule + + +class OutcomeMappingRule(UniversalBaseModel): + failed_below: typing.Optional[float] = pydantic.Field(default=None) + """ + FailedBelow is the optional score threshold for failure. + """ + + key: typing.Optional[str] = pydantic.Field(default=None) + """ + Key is the metadata key for a metadata rule. + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + Name is the score name for a score rule. + """ + + rule: typing.Optional[OutcomeMappingRuleRule] = pydantic.Field(default=None) + """ + Rule is the outcome mapping rule type. + """ + + succeeded_at_or_above: typing.Optional[float] = pydantic.Field(default=None) + """ + SucceededAtOrAbove is the score threshold for success. + """ + + values: typing.Optional[typing.Dict[str, str]] = pydantic.Field(default=None) + """ + Values maps metadata strings to Trajectory outcomes. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/outcome_mapping_rule_rule.py b/src/zep_cloud/types/outcome_mapping_rule_rule.py new file mode 100644 index 00000000..077e8b79 --- /dev/null +++ b/src/zep_cloud/types/outcome_mapping_rule_rule.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +OutcomeMappingRuleRule = typing.Union[typing.Literal["score", "metadata", "error"], typing.Any] diff --git a/src/zep_cloud/types/pagev4agent_skill_candidate_review_summary.py b/src/zep_cloud/types/pagev4agent_skill_candidate_review_summary.py new file mode 100644 index 00000000..1a6dcbc5 --- /dev/null +++ b/src/zep_cloud/types/pagev4agent_skill_candidate_review_summary.py @@ -0,0 +1,22 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .agent_skill_candidate_review_summary import AgentSkillCandidateReviewSummary + + +class Pagev4AgentSkillCandidateReviewSummary(UniversalBaseModel): + items: typing.Optional[typing.List[AgentSkillCandidateReviewSummary]] = None + next_cursor: typing.Optional[str] = None + total_size: typing.Optional[int] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/pagev4agent_skill_compilation_outcome.py b/src/zep_cloud/types/pagev4agent_skill_compilation_outcome.py new file mode 100644 index 00000000..9493e5a8 --- /dev/null +++ b/src/zep_cloud/types/pagev4agent_skill_compilation_outcome.py @@ -0,0 +1,22 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .agent_skill_compilation_outcome import AgentSkillCompilationOutcome + + +class Pagev4AgentSkillCompilationOutcome(UniversalBaseModel): + items: typing.Optional[typing.List[AgentSkillCompilationOutcome]] = None + next_cursor: typing.Optional[str] = None + total_size: typing.Optional[int] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/pagev4agent_skill_evidence.py b/src/zep_cloud/types/pagev4agent_skill_evidence.py new file mode 100644 index 00000000..fd08096b --- /dev/null +++ b/src/zep_cloud/types/pagev4agent_skill_evidence.py @@ -0,0 +1,22 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .agent_skill_evidence import AgentSkillEvidence + + +class Pagev4AgentSkillEvidence(UniversalBaseModel): + items: typing.Optional[typing.List[AgentSkillEvidence]] = None + next_cursor: typing.Optional[str] = None + total_size: typing.Optional[int] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/pagev4agent_skill_relationship.py b/src/zep_cloud/types/pagev4agent_skill_relationship.py new file mode 100644 index 00000000..7705742e --- /dev/null +++ b/src/zep_cloud/types/pagev4agent_skill_relationship.py @@ -0,0 +1,22 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .agent_skill_relationship import AgentSkillRelationship + + +class Pagev4AgentSkillRelationship(UniversalBaseModel): + items: typing.Optional[typing.List[AgentSkillRelationship]] = None + next_cursor: typing.Optional[str] = None + total_size: typing.Optional[int] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/pagev4agent_skill_search_hit.py b/src/zep_cloud/types/pagev4agent_skill_search_hit.py new file mode 100644 index 00000000..3b64f420 --- /dev/null +++ b/src/zep_cloud/types/pagev4agent_skill_search_hit.py @@ -0,0 +1,22 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .agent_skill_search_hit import AgentSkillSearchHit + + +class Pagev4AgentSkillSearchHit(UniversalBaseModel): + items: typing.Optional[typing.List[AgentSkillSearchHit]] = None + next_cursor: typing.Optional[str] = None + total_size: typing.Optional[int] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/pagev4agent_skill_version.py b/src/zep_cloud/types/pagev4agent_skill_version.py new file mode 100644 index 00000000..4a2ce802 --- /dev/null +++ b/src/zep_cloud/types/pagev4agent_skill_version.py @@ -0,0 +1,22 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .agent_skill_version import AgentSkillVersion + + +class Pagev4AgentSkillVersion(UniversalBaseModel): + items: typing.Optional[typing.List[AgentSkillVersion]] = None + next_cursor: typing.Optional[str] = None + total_size: typing.Optional[int] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/pagev4agent_verifier.py b/src/zep_cloud/types/pagev4agent_verifier.py new file mode 100644 index 00000000..7eb6d06e --- /dev/null +++ b/src/zep_cloud/types/pagev4agent_verifier.py @@ -0,0 +1,22 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .agent_verifier import AgentVerifier + + +class Pagev4AgentVerifier(UniversalBaseModel): + items: typing.Optional[typing.List[AgentVerifier]] = None + next_cursor: typing.Optional[str] = None + total_size: typing.Optional[int] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/project.py b/src/zep_cloud/types/project.py index 44720fa8..09a2e2b3 100644 --- a/src/zep_cloud/types/project.py +++ b/src/zep_cloud/types/project.py @@ -25,6 +25,12 @@ class Project(UniversalBaseModel): A human-readable description of the project. """ + include_policy_violating_episodes: typing.Optional[bool] = pydantic.Field(default=None) + """ + When true, episode reads on graphs with a content policy include the + episodes that violated the policy. The default is false. + """ + name: typing.Optional[str] = pydantic.Field(default=None) """ The name of the project. @@ -35,6 +41,9 @@ class Project(UniversalBaseModel): FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid", description="The unique identifier of the project."), ] = None + """ + The unique identifier of the project. + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/zep_cloud/types/property_filter.py b/src/zep_cloud/types/property_filter.py index 48420e85..095f6ebb 100644 --- a/src/zep_cloud/types/property_filter.py +++ b/src/zep_cloud/types/property_filter.py @@ -4,25 +4,24 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -from .comparison_operator import ComparisonOperator +from .property_filter_operator import PropertyFilterOperator +from .property_filter_value import PropertyFilterValue class PropertyFilter(UniversalBaseModel): - comparison_operator: ComparisonOperator = pydantic.Field() + operator: typing.Optional[PropertyFilterOperator] = pydantic.Field(default=None) """ - Comparison operator for property filter + The lowercase comparison operator. """ - property_name: str = pydantic.Field() + property_name: typing.Optional[str] = pydantic.Field(default=None) """ - Property name to filter on + The property name to compare. """ - property_value: typing.Optional[typing.Any] = pydantic.Field(default=None) + value: typing.Optional[PropertyFilterValue] = pydantic.Field(default=None) """ - Property value to match on. Accepted types: string, int, float64, bool, or nil. - Invalid types (e.g., arrays, objects) will be rejected by validation. - Must be non-nil for non-null operators (`=`, `<>`, `>`, `<`, `>=`, `<=`). + The comparison value. Use an array for in. Its string members must be non-empty, contain no comma, and have no surrounding whitespace. """ if IS_PYDANTIC_V2: diff --git a/src/zep_cloud/types/property_filter_operator.py b/src/zep_cloud/types/property_filter_operator.py new file mode 100644 index 00000000..f31acec2 --- /dev/null +++ b/src/zep_cloud/types/property_filter_operator.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +PropertyFilterOperator = typing.Union[ + typing.Literal["eq", "ne", "gt", "lt", "gte", "lte", "in", "is_null", "is_not_null"], typing.Any +] diff --git a/src/zep_cloud/types/property_filter_value.py b/src/zep_cloud/types/property_filter_value.py new file mode 100644 index 00000000..6988f90f --- /dev/null +++ b/src/zep_cloud/types/property_filter_value.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from .property_filter_value_three_item import PropertyFilterValueThreeItem + +PropertyFilterValue = typing.Union[str, float, bool, typing.List[PropertyFilterValueThreeItem]] diff --git a/src/zep_cloud/types/property_filter_value_three_item.py b/src/zep_cloud/types/property_filter_value_three_item.py new file mode 100644 index 00000000..d5ab2b22 --- /dev/null +++ b/src/zep_cloud/types/property_filter_value_three_item.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +PropertyFilterValueThreeItem = typing.Union[str, float, bool] diff --git a/src/zep_cloud/types/search_filters.py b/src/zep_cloud/types/search_filters.py index 38263d69..f3f82d08 100644 --- a/src/zep_cloud/types/search_filters.py +++ b/src/zep_cloud/types/search_filters.py @@ -6,110 +6,74 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel, update_forward_refs -from .date_filter import DateFilter +from .date_filters import DateFilters from .property_filter import PropertyFilter class SearchFilters(UniversalBaseModel): connected_node_uuids: typing.Optional[typing.List[str]] = pydantic.Field(default=None) """ - List of node UUIDs to filter edges on: an edge matches if its source OR - target node UUID is in this list. Applies to edges only; rejected on - requests whose result type contains no edges. Max 256 entries. + Include edges connected to any of these node UUIDs. """ - created_at: typing.Optional[typing.List[typing.List[DateFilter]]] = pydantic.Field(default=None) + content_policy_violated: typing.Optional[bool] = pydantic.Field(default=None) """ - 2D array of date filters for the created_at field. - The outer array elements are combined with OR logic. - The inner array elements are combined with AND logic. - Example: `[[{">", date1}, {"<", date2}], [{"=", date3}]]` - This translates to: `(created_at > date1 AND created_at < date2) OR (created_at = date3)` + Match episodes by their content-policy result. Supported only on episode search when the project setting include_policy_violating_episodes is true. """ - edge_types: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + date_filters: typing.Optional[DateFilters] = pydantic.Field(default=None) """ - List of edge types to filter on + Filter results by temporal values. """ - edge_uuids: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + edge_types: typing.Optional[typing.List[str]] = pydantic.Field(default=None) """ - List of edge UUIDs to filter on. Max 256 to align with graph-service filter limits. + Include results with any of these edge types. """ - episode_metadata_filters: typing.Optional["MetadataFilterGroup"] = pydantic.Field(default=None) + edge_uuids: typing.Optional[typing.List[str]] = pydantic.Field(default=None) """ - [Experimental] Episode metadata filter. Restricts results to edges/nodes derived from episodes - matching the metadata predicates. Uses explicit AND/OR groups. This feature is experimental and may change in future releases. + Include results with any of these edge UUIDs. """ episode_uuids: typing.Optional[typing.List[str]] = pydantic.Field(default=None) """ - List of episode UUIDs to filter on. An edge matches if it was derived - from any listed episode; a node matches if it is mentioned by any - listed episode. Valid for both edge and node result types. Max 256 - entries. + Include results derived from any of these episode UUIDs. """ exclude_edge_types: typing.Optional[typing.List[str]] = pydantic.Field(default=None) """ - List of edge types to exclude from results + Exclude results with any of these edge types. """ exclude_node_labels: typing.Optional[typing.List[str]] = pydantic.Field(default=None) """ - List of node labels to exclude from results - """ - - expired_at: typing.Optional[typing.List[typing.List[DateFilter]]] = pydantic.Field(default=None) - """ - 2D array of date filters for the expired_at field. - The outer array elements are combined with OR logic. - The inner array elements are combined with AND logic. - Example: `[[{">", date1}, {"<", date2}], [{"=", date3}]]` - This translates to: `(expired_at > date1 AND expired_at < date2) OR (expired_at = date3)` + Exclude results with any of these node labels. """ - invalid_at: typing.Optional[typing.List[typing.List[DateFilter]]] = pydantic.Field(default=None) + metadata_filters: typing.Optional["MetadataFilterGroup"] = pydantic.Field(default=None) """ - 2D array of date filters for the invalid_at field. - The outer array elements are combined with OR logic. - The inner array elements are combined with AND logic. - Example: `[[{">", date1}, {"<", date2}], [{"=", date3}]]` - This translates to: `(invalid_at > date1 AND invalid_at < date2) OR (invalid_at = date3)` + Filter results by episode metadata. """ node_labels: typing.Optional[typing.List[str]] = pydantic.Field(default=None) """ - List of node labels to filter on + Include results with any of these node labels. """ property_filters: typing.Optional[typing.List[PropertyFilter]] = pydantic.Field(default=None) """ - List of property filters to apply to nodes and edges + Filter results by node or edge properties. """ source_node_uuids: typing.Optional[typing.List[str]] = pydantic.Field(default=None) """ - List of node UUIDs to filter edges on: an edge matches if its source - node UUID is in this list. Applies to edges only; rejected on requests - whose result type contains no edges. Max 256 entries. + Include edges that start at any of these node UUIDs. """ target_node_uuids: typing.Optional[typing.List[str]] = pydantic.Field(default=None) """ - List of node UUIDs to filter edges on: an edge matches if its target - node UUID is in this list. Applies to edges only; rejected on requests - whose result type contains no edges. Max 256 entries. - """ - - valid_at: typing.Optional[typing.List[typing.List[DateFilter]]] = pydantic.Field(default=None) - """ - 2D array of date filters for the valid_at field. - The outer array elements are combined with OR logic. - The inner array elements are combined with AND logic. - Example: `[[{">", date1}, {"<", date2}], [{"=", date3}]]` - This translates to: `(valid_at > date1 AND valid_at < date2) OR (valid_at = date3)` + Include edges that end at any of these node UUIDs. """ if IS_PYDANTIC_V2: diff --git a/src/zep_cloud/types/search_request.py b/src/zep_cloud/types/search_request.py index 5a9a7b31..63831da7 100644 --- a/src/zep_cloud/types/search_request.py +++ b/src/zep_cloud/types/search_request.py @@ -7,7 +7,7 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel, update_forward_refs from .search_filters import SearchFilters -from .v4search_request_reranker import V4SearchRequestReranker +from .search_request_reranker import SearchRequestReranker class SearchRequest(UniversalBaseModel): @@ -38,7 +38,7 @@ class SearchRequest(UniversalBaseModel): The search query. """ - reranker: typing.Optional[V4SearchRequestReranker] = pydantic.Field(default=None) + reranker: typing.Optional[SearchRequestReranker] = pydantic.Field(default=None) """ The reranking strategy applied to retrieved results. Defaults to rrf. """ diff --git a/src/zep_cloud/types/v4search_request_reranker.py b/src/zep_cloud/types/search_request_reranker.py similarity index 81% rename from src/zep_cloud/types/v4search_request_reranker.py rename to src/zep_cloud/types/search_request_reranker.py index e4733141..42e1cc4a 100644 --- a/src/zep_cloud/types/v4search_request_reranker.py +++ b/src/zep_cloud/types/search_request_reranker.py @@ -2,6 +2,6 @@ import typing -V4SearchRequestReranker = typing.Union[ +SearchRequestReranker = typing.Union[ typing.Literal["rrf", "mmr", "node_distance", "episode_mentions", "cross_encoder"], typing.Any ] diff --git a/src/zep_cloud/types/skill_definition.py b/src/zep_cloud/types/skill_definition.py new file mode 100644 index 00000000..7fbfbfad --- /dev/null +++ b/src/zep_cloud/types/skill_definition.py @@ -0,0 +1,42 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .skill_definition_section import SkillDefinitionSection +from .skill_failure import SkillFailure +from .skill_procedure_step import SkillProcedureStep +from .skill_relation import SkillRelation +from .skill_resource import SkillResource + + +class SkillDefinition(UniversalBaseModel): + agent_versions: typing.Optional[typing.List[str]] = None + aliases: typing.Optional[typing.List[str]] = None + description: typing.Optional[str] = None + do_not_use_when: typing.Optional[typing.List[str]] = None + done_when: typing.Optional[typing.List[str]] = None + environments: typing.Optional[typing.List[SkillResource]] = None + failures: typing.Optional[typing.List[SkillFailure]] = None + kind: typing.Optional[str] = None + name: typing.Optional[str] = None + outputs: typing.Optional[typing.List[str]] = None + package_name: typing.Optional[str] = None + preconditions: typing.Optional[typing.List[str]] = None + procedure: typing.Optional[typing.List[SkillProcedureStep]] = None + related_skills: typing.Optional[typing.List[SkillRelation]] = None + sections: typing.Optional[typing.List[SkillDefinitionSection]] = None + stop_when: typing.Optional[typing.List[str]] = None + task_family: typing.Optional[str] = None + tools: typing.Optional[typing.List[SkillResource]] = None + use_when: typing.Optional[typing.List[str]] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/skill_definition_section.py b/src/zep_cloud/types/skill_definition_section.py new file mode 100644 index 00000000..00ff402a --- /dev/null +++ b/src/zep_cloud/types/skill_definition_section.py @@ -0,0 +1,21 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class SkillDefinitionSection(UniversalBaseModel): + heading: typing.Optional[str] = None + id: typing.Optional[str] = None + markdown: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/skill_failure.py b/src/zep_cloud/types/skill_failure.py new file mode 100644 index 00000000..64e132f0 --- /dev/null +++ b/src/zep_cloud/types/skill_failure.py @@ -0,0 +1,20 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class SkillFailure(UniversalBaseModel): + recover: typing.Optional[typing.List[str]] = None + when: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/skill_procedure_step.py b/src/zep_cloud/types/skill_procedure_step.py new file mode 100644 index 00000000..167fa081 --- /dev/null +++ b/src/zep_cloud/types/skill_procedure_step.py @@ -0,0 +1,21 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class SkillProcedureStep(UniversalBaseModel): + decision: typing.Optional[str] = None + expect: typing.Optional[typing.List[str]] = None + instruction: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/skill_relation.py b/src/zep_cloud/types/skill_relation.py new file mode 100644 index 00000000..7837b488 --- /dev/null +++ b/src/zep_cloud/types/skill_relation.py @@ -0,0 +1,21 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class SkillRelation(UniversalBaseModel): + relation: typing.Optional[str] = None + skill: typing.Optional[str] = None + version: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/skill_resource.py b/src/zep_cloud/types/skill_resource.py new file mode 100644 index 00000000..c102f15d --- /dev/null +++ b/src/zep_cloud/types/skill_resource.py @@ -0,0 +1,21 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class SkillResource(UniversalBaseModel): + aliases: typing.Optional[typing.List[str]] = None + name: typing.Optional[str] = None + version: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/source_span.py b/src/zep_cloud/types/source_span.py new file mode 100644 index 00000000..ec4bfdd9 --- /dev/null +++ b/src/zep_cloud/types/source_span.py @@ -0,0 +1,82 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class SourceSpan(UniversalBaseModel): + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + CreatedAt is the span creation time. + """ + + ended_at: typing.Optional[str] = pydantic.Field(default=None) + """ + EndedAt is the span end time, when present. + """ + + error: typing.Optional[str] = pydantic.Field(default=None) + """ + Error is the span error text, when present. + """ + + input: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Input is the provider span input. Example: {"messages":[]}. + """ + + kind: typing.Optional[str] = pydantic.Field(default=None) + """ + Kind is the normalized span kind. + """ + + metadata: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Metadata contains provider span metadata. Example: {"team":"support"}. + """ + + model: typing.Optional[str] = pydantic.Field(default=None) + """ + Model is the model identifier, when present. + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + Name is the provider span name. + """ + + output: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Output is the provider span output. Example: {"text":"Hello"}. + """ + + parent_span_id: typing.Optional[str] = pydantic.Field(default=None) + """ + ParentSpanID is the parent span identifier, when present. + """ + + span_id: typing.Optional[str] = pydantic.Field(default=None) + """ + SpanID is the provider span identifier. + """ + + started_at: typing.Optional[str] = pydantic.Field(default=None) + """ + StartedAt is the span start time, when present. + """ + + tool_name: typing.Optional[str] = pydantic.Field(default=None) + """ + ToolName is the tool name, when present. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/source_trace.py b/src/zep_cloud/types/source_trace.py new file mode 100644 index 00000000..8b5bb1e7 --- /dev/null +++ b/src/zep_cloud/types/source_trace.py @@ -0,0 +1,94 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .imported_trajectory_reference import ImportedTrajectoryReference +from .source_span import SourceSpan + + +class SourceTrace(UniversalBaseModel): + closed: typing.Optional[bool] = pydantic.Field(default=None) + """ + Closed reports whether the root span has ended. + """ + + ended_at: typing.Optional[str] = pydantic.Field(default=None) + """ + EndedAt is the trace end time, when present. + """ + + has_error: typing.Optional[bool] = pydantic.Field(default=None) + """ + HasError reports whether the trace contains an error. + """ + + imported_trajectories: typing.Optional[typing.List[ImportedTrajectoryReference]] = pydantic.Field(default=None) + """ + ImportedTrajectories contains visible Zep Trajectories imported from this trace. Example: [{"agent_uuid":"f8b28f94-4f5a-4b3a-b782-87aa8464ac04","trajectory_uuid":"6a906e70-50ca-4e43-a874-5fcae02a71fa","import_uuid":"332c28e1-e6a7-4bca-97b2-ef1ec82c65fa"}]. + """ + + last_activity_at: typing.Optional[str] = pydantic.Field(default=None) + """ + LastActivityAt is the most recent activity time across spans. + """ + + metadata: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Metadata contains the root span metadata summary. Example: {"team":"support"}. + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + Name is the trace name, when present. + """ + + scores: typing.Optional[typing.Dict[str, float]] = pydantic.Field(default=None) + """ + Scores contains the trace score values. + """ + + source_revision: typing.Optional[str] = pydantic.Field(default=None) + """ + SourceRevision is the provider revision for the trace. + """ + + source_url: typing.Optional[str] = pydantic.Field(default=None) + """ + SourceURL is the provider link, when available. + """ + + span_count: typing.Optional[int] = pydantic.Field(default=None) + """ + SpanCount is the number of spans in the trace. + """ + + spans: typing.Optional[typing.List[SourceSpan]] = pydantic.Field(default=None) + """ + Spans contains the trace spans. Example: [{"span_id":"span_123","kind":"llm","name":"assistant_response"}]. + """ + + started_at: typing.Optional[str] = pydantic.Field(default=None) + """ + StartedAt is the trace start time, when present. + """ + + tags: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + Tags contains the trace tags. + """ + + trace_id: typing.Optional[str] = pydantic.Field(default=None) + """ + TraceID is the provider trace identifier. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/source_trace_page.py b/src/zep_cloud/types/source_trace_page.py new file mode 100644 index 00000000..318bf59e --- /dev/null +++ b/src/zep_cloud/types/source_trace_page.py @@ -0,0 +1,28 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .source_trace_summary import SourceTraceSummary + + +class SourceTracePage(UniversalBaseModel): + items: typing.Optional[typing.List[SourceTraceSummary]] = pydantic.Field(default=None) + """ + Items contains the source trace summaries on this page. Example: [{"trace_id":"trace_123","name":"Support trace"}]. + """ + + next_cursor: typing.Optional[str] = pydantic.Field(default=None) + """ + NextCursor is the cursor for the next provider page. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/source_trace_response.py b/src/zep_cloud/types/source_trace_response.py new file mode 100644 index 00000000..365da141 --- /dev/null +++ b/src/zep_cloud/types/source_trace_response.py @@ -0,0 +1,29 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .source_trace import SourceTrace +from .trace_preview import TracePreview + + +class SourceTraceResponse(UniversalBaseModel): + preview: typing.Optional[TracePreview] = pydantic.Field(default=None) + """ + Preview contains the optional mapping preview. Example: {"event_count":4}. + """ + + trace: typing.Optional[SourceTrace] = pydantic.Field(default=None) + """ + Trace is the requested provider trace. Example: {"trace_id":"trace_123","spans":[]}. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/source_trace_summary.py b/src/zep_cloud/types/source_trace_summary.py new file mode 100644 index 00000000..a5197c63 --- /dev/null +++ b/src/zep_cloud/types/source_trace_summary.py @@ -0,0 +1,88 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .imported_trajectory_reference import ImportedTrajectoryReference + + +class SourceTraceSummary(UniversalBaseModel): + closed: typing.Optional[bool] = pydantic.Field(default=None) + """ + Closed reports whether the root span has ended. + """ + + ended_at: typing.Optional[str] = pydantic.Field(default=None) + """ + EndedAt is the trace end time, when present. + """ + + has_error: typing.Optional[bool] = pydantic.Field(default=None) + """ + HasError reports whether the trace contains an error. + """ + + imported_trajectories: typing.Optional[typing.List[ImportedTrajectoryReference]] = pydantic.Field(default=None) + """ + ImportedTrajectories contains visible Zep Trajectories imported from this trace. Example: [{"agent_uuid":"f8b28f94-4f5a-4b3a-b782-87aa8464ac04","trajectory_uuid":"6a906e70-50ca-4e43-a874-5fcae02a71fa","import_uuid":"332c28e1-e6a7-4bca-97b2-ef1ec82c65fa"}]. + """ + + last_activity_at: typing.Optional[str] = pydantic.Field(default=None) + """ + LastActivityAt is the most recent activity time across spans. + """ + + metadata: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Metadata contains the root span metadata summary. Example: {"team":"support"}. + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + Name is the trace name, when present. + """ + + scores: typing.Optional[typing.Dict[str, float]] = pydantic.Field(default=None) + """ + Scores contains the trace score values. + """ + + source_revision: typing.Optional[str] = pydantic.Field(default=None) + """ + SourceRevision is the provider revision for the trace. + """ + + source_url: typing.Optional[str] = pydantic.Field(default=None) + """ + SourceURL is the provider link, when available. + """ + + span_count: typing.Optional[int] = pydantic.Field(default=None) + """ + SpanCount is the number of spans in the trace. + """ + + started_at: typing.Optional[str] = pydantic.Field(default=None) + """ + StartedAt is the trace start time, when present. + """ + + tags: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + Tags contains the trace tags. + """ + + trace_id: typing.Optional[str] = pydantic.Field(default=None) + """ + TraceID is the provider trace identifier. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/task.py b/src/zep_cloud/types/task.py index a2614b13..e0ee102d 100644 --- a/src/zep_cloud/types/task.py +++ b/src/zep_cloud/types/task.py @@ -67,6 +67,9 @@ class Task(UniversalBaseModel): FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid", description="The unique identifier of the task, used to poll its status."), ] = None + """ + The unique identifier of the task, used to poll its status. + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/zep_cloud/types/task_family_mapping_rule.py b/src/zep_cloud/types/task_family_mapping_rule.py new file mode 100644 index 00000000..2d6ca31d --- /dev/null +++ b/src/zep_cloud/types/task_family_mapping_rule.py @@ -0,0 +1,43 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .task_family_mapping_rule_source import TaskFamilyMappingRuleSource + + +class TaskFamilyMappingRule(UniversalBaseModel): + fallback: typing.Optional[str] = pydantic.Field(default=None) + """ + Fallback is used when the selected source has no value. + """ + + key: typing.Optional[str] = pydantic.Field(default=None) + """ + Key is the metadata key for metadata mapping. + """ + + prefix: typing.Optional[str] = pydantic.Field(default=None) + """ + Prefix is the tag prefix for tag mapping. + """ + + source: typing.Optional[TaskFamilyMappingRuleSource] = pydantic.Field(default=None) + """ + Source selects the task family source. + """ + + value: typing.Optional[str] = pydantic.Field(default=None) + """ + Value is the fixed task family value. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/task_family_mapping_rule_source.py b/src/zep_cloud/types/task_family_mapping_rule_source.py new file mode 100644 index 00000000..a1c425f8 --- /dev/null +++ b/src/zep_cloud/types/task_family_mapping_rule_source.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +TaskFamilyMappingRuleSource = typing.Union[typing.Literal["fixed", "metadata", "tag_prefix", "name"], typing.Any] diff --git a/src/zep_cloud/types/thread.py b/src/zep_cloud/types/thread.py index 5a4ab0bf..f4f05913 100644 --- a/src/zep_cloud/types/thread.py +++ b/src/zep_cloud/types/thread.py @@ -39,6 +39,9 @@ class Thread(UniversalBaseModel): FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid", description="The unique identifier of the thread."), ] = None + """ + The unique identifier of the thread. + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/zep_cloud/types/thread_context_response.py b/src/zep_cloud/types/thread_context_response.py index b36725f6..dd87bfe7 100644 --- a/src/zep_cloud/types/thread_context_response.py +++ b/src/zep_cloud/types/thread_context_response.py @@ -10,8 +10,8 @@ class ThreadContextResponse(UniversalBaseModel): context: typing.Optional[str] = pydantic.Field(default=None) """ The context block containing relevant facts, entities, and messages or - episodes from the user's graph, meant to be placed in the system prompt on - every turn. + episodes from the user's graph. Pass it through the model provider's + untrusted-data channel. """ if IS_PYDANTIC_V2: diff --git a/src/zep_cloud/types/thread_summary.py b/src/zep_cloud/types/thread_summary.py index e43ac320..7a697f4b 100644 --- a/src/zep_cloud/types/thread_summary.py +++ b/src/zep_cloud/types/thread_summary.py @@ -53,6 +53,9 @@ class ThreadSummary(UniversalBaseModel): FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid", description="The unique identifier of the thread summary."), ] = None + """ + The unique identifier of the thread summary. + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/zep_cloud/types/trace_connection.py b/src/zep_cloud/types/trace_connection.py new file mode 100644 index 00000000..f62fea45 --- /dev/null +++ b/src/zep_cloud/types/trace_connection.py @@ -0,0 +1,89 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .trace_connection_settings import TraceConnectionSettings + + +class TraceConnection(UniversalBaseModel): + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + CreatedAt is the resource creation time. + """ + + credential_hint: typing.Optional[str] = pydantic.Field(default=None) + """ + CredentialHint contains the final four characters of the credential. + """ + + credential_version: typing.Optional[int] = pydantic.Field(default=None) + """ + CredentialVersion is the current credential version. + """ + + import_count: typing.Optional[int] = pydantic.Field(default=None) + """ + ImportCount is the number of non-deleted imports that use this connection. + """ + + last_verified_at: typing.Optional[str] = pydantic.Field(default=None) + """ + LastVerifiedAt is the last successful credential verification time. + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + Name is the display name. + """ + + provider: typing.Optional[str] = pydantic.Field(default=None) + """ + Provider is the observability provider. + """ + + provider_organization_id: typing.Optional[str] = pydantic.Field(default=None) + """ + ProviderOrganizationID is the provider organization identifier. + """ + + provider_organization_name: typing.Optional[str] = pydantic.Field(default=None) + """ + ProviderOrganizationName is the provider organization name. + """ + + settings: typing.Optional[TraceConnectionSettings] = pydantic.Field(default=None) + """ + Settings contains provider request and retention settings. Example: {"requests_per_minute":10}. + """ + + status: typing.Optional[str] = pydantic.Field(default=None) + """ + Status is the provider verification status. + """ + + updated_at: typing.Optional[str] = pydantic.Field(default=None) + """ + UpdatedAt is the last resource update time. + """ + + uuid_: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="UUID is the trace connection identifier."), + ] = None + """ + UUID is the trace connection identifier. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/trace_connection_page.py b/src/zep_cloud/types/trace_connection_page.py new file mode 100644 index 00000000..2faac1c6 --- /dev/null +++ b/src/zep_cloud/types/trace_connection_page.py @@ -0,0 +1,33 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .trace_connection import TraceConnection + + +class TraceConnectionPage(UniversalBaseModel): + items: typing.Optional[typing.List[TraceConnection]] = pydantic.Field(default=None) + """ + Items contains the trace connections on this page. Example: [{"uuid":"8c78a85e-eac2-4f57-b5f5-59a68a1e77a1"}]. + """ + + next_cursor: typing.Optional[str] = pydantic.Field(default=None) + """ + NextCursor is the cursor for the next page. + """ + + total_size: typing.Optional[int] = pydantic.Field(default=None) + """ + TotalSize is the number of matching connections. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/trace_connection_settings.py b/src/zep_cloud/types/trace_connection_settings.py new file mode 100644 index 00000000..26d64e63 --- /dev/null +++ b/src/zep_cloud/types/trace_connection_settings.py @@ -0,0 +1,32 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class TraceConnectionSettings(UniversalBaseModel): + api_url: typing.Optional[str] = pydantic.Field(default=None) + """ + APIURL is an optional custom provider endpoint. + """ + + requests_per_minute: typing.Optional[int] = pydantic.Field(default=None) + """ + RequestsPerMinute is the maximum provider request rate. + """ + + retention_days: typing.Optional[int] = pydantic.Field(default=None) + """ + RetentionDays is the provider retention window, when known. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/trace_filter.py b/src/zep_cloud/types/trace_filter.py new file mode 100644 index 00000000..204db10c --- /dev/null +++ b/src/zep_cloud/types/trace_filter.py @@ -0,0 +1,58 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .trace_score_range import TraceScoreRange + + +class TraceFilter(UniversalBaseModel): + has_error: typing.Optional[bool] = pydantic.Field(default=None) + """ + HasError filters traces by their error state. + """ + + metadata: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Metadata contains exact-match root metadata filters. Example: {"team":"support"}. + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + Name is the exact trace name filter. + """ + + scores: typing.Optional[typing.List[TraceScoreRange]] = pydantic.Field(default=None) + """ + Scores contains score name and range filters. Example: [{"name":"quality","min":0.5}]. + """ + + started_after: typing.Optional[str] = pydantic.Field(default=None) + """ + StartedAfter is the inclusive trace start-time lower bound. + """ + + started_before: typing.Optional[str] = pydantic.Field(default=None) + """ + StartedBefore is the exclusive trace start-time upper bound. + """ + + tags_all: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + TagsAll contains tags that every result must include. + """ + + tags_any: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + TagsAny contains tags that at least one result must include. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/trace_preview.py b/src/zep_cloud/types/trace_preview.py new file mode 100644 index 00000000..beb2ad9d --- /dev/null +++ b/src/zep_cloud/types/trace_preview.py @@ -0,0 +1,33 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .trajectory_mapping_result import TrajectoryMappingResult + + +class TracePreview(UniversalBaseModel): + event_count: typing.Optional[int] = pydantic.Field(default=None) + """ + EventCount is the number of mapped events. + """ + + mapping_result: typing.Optional[TrajectoryMappingResult] = pydantic.Field(default=None) + """ + MappingResult contains the resolved Trajectory fields. Example: {"task_family":"support","objective":"Help the customer"}. + """ + + skip_reason: typing.Optional[str] = pydantic.Field(default=None) + """ + SkipReason is the reason the trace cannot be imported, when present. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/trace_provider_project.py b/src/zep_cloud/types/trace_provider_project.py new file mode 100644 index 00000000..3448de45 --- /dev/null +++ b/src/zep_cloud/types/trace_provider_project.py @@ -0,0 +1,32 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class TraceProviderProject(UniversalBaseModel): + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + CreatedAt is the project creation time, when the provider returns it. + """ + + id: typing.Optional[str] = pydantic.Field(default=None) + """ + ID is the provider project identifier. + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + Name is the provider project name. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/trace_provider_project_page.py b/src/zep_cloud/types/trace_provider_project_page.py new file mode 100644 index 00000000..9a826ced --- /dev/null +++ b/src/zep_cloud/types/trace_provider_project_page.py @@ -0,0 +1,28 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .trace_provider_project import TraceProviderProject + + +class TraceProviderProjectPage(UniversalBaseModel): + items: typing.Optional[typing.List[TraceProviderProject]] = pydantic.Field(default=None) + """ + Items contains the provider projects on this page. Example: [{"id":"project_123","name":"Support"}]. + """ + + next_cursor: typing.Optional[str] = pydantic.Field(default=None) + """ + NextCursor is the provider cursor for the next page. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/trace_score_range.py b/src/zep_cloud/types/trace_score_range.py new file mode 100644 index 00000000..396851c3 --- /dev/null +++ b/src/zep_cloud/types/trace_score_range.py @@ -0,0 +1,32 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class TraceScoreRange(UniversalBaseModel): + max: typing.Optional[float] = pydantic.Field(default=None) + """ + Max is the inclusive score upper bound. + """ + + min: typing.Optional[float] = pydantic.Field(default=None) + """ + Min is the inclusive score lower bound. + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + Name is the provider score name. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/trajectory_content_mapping.py b/src/zep_cloud/types/trajectory_content_mapping.py new file mode 100644 index 00000000..82161a64 --- /dev/null +++ b/src/zep_cloud/types/trajectory_content_mapping.py @@ -0,0 +1,27 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class TrajectoryContentMapping(UniversalBaseModel): + include_system_messages: typing.Optional[bool] = pydantic.Field(default=None) + """ + IncludeSystemMessages controls whether system messages become events. + """ + + metadata_keys: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + MetadataKeys contains root metadata keys copied to the Trajectory. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/trajectory_import.py b/src/zep_cloud/types/trajectory_import.py new file mode 100644 index 00000000..16cec072 --- /dev/null +++ b/src/zep_cloud/types/trajectory_import.py @@ -0,0 +1,138 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .trajectory_import_pause_reason import TrajectoryImportPauseReason +from .trajectory_import_run_reference import TrajectoryImportRunReference +from .trajectory_import_schedule import TrajectoryImportSchedule +from .trajectory_import_selection import TrajectoryImportSelection +from .trajectory_mapping import TrajectoryMapping + + +class TrajectoryImport(UniversalBaseModel): + agent_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + AgentUUID is the owning Agent identifier. + """ + + connection_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + ConnectionUUID is the trace connection identifier. + """ + + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + CreatedAt is the resource creation time. + """ + + imported_trajectory_count: typing.Optional[int] = pydantic.Field(default=None) + """ + ImportedTrajectoryCount is the number of Trajectories currently owned by this import. + """ + + last_run: typing.Optional[TrajectoryImportRunReference] = pydantic.Field(default=None) + """ + LastRun is the latest run for this import, when one exists. + """ + + learn_from: typing.Optional[bool] = pydantic.Field(default=None) + """ + LearnFrom reports whether imported evidence can support Skills. + """ + + mapping: typing.Optional[TrajectoryMapping] = pydantic.Field(default=None) + """ + Mapping defines how traces become Trajectories. Example: {"task_family":{"source":"fixed","value":"support"}}. + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + Name is the import display name. + """ + + next_run_at: typing.Optional[str] = pydantic.Field(default=None) + """ + NextRunAt is the next scheduled run time. + """ + + on_source_change: typing.Optional[str] = pydantic.Field(default=None) + """ + OnSourceChange defines how changed source traces are handled. + """ + + pause_reason: typing.Optional[TrajectoryImportPauseReason] = pydantic.Field(default=None) + """ + PauseReason is the reason for a paused import, when present. + """ + + provider: typing.Optional[str] = pydantic.Field(default=None) + """ + Provider is the observability provider. + """ + + provider_organization_id: typing.Optional[str] = pydantic.Field(default=None) + """ + ProviderOrganizationID is the provider organization identifier. + """ + + provider_project_id: typing.Optional[str] = pydantic.Field(default=None) + """ + ProviderProjectID is the source project identifier. + """ + + require_review: typing.Optional[bool] = pydantic.Field(default=None) + """ + RequireReview reports whether candidate review is required. + """ + + revision: typing.Optional[int] = pydantic.Field(default=None) + """ + Revision is the import update revision. + """ + + schedule: typing.Optional[TrajectoryImportSchedule] = pydantic.Field(default=None) + """ + Schedule contains recurring import settings, when enabled. Example: {"interval_hours":4,"start_from":"24h","settle_minutes":5,"max_open_hours":24}. + """ + + selection: typing.Optional[TrajectoryImportSelection] = pydantic.Field(default=None) + """ + Selection defines the source traces to import. Example: {"trace_ids":["trace_123"]}. + """ + + source_cursor_updated_at: typing.Optional[str] = pydantic.Field(default=None) + """ + SourceCursorUpdatedAt is the last source cursor update time. + """ + + status: typing.Optional[str] = pydantic.Field(default=None) + """ + Status is the import status. + """ + + updated_at: typing.Optional[str] = pydantic.Field(default=None) + """ + UpdatedAt is the last resource update time. + """ + + uuid_: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="UUID is the trajectory import identifier."), + ] = None + """ + UUID is the trajectory import identifier. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/trajectory_import_page.py b/src/zep_cloud/types/trajectory_import_page.py new file mode 100644 index 00000000..0f761326 --- /dev/null +++ b/src/zep_cloud/types/trajectory_import_page.py @@ -0,0 +1,33 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .trajectory_import import TrajectoryImport + + +class TrajectoryImportPage(UniversalBaseModel): + items: typing.Optional[typing.List[TrajectoryImport]] = pydantic.Field(default=None) + """ + Items contains trajectory imports on this page. Example: [{"uuid":"332c28e1-e6a7-4bca-97b2-ef1ec82c65fa","name":"Support traces"}]. + """ + + next_cursor: typing.Optional[str] = pydantic.Field(default=None) + """ + NextCursor is the cursor for the next page. + """ + + total_size: typing.Optional[int] = pydantic.Field(default=None) + """ + TotalSize is the number of matching imports. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/trajectory_import_pause_reason.py b/src/zep_cloud/types/trajectory_import_pause_reason.py new file mode 100644 index 00000000..9039fd3f --- /dev/null +++ b/src/zep_cloud/types/trajectory_import_pause_reason.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +TrajectoryImportPauseReason = typing.Union[ + typing.Literal["user", "credential_rejected", "provider_project_not_found"], typing.Any +] diff --git a/src/zep_cloud/types/trajectory_import_run.py b/src/zep_cloud/types/trajectory_import_run.py new file mode 100644 index 00000000..802ea7f0 --- /dev/null +++ b/src/zep_cloud/types/trajectory_import_run.py @@ -0,0 +1,88 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata + + +class TrajectoryImportRun(UniversalBaseModel): + completed_at: typing.Optional[str] = pydantic.Field(default=None) + """ + CompletedAt is the run completion time, when present. + """ + + counts: typing.Optional[typing.Dict[str, int]] = pydantic.Field(default=None) + """ + Counts contains run totals by result type. + """ + + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + CreatedAt is the run creation time. + """ + + due_at: typing.Optional[str] = pydantic.Field(default=None) + """ + DueAt is the scheduled run time, when present. + """ + + error_code: typing.Optional[str] = pydantic.Field(default=None) + """ + ErrorCode is the safe run error code, when present. + """ + + import_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + ImportUUID is the owning import identifier. + """ + + more_available: typing.Optional[bool] = pydantic.Field(default=None) + """ + MoreAvailable reports whether more matching traces remain. + """ + + skip_reasons: typing.Optional[typing.Dict[str, int]] = pydantic.Field(default=None) + """ + SkipReasons contains skip totals by reason. + """ + + started_at: typing.Optional[str] = pydantic.Field(default=None) + """ + StartedAt is the run start time, when present. + """ + + status: typing.Optional[str] = pydantic.Field(default=None) + """ + Status is the run status. + """ + + task_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + TaskUUID is the Task identifier. + """ + + trigger: typing.Optional[str] = pydantic.Field(default=None) + """ + Trigger is the event that created the run. + """ + + uuid_: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="UUID is the run identifier."), + ] = None + """ + UUID is the run identifier. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/trajectory_import_run_item.py b/src/zep_cloud/types/trajectory_import_run_item.py new file mode 100644 index 00000000..4e9c3fbf --- /dev/null +++ b/src/zep_cloud/types/trajectory_import_run_item.py @@ -0,0 +1,47 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class TrajectoryImportRunItem(UniversalBaseModel): + created_at: typing.Optional[str] = pydantic.Field(default=None) + """ + CreatedAt is the item creation time. + """ + + reason: typing.Optional[str] = pydantic.Field(default=None) + """ + Reason is the safe skip or failure reason, when present. + """ + + source_revision: typing.Optional[str] = pydantic.Field(default=None) + """ + SourceRevision is the provider revision processed by the run. + """ + + status: typing.Optional[str] = pydantic.Field(default=None) + """ + Status is the trace result status. + """ + + trace_id: typing.Optional[str] = pydantic.Field(default=None) + """ + TraceID is the provider trace identifier. + """ + + trajectory_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + TrajectoryUUID is the created Trajectory identifier, when present. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/trajectory_import_run_item_page.py b/src/zep_cloud/types/trajectory_import_run_item_page.py new file mode 100644 index 00000000..de330df6 --- /dev/null +++ b/src/zep_cloud/types/trajectory_import_run_item_page.py @@ -0,0 +1,33 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .trajectory_import_run_item import TrajectoryImportRunItem + + +class TrajectoryImportRunItemPage(UniversalBaseModel): + items: typing.Optional[typing.List[TrajectoryImportRunItem]] = pydantic.Field(default=None) + """ + Items contains run items on this page. Example: [{"trace_id":"trace_123","status":"imported"}]. + """ + + next_cursor: typing.Optional[str] = pydantic.Field(default=None) + """ + NextCursor is the cursor for the next page. + """ + + total_size: typing.Optional[int] = pydantic.Field(default=None) + """ + TotalSize is the number of matching run items. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/trajectory_import_run_page.py b/src/zep_cloud/types/trajectory_import_run_page.py new file mode 100644 index 00000000..cab8b103 --- /dev/null +++ b/src/zep_cloud/types/trajectory_import_run_page.py @@ -0,0 +1,33 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .trajectory_import_run import TrajectoryImportRun + + +class TrajectoryImportRunPage(UniversalBaseModel): + items: typing.Optional[typing.List[TrajectoryImportRun]] = pydantic.Field(default=None) + """ + Items contains runs on this page. Example: [{"uuid":"ea7e2724-9bfd-4ca1-aa5c-40a1dd72a688","status":"pending"}]. + """ + + next_cursor: typing.Optional[str] = pydantic.Field(default=None) + """ + NextCursor is the cursor for the next page. + """ + + total_size: typing.Optional[int] = pydantic.Field(default=None) + """ + TotalSize is the number of matching runs. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/trajectory_import_run_reference.py b/src/zep_cloud/types/trajectory_import_run_reference.py new file mode 100644 index 00000000..bb27a020 --- /dev/null +++ b/src/zep_cloud/types/trajectory_import_run_reference.py @@ -0,0 +1,50 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .trajectory_import_run_reference_status import TrajectoryImportRunReferenceStatus +from .trajectory_import_run_reference_trigger import TrajectoryImportRunReferenceTrigger + + +class TrajectoryImportRunReference(UniversalBaseModel): + completed_at: typing.Optional[str] = pydantic.Field(default=None) + """ + CompletedAt is the run completion time, when present. + """ + + started_at: typing.Optional[str] = pydantic.Field(default=None) + """ + StartedAt is the run start time, when present. + """ + + status: typing.Optional[TrajectoryImportRunReferenceStatus] = pydantic.Field(default=None) + """ + Status is the run status. + """ + + trigger: typing.Optional[TrajectoryImportRunReferenceTrigger] = pydantic.Field(default=None) + """ + Trigger is the event that created the run. + """ + + uuid_: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="uuid"), + pydantic.Field(alias="uuid", description="UUID is the run identifier."), + ] = None + """ + UUID is the run identifier. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/trajectory_import_run_reference_status.py b/src/zep_cloud/types/trajectory_import_run_reference_status.py new file mode 100644 index 00000000..93322cae --- /dev/null +++ b/src/zep_cloud/types/trajectory_import_run_reference_status.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +TrajectoryImportRunReferenceStatus = typing.Union[ + typing.Literal["pending", "running", "succeeded", "partial", "failed", "canceled"], typing.Any +] diff --git a/src/zep_cloud/types/trajectory_import_run_reference_trigger.py b/src/zep_cloud/types/trajectory_import_run_reference_trigger.py new file mode 100644 index 00000000..c5d28c99 --- /dev/null +++ b/src/zep_cloud/types/trajectory_import_run_reference_trigger.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +TrajectoryImportRunReferenceTrigger = typing.Union[typing.Literal["create", "schedule", "manual"], typing.Any] diff --git a/src/zep_cloud/types/trajectory_import_schedule.py b/src/zep_cloud/types/trajectory_import_schedule.py new file mode 100644 index 00000000..65283eca --- /dev/null +++ b/src/zep_cloud/types/trajectory_import_schedule.py @@ -0,0 +1,37 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class TrajectoryImportSchedule(UniversalBaseModel): + interval_hours: typing.Optional[int] = pydantic.Field(default=None) + """ + IntervalHours is the scheduled run interval. + """ + + max_open_hours: typing.Optional[int] = pydantic.Field(default=None) + """ + MaxOpenHours is the maximum wait for an open trace. + """ + + settle_minutes: typing.Optional[int] = pydantic.Field(default=None) + """ + SettleMinutes is the wait time for trace updates. + """ + + start_from: typing.Optional[str] = pydantic.Field(default=None) + """ + StartFrom selects the initial history window. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/trajectory_import_selection.py b/src/zep_cloud/types/trajectory_import_selection.py new file mode 100644 index 00000000..bc74e806 --- /dev/null +++ b/src/zep_cloud/types/trajectory_import_selection.py @@ -0,0 +1,28 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .trace_filter import TraceFilter + + +class TrajectoryImportSelection(UniversalBaseModel): + filter: typing.Optional[TraceFilter] = pydantic.Field(default=None) + """ + Filter selects traces by provider fields. Example: {"started_after":"2026-01-01T00:00:00Z"}. + """ + + trace_ids: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + TraceIDs contains explicit provider trace identifiers. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/trajectory_mapping.py b/src/zep_cloud/types/trajectory_mapping.py new file mode 100644 index 00000000..ed8824af --- /dev/null +++ b/src/zep_cloud/types/trajectory_mapping.py @@ -0,0 +1,52 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .objective_mapping_rule import ObjectiveMappingRule +from .outcome_mapping_rule import OutcomeMappingRule +from .task_family_mapping_rule import TaskFamilyMappingRule +from .trajectory_content_mapping import TrajectoryContentMapping +from .trajectory_mapping_include_outcomes_item import TrajectoryMappingIncludeOutcomesItem + + +class TrajectoryMapping(UniversalBaseModel): + content: typing.Optional[TrajectoryContentMapping] = pydantic.Field(default=None) + """ + Content configures copied span content. Example: {"include_system_messages":false}. + """ + + include_outcomes: typing.Optional[typing.List[TrajectoryMappingIncludeOutcomesItem]] = pydantic.Field(default=None) + """ + IncludeOutcomes lists outcomes that can support a Skill. + """ + + objective: typing.Optional[ObjectiveMappingRule] = pydantic.Field(default=None) + """ + Objective maps provider data to a Trajectory objective. Example: {"source":"first_user_message"}. + """ + + outcome: typing.Optional[typing.List[OutcomeMappingRule]] = pydantic.Field(default=None) + """ + Outcome contains ordered outcome mapping rules. Example: [{"rule":"score","name":"quality","succeeded_at_or_above":0.8}]. + """ + + score_verifier: typing.Optional[bool] = pydantic.Field(default=None) + """ + ScoreVerifier enables score-based verification. + """ + + task_family: typing.Optional[TaskFamilyMappingRule] = pydantic.Field(default=None) + """ + TaskFamily maps provider data to a task family. Example: {"source":"fixed","value":"support"}. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/trajectory_mapping_include_outcomes_item.py b/src/zep_cloud/types/trajectory_mapping_include_outcomes_item.py new file mode 100644 index 00000000..973691c5 --- /dev/null +++ b/src/zep_cloud/types/trajectory_mapping_include_outcomes_item.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +TrajectoryMappingIncludeOutcomesItem = typing.Union[ + typing.Literal["succeeded", "failed", "partial", "abandoned", "unknown"], typing.Any +] diff --git a/src/zep_cloud/types/trajectory_mapping_result.py b/src/zep_cloud/types/trajectory_mapping_result.py new file mode 100644 index 00000000..cf4c9efe --- /dev/null +++ b/src/zep_cloud/types/trajectory_mapping_result.py @@ -0,0 +1,54 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .trajectory_mapping_result_outcome import TrajectoryMappingResultOutcome +from .trajectory_mapping_result_outcome_rule import TrajectoryMappingResultOutcomeRule + + +class TrajectoryMappingResult(UniversalBaseModel): + metadata: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Metadata contains mapped source metadata. Example: {"ticket_id":"123"}. + """ + + objective: typing.Optional[str] = pydantic.Field(default=None) + """ + Objective is the resolved objective. + """ + + outcome: typing.Optional[TrajectoryMappingResultOutcome] = pydantic.Field(default=None) + """ + Outcome is the resolved outcome. + """ + + outcome_rule: typing.Optional[TrajectoryMappingResultOutcomeRule] = pydantic.Field(default=None) + """ + OutcomeRule is the rule that selected the outcome. + """ + + scores: typing.Optional[typing.Dict[str, float]] = pydantic.Field(default=None) + """ + Scores contains provider score values. + """ + + task_family: typing.Optional[str] = pydantic.Field(default=None) + """ + TaskFamily is the resolved task family. + """ + + verification: typing.Optional[str] = pydantic.Field(default=None) + """ + Verification is the resolved verification state. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/zep_cloud/types/trajectory_mapping_result_outcome.py b/src/zep_cloud/types/trajectory_mapping_result_outcome.py new file mode 100644 index 00000000..5c92e5b5 --- /dev/null +++ b/src/zep_cloud/types/trajectory_mapping_result_outcome.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +TrajectoryMappingResultOutcome = typing.Union[ + typing.Literal["succeeded", "failed", "partial", "abandoned", "unknown"], typing.Any +] diff --git a/src/zep_cloud/types/trajectory_mapping_result_outcome_rule.py b/src/zep_cloud/types/trajectory_mapping_result_outcome_rule.py new file mode 100644 index 00000000..2e3ccc86 --- /dev/null +++ b/src/zep_cloud/types/trajectory_mapping_result_outcome_rule.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +TrajectoryMappingResultOutcomeRule = typing.Union[typing.Literal["score", "metadata", "error"], typing.Any] diff --git a/src/zep_cloud/types/user.py b/src/zep_cloud/types/user.py index 80af802d..a6fada65 100644 --- a/src/zep_cloud/types/user.py +++ b/src/zep_cloud/types/user.py @@ -61,6 +61,9 @@ class User(UniversalBaseModel): FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid", description="The unique identifier of the user."), ] = None + """ + The unique identifier of the user. + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/zep_cloud/types/user_group.py b/src/zep_cloud/types/user_group.py index 4d2665ea..23a97674 100644 --- a/src/zep_cloud/types/user_group.py +++ b/src/zep_cloud/types/user_group.py @@ -34,6 +34,10 @@ class UserGroup(UniversalBaseModel): FieldMetadata(alias="uuid"), pydantic.Field(alias="uuid", description="The unique identifier of the user group."), ] = None + """ + The unique identifier of the user group. + """ + version: typing.Optional[int] = pydantic.Field(default=None) """ The user group's version, used for optimistic concurrency on updates. diff --git a/src/zep_cloud/types/v4batch_item_input_data_type.py b/src/zep_cloud/types/v4batch_item_input_data_type.py deleted file mode 100644 index 8a38865e..00000000 --- a/src/zep_cloud/types/v4batch_item_input_data_type.py +++ /dev/null @@ -1,5 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -V4BatchItemInputDataType = typing.Union[typing.Literal["text", "json", "message"], typing.Any] diff --git a/src/zep_cloud/types/v4batch_item_input_role.py b/src/zep_cloud/types/v4batch_item_input_role.py deleted file mode 100644 index 938d52b6..00000000 --- a/src/zep_cloud/types/v4batch_item_input_role.py +++ /dev/null @@ -1,5 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -V4BatchItemInputRole = typing.Union[typing.Literal["system", "assistant", "user", "function", "tool"], typing.Any] diff --git a/src/zep_cloud/types/v4batch_item_input_type.py b/src/zep_cloud/types/v4batch_item_input_type.py deleted file mode 100644 index 32203c4c..00000000 --- a/src/zep_cloud/types/v4batch_item_input_type.py +++ /dev/null @@ -1,5 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -V4BatchItemInputType = typing.Union[typing.Literal["graph_episode", "thread_message"], typing.Any] diff --git a/src/zep_cloud/user/__init__.py b/src/zep_cloud/user/__init__.py index 5cde0202..cb015d2f 100644 --- a/src/zep_cloud/user/__init__.py +++ b/src/zep_cloud/user/__init__.py @@ -2,3 +2,33 @@ # isort: skip_file +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .types import UserListRequestOrder, UserListRequestOrderBy +_dynamic_imports: typing.Dict[str, str] = {"UserListRequestOrder": ".types", "UserListRequestOrderBy": ".types"} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = ["UserListRequestOrder", "UserListRequestOrderBy"] diff --git a/src/zep_cloud/user/client.py b/src/zep_cloud/user/client.py index 1ade51d7..3219075e 100644 --- a/src/zep_cloud/user/client.py +++ b/src/zep_cloud/user/client.py @@ -5,6 +5,7 @@ from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ..core.pagination import AsyncPager, SyncPager from ..core.request_options import RequestOptions +from ..types.graph_content_policy_request import GraphContentPolicyRequest from ..types.node import Node from ..types.user import User from ..types.user_delete_result import UserDeleteResult @@ -12,6 +13,8 @@ from ..types.user_page import UserPage from ..types.user_summary_instructions import UserSummaryInstructions from .raw_client import AsyncRawUserClient, RawUserClient +from .types.user_list_request_order import UserListRequestOrder +from .types.user_list_request_order_by import UserListRequestOrderBy # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -35,19 +38,24 @@ def with_raw_response(self) -> RawUserClient: def create( self, *, + content_policy: typing.Optional[GraphContentPolicyRequest] = OMIT, disable_default_ontology: typing.Optional[bool] = OMIT, email: typing.Optional[str] = OMIT, first_name: typing.Optional[str] = OMIT, last_name: typing.Optional[str] = OMIT, metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, time_zone: typing.Optional[str] = OMIT, - user_id: typing.Optional[str] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> User: """ Parameters ---------- + content_policy : typing.Optional[GraphContentPolicyRequest] + Content policy additions for the user's graph. The graph binds the + current project content policy plus these additions, and the binding + does not change after creation. + disable_default_ontology : typing.Optional[bool] When true, disables the default ontology for the user's graph. @@ -66,9 +74,6 @@ def create( time_zone : typing.Optional[str] The user's IANA time zone. - user_id : typing.Optional[str] - An optional developer-assigned identifier for the user. - idempotency_key : typing.Optional[str] request_options : typing.Optional[RequestOptions] @@ -89,13 +94,13 @@ def create( client.user.create() """ _response = self._raw_client.create( + content_policy=content_policy, disable_default_ontology=disable_default_ontology, email=email, first_name=first_name, last_name=last_name, metadata=metadata, time_zone=time_zone, - user_id=user_id, idempotency_key=idempotency_key, request_options=request_options, ) @@ -106,10 +111,9 @@ def list( *, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, - order_by: typing.Optional[str] = None, - order: typing.Optional[str] = None, + order_by: typing.Optional[UserListRequestOrderBy] = None, + order: typing.Optional[UserListRequestOrder] = None, search: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[User, UserPage]: """ @@ -121,17 +125,15 @@ def list( cursor : typing.Optional[str] Opaque page cursor - order_by : typing.Optional[str] + order_by : typing.Optional[UserListRequestOrderBy] Sort field - order : typing.Optional[str] + order : typing.Optional[UserListRequestOrder] asc or desc search : typing.Optional[str] Filters results to users whose user ID, email, or name contains this text. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -147,12 +149,7 @@ def list( client = Zep( api_key="YOUR_API_KEY", ) - response = client.user.list( - limit=1, - cursor="cursor", - order_by="order_by", - order="order", - ) + response = client.user.list() for item in response: yield item # alternatively, you can paginate page-by-page @@ -160,13 +157,7 @@ def list( yield page """ return self._raw_client.list( - limit=limit, - cursor=cursor, - order_by=order_by, - order=order, - search=search, - idempotency_key=idempotency_key, - request_options=request_options, + limit=limit, cursor=cursor, order_by=order_by, order=order, search=search, request_options=request_options ) def lookup( @@ -175,7 +166,6 @@ def lookup( graph_id: typing.Optional[str] = OMIT, thread_id: typing.Optional[str] = OMIT, user_id: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> User: """ @@ -193,8 +183,6 @@ def lookup( The developer-assigned user ID to resolve to a UUID. Mutually exclusive with thread_id and graph_id. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -213,11 +201,7 @@ def lookup( client.user.lookup() """ _response = self._raw_client.lookup( - graph_id=graph_id, - thread_id=thread_id, - user_id=user_id, - idempotency_key=idempotency_key, - request_options=request_options, + graph_id=graph_id, thread_id=thread_id, user_id=user_id, request_options=request_options ) return _response.data @@ -490,19 +474,24 @@ def with_raw_response(self) -> AsyncRawUserClient: async def create( self, *, + content_policy: typing.Optional[GraphContentPolicyRequest] = OMIT, disable_default_ontology: typing.Optional[bool] = OMIT, email: typing.Optional[str] = OMIT, first_name: typing.Optional[str] = OMIT, last_name: typing.Optional[str] = OMIT, metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, time_zone: typing.Optional[str] = OMIT, - user_id: typing.Optional[str] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> User: """ Parameters ---------- + content_policy : typing.Optional[GraphContentPolicyRequest] + Content policy additions for the user's graph. The graph binds the + current project content policy plus these additions, and the binding + does not change after creation. + disable_default_ontology : typing.Optional[bool] When true, disables the default ontology for the user's graph. @@ -521,9 +510,6 @@ async def create( time_zone : typing.Optional[str] The user's IANA time zone. - user_id : typing.Optional[str] - An optional developer-assigned identifier for the user. - idempotency_key : typing.Optional[str] request_options : typing.Optional[RequestOptions] @@ -552,13 +538,13 @@ async def main() -> None: asyncio.run(main()) """ _response = await self._raw_client.create( + content_policy=content_policy, disable_default_ontology=disable_default_ontology, email=email, first_name=first_name, last_name=last_name, metadata=metadata, time_zone=time_zone, - user_id=user_id, idempotency_key=idempotency_key, request_options=request_options, ) @@ -569,10 +555,9 @@ async def list( *, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, - order_by: typing.Optional[str] = None, - order: typing.Optional[str] = None, + order_by: typing.Optional[UserListRequestOrderBy] = None, + order: typing.Optional[UserListRequestOrder] = None, search: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[User, UserPage]: """ @@ -584,17 +569,15 @@ async def list( cursor : typing.Optional[str] Opaque page cursor - order_by : typing.Optional[str] + order_by : typing.Optional[UserListRequestOrderBy] Sort field - order : typing.Optional[str] + order : typing.Optional[UserListRequestOrder] asc or desc search : typing.Optional[str] Filters results to users whose user ID, email, or name contains this text. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -615,12 +598,7 @@ async def list( async def main() -> None: - response = await client.user.list( - limit=1, - cursor="cursor", - order_by="order_by", - order="order", - ) + response = await client.user.list() async for item in response: yield item @@ -632,13 +610,7 @@ async def main() -> None: asyncio.run(main()) """ return await self._raw_client.list( - limit=limit, - cursor=cursor, - order_by=order_by, - order=order, - search=search, - idempotency_key=idempotency_key, - request_options=request_options, + limit=limit, cursor=cursor, order_by=order_by, order=order, search=search, request_options=request_options ) async def lookup( @@ -647,7 +619,6 @@ async def lookup( graph_id: typing.Optional[str] = OMIT, thread_id: typing.Optional[str] = OMIT, user_id: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> User: """ @@ -665,8 +636,6 @@ async def lookup( The developer-assigned user ID to resolve to a UUID. Mutually exclusive with thread_id and graph_id. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -693,11 +662,7 @@ async def main() -> None: asyncio.run(main()) """ _response = await self._raw_client.lookup( - graph_id=graph_id, - thread_id=thread_id, - user_id=user_id, - idempotency_key=idempotency_key, - request_options=request_options, + graph_id=graph_id, thread_id=thread_id, user_id=user_id, request_options=request_options ) return _response.data diff --git a/src/zep_cloud/user/raw_client.py b/src/zep_cloud/user/raw_client.py index e7c5d1e0..24fa0b94 100644 --- a/src/zep_cloud/user/raw_client.py +++ b/src/zep_cloud/user/raw_client.py @@ -6,7 +6,8 @@ from ..core.api_error import ApiError as core_api_error_ApiError from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ..core.http_response import AsyncHttpResponse, HttpResponse -from ..core.jsonable_encoder import jsonable_encoder +from ..core.idempotency import generate_idempotency_key +from ..core.jsonable_encoder import encode_path_param from ..core.pagination import AsyncPager, SyncPager from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as @@ -18,12 +19,15 @@ from ..errors.not_found_error import NotFoundError from ..errors.unauthorized_error import UnauthorizedError from ..types.api_error import ApiError as types_api_error_ApiError +from ..types.graph_content_policy_request import GraphContentPolicyRequest from ..types.node import Node from ..types.user import User from ..types.user_delete_result import UserDeleteResult from ..types.user_instruction import UserInstruction from ..types.user_page import UserPage from ..types.user_summary_instructions import UserSummaryInstructions +from .types.user_list_request_order import UserListRequestOrder +from .types.user_list_request_order_by import UserListRequestOrderBy from pydantic import ValidationError # this is used as the default value for optional parameters @@ -37,19 +41,24 @@ def __init__(self, *, client_wrapper: SyncClientWrapper): def create( self, *, + content_policy: typing.Optional[GraphContentPolicyRequest] = OMIT, disable_default_ontology: typing.Optional[bool] = OMIT, email: typing.Optional[str] = OMIT, first_name: typing.Optional[str] = OMIT, last_name: typing.Optional[str] = OMIT, metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, time_zone: typing.Optional[str] = OMIT, - user_id: typing.Optional[str] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[User]: """ Parameters ---------- + content_policy : typing.Optional[GraphContentPolicyRequest] + Content policy additions for the user's graph. The graph binds the + current project content policy plus these additions, and the binding + does not change after creation. + disable_default_ontology : typing.Optional[bool] When true, disables the default ontology for the user's graph. @@ -68,9 +77,6 @@ def create( time_zone : typing.Optional[str] The user's IANA time zone. - user_id : typing.Optional[str] - An optional developer-assigned identifier for the user. - idempotency_key : typing.Optional[str] request_options : typing.Optional[RequestOptions] @@ -85,17 +91,19 @@ def create( "users", method="POST", json={ + "content_policy": convert_and_respect_annotation_metadata( + object_=content_policy, annotation=GraphContentPolicyRequest, direction="write" + ), "disable_default_ontology": disable_default_ontology, "email": email, "first_name": first_name, "last_name": last_name, "metadata": metadata, "time_zone": time_zone, - "user_id": user_id, }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -172,10 +180,9 @@ def list( *, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, - order_by: typing.Optional[str] = None, - order: typing.Optional[str] = None, + order_by: typing.Optional[UserListRequestOrderBy] = None, + order: typing.Optional[UserListRequestOrder] = None, search: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[User, UserPage]: """ @@ -187,17 +194,15 @@ def list( cursor : typing.Optional[str] Opaque page cursor - order_by : typing.Optional[str] + order_by : typing.Optional[UserListRequestOrderBy] Sort field - order : typing.Optional[str] + order : typing.Optional[UserListRequestOrder] asc or desc search : typing.Optional[str] Filters results to users whose user ID, email, or name contains this text. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -220,7 +225,7 @@ def list( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -243,7 +248,6 @@ def list( order_by=order_by, order=order, search=search, - idempotency_key=idempotency_key, request_options=request_options, ) return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) @@ -299,7 +303,6 @@ def lookup( graph_id: typing.Optional[str] = OMIT, thread_id: typing.Optional[str] = OMIT, user_id: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[User]: """ @@ -317,8 +320,6 @@ def lookup( The developer-assigned user ID to resolve to a UUID. Mutually exclusive with thread_id and graph_id. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -337,7 +338,7 @@ def lookup( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -414,7 +415,7 @@ def get(self, user_uuid: str, *, request_options: typing.Optional[RequestOptions OK """ _response = self._client_wrapper.httpx_client.request( - f"users/{jsonable_encoder(user_uuid)}", + f"users/{encode_path_param(user_uuid)}", method="GET", request_options=request_options, ) @@ -498,10 +499,10 @@ def delete( Accepted """ _response = self._client_wrapper.httpx_client.request( - f"users/{jsonable_encoder(user_uuid)}", + f"users/{encode_path_param(user_uuid)}", method="DELETE", headers={ - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, ) @@ -620,7 +621,7 @@ def update( OK """ _response = self._client_wrapper.httpx_client.request( - f"users/{jsonable_encoder(user_uuid)}", + f"users/{encode_path_param(user_uuid)}", method="PATCH", json={ "disable_default_ontology": disable_default_ontology, @@ -632,7 +633,7 @@ def update( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -722,7 +723,7 @@ def get_node( OK """ _response = self._client_wrapper.httpx_client.request( - f"users/{jsonable_encoder(user_uuid)}/node", + f"users/{encode_path_param(user_uuid)}/node", method="GET", request_options=request_options, ) @@ -822,7 +823,7 @@ def get_summary_instructions( OK """ _response = self._client_wrapper.httpx_client.request( - f"users/{jsonable_encoder(user_uuid)}/summary-instructions", + f"users/{encode_path_param(user_uuid)}/summary-instructions", method="GET", request_options=request_options, ) @@ -916,7 +917,7 @@ def set_summary_instructions( OK """ _response = self._client_wrapper.httpx_client.request( - f"users/{jsonable_encoder(user_uuid)}/summary-instructions", + f"users/{encode_path_param(user_uuid)}/summary-instructions", method="PUT", json={ "inherited": inherited, @@ -926,7 +927,7 @@ def set_summary_instructions( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -995,19 +996,24 @@ def __init__(self, *, client_wrapper: AsyncClientWrapper): async def create( self, *, + content_policy: typing.Optional[GraphContentPolicyRequest] = OMIT, disable_default_ontology: typing.Optional[bool] = OMIT, email: typing.Optional[str] = OMIT, first_name: typing.Optional[str] = OMIT, last_name: typing.Optional[str] = OMIT, metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, time_zone: typing.Optional[str] = OMIT, - user_id: typing.Optional[str] = OMIT, idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[User]: """ Parameters ---------- + content_policy : typing.Optional[GraphContentPolicyRequest] + Content policy additions for the user's graph. The graph binds the + current project content policy plus these additions, and the binding + does not change after creation. + disable_default_ontology : typing.Optional[bool] When true, disables the default ontology for the user's graph. @@ -1026,9 +1032,6 @@ async def create( time_zone : typing.Optional[str] The user's IANA time zone. - user_id : typing.Optional[str] - An optional developer-assigned identifier for the user. - idempotency_key : typing.Optional[str] request_options : typing.Optional[RequestOptions] @@ -1043,17 +1046,19 @@ async def create( "users", method="POST", json={ + "content_policy": convert_and_respect_annotation_metadata( + object_=content_policy, annotation=GraphContentPolicyRequest, direction="write" + ), "disable_default_ontology": disable_default_ontology, "email": email, "first_name": first_name, "last_name": last_name, "metadata": metadata, "time_zone": time_zone, - "user_id": user_id, }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -1130,10 +1135,9 @@ async def list( *, limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, - order_by: typing.Optional[str] = None, - order: typing.Optional[str] = None, + order_by: typing.Optional[UserListRequestOrderBy] = None, + order: typing.Optional[UserListRequestOrder] = None, search: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[User, UserPage]: """ @@ -1145,17 +1149,15 @@ async def list( cursor : typing.Optional[str] Opaque page cursor - order_by : typing.Optional[str] + order_by : typing.Optional[UserListRequestOrderBy] Sort field - order : typing.Optional[str] + order : typing.Optional[UserListRequestOrder] asc or desc search : typing.Optional[str] Filters results to users whose user ID, email, or name contains this text. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1178,7 +1180,7 @@ async def list( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -1203,7 +1205,6 @@ async def _get_next(): order_by=order_by, order=order, search=search, - idempotency_key=idempotency_key, request_options=request_options, ) @@ -1260,7 +1261,6 @@ async def lookup( graph_id: typing.Optional[str] = OMIT, thread_id: typing.Optional[str] = OMIT, user_id: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[User]: """ @@ -1278,8 +1278,6 @@ async def lookup( The developer-assigned user ID to resolve to a UUID. Mutually exclusive with thread_id and graph_id. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1298,7 +1296,7 @@ async def lookup( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -1377,7 +1375,7 @@ async def get( OK """ _response = await self._client_wrapper.httpx_client.request( - f"users/{jsonable_encoder(user_uuid)}", + f"users/{encode_path_param(user_uuid)}", method="GET", request_options=request_options, ) @@ -1461,10 +1459,10 @@ async def delete( Accepted """ _response = await self._client_wrapper.httpx_client.request( - f"users/{jsonable_encoder(user_uuid)}", + f"users/{encode_path_param(user_uuid)}", method="DELETE", headers={ - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, ) @@ -1583,7 +1581,7 @@ async def update( OK """ _response = await self._client_wrapper.httpx_client.request( - f"users/{jsonable_encoder(user_uuid)}", + f"users/{encode_path_param(user_uuid)}", method="PATCH", json={ "disable_default_ontology": disable_default_ontology, @@ -1595,7 +1593,7 @@ async def update( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -1685,7 +1683,7 @@ async def get_node( OK """ _response = await self._client_wrapper.httpx_client.request( - f"users/{jsonable_encoder(user_uuid)}/node", + f"users/{encode_path_param(user_uuid)}/node", method="GET", request_options=request_options, ) @@ -1785,7 +1783,7 @@ async def get_summary_instructions( OK """ _response = await self._client_wrapper.httpx_client.request( - f"users/{jsonable_encoder(user_uuid)}/summary-instructions", + f"users/{encode_path_param(user_uuid)}/summary-instructions", method="GET", request_options=request_options, ) @@ -1879,7 +1877,7 @@ async def set_summary_instructions( OK """ _response = await self._client_wrapper.httpx_client.request( - f"users/{jsonable_encoder(user_uuid)}/summary-instructions", + f"users/{encode_path_param(user_uuid)}/summary-instructions", method="PUT", json={ "inherited": inherited, @@ -1889,7 +1887,7 @@ async def set_summary_instructions( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, diff --git a/src/zep_cloud/user/types/__init__.py b/src/zep_cloud/user/types/__init__.py new file mode 100644 index 00000000..d3c27d36 --- /dev/null +++ b/src/zep_cloud/user/types/__init__.py @@ -0,0 +1,38 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .user_list_request_order import UserListRequestOrder + from .user_list_request_order_by import UserListRequestOrderBy +_dynamic_imports: typing.Dict[str, str] = { + "UserListRequestOrder": ".user_list_request_order", + "UserListRequestOrderBy": ".user_list_request_order_by", +} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = ["UserListRequestOrder", "UserListRequestOrderBy"] diff --git a/src/zep_cloud/user/types/user_list_request_order.py b/src/zep_cloud/user/types/user_list_request_order.py new file mode 100644 index 00000000..c7e95fd6 --- /dev/null +++ b/src/zep_cloud/user/types/user_list_request_order.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +UserListRequestOrder = typing.Union[typing.Literal["asc", "desc"], typing.Any] diff --git a/src/zep_cloud/user/types/user_list_request_order_by.py b/src/zep_cloud/user/types/user_list_request_order_by.py new file mode 100644 index 00000000..ef0d1841 --- /dev/null +++ b/src/zep_cloud/user/types/user_list_request_order_by.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +UserListRequestOrderBy = typing.Union[typing.Literal["created_at", "user_id", "email", "uuid"], typing.Any] diff --git a/src/zep_cloud/user_group/client.py b/src/zep_cloud/user_group/client.py index f9d01e71..3a849190 100644 --- a/src/zep_cloud/user_group/client.py +++ b/src/zep_cloud/user_group/client.py @@ -82,7 +82,6 @@ def list( limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, search: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[UserGroup, UserGroupPage]: """ @@ -99,8 +98,6 @@ def list( search : typing.Optional[str] Filters results to items matching this free-text search term. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -116,19 +113,14 @@ def list( client = Zep( api_key="YOUR_API_KEY", ) - response = client.user_group.list( - limit=1, - cursor="cursor", - ) + response = client.user_group.list() for item in response: yield item # alternatively, you can paginate page-by-page for page in response.iter_pages(): yield page """ - return self._raw_client.list( - limit=limit, cursor=cursor, search=search, idempotency_key=idempotency_key, request_options=request_options - ) + return self._raw_client.list(limit=limit, cursor=cursor, search=search, request_options=request_options) def get(self, group_uuid: str, *, request_options: typing.Optional[RequestOptions] = None) -> UserGroup: """ @@ -266,7 +258,6 @@ def list_member_candidates( limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, search: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[User, UserPage]: """ @@ -286,8 +277,6 @@ def list_member_candidates( search : typing.Optional[str] Filters results to items matching this free-text search term. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -305,8 +294,6 @@ def list_member_candidates( ) response = client.user_group.list_member_candidates( group_uuid="group_uuid", - limit=1, - cursor="cursor", ) for item in response: yield item @@ -315,12 +302,7 @@ def list_member_candidates( yield page """ return self._raw_client.list_member_candidates( - group_uuid, - limit=limit, - cursor=cursor, - search=search, - idempotency_key=idempotency_key, - request_options=request_options, + group_uuid, limit=limit, cursor=cursor, search=search, request_options=request_options ) def add_members( @@ -376,7 +358,6 @@ def list_members( limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, search: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[User, UserPage]: """ @@ -396,8 +377,6 @@ def list_members( search : typing.Optional[str] Filters results to items matching this free-text search term. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -415,8 +394,6 @@ def list_members( ) response = client.user_group.list_members( group_uuid="group_uuid", - limit=1, - cursor="cursor", ) for item in response: yield item @@ -425,12 +402,7 @@ def list_members( yield page """ return self._raw_client.list_members( - group_uuid, - limit=limit, - cursor=cursor, - search=search, - idempotency_key=idempotency_key, - request_options=request_options, + group_uuid, limit=limit, cursor=cursor, search=search, request_options=request_options ) def remove_members( @@ -563,8 +535,6 @@ def list_for_user( ) response = client.user_group.list_for_user( user_uuid="user_uuid", - limit=1, - cursor="cursor", ) for item in response: yield item @@ -649,7 +619,6 @@ async def list( limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, search: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[UserGroup, UserGroupPage]: """ @@ -666,8 +635,6 @@ async def list( search : typing.Optional[str] Filters results to items matching this free-text search term. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -688,10 +655,7 @@ async def list( async def main() -> None: - response = await client.user_group.list( - limit=1, - cursor="cursor", - ) + response = await client.user_group.list() async for item in response: yield item @@ -702,9 +666,7 @@ async def main() -> None: asyncio.run(main()) """ - return await self._raw_client.list( - limit=limit, cursor=cursor, search=search, idempotency_key=idempotency_key, request_options=request_options - ) + return await self._raw_client.list(limit=limit, cursor=cursor, search=search, request_options=request_options) async def get(self, group_uuid: str, *, request_options: typing.Optional[RequestOptions] = None) -> UserGroup: """ @@ -866,7 +828,6 @@ async def list_member_candidates( limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, search: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[User, UserPage]: """ @@ -886,8 +847,6 @@ async def list_member_candidates( search : typing.Optional[str] Filters results to items matching this free-text search term. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -910,8 +869,6 @@ async def list_member_candidates( async def main() -> None: response = await client.user_group.list_member_candidates( group_uuid="group_uuid", - limit=1, - cursor="cursor", ) async for item in response: yield item @@ -924,12 +881,7 @@ async def main() -> None: asyncio.run(main()) """ return await self._raw_client.list_member_candidates( - group_uuid, - limit=limit, - cursor=cursor, - search=search, - idempotency_key=idempotency_key, - request_options=request_options, + group_uuid, limit=limit, cursor=cursor, search=search, request_options=request_options ) async def add_members( @@ -993,7 +945,6 @@ async def list_members( limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, search: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[User, UserPage]: """ @@ -1013,8 +964,6 @@ async def list_members( search : typing.Optional[str] Filters results to items matching this free-text search term. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1037,8 +986,6 @@ async def list_members( async def main() -> None: response = await client.user_group.list_members( group_uuid="group_uuid", - limit=1, - cursor="cursor", ) async for item in response: yield item @@ -1051,12 +998,7 @@ async def main() -> None: asyncio.run(main()) """ return await self._raw_client.list_members( - group_uuid, - limit=limit, - cursor=cursor, - search=search, - idempotency_key=idempotency_key, - request_options=request_options, + group_uuid, limit=limit, cursor=cursor, search=search, request_options=request_options ) async def remove_members( @@ -1210,8 +1152,6 @@ async def list_for_user( async def main() -> None: response = await client.user_group.list_for_user( user_uuid="user_uuid", - limit=1, - cursor="cursor", ) async for item in response: yield item diff --git a/src/zep_cloud/user_group/raw_client.py b/src/zep_cloud/user_group/raw_client.py index 518b06ca..06bb3f70 100644 --- a/src/zep_cloud/user_group/raw_client.py +++ b/src/zep_cloud/user_group/raw_client.py @@ -6,7 +6,8 @@ from ..core.api_error import ApiError as core_api_error_ApiError from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ..core.http_response import AsyncHttpResponse, HttpResponse -from ..core.jsonable_encoder import jsonable_encoder +from ..core.idempotency import generate_idempotency_key +from ..core.jsonable_encoder import encode_path_param from ..core.pagination import AsyncPager, SyncPager from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as @@ -70,7 +71,7 @@ def create( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -159,7 +160,6 @@ def list( limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, search: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[UserGroup, UserGroupPage]: """ @@ -176,8 +176,6 @@ def list( search : typing.Optional[str] Filters results to items matching this free-text search term. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -198,7 +196,7 @@ def list( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -219,7 +217,6 @@ def list( limit=limit, cursor=_parsed_next, search=search, - idempotency_key=idempotency_key, request_options=request_options, ) return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) @@ -300,7 +297,7 @@ def get( OK """ _response = self._client_wrapper.httpx_client.request( - f"user-groups/{jsonable_encoder(group_uuid)}", + f"user-groups/{encode_path_param(group_uuid)}", method="GET", request_options=request_options, ) @@ -396,10 +393,10 @@ def delete( HttpResponse[None] """ _response = self._client_wrapper.httpx_client.request( - f"user-groups/{jsonable_encoder(group_uuid)}", + f"user-groups/{encode_path_param(group_uuid)}", method="DELETE", headers={ - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, ) @@ -512,7 +509,7 @@ def update( OK """ _response = self._client_wrapper.httpx_client.request( - f"user-groups/{jsonable_encoder(group_uuid)}", + f"user-groups/{encode_path_param(group_uuid)}", method="PATCH", json={ "description": description, @@ -521,7 +518,7 @@ def update( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -611,7 +608,6 @@ def list_member_candidates( limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, search: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[User, UserPage]: """ @@ -631,8 +627,6 @@ def list_member_candidates( search : typing.Optional[str] Filters results to items matching this free-text search term. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -642,7 +636,7 @@ def list_member_candidates( OK """ _response = self._client_wrapper.httpx_client.request( - f"user-groups/{jsonable_encoder(group_uuid)}/member-candidates/list", + f"user-groups/{encode_path_param(group_uuid)}/member-candidates/list", method="POST", params={ "limit": limit, @@ -653,7 +647,7 @@ def list_member_candidates( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -675,7 +669,6 @@ def list_member_candidates( limit=limit, cursor=_parsed_next, search=search, - idempotency_key=idempotency_key, request_options=request_options, ) return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) @@ -777,14 +770,14 @@ def add_members( OK """ _response = self._client_wrapper.httpx_client.request( - f"user-groups/{jsonable_encoder(group_uuid)}/members", + f"user-groups/{encode_path_param(group_uuid)}/members", method="POST", json={ "user_uuids": user_uuids, }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -874,7 +867,6 @@ def list_members( limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, search: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[User, UserPage]: """ @@ -894,8 +886,6 @@ def list_members( search : typing.Optional[str] Filters results to items matching this free-text search term. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -905,7 +895,7 @@ def list_members( OK """ _response = self._client_wrapper.httpx_client.request( - f"user-groups/{jsonable_encoder(group_uuid)}/members/list", + f"user-groups/{encode_path_param(group_uuid)}/members/list", method="POST", params={ "limit": limit, @@ -916,7 +906,7 @@ def list_members( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -938,7 +928,6 @@ def list_members( limit=limit, cursor=_parsed_next, search=search, - idempotency_key=idempotency_key, request_options=request_options, ) return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) @@ -1029,14 +1018,14 @@ def remove_members( OK """ _response = self._client_wrapper.httpx_client.request( - f"user-groups/{jsonable_encoder(group_uuid)}/members/remove", + f"user-groups/{encode_path_param(group_uuid)}/members/remove", method="POST", json={ "user_uuids": user_uuids, }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -1148,10 +1137,10 @@ def remove_member( HttpResponse[None] """ _response = self._client_wrapper.httpx_client.request( - f"user-groups/{jsonable_encoder(group_uuid)}/members/{jsonable_encoder(user_uuid)}", + f"user-groups/{encode_path_param(group_uuid)}/members/{encode_path_param(user_uuid)}", method="DELETE", headers={ - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, ) @@ -1257,7 +1246,7 @@ def list_for_user( OK """ _response = self._client_wrapper.httpx_client.request( - f"users/{jsonable_encoder(user_uuid)}/user-groups", + f"users/{encode_path_param(user_uuid)}/user-groups", method="GET", params={ "limit": limit, @@ -1395,7 +1384,7 @@ async def create( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -1484,7 +1473,6 @@ async def list( limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, search: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[UserGroup, UserGroupPage]: """ @@ -1501,8 +1489,6 @@ async def list( search : typing.Optional[str] Filters results to items matching this free-text search term. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1523,7 +1509,7 @@ async def list( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -1546,7 +1532,6 @@ async def _get_next(): limit=limit, cursor=_parsed_next, search=search, - idempotency_key=idempotency_key, request_options=request_options, ) @@ -1628,7 +1613,7 @@ async def get( OK """ _response = await self._client_wrapper.httpx_client.request( - f"user-groups/{jsonable_encoder(group_uuid)}", + f"user-groups/{encode_path_param(group_uuid)}", method="GET", request_options=request_options, ) @@ -1724,10 +1709,10 @@ async def delete( AsyncHttpResponse[None] """ _response = await self._client_wrapper.httpx_client.request( - f"user-groups/{jsonable_encoder(group_uuid)}", + f"user-groups/{encode_path_param(group_uuid)}", method="DELETE", headers={ - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, ) @@ -1840,7 +1825,7 @@ async def update( OK """ _response = await self._client_wrapper.httpx_client.request( - f"user-groups/{jsonable_encoder(group_uuid)}", + f"user-groups/{encode_path_param(group_uuid)}", method="PATCH", json={ "description": description, @@ -1849,7 +1834,7 @@ async def update( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -1939,7 +1924,6 @@ async def list_member_candidates( limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, search: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[User, UserPage]: """ @@ -1959,8 +1943,6 @@ async def list_member_candidates( search : typing.Optional[str] Filters results to items matching this free-text search term. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1970,7 +1952,7 @@ async def list_member_candidates( OK """ _response = await self._client_wrapper.httpx_client.request( - f"user-groups/{jsonable_encoder(group_uuid)}/member-candidates/list", + f"user-groups/{encode_path_param(group_uuid)}/member-candidates/list", method="POST", params={ "limit": limit, @@ -1981,7 +1963,7 @@ async def list_member_candidates( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -2005,7 +1987,6 @@ async def _get_next(): limit=limit, cursor=_parsed_next, search=search, - idempotency_key=idempotency_key, request_options=request_options, ) @@ -2108,14 +2089,14 @@ async def add_members( OK """ _response = await self._client_wrapper.httpx_client.request( - f"user-groups/{jsonable_encoder(group_uuid)}/members", + f"user-groups/{encode_path_param(group_uuid)}/members", method="POST", json={ "user_uuids": user_uuids, }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -2205,7 +2186,6 @@ async def list_members( limit: typing.Optional[int] = None, cursor: typing.Optional[str] = None, search: typing.Optional[str] = OMIT, - idempotency_key: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[User, UserPage]: """ @@ -2225,8 +2205,6 @@ async def list_members( search : typing.Optional[str] Filters results to items matching this free-text search term. - idempotency_key : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -2236,7 +2214,7 @@ async def list_members( OK """ _response = await self._client_wrapper.httpx_client.request( - f"user-groups/{jsonable_encoder(group_uuid)}/members/list", + f"user-groups/{encode_path_param(group_uuid)}/members/list", method="POST", params={ "limit": limit, @@ -2247,7 +2225,7 @@ async def list_members( }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -2271,7 +2249,6 @@ async def _get_next(): limit=limit, cursor=_parsed_next, search=search, - idempotency_key=idempotency_key, request_options=request_options, ) @@ -2363,14 +2340,14 @@ async def remove_members( OK """ _response = await self._client_wrapper.httpx_client.request( - f"user-groups/{jsonable_encoder(group_uuid)}/members/remove", + f"user-groups/{encode_path_param(group_uuid)}/members/remove", method="POST", json={ "user_uuids": user_uuids, }, headers={ "content-type": "application/json", - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, omit=OMIT, @@ -2482,10 +2459,10 @@ async def remove_member( AsyncHttpResponse[None] """ _response = await self._client_wrapper.httpx_client.request( - f"user-groups/{jsonable_encoder(group_uuid)}/members/{jsonable_encoder(user_uuid)}", + f"user-groups/{encode_path_param(group_uuid)}/members/{encode_path_param(user_uuid)}", method="DELETE", headers={ - "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else None, + "Idempotency-Key": str(idempotency_key) if idempotency_key is not None else generate_idempotency_key(), }, request_options=request_options, ) @@ -2591,7 +2568,7 @@ async def list_for_user( OK """ _response = await self._client_wrapper.httpx_client.request( - f"users/{jsonable_encoder(user_uuid)}/user-groups", + f"users/{encode_path_param(user_uuid)}/user-groups", method="GET", params={ "limit": limit, diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 00000000..25710dbe --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,21 @@ +import pytest + + +def _has_httpx_aiohttp() -> bool: + """Check if httpx_aiohttp is importable.""" + try: + import httpx_aiohttp # type: ignore[import-not-found] # noqa: F401 + + return True + except ImportError: + return False + + +def pytest_collection_modifyitems(config: pytest.Config, items: list) -> None: + """Auto-skip @pytest.mark.aiohttp tests when httpx_aiohttp is not installed.""" + if _has_httpx_aiohttp(): + return + skip_aiohttp = pytest.mark.skip(reason="httpx_aiohttp not installed") + for item in items: + if "aiohttp" in item.keywords: + item.add_marker(skip_aiohttp) diff --git a/tests/test_aiohttp_autodetect.py b/tests/test_aiohttp_autodetect.py new file mode 100644 index 00000000..3ef2f902 --- /dev/null +++ b/tests/test_aiohttp_autodetect.py @@ -0,0 +1,116 @@ +import importlib +import sys +import unittest +from unittest import mock + +import httpx +import pytest + + +class TestMakeDefaultAsyncClientWithoutAiohttp(unittest.TestCase): + """Tests for _make_default_async_client when httpx_aiohttp is NOT installed.""" + + def test_returns_httpx_async_client(self) -> None: + """When httpx_aiohttp is not installed, returns plain httpx.AsyncClient.""" + with mock.patch.dict(sys.modules, {"httpx_aiohttp": None}): + from zep_cloud.base_client import _make_default_async_client + + client = _make_default_async_client(timeout=60, follow_redirects=True) + self.assertIsInstance(client, httpx.AsyncClient) + self.assertEqual(client.timeout.read, 60) + self.assertTrue(client.follow_redirects) + + def test_follow_redirects_none(self) -> None: + """When follow_redirects is None, omits it from httpx.AsyncClient.""" + with mock.patch.dict(sys.modules, {"httpx_aiohttp": None}): + from zep_cloud.base_client import _make_default_async_client + + client = _make_default_async_client(timeout=60, follow_redirects=None) + self.assertIsInstance(client, httpx.AsyncClient) + self.assertFalse(client.follow_redirects) + + def test_explicit_httpx_client_bypasses_autodetect(self) -> None: + """When user passes httpx_client explicitly, _make_default_async_client is not called.""" + + explicit_client = httpx.AsyncClient(timeout=120) + with mock.patch("zep_cloud.base_client._make_default_async_client") as mock_make: + # Replicate the generated conditional: httpx_client if httpx_client is not None else _make_default_async_client(...) + result = explicit_client if explicit_client is not None else mock_make(timeout=60, follow_redirects=True) + mock_make.assert_not_called() + self.assertIs(result, explicit_client) + + +@pytest.mark.aiohttp +class TestMakeDefaultAsyncClientWithAiohttp(unittest.TestCase): + """Tests for _make_default_async_client when httpx_aiohttp IS installed.""" + + def test_returns_aiohttp_client(self) -> None: + """When httpx_aiohttp is installed, returns HttpxAiohttpClient.""" + import httpx_aiohttp # type: ignore[import-not-found] + + from zep_cloud.base_client import _make_default_async_client + + client = _make_default_async_client(timeout=60, follow_redirects=True) + self.assertIsInstance(client, httpx_aiohttp.HttpxAiohttpClient) + self.assertEqual(client.timeout.read, 60) + self.assertTrue(client.follow_redirects) + + def test_follow_redirects_none(self) -> None: + """When httpx_aiohttp is installed and follow_redirects is None, omits it.""" + import httpx_aiohttp # type: ignore[import-not-found] + + from zep_cloud.base_client import _make_default_async_client + + client = _make_default_async_client(timeout=60, follow_redirects=None) + self.assertIsInstance(client, httpx_aiohttp.HttpxAiohttpClient) + self.assertFalse(client.follow_redirects) + + +class TestDefaultClientsWithoutAiohttp(unittest.TestCase): + """Tests for _default_clients.py convenience classes (no aiohttp).""" + + def test_default_async_httpx_client_defaults(self) -> None: + """DefaultAsyncHttpxClient applies SDK defaults.""" + from zep_cloud._default_clients import SDK_DEFAULT_TIMEOUT, DefaultAsyncHttpxClient + + client = DefaultAsyncHttpxClient() + self.assertIsInstance(client, httpx.AsyncClient) + self.assertEqual(client.timeout.read, SDK_DEFAULT_TIMEOUT) + self.assertTrue(client.follow_redirects) + + def test_default_async_httpx_client_overrides(self) -> None: + """DefaultAsyncHttpxClient allows overriding defaults.""" + from zep_cloud._default_clients import DefaultAsyncHttpxClient + + client = DefaultAsyncHttpxClient(timeout=30, follow_redirects=False) + self.assertEqual(client.timeout.read, 30) + self.assertFalse(client.follow_redirects) + + def test_default_aiohttp_client_raises_without_package(self) -> None: + """DefaultAioHttpClient raises RuntimeError when httpx_aiohttp not installed.""" + import zep_cloud._default_clients + + with mock.patch.dict(sys.modules, {"httpx_aiohttp": None}): + importlib.reload(zep_cloud._default_clients) + + with self.assertRaises(RuntimeError) as ctx: + zep_cloud._default_clients.DefaultAioHttpClient() + self.assertIn("pip install zep-cloud[aiohttp]", str(ctx.exception)) + + importlib.reload(zep_cloud._default_clients) + + +@pytest.mark.aiohttp +class TestDefaultClientsWithAiohttp(unittest.TestCase): + """Tests for _default_clients.py when httpx_aiohttp IS installed.""" + + def test_default_aiohttp_client_defaults(self) -> None: + """DefaultAioHttpClient works when httpx_aiohttp is installed.""" + import httpx_aiohttp # type: ignore[import-not-found] + + from zep_cloud._default_clients import SDK_DEFAULT_TIMEOUT, DefaultAioHttpClient + + client = DefaultAioHttpClient() + self.assertIsInstance(client, httpx_aiohttp.HttpxAiohttpClient) + self.assertEqual(client.timeout.read, SDK_DEFAULT_TIMEOUT) + self.assertTrue(client.follow_redirects) diff --git a/tests/utils/test_http_client.py b/tests/utils/test_http_client.py index 87b8183d..762f5537 100644 --- a/tests/utils/test_http_client.py +++ b/tests/utils/test_http_client.py @@ -1,13 +1,19 @@ # This file was auto-generated by Fern from our API Definition. -from typing import Any, Dict +from typing import Any, Dict, Tuple, cast +from unittest.mock import AsyncMock, MagicMock, patch +import httpx import pytest from zep_cloud.core.http_client import ( AsyncHttpClient, HttpClient, _build_url, + _merge_headers, + _redact_headers, + _should_retry, + drop_content_type_without_body, get_request_body, remove_none_from_dict, ) @@ -118,6 +124,67 @@ def test_explicit_empty_json_body_is_preserved() -> None: assert data_body2 == {} +def test_omitted_body_sends_no_content() -> None: + """A body left at the sentinel was never passed, so nothing is sent. + + This is how an endpoint whose body may be omitted stays bodyless, as opposed to + sending an empty ``{}``. An explicit ``None`` still reaches the wire as ``null``. + """ + omit = cast(Any, ...) + unrelated_request_options: RequestOptions = {"max_retries": 3} + + json_body, data_body = get_request_body(json=omit, data=None, request_options=unrelated_request_options, omit=omit) + assert json_body is None + assert data_body is None + + json_body2, data_body2 = get_request_body( + json=None, data=omit, request_options=unrelated_request_options, omit=omit + ) + assert json_body2 is None + assert data_body2 is None + + # an explicitly passed body is untouched + json_body3, _ = get_request_body(json={"hello": "world"}, data=None, request_options=None, omit=omit) + assert json_body3 == {"hello": "world"} + + +def test_optional_body_sends_no_content_when_every_property_is_omitted() -> None: + """An endpoint that inlines an omittable body sends nothing once every property is omitted. + + The body reaches the client as a dict of sentinels rather than as a single argument, so + ``optional_body`` is what tells the client that an empty result means "no body at all". + """ + omit = cast(Any, ...) + + json_body, data_body = get_request_body( + json={"amount": omit, "source": omit}, data=None, request_options=None, omit=omit, optional_body=True + ) + assert json_body is None + assert data_body is None + + # a body the API requires still goes out as `{}` + required_json_body, _ = get_request_body( + json={"amount": omit, "source": omit}, data=None, request_options=None, omit=omit + ) + assert required_json_body == {} + + # a property the caller did pass keeps the body + populated_json_body, _ = get_request_body( + json={"amount": 1, "source": omit}, data=None, request_options=None, omit=omit, optional_body=True + ) + assert populated_json_body == {"amount": 1} + + # additional body parameters keep the body, since the caller asked for them + with_additional_body_parameters, _ = get_request_body( + json={"amount": omit}, + data=None, + request_options={"additional_body_parameters": {"custom": "value"}}, + omit=omit, + optional_body=True, + ) + assert with_additional_body_parameters == {"custom": "value"} + + def test_json_body_preserves_none_values() -> None: """Test that JSON bodies preserve None values (they become JSON null).""" json_body, data_body = get_request_body( @@ -298,3 +365,516 @@ def test_preserves_base_url_path_prefix_trailing_slash() -> None: """Test that path prefixes in base URL are preserved.""" result = _build_url("https://cloud.example.com/org/tenant/api/", "/users") assert result == "https://cloud.example.com/org/tenant/api/users" + + +# --------------------------------------------------------------------------- +# Connection error retry tests +# --------------------------------------------------------------------------- + + +def _make_sync_http_client(mock_client: Any) -> HttpClient: + return HttpClient( + httpx_client=mock_client, # type: ignore[arg-type] + base_timeout=lambda: None, + base_headers=lambda: {}, + base_url=lambda: "https://example.com", + ) + + +def _make_async_http_client(mock_client: Any) -> AsyncHttpClient: + return AsyncHttpClient( + httpx_client=mock_client, # type: ignore[arg-type] + base_timeout=lambda: None, + base_headers=lambda: {}, + base_url=lambda: "https://example.com", + async_base_headers=None, + ) + + +@patch("zep_cloud.core.http_client.time.sleep", return_value=None) +def test_sync_retries_on_connect_error(mock_sleep: MagicMock) -> None: + """Sync: connection error retries on httpx.ConnectError.""" + mock_client = MagicMock() + mock_client.request.side_effect = [ + httpx.ConnectError("connection failed"), + _DummyResponse(), + ] + http_client = _make_sync_http_client(mock_client) + + response = http_client.request(path="/test", method="GET") + + assert response.status_code == 200 + assert mock_client.request.call_count == 2 + mock_sleep.assert_called_once() + + +@patch("zep_cloud.core.http_client.time.sleep", return_value=None) +def test_sync_retries_on_remote_protocol_error(mock_sleep: MagicMock) -> None: + """Sync: connection error retries on httpx.RemoteProtocolError.""" + mock_client = MagicMock() + mock_client.request.side_effect = [ + httpx.RemoteProtocolError("Remote end closed connection without response"), + _DummyResponse(), + ] + http_client = _make_sync_http_client(mock_client) + + response = http_client.request(path="/test", method="GET") + + assert response.status_code == 200 + assert mock_client.request.call_count == 2 + mock_sleep.assert_called_once() + + +@patch("zep_cloud.core.http_client.time.sleep", return_value=None) +def test_sync_connection_error_exhausts_retries(mock_sleep: MagicMock) -> None: + """Sync: connection error exhausts retries then raises.""" + mock_client = MagicMock() + mock_client.request.side_effect = httpx.ConnectError("connection failed") + http_client = _make_sync_http_client(mock_client) + + with pytest.raises(httpx.ConnectError): + http_client.request( + path="/test", + method="GET", + request_options={"max_retries": 2}, + ) + + # 1 initial + 2 retries = 3 total attempts + assert mock_client.request.call_count == 3 + assert mock_sleep.call_count == 2 + + +@patch("zep_cloud.core.http_client.time.sleep", return_value=None) +def test_sync_connection_error_respects_max_retries_zero(mock_sleep: MagicMock) -> None: + """Sync: connection error respects max_retries=0.""" + mock_client = MagicMock() + mock_client.request.side_effect = httpx.ConnectError("connection failed") + http_client = _make_sync_http_client(mock_client) + + with pytest.raises(httpx.ConnectError): + http_client.request( + path="/test", + method="GET", + request_options={"max_retries": 0}, + ) + + # No retries, just the initial attempt + assert mock_client.request.call_count == 1 + mock_sleep.assert_not_called() + + +@pytest.mark.asyncio +@patch("zep_cloud.core.http_client.asyncio.sleep", new_callable=AsyncMock) +async def test_async_retries_on_connect_error(mock_sleep: AsyncMock) -> None: + """Async: connection error retries on httpx.ConnectError.""" + mock_client = MagicMock() + mock_client.request = AsyncMock( + side_effect=[ + httpx.ConnectError("connection failed"), + _DummyResponse(), + ] + ) + http_client = _make_async_http_client(mock_client) + + response = await http_client.request(path="/test", method="GET") + + assert response.status_code == 200 + assert mock_client.request.call_count == 2 + mock_sleep.assert_called_once() + + +@pytest.mark.asyncio +@patch("zep_cloud.core.http_client.asyncio.sleep", new_callable=AsyncMock) +async def test_async_retries_on_remote_protocol_error(mock_sleep: AsyncMock) -> None: + """Async: connection error retries on httpx.RemoteProtocolError.""" + mock_client = MagicMock() + mock_client.request = AsyncMock( + side_effect=[ + httpx.RemoteProtocolError("Remote end closed connection without response"), + _DummyResponse(), + ] + ) + http_client = _make_async_http_client(mock_client) + + response = await http_client.request(path="/test", method="GET") + + assert response.status_code == 200 + assert mock_client.request.call_count == 2 + mock_sleep.assert_called_once() + + +@pytest.mark.asyncio +@patch("zep_cloud.core.http_client.asyncio.sleep", new_callable=AsyncMock) +async def test_async_connection_error_exhausts_retries(mock_sleep: AsyncMock) -> None: + """Async: connection error exhausts retries then raises.""" + mock_client = MagicMock() + mock_client.request = AsyncMock(side_effect=httpx.ConnectError("connection failed")) + http_client = _make_async_http_client(mock_client) + + with pytest.raises(httpx.ConnectError): + await http_client.request( + path="/test", + method="GET", + request_options={"max_retries": 2}, + ) + + # 1 initial + 2 retries = 3 total attempts + assert mock_client.request.call_count == 3 + assert mock_sleep.call_count == 2 + + +# --------------------------------------------------------------------------- +# base_max_retries constructor parameter tests +# --------------------------------------------------------------------------- + + +def test_sync_http_client_default_base_max_retries() -> None: + """HttpClient defaults to base_max_retries=2.""" + http_client = HttpClient( + httpx_client=MagicMock(), # type: ignore[arg-type] + base_timeout=lambda: None, + base_headers=lambda: {}, + ) + assert http_client.base_max_retries == 2 + + +def test_async_http_client_default_base_max_retries() -> None: + """AsyncHttpClient defaults to base_max_retries=2.""" + http_client = AsyncHttpClient( + httpx_client=MagicMock(), # type: ignore[arg-type] + base_timeout=lambda: None, + base_headers=lambda: {}, + ) + assert http_client.base_max_retries == 2 + + +def test_sync_http_client_custom_base_max_retries() -> None: + """HttpClient accepts a custom base_max_retries value.""" + http_client = HttpClient( + httpx_client=MagicMock(), # type: ignore[arg-type] + base_timeout=lambda: None, + base_headers=lambda: {}, + base_max_retries=5, + ) + assert http_client.base_max_retries == 5 + + +def test_async_http_client_custom_base_max_retries() -> None: + """AsyncHttpClient accepts a custom base_max_retries value.""" + http_client = AsyncHttpClient( + httpx_client=MagicMock(), # type: ignore[arg-type] + base_timeout=lambda: None, + base_headers=lambda: {}, + base_max_retries=5, + ) + assert http_client.base_max_retries == 5 + + +@patch("zep_cloud.core.http_client.time.sleep", return_value=None) +def test_sync_base_max_retries_zero_disables_retries(mock_sleep: MagicMock) -> None: + """Sync: base_max_retries=0 disables retries when no request_options override.""" + mock_client = MagicMock() + mock_client.request.side_effect = httpx.ConnectError("connection failed") + http_client = HttpClient( + httpx_client=mock_client, # type: ignore[arg-type] + base_timeout=lambda: None, + base_headers=lambda: {}, + base_url=lambda: "https://example.com", + base_max_retries=0, + ) + + with pytest.raises(httpx.ConnectError): + http_client.request(path="/test", method="GET") + + # No retries, just the initial attempt + assert mock_client.request.call_count == 1 + mock_sleep.assert_not_called() + + +@pytest.mark.asyncio +@patch("zep_cloud.core.http_client.asyncio.sleep", new_callable=AsyncMock) +async def test_async_base_max_retries_zero_disables_retries(mock_sleep: AsyncMock) -> None: + """Async: base_max_retries=0 disables retries when no request_options override.""" + mock_client = MagicMock() + mock_client.request = AsyncMock(side_effect=httpx.ConnectError("connection failed")) + http_client = AsyncHttpClient( + httpx_client=mock_client, # type: ignore[arg-type] + base_timeout=lambda: None, + base_headers=lambda: {}, + base_url=lambda: "https://example.com", + base_max_retries=0, + ) + + with pytest.raises(httpx.ConnectError): + await http_client.request(path="/test", method="GET") + + # No retries, just the initial attempt + assert mock_client.request.call_count == 1 + mock_sleep.assert_not_called() + + +@patch("zep_cloud.core.http_client.time.sleep", return_value=None) +def test_sync_request_options_override_base_max_retries(mock_sleep: MagicMock) -> None: + """Sync: request_options max_retries overrides base_max_retries.""" + mock_client = MagicMock() + mock_client.request.side_effect = [ + httpx.ConnectError("connection failed"), + httpx.ConnectError("connection failed"), + _DummyResponse(), + ] + http_client = HttpClient( + httpx_client=mock_client, # type: ignore[arg-type] + base_timeout=lambda: None, + base_headers=lambda: {}, + base_url=lambda: "https://example.com", + base_max_retries=0, # base says no retries + ) + + # But request_options overrides to allow 2 retries + response = http_client.request( + path="/test", + method="GET", + request_options={"max_retries": 2}, + ) + + assert response.status_code == 200 + # 1 initial + 2 retries = 3 total attempts + assert mock_client.request.call_count == 3 + + +@pytest.mark.asyncio +@patch("zep_cloud.core.http_client.asyncio.sleep", new_callable=AsyncMock) +async def test_async_request_options_override_base_max_retries(mock_sleep: AsyncMock) -> None: + """Async: request_options max_retries overrides base_max_retries.""" + mock_client = MagicMock() + mock_client.request = AsyncMock( + side_effect=[ + httpx.ConnectError("connection failed"), + httpx.ConnectError("connection failed"), + _DummyResponse(), + ] + ) + http_client = AsyncHttpClient( + httpx_client=mock_client, # type: ignore[arg-type] + base_timeout=lambda: None, + base_headers=lambda: {}, + base_url=lambda: "https://example.com", + base_max_retries=0, # base says no retries + ) + + # But request_options overrides to allow 2 retries + response = await http_client.request( + path="/test", + method="GET", + request_options={"max_retries": 2}, + ) + + assert response.status_code == 200 + # 1 initial + 2 retries = 3 total attempts + assert mock_client.request.call_count == 3 + + +@patch("zep_cloud.core.http_client.time.sleep", return_value=None) +def test_sync_base_max_retries_used_as_default(mock_sleep: MagicMock) -> None: + """Sync: base_max_retries is used when request_options has no max_retries.""" + mock_client = MagicMock() + mock_client.request.side_effect = [ + httpx.ConnectError("fail"), + httpx.ConnectError("fail"), + httpx.ConnectError("fail"), + _DummyResponse(), + ] + http_client = HttpClient( + httpx_client=mock_client, # type: ignore[arg-type] + base_timeout=lambda: None, + base_headers=lambda: {}, + base_url=lambda: "https://example.com", + base_max_retries=3, + ) + + response = http_client.request(path="/test", method="GET") + + assert response.status_code == 200 + # 1 initial + 3 retries = 4 total attempts + assert mock_client.request.call_count == 4 + + +@pytest.mark.asyncio +@patch("zep_cloud.core.http_client.asyncio.sleep", new_callable=AsyncMock) +async def test_async_base_max_retries_used_as_default(mock_sleep: AsyncMock) -> None: + """Async: base_max_retries is used when request_options has no max_retries.""" + mock_client = MagicMock() + mock_client.request = AsyncMock( + side_effect=[ + httpx.ConnectError("fail"), + httpx.ConnectError("fail"), + httpx.ConnectError("fail"), + _DummyResponse(), + ] + ) + http_client = AsyncHttpClient( + httpx_client=mock_client, # type: ignore[arg-type] + base_timeout=lambda: None, + base_headers=lambda: {}, + base_url=lambda: "https://example.com", + base_max_retries=3, + ) + + response = await http_client.request(path="/test", method="GET") + + assert response.status_code == 200 + # 1 initial + 3 retries = 4 total attempts + assert mock_client.request.call_count == 4 + + +# --------------------------------------------------------------------------- +# _should_retry unit tests +# --------------------------------------------------------------------------- + + +def _make_response(status_code: int) -> httpx.Response: + return httpx.Response(status_code=status_code, content=b"") + + +RETRYABLE_STATUS_CODES = [408, 409, 429, 500, 501, 502, 503, 504, 599] +NON_RETRYABLE_STATUS_CODES = [200, 201, 301, 400, 401, 403, 404] + + +@pytest.mark.parametrize("status_code", RETRYABLE_STATUS_CODES) +def test_should_retry_retryable_status_codes(status_code: int) -> None: + assert _should_retry(_make_response(status_code)) is True + + +@pytest.mark.parametrize("status_code", NON_RETRYABLE_STATUS_CODES) +def test_should_not_retry_non_retryable_status_codes(status_code: int) -> None: + assert _should_retry(_make_response(status_code)) is False + + +# --------------------------------------------------------------------------- +# RequestOptions timeout resolution tests (timeout / deprecated timeout_in_seconds) +# --------------------------------------------------------------------------- + + +def _sync_client_with_base_timeout(base_timeout: Any) -> Tuple[HttpClient, _DummySyncClient]: + dummy_client = _DummySyncClient() + http_client = HttpClient( + httpx_client=dummy_client, # type: ignore[arg-type] + base_timeout=lambda: base_timeout, + base_headers=lambda: {}, + base_url=lambda: "https://example.com", + ) + return http_client, dummy_client + + +def test_sync_request_options_timeout_used() -> None: + """The new `timeout` request option is passed through to httpx (in seconds).""" + http_client, dummy_client = _sync_client_with_base_timeout(60) + http_client.request(path="/test", method="GET", request_options={"timeout": 30}) + assert dummy_client.last_request_kwargs["timeout"] == 30 + + +def test_sync_request_options_timeout_in_seconds_still_works() -> None: + """The deprecated `timeout_in_seconds` request option remains backwards compatible.""" + http_client, dummy_client = _sync_client_with_base_timeout(60) + http_client.request(path="/test", method="GET", request_options={"timeout_in_seconds": 45}) + assert dummy_client.last_request_kwargs["timeout"] == 45 + + +def test_sync_request_options_timeout_takes_precedence() -> None: + """When both are set, `timeout` wins over `timeout_in_seconds` (same seconds unit).""" + http_client, dummy_client = _sync_client_with_base_timeout(60) + http_client.request(path="/test", method="GET", request_options={"timeout": 30, "timeout_in_seconds": 45}) + assert dummy_client.last_request_kwargs["timeout"] == 30 + + +def test_sync_request_options_timeout_falls_back_to_base() -> None: + """When neither key is set, the client-level base timeout is used.""" + http_client, dummy_client = _sync_client_with_base_timeout(60) + http_client.request(path="/test", method="GET", request_options=None) + assert dummy_client.last_request_kwargs["timeout"] == 60 + + +def test_sync_request_options_timeout_none_falls_back_to_deprecated() -> None: + """An explicit `timeout=None` (dynamic caller) falls back to the deprecated `timeout_in_seconds`.""" + http_client, dummy_client = _sync_client_with_base_timeout(60) + request_options = cast(RequestOptions, {"timeout": None, "timeout_in_seconds": 45}) + http_client.request(path="/test", method="GET", request_options=request_options) + assert dummy_client.last_request_kwargs["timeout"] == 45 + + +@pytest.mark.asyncio +async def test_async_request_options_timeout_takes_precedence() -> None: + """Async: `timeout` wins over the deprecated `timeout_in_seconds`.""" + dummy_client = _DummyAsyncClient() + http_client = AsyncHttpClient( + httpx_client=dummy_client, # type: ignore[arg-type] + base_timeout=lambda: 60, + base_headers=lambda: {}, + base_url=lambda: "https://example.com", + async_base_headers=None, + ) + await http_client.request(path="/test", method="GET", request_options={"timeout": 30, "timeout_in_seconds": 45}) + assert dummy_client.last_request_kwargs["timeout"] == 30 + + +def test_drop_content_type_without_body_omits_header_for_bodyless_optional_call() -> None: + """An optional-body endpoint the caller left empty must not advertise a media type. + + `get_request_body` drops the body, but the endpoint still hands over the content type it + would have used, so a server that branches on the header would see a JSON request carrying + nothing at all. + """ + headers = {"content-type": "application/json", "authorization": "Bearer x"} + + assert drop_content_type_without_body(headers, json_body=None, data_body=None, optional_body=True) == { + "authorization": "Bearer x" + } + + +def test_drop_content_type_without_body_keeps_header_when_a_body_is_sent() -> None: + headers = {"content-type": "application/json"} + + assert ( + drop_content_type_without_body(headers, json_body={"amount": 60}, data_body=None, optional_body=True) == headers + ) + assert drop_content_type_without_body(headers, json_body=None, data_body="raw", optional_body=True) == headers + + +def test_drop_content_type_without_body_leaves_required_body_endpoints_alone() -> None: + """Without the opt-in, an endpoint keeps the header it has always sent.""" + headers = {"Content-Type": "application/json"} + + assert drop_content_type_without_body(headers, json_body=None, data_body=None, optional_body=False) == headers + + +def test_merge_headers_replaces_case_variants() -> None: + merged = _merge_headers( + {"PLAID-SECRET": "base", "X-Other": "1"}, + {"plaid-secret": "endpoint"}, + None, + {"Plaid-Secret": "override"}, + ) + assert merged == {"X-Other": "1", "Plaid-Secret": "override"} + + +def test_redact_headers_is_case_insensitive() -> None: + redacted = _redact_headers({"AUTHORIZATION": "Bearer t", "X-Api-Key": "k", "Accept": "application/json"}) + assert redacted == {"AUTHORIZATION": "[REDACTED]", "X-Api-Key": "[REDACTED]", "Accept": "application/json"} + + +def test_http_client_sends_single_header_for_case_variant_override() -> None: + dummy_client = _DummySyncClient() + http_client = HttpClient( + httpx_client=dummy_client, # type: ignore[arg-type] + base_timeout=lambda: None, + base_headers=lambda: {"PLAID-SECRET": "base"}, + base_url=lambda: "https://example.com", + ) + http_client.request( + path="resource", + method="GET", + request_options={"additional_headers": {"plaid-secret": "override"}}, + ) + sent = dummy_client.last_request_kwargs["headers"] + assert [k for k in sent if k.lower() == "plaid-secret"] == ["plaid-secret"] + assert sent["plaid-secret"] == "override" From 1aeeef62ad1018d5bb1cf3270569aedd8d9e809a Mon Sep 17 00:00:00 2001 From: "fern-api[bot]" <115122769+fern-api[bot]@users.noreply.github.com> Date: Tue, 6 Oct 2026 17:55:33 +0000 Subject: [PATCH 2/3] [fern-replay] Applied customizations Patches applied (1): - patch-082f322d: Let an ontology field opt out, and fix the README (#348) --- .fern/replay.lock | 75 ++++++++++++++++++++++++++++++++++------------- README.md | 60 ------------------------------------- 2 files changed, 55 insertions(+), 80 deletions(-) diff --git a/.fern/replay.lock b/.fern/replay.lock index a25ea8cb..2093f38a 100644 --- a/.fern/replay.lock +++ b/.fern/replay.lock @@ -36,22 +36,28 @@ generations: cli_version: unknown generator_versions: fernapi/fern-python-sdk: 4.64.1 -current_generation: 307ba9f1f528288490ca0530f925b2ee22fe77a5 + - commit_sha: df5e05eb2b9d6e980f95ae3d41cb22a8230489c1 + tree_hash: 1c364b8652950aaeb304b54ed74819e631aab145 + timestamp: 2026-10-06T17:55:27.831Z + cli_version: unknown + generator_versions: + fernapi/fern-python-sdk: 5.34.3 +current_generation: df5e05eb2b9d6e980f95ae3d41cb22a8230489c1 patches: - id: patch-082f322d - content_hash: sha256:224b66a70143bfc3108720a64cc8e3347d9918ced9061c366471f239407f391a + content_hash: sha256:80c233468a0236864659e748ffa647c6c6a89435d3fca6dec28965e48b901c46 original_commit: 082f322d1bd077cff00e3630500ac6187251a000 original_message: Let an ontology field opt out, and fix the README (#348) original_author: Pavlo Paliychuk - base_generation: 307ba9f1f528288490ca0530f925b2ee22fe77a5 + base_generation: df5e05eb2b9d6e980f95ae3d41cb22a8230489c1 files: - README.md patch_content: | diff --git a/README.md b/README.md - index 08ab94f..7775bfb 100644 + index c775b5f..c861b30 100644 --- a/README.md +++ b/README.md - @@ -32,78 +32,18 @@ pip install zep-cloud + @@ -33,78 +33,18 @@ pip install zep-cloud > [!NOTE] > Zep Cloud [overview](https://help.getzep.com/concepts) and [cloud sdk guide](https://help.getzep.com/sdks). @@ -145,6 +151,7 @@ patches: - [Installation](#installation) - [Reference](#reference) - [Usage](#usage) + - [Environments](#environments) - [Async Client](#async-client) - [Exception Handling](#exception-handling) - [Pagination](#pagination) @@ -199,7 +206,24 @@ patches: api_key="", ) - client.batch.create() + client.agent.create( + agent_id="agent_id", + name="name", + security_domain="security_domain", + ) + ``` + + ## Environments + + This SDK allows you to configure different environments for API requests. + + ```python + from zep_cloud import Zep + from zep_cloud.environment import ZepEnvironment + + client = Zep( + environment=ZepEnvironment.DEFAULT, + ) ``` ## Async Client @@ -217,7 +241,11 @@ patches: async def main() -> None: - await client.batch.create() + await client.agent.create( + agent_id="agent_id", + name="name", + security_domain="security_domain", + ) asyncio.run(main()) @@ -232,7 +260,7 @@ patches: from zep_cloud.core.api_error import ApiError try: - client.batch.create(...) + client.agent.create(...) except ApiError as e: print(e.status_code) print(e.body) @@ -249,16 +277,12 @@ patches: api_key="", ) - client.batch.list( - limit=1, - cursor="cursor", - status="status", - ) + client.agent.list() ``` ```python # You can also iterate through pages and access the typed response per page - pager = client.batch.list(...) + pager = client.agent.list(...) for page in pager.iter_pages(): print(page.response) # access the typed response for each page for item in page: @@ -276,7 +300,7 @@ patches: from zep_cloud import Zep client = Zep(...) - response = client.batch.with_raw_response.create(...) + response = client.agent.with_raw_response.create(...) print(response.headers) # access the response headers print(response.status_code) # access the response status code print(response.data) # access the underlying object @@ -288,16 +312,26 @@ patches: as the request is deemed retryable and the number of retry attempts has not grown larger than the configured retry limit (default: 2). - A request is deemed retryable when any of the following HTTP status codes is returned: + Which status codes are retried depends on the `retryStatusCodes` generator configuration: + + **`legacy`** (current default): retries on + - [408](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/408) (Timeout) + - [409](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/409) (Conflict) + - [429](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429) (Too Many Requests) + - [5XX](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#server_error_responses) (All server errors, including 500) + **`recommended`**: retries on - [408](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/408) (Timeout) + - [409](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/409) (Conflict) - [429](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429) (Too Many Requests) - - [5XX](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500) (Internal Server Errors) + - [502](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502) (Bad Gateway) + - [503](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/503) (Service Unavailable) + - [504](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/504) (Gateway Timeout) Use the `max_retries` request option to configure this behavior. ```python - client.batch.create(..., request_options={ + client.agent.create(..., request_options={ "max_retries": 1 }) ``` @@ -312,8 +346,8 @@ patches: client = Zep(..., timeout=20.0) # Override timeout for a specific method - client.batch.create(..., request_options={ - "timeout_in_seconds": 1 + client.agent.create(..., request_options={ + "timeout": 1 }) ``` @@ -344,3 +378,4 @@ patches: an issue first to discuss with us! On the other hand, contributions to the README are always very welcome! + user_owned: true diff --git a/README.md b/README.md index c775b5f8..c861b306 100644 --- a/README.md +++ b/README.md @@ -33,78 +33,18 @@ pip install zep-cloud > [!NOTE] > Zep Cloud [overview](https://help.getzep.com/concepts) and [cloud sdk guide](https://help.getzep.com/sdks). -### Community Installation -```bash -pip install zep-python -``` -> [!NOTE] -> Zep Community Edition [quick start](https://help.getzep.com/ce/quickstart) and [sdk guide](https://help.getzep.com/ce/sdks). - -### Zep v0.x Compatible SDK -You can install Zep v0.x compatible sdk by running: -```bash -pip install "zep-python>=1.5.0,<2.0.0" -``` -> [!NOTE] -> Zep v0.x [quick start](https://help.getzep.com/ce/legacy/deployment/quickstart) and [sdk guide](https://help.getzep.com/ce/legacy/sdk). - ### How Zep works Zep persists and recalls chat histories, and automatically generates summaries and other artifacts from these chat histories. It also embeds messages and summaries, enabling you to search Zep for relevant context from past conversations. Zep does all of this asynchronously, ensuring these operations don't impact your user's chat experience. Data is persisted to database, allowing you to scale out when growth demands. -Zep also provides a simple, easy to use abstraction for document vector search called Document Collections. This is designed to complement Zep's core context features, but is not designed to be a general purpose vector database. - Zep allows you to be more intentional about constructing your prompt: 1. automatically adding a few recent messages, with the number customized for your app; 2. a summary of recent conversations prior to the messages above; 3. and/or contextually relevant summaries or messages surfaced from the entire chat session. -4. and/or relevant Business data from Zep Document Collections. - -Zep Cloud offers: -- **Fact Extraction:** Automatically build fact tables from conversations, without having to define a data schema upfront. -- **Dialog Classification:** Instantly and accurately classify chat dialog. Understand user intent and emotion, segment users, and more. Route chains based on semantic context, and trigger events. -- **Structured Data Extraction:** Quickly extract business data from chat conversations using a schema you define. Understand what your Assistant should ask for next in order to complete its task. You will also need to provide a Zep Project API key to your zep client. You can find out about zep projects in our [cloud docs](https://help.getzep.com/projects.html) -### Using LangChain Zep Classes with `zep-python` - -(Currently only available on release candidate versions) - -In the pre-release version `zep-python` sdk comes with `ZepChatMessageHistory` and `ZepVectorStore` -classes that are compatible with [LangChain's Python expression language](https://python.langchain.com/docs/expression_language/) - -In order to use these classes in your application, you need to make sure that you have -`langchain_core` package installed, please refer to [Langchain's docs installation section](https://python.langchain.com/docs/get_started/installation#langchain-core). - -We support `langchain_core@>=0.1.3<0.2.0` - -You can import these classes in the following way: - -```python -from zep_cloud.langchain import ZepChatMessageHistory, ZepVectorStore -``` - -### Running Examples -You will need to set the following environment variables to run examples in the `examples` directory: - -```dotenv -# Please use examples/.env.example as a template for .env file - -# Required -ZEP_API_KEY=# Your Zep Project API Key -ZEP_COLLECTION=# used in ingestion script and in vector store examples -OPENAI_API_KEY=# Your OpenAI API Key - -# Optional (If you want to use langsmith with LangServe Sample App) -LANGCHAIN_TRACING_V2=true -LANGCHAIN_API_KEY= -LANGCHAIN_PROJECT=# If not specified, defaults to "default" -``` - - - ## Installation ```sh From e69d20109cbd1ce4e11fb364a23ca15799ab2704 Mon Sep 17 00:00:00 2001 From: "zep-sdk-release-bot[bot]" Date: Tue, 6 Oct 2026 17:55:43 +0000 Subject: [PATCH 3/3] chore: bump SDK version to 4.0.0-beta.1 --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 48ed0a49..77163907 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,7 @@ [project] name = "zep-cloud" dynamic = ["version"] +version = "4.0.0b1" [tool.poetry] name = "zep-cloud"