From 0cd8c830c962c556d5439d0679150ac8b8cee0fa Mon Sep 17 00:00:00 2001 From: Kian Jones <11655409+kianjones9@users.noreply.github.com> Date: Thu, 17 Jul 2025 18:04:13 -0700 Subject: [PATCH] feat(sqlite): CI Tests for Alembic and SQLite (#3358) Co-authored-by: Matt Zhou --- ...5b1eb9c40_add_batch_item_id_to_messages.py | 9 + .../08b2f8225812_adding_toolsagents_orm.py | 9 + .../0b496eae90de_add_file_agent_table.py | 9 + .../0ceb975e0063_add_llm_batch_jobs_tables.py | 9 + .../167491cfb7a8_add_identities_for_blocks.py | 9 + ...09530_add_instructions_field_to_sources.py | 9 + ...f251a42c06_fix_files_agents_constraints.py | 9 + ...b6a38b713_add_pip_requirements_to_tools.py | 9 + ...1ee_make_an_blocks_agents_mapping_table.py | 9 + .../1dc0fee72dea_add_block_related_indexes.py | 9 + .../1e553a664210_add_metadata_to_tools.py | 9 + .../220856bbf43b_add_read_only_column.py | 9 + ...2a6e413d89c_remove_module_field_on_tool.py | 9 + ...25fc99e97839_fix_alembic_check_warnings.py | 9 + ..._add_support_for_structured_outputs_in_.py | 9 + ...59cad97cc_create_sqlite_baseline_schema.py | 798 ++++++++++++++++++ ...ceb07c2384_add_content_parts_to_message.py | 9 + ...33b_add_otid_and_tool_return_to_message.py | 9 + ...9f14_add_preserve_on_migration_to_block.py | 9 + .../348214cbc081_add_org_agent_id_indices.py | 9 + ...f_add_byok_fields_and_unique_constraint.py | 9 + .../3c683a662c82_migrate_jobs_to_the_orm.py | 9 + ...bf0_add_per_agent_environment_variables.py | 9 + ...b_repurpose_jobusagestatistics_for_new_.py | 9 + ..._add_unique_constraint_to_source_names_.py | 9 + ...dd_total_chunks_and_chunks_embedded_to_.py | 9 + ...rite_source_id_directly_to_files_agents.py | 9 + ...88e702f85e_drop_api_tokens_table_in_oss.py | 9 + .../51999513bcf1_steps_feedback_field.py | 9 + ...pdate_identities_unique_constraint_and_.py | 9 + ...54dec07619c4_divide_passage_table_into_.py | 9 + .../54f2311edb62_add_args_schema_to_tools.py | 9 + ...16524f_add_custom_headers_to_mcp_server.py | 9 + .../5987401b40ae_refactor_agent_memory.py | 9 + ...ed28ee7138_add_project_id_to_step_model.py | 9 + ...e_add_unique_constraint_to_file_id_and_.py | 9 + ..._add_index_on_source_passages_for_files.py | 9 + ...224a7a58_add_provider_category_to_steps.py | 9 + .../6fbe9cace832_adding_indexes_to_models.py | 9 + ...79c0525f2_enable_sleeptime_agent_fields.py | 9 + ...f2ede29317_add_background_group_support.py | 9 + ...731d15e2_added_jobusagestatistics_table.py | 9 + ...77de976590ae_add_groups_for_multi_agent.py | 9 + ...a08_add_stateless_option_for_agentstate.py | 9 + ...rename_batch_id_to_llm_batch_id_on_llm_.py | 9 + ...change_jobmessage_unique_constraint_to_.py | 9 + .../878607e41ca4_add_provider_category.py | 9 + .../88f9432739a9_add_jobtype_to_job_table.py | 9 + .../8d70372ad130_adding_jobmessages_table.py | 9 + ...6e71df_rename_sleeptime_agent_frequency.py | 9 + ...4d0cda_add_callback_error_field_to_jobs.py | 9 + .../915b68780108_add_providers_data_to_orm.py | 9 + .../9556081ce65b_add_bedrock_creds_to_byok.py | 9 + ...5badb46fdf9_migrate_messages_to_the_orm.py | 9 + ...dd3_add_run_completion_and_duration_to_.py | 9 + ...f94e961d_add_file_processing_status_to_.py | 9 + ...505cc7eca9_create_a_baseline_migrations.py | 9 + ...dbaa409f_add_table_to_store_mcp_servers.py | 9 + .../a113caac453e_add_identities_table.py | 9 + ...047a624130_add_identifier_key_to_agents.py | 9 + ...62e08ca_add_callback_data_to_jobs_table.py | 9 + ...0f83fc2_add_ordered_agent_ids_to_groups.py | 9 + ...f_add_column_to_tools_table_to_contain_.py | 9 + ...183663c6769_add_trace_id_to_steps_table.py | 9 + .../b6d7ca024aa9_add_agents_tags_table.py | 9 + ...41_add_privileged_tools_to_organization.py | 9 + .../bff040379479_add_block_history_tables.py | 9 + .../c0ef3ff26306_add_token_to_mcp_server.py | 9 + .../c3b1da3d1157_add_sender_id_to_message.py | 9 + ...71_add_buffer_length_min_max_for_voice_.py | 9 + ..._add_passages_orm_drop_legacy_passages_.py | 9 + ...ac45f69849_add_timezone_to_agents_table.py | 9 + .../c85a3d07c028_move_files_to_orm.py | 9 + ...433aef_add_file_name_to_source_passages.py | 9 + ...d_add_support_for_request_and_response_.py | 9 + .../cda66b6cb0d6_move_sources_to_orm.py | 9 + ...emove_unique_name_restriction_on_agents.py | 9 + ...add_file_name_to_fileagent_association_.py | 9 + .../d05669b60ebe_migrate_agents_to_orm.py | 9 + ...c_move_organizations_users_tools_to_orm.py | 9 + .../d211df879a5f_add_agent_id_to_steps.py | 9 + ...d_add_composite_index_to_messages_table.py | 9 + ...add_index_on_agent_id_for_agent_env_var.py | 9 + ...210ca_add_model_endpoint_to_steps_table.py | 9 + ...dbf_tweak_created_at_field_for_messages.py | 9 + .../versions/e20573fe9b86_add_tool_types.py | 9 + ...0_add_cascading_deletes_for_sources_to_.py | 9 + ...28_add_monotonically_increasing_ids_to_.py | 9 + ...add_letta_batch_job_id_to_llm_batch_job.py | 9 + ...013e_adding_request_config_to_job_table.py | 9 + ...7507eab4bb9_migrate_blocks_to_orm_model.py | 9 + ..._create_sandbox_config_and_sandbox_env_.py | 9 + .../f895232c144a_backfill_composio_tools.py | 9 + ...2c_add_project_and_template_id_to_agent.py | 9 + ...b11cf_identity_properties_jsonb_to_json.py | 9 + letta/orm/identity.py | 2 + letta/orm/message.py | 138 ++- letta/orm/sqlalchemy_base.py | 10 +- letta/server/db.py | 26 +- letta/services/agent_manager.py | 16 +- .../services/helpers/agent_manager_helper.py | 13 +- letta/services/identity_manager.py | 22 + letta/services/job_manager.py | 92 +- letta/services/message_manager.py | 49 +- poetry.lock | 572 +++++++++++-- pyproject.toml | 4 + tests/test_client_legacy.py | 22 - tests/test_managers.py | 52 +- tests/test_sources.py | 15 + 109 files changed, 2539 insertions(+), 138 deletions(-) create mode 100644 alembic/versions/2c059cad97cc_create_sqlite_baseline_schema.py diff --git a/alembic/versions/0335b1eb9c40_add_batch_item_id_to_messages.py b/alembic/versions/0335b1eb9c40_add_batch_item_id_to_messages.py index 01c87429..1c047db8 100644 --- a/alembic/versions/0335b1eb9c40_add_batch_item_id_to_messages.py +++ b/alembic/versions/0335b1eb9c40_add_batch_item_id_to_messages.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "0335b1eb9c40" @@ -20,12 +21,20 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("messages", sa.Column("batch_item_id", sa.String(), nullable=True)) # ### end Alembic commands ### def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_column("messages", "batch_item_id") # ### end Alembic commands ### diff --git a/alembic/versions/08b2f8225812_adding_toolsagents_orm.py b/alembic/versions/08b2f8225812_adding_toolsagents_orm.py index 0da80aae..da0e190e 100644 --- a/alembic/versions/08b2f8225812_adding_toolsagents_orm.py +++ b/alembic/versions/08b2f8225812_adding_toolsagents_orm.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "08b2f8225812" @@ -20,6 +21,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.create_table( "tools_agents", @@ -44,6 +49,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_table("tools_agents") # ### end Alembic commands ### diff --git a/alembic/versions/0b496eae90de_add_file_agent_table.py b/alembic/versions/0b496eae90de_add_file_agent_table.py index 91b10781..e5222067 100644 --- a/alembic/versions/0b496eae90de_add_file_agent_table.py +++ b/alembic/versions/0b496eae90de_add_file_agent_table.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "0b496eae90de" @@ -20,6 +21,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.create_table( "files_agents", @@ -48,6 +53,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_index("ix_files_agents_file_id_agent_id", table_name="files_agents") op.drop_table("files_agents") diff --git a/alembic/versions/0ceb975e0063_add_llm_batch_jobs_tables.py b/alembic/versions/0ceb975e0063_add_llm_batch_jobs_tables.py index fee45f75..625a6e0f 100644 --- a/alembic/versions/0ceb975e0063_add_llm_batch_jobs_tables.py +++ b/alembic/versions/0ceb975e0063_add_llm_batch_jobs_tables.py @@ -12,6 +12,7 @@ import sqlalchemy as sa import letta from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "0ceb975e0063" @@ -21,6 +22,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.create_table( "llm_batch_job", @@ -75,6 +80,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_index("ix_llm_batch_items_status", table_name="llm_batch_items") op.drop_index("ix_llm_batch_items_batch_id", table_name="llm_batch_items") diff --git a/alembic/versions/167491cfb7a8_add_identities_for_blocks.py b/alembic/versions/167491cfb7a8_add_identities_for_blocks.py index 8e0b8a17..8f0e04d2 100644 --- a/alembic/versions/167491cfb7a8_add_identities_for_blocks.py +++ b/alembic/versions/167491cfb7a8_add_identities_for_blocks.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "167491cfb7a8" @@ -20,6 +21,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.create_table( "identities_blocks", @@ -33,6 +38,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_table("identities_blocks") # ### end Alembic commands ### diff --git a/alembic/versions/18e300709530_add_instructions_field_to_sources.py b/alembic/versions/18e300709530_add_instructions_field_to_sources.py index 138494d0..9d730c92 100644 --- a/alembic/versions/18e300709530_add_instructions_field_to_sources.py +++ b/alembic/versions/18e300709530_add_instructions_field_to_sources.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "18e300709530" @@ -20,12 +21,20 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("sources", sa.Column("instructions", sa.String(), nullable=True)) # ### end Alembic commands ### def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_column("sources", "instructions") # ### end Alembic commands ### diff --git a/alembic/versions/1af251a42c06_fix_files_agents_constraints.py b/alembic/versions/1af251a42c06_fix_files_agents_constraints.py index b5b40eee..d95d79e3 100644 --- a/alembic/versions/1af251a42c06_fix_files_agents_constraints.py +++ b/alembic/versions/1af251a42c06_fix_files_agents_constraints.py @@ -9,6 +9,7 @@ Create Date: 2025-06-30 11:50:42.200885 from typing import Sequence, Union from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "1af251a42c06" @@ -18,6 +19,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_index("ix_files_agents_agent_file_name", table_name="files_agents") op.drop_index("ix_files_agents_file_id_agent_id", table_name="files_agents") @@ -31,6 +36,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_constraint("uq_file_agent", "files_agents", type_="unique") op.drop_constraint("uq_agent_filename", "files_agents", type_="unique") diff --git a/alembic/versions/1c6b6a38b713_add_pip_requirements_to_tools.py b/alembic/versions/1c6b6a38b713_add_pip_requirements_to_tools.py index 52a48198..a4eff890 100644 --- a/alembic/versions/1c6b6a38b713_add_pip_requirements_to_tools.py +++ b/alembic/versions/1c6b6a38b713_add_pip_requirements_to_tools.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "1c6b6a38b713" @@ -20,12 +21,20 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("tools", sa.Column("pip_requirements", sa.JSON(), nullable=True)) # ### end Alembic commands ### def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_column("tools", "pip_requirements") # ### end Alembic commands ### diff --git a/alembic/versions/1c8880d671ee_make_an_blocks_agents_mapping_table.py b/alembic/versions/1c8880d671ee_make_an_blocks_agents_mapping_table.py index ffcb0b67..01062363 100644 --- a/alembic/versions/1c8880d671ee_make_an_blocks_agents_mapping_table.py +++ b/alembic/versions/1c8880d671ee_make_an_blocks_agents_mapping_table.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "1c8880d671ee" @@ -20,6 +21,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.create_unique_constraint("unique_block_id_label", "block", ["id", "label"]) @@ -46,6 +51,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_constraint("unique_block_id_label", "block", type_="unique") op.drop_table("blocks_agents") diff --git a/alembic/versions/1dc0fee72dea_add_block_related_indexes.py b/alembic/versions/1dc0fee72dea_add_block_related_indexes.py index 89c7d739..489a14ff 100644 --- a/alembic/versions/1dc0fee72dea_add_block_related_indexes.py +++ b/alembic/versions/1dc0fee72dea_add_block_related_indexes.py @@ -9,6 +9,7 @@ Create Date: 2025-05-12 17:06:32.055091 from typing import Sequence, Union from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "1dc0fee72dea" @@ -18,6 +19,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade(): + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # add index for blocks_agents table op.create_index("ix_blocks_agents_block_label_agent_id", "blocks_agents", ["block_label", "agent_id"], unique=False) @@ -29,6 +34,10 @@ def upgrade(): def downgrade(): + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + op.drop_index("ix_blocks_agents_block_label_agent_id", table_name="blocks_agents") op.drop_index("ix_blocks_block_label", table_name="blocks_agents") op.drop_index("ix_agents_tags_agent_id_tag", table_name="agents_tags") diff --git a/alembic/versions/1e553a664210_add_metadata_to_tools.py b/alembic/versions/1e553a664210_add_metadata_to_tools.py index 51b6da20..dd902830 100644 --- a/alembic/versions/1e553a664210_add_metadata_to_tools.py +++ b/alembic/versions/1e553a664210_add_metadata_to_tools.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "1e553a664210" @@ -20,12 +21,20 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("tools", sa.Column("metadata_", sa.JSON(), nullable=True)) # ### end Alembic commands ### def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_column("tools", "metadata_") # ### end Alembic commands ### diff --git a/alembic/versions/220856bbf43b_add_read_only_column.py b/alembic/versions/220856bbf43b_add_read_only_column.py index a8a962de..ed4bdb39 100644 --- a/alembic/versions/220856bbf43b_add_read_only_column.py +++ b/alembic/versions/220856bbf43b_add_read_only_column.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "220856bbf43b" @@ -20,6 +21,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # add default value of `False` op.add_column("block", sa.Column("read_only", sa.Boolean(), nullable=True)) op.execute( @@ -32,4 +37,8 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + op.drop_column("block", "read_only") diff --git a/alembic/versions/22a6e413d89c_remove_module_field_on_tool.py b/alembic/versions/22a6e413d89c_remove_module_field_on_tool.py index 8d05aabe..1bab710e 100644 --- a/alembic/versions/22a6e413d89c_remove_module_field_on_tool.py +++ b/alembic/versions/22a6e413d89c_remove_module_field_on_tool.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "22a6e413d89c" @@ -20,12 +21,20 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_column("tools", "module") # ### end Alembic commands ### def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("tools", sa.Column("module", sa.VARCHAR(), autoincrement=False, nullable=True)) # ### end Alembic commands ### diff --git a/alembic/versions/25fc99e97839_fix_alembic_check_warnings.py b/alembic/versions/25fc99e97839_fix_alembic_check_warnings.py index 47566a8a..d1cb27f4 100644 --- a/alembic/versions/25fc99e97839_fix_alembic_check_warnings.py +++ b/alembic/versions/25fc99e97839_fix_alembic_check_warnings.py @@ -9,6 +9,7 @@ Create Date: 2025-01-16 16:48:21.000000 from typing import Sequence, Union from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "25fc99e97839" @@ -18,6 +19,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # Remove indices from job_messages op.drop_index("ix_job_messages_created_at", table_name="job_messages") op.drop_index("ix_job_messages_job_id", table_name="job_messages") @@ -31,6 +36,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # Remove the foreign key constraint op.drop_constraint("fk_job_messages_message_id", "job_messages", type_="foreignkey") diff --git a/alembic/versions/28b8765bdd0a_add_support_for_structured_outputs_in_.py b/alembic/versions/28b8765bdd0a_add_support_for_structured_outputs_in_.py index e5bcab08..a76a8d00 100644 --- a/alembic/versions/28b8765bdd0a_add_support_for_structured_outputs_in_.py +++ b/alembic/versions/28b8765bdd0a_add_support_for_structured_outputs_in_.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "28b8765bdd0a" @@ -20,12 +21,20 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("agents", sa.Column("response_format", sa.JSON(), nullable=True)) # ### end Alembic commands ### def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_column("agents", "response_format") # ### end Alembic commands ### diff --git a/alembic/versions/2c059cad97cc_create_sqlite_baseline_schema.py b/alembic/versions/2c059cad97cc_create_sqlite_baseline_schema.py new file mode 100644 index 00000000..36410d7b --- /dev/null +++ b/alembic/versions/2c059cad97cc_create_sqlite_baseline_schema.py @@ -0,0 +1,798 @@ +"""create_sqlite_baseline_schema + +Revision ID: 2c059cad97cc +Revises: 495f3f474131 +Create Date: 2025-07-16 14:34:21.280233 + +""" + +from typing import Sequence, Union + +import sqlalchemy as sa + +from alembic import op +from letta.settings import settings + +# revision identifiers, used by Alembic. +revision: str = "2c059cad97cc" +down_revision: Union[str, None] = "495f3f474131" +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + # Only run this migration for SQLite + if settings.letta_pg_uri_no_default: + return + + # Create the exact schema that matches the current PostgreSQL state + # This is a snapshot of the schema at the time of this migration + # Based on the schema provided by Andy + + # Organizations table + op.create_table( + "organizations", + sa.Column("id", sa.String(), nullable=False), + sa.Column("name", sa.String(), nullable=False), + sa.Column("created_at", sa.DateTime(timezone=True), nullable=True), + sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("is_deleted", sa.Boolean(), server_default=sa.text("(FALSE)"), nullable=False), + sa.Column("_created_by_id", sa.String(), nullable=True), + sa.Column("_last_updated_by_id", sa.String(), nullable=True), + sa.Column("privileged_tools", sa.Boolean(), nullable=False), + sa.PrimaryKeyConstraint("id"), + ) + + # Agents table + op.create_table( + "agents", + sa.Column("id", sa.String(), nullable=False), + sa.Column("name", sa.String(), nullable=True), + sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("description", sa.String(), nullable=True), + sa.Column("message_ids", sa.JSON(), nullable=True), + sa.Column("system", sa.String(), nullable=True), + sa.Column("agent_type", sa.String(), nullable=True), + sa.Column("llm_config", sa.JSON(), nullable=True), + sa.Column("embedding_config", sa.JSON(), nullable=True), + sa.Column("metadata_", sa.JSON(), nullable=True), + sa.Column("tool_rules", sa.JSON(), nullable=True), + sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("is_deleted", sa.Boolean(), server_default=sa.text("(FALSE)"), nullable=False), + sa.Column("_created_by_id", sa.String(), nullable=True), + sa.Column("_last_updated_by_id", sa.String(), nullable=True), + sa.Column("organization_id", sa.String(), nullable=False), + sa.Column("project_id", sa.String(), nullable=True), + sa.Column("template_id", sa.String(), nullable=True), + sa.Column("base_template_id", sa.String(), nullable=True), + sa.Column("message_buffer_autoclear", sa.Boolean(), nullable=False), + sa.Column("enable_sleeptime", sa.Boolean(), nullable=True), + sa.Column("response_format", sa.JSON(), nullable=True), + sa.Column("last_run_completion", sa.DateTime(timezone=True), nullable=True), + sa.Column("last_run_duration_ms", sa.Integer(), nullable=True), + sa.Column("timezone", sa.String(), nullable=True), + sa.PrimaryKeyConstraint("id"), + sa.ForeignKeyConstraint(["organization_id"], ["organizations.id"]), + ) + op.create_index("ix_agents_created_at", "agents", ["created_at", "id"]) + + # Block history table (created before block table so block can reference it) + op.create_table( + "block_history", + sa.Column("id", sa.String(), nullable=False), + sa.Column("description", sa.Text(), nullable=True), + sa.Column("label", sa.String(), nullable=False), + sa.Column("value", sa.Text(), nullable=False), + sa.Column("limit", sa.BigInteger(), nullable=False), + sa.Column("metadata_", sa.JSON(), nullable=True), + sa.Column("actor_type", sa.String(), nullable=True), + sa.Column("actor_id", sa.String(), nullable=True), + sa.Column("block_id", sa.String(), nullable=False), + sa.Column("sequence_number", sa.Integer(), nullable=False), + sa.Column("organization_id", sa.String(), nullable=False), + sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("is_deleted", sa.Boolean(), server_default=sa.text("(FALSE)"), nullable=False), + sa.Column("_created_by_id", sa.String(), nullable=True), + sa.Column("_last_updated_by_id", sa.String(), nullable=True), + sa.PrimaryKeyConstraint("id"), + sa.ForeignKeyConstraint(["organization_id"], ["organizations.id"]), + # Note: block_id foreign key will be added later since block table doesn't exist yet + ) + op.create_index("ix_block_history_block_id_sequence", "block_history", ["block_id", "sequence_number"], unique=True) + + # Block table + op.create_table( + "block", + sa.Column("id", sa.String(), nullable=False), + sa.Column("value", sa.String(), nullable=False), + sa.Column("limit", sa.Integer(), nullable=False), + sa.Column("template_name", sa.String(), nullable=True), + sa.Column("label", sa.String(), nullable=False), + sa.Column("metadata_", sa.JSON(), nullable=True), + sa.Column("description", sa.String(), nullable=True), + sa.Column("is_template", sa.Boolean(), nullable=False), + sa.Column("organization_id", sa.String(), nullable=False), + sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("is_deleted", sa.Boolean(), server_default=sa.text("(FALSE)"), nullable=False), + sa.Column("_created_by_id", sa.String(), nullable=True), + sa.Column("_last_updated_by_id", sa.String(), nullable=True), + sa.Column("current_history_entry_id", sa.String(), nullable=True), + sa.Column("version", sa.Integer(), server_default="1", nullable=False), + sa.Column("read_only", sa.Boolean(), nullable=False), + sa.Column("preserve_on_migration", sa.Boolean(), nullable=True), + sa.PrimaryKeyConstraint("id"), + sa.ForeignKeyConstraint(["organization_id"], ["organizations.id"]), + sa.ForeignKeyConstraint(["current_history_entry_id"], ["block_history.id"], name="fk_block_current_history_entry"), + sa.UniqueConstraint("id", "label", name="unique_block_id_label"), + ) + op.create_index("created_at_label_idx", "block", ["created_at", "label"]) + op.create_index("ix_block_current_history_entry_id", "block", ["current_history_entry_id"]) + + # Note: Foreign key constraint for block_history.block_id cannot be added in SQLite after table creation + # This will be enforced at the ORM level + + # Sources table + op.create_table( + "sources", + sa.Column("id", sa.String(), nullable=False), + sa.Column("name", sa.String(), nullable=False), + sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("embedding_config", sa.JSON(), nullable=False), + sa.Column("description", sa.String(), nullable=True), + sa.Column("metadata_", sa.JSON(), nullable=True), + sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("is_deleted", sa.Boolean(), server_default=sa.text("(FALSE)"), nullable=False), + sa.Column("_created_by_id", sa.String(), nullable=True), + sa.Column("_last_updated_by_id", sa.String(), nullable=True), + sa.Column("organization_id", sa.String(), nullable=False), + sa.Column("instructions", sa.String(), nullable=True), + sa.PrimaryKeyConstraint("id"), + sa.ForeignKeyConstraint(["organization_id"], ["organizations.id"]), + sa.UniqueConstraint("name", "organization_id", name="uq_source_name_organization"), + ) + op.create_index("source_created_at_id_idx", "sources", ["created_at", "id"]) + + # Files table + op.create_table( + "files", + sa.Column("id", sa.String(), nullable=False), + sa.Column("source_id", sa.String(), nullable=False), + sa.Column("file_name", sa.String(), nullable=True), + sa.Column("file_path", sa.String(), nullable=True), + sa.Column("file_type", sa.String(), nullable=True), + sa.Column("file_size", sa.Integer(), nullable=True), + sa.Column("file_creation_date", sa.String(), nullable=True), + sa.Column("file_last_modified_date", sa.String(), nullable=True), + sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("is_deleted", sa.Boolean(), server_default=sa.text("(FALSE)"), nullable=False), + sa.Column("_created_by_id", sa.String(), nullable=True), + sa.Column("_last_updated_by_id", sa.String(), nullable=True), + sa.Column("organization_id", sa.String(), nullable=False), + sa.Column("processing_status", sa.String(), nullable=False), + sa.Column("error_message", sa.Text(), nullable=True), + sa.Column("original_file_name", sa.String(), nullable=True), + sa.Column("total_chunks", sa.Integer(), nullable=True), + sa.Column("chunks_embedded", sa.Integer(), nullable=True), + sa.PrimaryKeyConstraint("id"), + sa.ForeignKeyConstraint(["source_id"], ["sources.id"], ondelete="CASCADE"), + sa.ForeignKeyConstraint(["organization_id"], ["organizations.id"]), + ) + # Note: SQLite doesn't support expression indexes, so these are simplified + op.create_index("ix_files_org_created", "files", ["organization_id"]) + op.create_index("ix_files_processing_status", "files", ["processing_status"]) + op.create_index("ix_files_source_created", "files", ["source_id"]) + + # Users table + op.create_table( + "users", + sa.Column("id", sa.String(), nullable=False), + sa.Column("name", sa.String(), nullable=False), + sa.Column("created_at", sa.DateTime(timezone=True), nullable=True), + sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("is_deleted", sa.Boolean(), server_default=sa.text("(FALSE)"), nullable=False), + sa.Column("_created_by_id", sa.String(), nullable=True), + sa.Column("_last_updated_by_id", sa.String(), nullable=True), + sa.Column("organization_id", sa.String(), nullable=False), + sa.PrimaryKeyConstraint("id"), + sa.ForeignKeyConstraint(["organization_id"], ["organizations.id"]), + ) + + # Jobs table + op.create_table( + "jobs", + sa.Column("id", sa.String(), nullable=False), + sa.Column("user_id", sa.String(), nullable=False), + sa.Column("status", sa.String(), nullable=False), + sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("completed_at", sa.DateTime(timezone=True), nullable=True), + sa.Column("metadata_", sa.JSON(), nullable=True), + sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("is_deleted", sa.Boolean(), server_default=sa.text("(FALSE)"), nullable=False), + sa.Column("_created_by_id", sa.String(), nullable=True), + sa.Column("_last_updated_by_id", sa.String(), nullable=True), + sa.Column("job_type", sa.String(), nullable=False), + sa.Column("request_config", sa.JSON(), nullable=True), + sa.Column("callback_url", sa.String(), nullable=True), + sa.Column("callback_sent_at", sa.DateTime(timezone=True), nullable=True), + sa.Column("callback_status_code", sa.Integer(), nullable=True), + sa.Column("callback_error", sa.String(), nullable=True), + sa.PrimaryKeyConstraint("id"), + sa.ForeignKeyConstraint(["user_id"], ["users.id"]), + ) + op.create_index("ix_jobs_created_at", "jobs", ["created_at", "id"]) + + # Tools table + op.create_table( + "tools", + sa.Column("id", sa.String(), nullable=False), + sa.Column("name", sa.String(), nullable=False), + sa.Column("description", sa.String(), nullable=True), + sa.Column("source_type", sa.String(), nullable=False), + sa.Column("source_code", sa.String(), nullable=True), + sa.Column("json_schema", sa.JSON(), nullable=True), + sa.Column("tags", sa.JSON(), nullable=False), + sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("is_deleted", sa.Boolean(), server_default=sa.text("(FALSE)"), nullable=False), + sa.Column("_created_by_id", sa.String(), nullable=True), + sa.Column("_last_updated_by_id", sa.String(), nullable=True), + sa.Column("organization_id", sa.String(), nullable=False), + sa.Column("return_char_limit", sa.Integer(), nullable=True), + sa.Column("tool_type", sa.String(), nullable=False), + sa.Column("args_json_schema", sa.JSON(), nullable=True), + sa.Column("metadata_", sa.JSON(), nullable=True), + sa.Column("pip_requirements", sa.JSON(), nullable=True), + sa.PrimaryKeyConstraint("id"), + sa.ForeignKeyConstraint(["organization_id"], ["organizations.id"]), + sa.UniqueConstraint("name", "organization_id", name="uix_name_organization"), + ) + op.create_index("ix_tools_created_at_name", "tools", ["created_at", "name"]) + + # Additional tables based on Andy's schema + + # Agents tags table + op.create_table( + "agents_tags", + sa.Column("agent_id", sa.String(), nullable=False), + sa.Column("tag", sa.String(), nullable=False), + sa.ForeignKeyConstraint(["agent_id"], ["agents.id"]), + sa.UniqueConstraint("agent_id", "tag", name="unique_agent_tag"), + ) + op.create_index("ix_agents_tags_agent_id_tag", "agents_tags", ["agent_id", "tag"]) + + # Sandbox configs table + op.create_table( + "sandbox_configs", + sa.Column("id", sa.String(), nullable=False), + sa.Column("type", sa.String(), nullable=False), # sandboxtype in PG + sa.Column("config", sa.JSON(), nullable=False), + sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("is_deleted", sa.Boolean(), server_default=sa.text("(FALSE)"), nullable=False), + sa.Column("_created_by_id", sa.String(), nullable=True), + sa.Column("_last_updated_by_id", sa.String(), nullable=True), + sa.Column("organization_id", sa.String(), nullable=False), + sa.PrimaryKeyConstraint("id"), + sa.ForeignKeyConstraint(["organization_id"], ["organizations.id"]), + sa.UniqueConstraint("type", "organization_id", name="uix_type_organization"), + ) + + # Sandbox environment variables table + op.create_table( + "sandbox_environment_variables", + sa.Column("id", sa.String(), nullable=False), + sa.Column("key", sa.String(), nullable=False), + sa.Column("value", sa.String(), nullable=False), + sa.Column("description", sa.String(), nullable=True), + sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("is_deleted", sa.Boolean(), server_default=sa.text("(FALSE)"), nullable=False), + sa.Column("_created_by_id", sa.String(), nullable=True), + sa.Column("_last_updated_by_id", sa.String(), nullable=True), + sa.Column("organization_id", sa.String(), nullable=False), + sa.Column("sandbox_config_id", sa.String(), nullable=False), + sa.PrimaryKeyConstraint("id"), + sa.ForeignKeyConstraint(["organization_id"], ["organizations.id"]), + sa.ForeignKeyConstraint(["sandbox_config_id"], ["sandbox_configs.id"]), + sa.UniqueConstraint("key", "sandbox_config_id", name="uix_key_sandbox_config"), + ) + + # Blocks agents table + op.create_table( + "blocks_agents", + sa.Column("agent_id", sa.String(), nullable=False), + sa.Column("block_id", sa.String(), nullable=False), + sa.Column("block_label", sa.String(), nullable=False), + sa.ForeignKeyConstraint(["agent_id"], ["agents.id"]), + sa.ForeignKeyConstraint(["block_id", "block_label"], ["block.id", "block.label"], deferrable=True, initially="DEFERRED"), + sa.UniqueConstraint("agent_id", "block_label", name="unique_label_per_agent"), + sa.UniqueConstraint("agent_id", "block_id", name="unique_agent_block"), + ) + op.create_index("ix_blocks_agents_block_label_agent_id", "blocks_agents", ["block_label", "agent_id"]) + op.create_index("ix_blocks_block_label", "blocks_agents", ["block_label"]) + + # Tools agents table + op.create_table( + "tools_agents", + sa.Column("agent_id", sa.String(), nullable=False), + sa.Column("tool_id", sa.String(), nullable=False), + sa.ForeignKeyConstraint(["agent_id"], ["agents.id"], ondelete="CASCADE"), + sa.ForeignKeyConstraint(["tool_id"], ["tools.id"], ondelete="CASCADE"), + sa.UniqueConstraint("agent_id", "tool_id", name="unique_agent_tool"), + ) + + # Sources agents table + op.create_table( + "sources_agents", + sa.Column("agent_id", sa.String(), nullable=False), + sa.Column("source_id", sa.String(), nullable=False), + sa.ForeignKeyConstraint(["agent_id"], ["agents.id"], ondelete="CASCADE"), + sa.ForeignKeyConstraint(["source_id"], ["sources.id"], ondelete="CASCADE"), + sa.PrimaryKeyConstraint("agent_id", "source_id"), + ) + + # Agent passages table (using BLOB for vectors in SQLite) + op.create_table( + "agent_passages", + sa.Column("id", sa.String(), nullable=False), + sa.Column("text", sa.String(), nullable=False), + sa.Column("embedding_config", sa.JSON(), nullable=False), + sa.Column("metadata_", sa.JSON(), nullable=False), + sa.Column("embedding", sa.BLOB(), nullable=True), # CommonVector becomes BLOB in SQLite + sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("is_deleted", sa.Boolean(), server_default=sa.text("(FALSE)"), nullable=False), + sa.Column("_created_by_id", sa.String(), nullable=True), + sa.Column("_last_updated_by_id", sa.String(), nullable=True), + sa.Column("organization_id", sa.String(), nullable=False), + sa.Column("agent_id", sa.String(), nullable=False), + sa.PrimaryKeyConstraint("id"), + sa.ForeignKeyConstraint(["organization_id"], ["organizations.id"]), + sa.ForeignKeyConstraint(["agent_id"], ["agents.id"], ondelete="CASCADE"), + ) + # Note: agent_passages_org_idx is not created for SQLite as it's expected to be different + op.create_index("agent_passages_created_at_id_idx", "agent_passages", ["created_at", "id"]) + op.create_index("ix_agent_passages_org_agent", "agent_passages", ["organization_id", "agent_id"]) + + # Source passages table (using BLOB for vectors in SQLite) + op.create_table( + "source_passages", + sa.Column("id", sa.String(), nullable=False), + sa.Column("text", sa.String(), nullable=False), + sa.Column("embedding_config", sa.JSON(), nullable=False), + sa.Column("metadata_", sa.JSON(), nullable=False), + sa.Column("embedding", sa.BLOB(), nullable=True), # CommonVector becomes BLOB in SQLite + sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("is_deleted", sa.Boolean(), server_default=sa.text("(FALSE)"), nullable=False), + sa.Column("_created_by_id", sa.String(), nullable=True), + sa.Column("_last_updated_by_id", sa.String(), nullable=True), + sa.Column("organization_id", sa.String(), nullable=False), + sa.Column("file_id", sa.String(), nullable=True), + sa.Column("source_id", sa.String(), nullable=False), + sa.Column("file_name", sa.String(), nullable=False), + sa.PrimaryKeyConstraint("id"), + sa.ForeignKeyConstraint(["organization_id"], ["organizations.id"]), + sa.ForeignKeyConstraint(["file_id"], ["files.id"], ondelete="CASCADE"), + sa.ForeignKeyConstraint(["source_id"], ["sources.id"], ondelete="CASCADE"), + ) + # Note: source_passages_org_idx is not created for SQLite as it's expected to be different + op.create_index("source_passages_created_at_id_idx", "source_passages", ["created_at", "id"]) + + # Message sequence is handled by the sequence_id field in messages table + + # Messages table + op.create_table( + "messages", + sa.Column("id", sa.String(), nullable=False), + sa.Column("agent_id", sa.String(), nullable=False), + sa.Column("role", sa.String(), nullable=False), + sa.Column("text", sa.String(), nullable=True), + sa.Column("model", sa.String(), nullable=True), + sa.Column("name", sa.String(), nullable=True), + sa.Column("tool_calls", sa.JSON(), nullable=False), + sa.Column("tool_call_id", sa.String(), nullable=True), + sa.Column("created_at", sa.DateTime(timezone=True), nullable=True), + sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("is_deleted", sa.Boolean(), server_default=sa.text("(FALSE)"), nullable=False), + sa.Column("_created_by_id", sa.String(), nullable=True), + sa.Column("_last_updated_by_id", sa.String(), nullable=True), + sa.Column("organization_id", sa.String(), nullable=False), + sa.Column("step_id", sa.String(), nullable=True), + sa.Column("otid", sa.String(), nullable=True), + sa.Column("tool_returns", sa.JSON(), nullable=True), + sa.Column("group_id", sa.String(), nullable=True), + sa.Column("content", sa.JSON(), nullable=True), + sa.Column("sequence_id", sa.BigInteger(), nullable=False), + sa.Column("sender_id", sa.String(), nullable=True), + sa.Column("batch_item_id", sa.String(), nullable=True), + sa.PrimaryKeyConstraint("id"), + sa.ForeignKeyConstraint(["organization_id"], ["organizations.id"]), + sa.ForeignKeyConstraint(["agent_id"], ["agents.id"], ondelete="CASCADE"), + sa.ForeignKeyConstraint(["step_id"], ["steps.id"], ondelete="SET NULL"), + sa.UniqueConstraint("sequence_id", name="uq_messages_sequence_id"), + ) + op.create_index("ix_messages_agent_created_at", "messages", ["agent_id", "created_at"]) + op.create_index("ix_messages_created_at", "messages", ["created_at", "id"]) + op.create_index("ix_messages_agent_sequence", "messages", ["agent_id", "sequence_id"]) + op.create_index("ix_messages_org_agent", "messages", ["organization_id", "agent_id"]) + + # Create sequence table for SQLite message sequence_id generation + op.create_table( + "message_sequence", + sa.Column("id", sa.Integer(), nullable=False), + sa.Column("next_val", sa.Integer(), nullable=False, server_default="1"), + sa.PrimaryKeyConstraint("id"), + ) + + # Initialize the sequence table with the next available sequence_id + op.execute("INSERT INTO message_sequence (id, next_val) VALUES (1, 1)") + + # Now create the rest of the tables that might reference messages/steps + + # Add missing tables and columns identified from alembic check + + # Identities table + op.create_table( + "identities", + sa.Column("id", sa.String(), nullable=False), + sa.Column("identifier_key", sa.String(), nullable=False), + sa.Column("name", sa.String(), nullable=False), + sa.Column("identity_type", sa.String(), nullable=False), + sa.Column("project_id", sa.String(), nullable=True), + sa.Column("organization_id", sa.String(), nullable=False), + sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("is_deleted", sa.Boolean(), server_default=sa.text("(FALSE)"), nullable=False), + sa.Column("_created_by_id", sa.String(), nullable=True), + sa.Column("_last_updated_by_id", sa.String(), nullable=True), + sa.Column("properties", sa.JSON(), nullable=False), + sa.PrimaryKeyConstraint("id"), + sa.ForeignKeyConstraint(["organization_id"], ["organizations.id"]), + sa.UniqueConstraint("identifier_key", "project_id", "organization_id", name="unique_identifier_key_project_id_organization_id"), + ) + + # MCP Server table + op.create_table( + "mcp_server", + sa.Column("id", sa.String(), nullable=False), + sa.Column("server_name", sa.String(), nullable=False), + sa.Column("server_type", sa.String(), nullable=False), + sa.Column("server_url", sa.String(), nullable=True), + sa.Column("stdio_config", sa.JSON(), nullable=True), + sa.Column("token", sa.String(), nullable=True), + sa.Column("custom_headers", sa.JSON(), nullable=True), + sa.Column("organization_id", sa.String(), nullable=False), + sa.Column("is_deleted", sa.Boolean(), server_default=sa.text("(FALSE)"), nullable=False), + sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("_created_by_id", sa.String(), nullable=True), + sa.Column("_last_updated_by_id", sa.String(), nullable=True), + sa.Column("metadata_", sa.JSON(), nullable=True), + sa.PrimaryKeyConstraint("id"), + sa.ForeignKeyConstraint(["organization_id"], ["organizations.id"]), + sa.UniqueConstraint("server_name", "organization_id", name="uix_name_organization_mcp_server"), + ) + + # Providers table + op.create_table( + "providers", + sa.Column("id", sa.String(), nullable=False), + sa.Column("name", sa.String(), nullable=False), + sa.Column("api_key", sa.String(), nullable=True), + sa.Column("access_key", sa.String(), nullable=True), + sa.Column("region", sa.String(), nullable=True), + sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("is_deleted", sa.Boolean(), server_default=sa.text("(FALSE)"), nullable=False), + sa.Column("_created_by_id", sa.String(), nullable=True), + sa.Column("_last_updated_by_id", sa.String(), nullable=True), + sa.Column("organization_id", sa.String(), nullable=False), + sa.Column("provider_type", sa.String(), nullable=True), + sa.Column("base_url", sa.String(), nullable=True), + sa.Column("provider_category", sa.String(), nullable=True), + sa.PrimaryKeyConstraint("id"), + sa.ForeignKeyConstraint(["organization_id"], ["organizations.id"]), + sa.UniqueConstraint("name", "organization_id", name="unique_name_organization_id"), + ) + + # Agent environment variables table + op.create_table( + "agent_environment_variables", + sa.Column("id", sa.String(), nullable=False), + sa.Column("key", sa.String(), nullable=False), + sa.Column("value", sa.String(), nullable=False), + sa.Column("description", sa.String(), nullable=True), + sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("is_deleted", sa.Boolean(), server_default=sa.text("(FALSE)"), nullable=False), + sa.Column("_created_by_id", sa.String(), nullable=True), + sa.Column("_last_updated_by_id", sa.String(), nullable=True), + sa.Column("organization_id", sa.String(), nullable=False), + sa.Column("agent_id", sa.String(), nullable=False), + sa.PrimaryKeyConstraint("id"), + sa.ForeignKeyConstraint(["organization_id"], ["organizations.id"]), + sa.ForeignKeyConstraint(["agent_id"], ["agents.id"], ondelete="CASCADE"), + sa.UniqueConstraint("key", "agent_id", name="uix_key_agent"), + ) + op.create_index("idx_agent_environment_variables_agent_id", "agent_environment_variables", ["agent_id"]) + + # Groups table + op.create_table( + "groups", + sa.Column("id", sa.String(), nullable=False), + sa.Column("description", sa.String(), nullable=False), + sa.Column("manager_type", sa.String(), nullable=False), + sa.Column("manager_agent_id", sa.String(), nullable=True), + sa.Column("termination_token", sa.String(), nullable=True), + sa.Column("max_turns", sa.Integer(), nullable=True), + sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("is_deleted", sa.Boolean(), server_default=sa.text("(FALSE)"), nullable=False), + sa.Column("_created_by_id", sa.String(), nullable=True), + sa.Column("_last_updated_by_id", sa.String(), nullable=True), + sa.Column("organization_id", sa.String(), nullable=False), + sa.Column("agent_ids", sa.JSON(), nullable=False), + sa.Column("sleeptime_agent_frequency", sa.Integer(), nullable=True), + sa.Column("turns_counter", sa.Integer(), nullable=True), + sa.Column("last_processed_message_id", sa.String(), nullable=True), + sa.Column("max_message_buffer_length", sa.Integer(), nullable=True), + sa.Column("min_message_buffer_length", sa.Integer(), nullable=True), + sa.PrimaryKeyConstraint("id"), + sa.ForeignKeyConstraint(["organization_id"], ["organizations.id"]), + sa.ForeignKeyConstraint(["manager_agent_id"], ["agents.id"], ondelete="RESTRICT"), + ) + + # Steps table + op.create_table( + "steps", + sa.Column("id", sa.String(), nullable=False), + sa.Column("job_id", sa.String(), nullable=True), + sa.Column("completion_tokens", sa.Integer(), nullable=False, default=0), + sa.Column("prompt_tokens", sa.Integer(), nullable=False, default=0), + sa.Column("total_tokens", sa.Integer(), nullable=False, default=0), + sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("is_deleted", sa.Boolean(), server_default=sa.text("(FALSE)"), nullable=False), + sa.Column("_created_by_id", sa.String(), nullable=True), + sa.Column("_last_updated_by_id", sa.String(), nullable=True), + sa.Column("origin", sa.String(), nullable=True), + sa.Column("organization_id", sa.String(), nullable=True), + sa.Column("provider_id", sa.String(), nullable=True), + sa.Column("provider_name", sa.String(), nullable=True), + sa.Column("model", sa.String(), nullable=True), + sa.Column("context_window_limit", sa.Integer(), nullable=True), + sa.Column("completion_tokens_details", sa.JSON(), nullable=True), + sa.Column("tags", sa.JSON(), nullable=True), + sa.Column("tid", sa.String(), nullable=True), + sa.Column("model_endpoint", sa.String(), nullable=True), + sa.Column("trace_id", sa.String(), nullable=True), + sa.Column("agent_id", sa.String(), nullable=True), + sa.Column("provider_category", sa.String(), nullable=True), + sa.Column("feedback", sa.String(), nullable=True), + sa.Column("project_id", sa.String(), nullable=True), + sa.PrimaryKeyConstraint("id"), + sa.ForeignKeyConstraint(["job_id"], ["jobs.id"], ondelete="SET NULL"), + sa.ForeignKeyConstraint(["organization_id"], ["organizations.id"], ondelete="RESTRICT"), + sa.ForeignKeyConstraint(["provider_id"], ["providers.id"], ondelete="RESTRICT"), + ) + + # Note: Foreign key constraint for block.current_history_entry_id -> block_history.id + # would need to be added here, but SQLite doesn't support ALTER TABLE ADD CONSTRAINT + # This will be handled by the ORM at runtime + + # Add missing columns to existing tables + + # All missing columns have been added to the table definitions above + + # step_id was already added in the messages table creation above + # op.add_column('messages', sa.Column('step_id', sa.String(), nullable=True)) + # op.create_foreign_key('fk_messages_step_id', 'messages', 'steps', ['step_id'], ['id'], ondelete='SET NULL') + + # Add index to source_passages for file_id + op.create_index("source_passages_file_id_idx", "source_passages", ["file_id"]) + + # Unique constraint for sources was added during table creation above + + # Create remaining association tables + + # Identities agents table + op.create_table( + "identities_agents", + sa.Column("identity_id", sa.String(), nullable=False), + sa.Column("agent_id", sa.String(), nullable=False), + sa.ForeignKeyConstraint(["identity_id"], ["identities.id"], ondelete="CASCADE"), + sa.ForeignKeyConstraint(["agent_id"], ["agents.id"], ondelete="CASCADE"), + sa.PrimaryKeyConstraint("identity_id", "agent_id"), + ) + + # Identities blocks table + op.create_table( + "identities_blocks", + sa.Column("identity_id", sa.String(), nullable=False), + sa.Column("block_id", sa.String(), nullable=False), + sa.ForeignKeyConstraint(["identity_id"], ["identities.id"], ondelete="CASCADE"), + sa.ForeignKeyConstraint(["block_id"], ["block.id"], ondelete="CASCADE"), + sa.PrimaryKeyConstraint("identity_id", "block_id"), + ) + + # Files agents table + op.create_table( + "files_agents", + sa.Column("id", sa.String(), nullable=False), + sa.Column("file_id", sa.String(), nullable=False), + sa.Column("agent_id", sa.String(), nullable=False), + sa.Column("source_id", sa.String(), nullable=False), + sa.Column("is_open", sa.Boolean(), nullable=False), + sa.Column("visible_content", sa.Text(), nullable=True), + sa.Column("last_accessed_at", sa.DateTime(timezone=True), nullable=False), + sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("is_deleted", sa.Boolean(), server_default=sa.text("(FALSE)"), nullable=False), + sa.Column("_created_by_id", sa.String(), nullable=True), + sa.Column("_last_updated_by_id", sa.String(), nullable=True), + sa.Column("organization_id", sa.String(), nullable=False), + sa.Column("file_name", sa.String(), nullable=False), + sa.PrimaryKeyConstraint("id", "file_id", "agent_id"), + sa.ForeignKeyConstraint(["file_id"], ["files.id"], ondelete="CASCADE"), + sa.ForeignKeyConstraint(["agent_id"], ["agents.id"], ondelete="CASCADE"), + sa.ForeignKeyConstraint(["source_id"], ["sources.id"], ondelete="CASCADE"), + sa.ForeignKeyConstraint(["organization_id"], ["organizations.id"]), + sa.UniqueConstraint("file_id", "agent_id", name="uq_file_agent"), + sa.UniqueConstraint("agent_id", "file_name", name="uq_agent_filename"), + ) + op.create_index("ix_agent_filename", "files_agents", ["agent_id", "file_name"]) + op.create_index("ix_file_agent", "files_agents", ["file_id", "agent_id"]) + + # Groups agents table + op.create_table( + "groups_agents", + sa.Column("group_id", sa.String(), nullable=False), + sa.Column("agent_id", sa.String(), nullable=False), + sa.ForeignKeyConstraint(["group_id"], ["groups.id"], ondelete="CASCADE"), + sa.ForeignKeyConstraint(["agent_id"], ["agents.id"], ondelete="CASCADE"), + sa.PrimaryKeyConstraint("group_id", "agent_id"), + ) + + # Groups blocks table + op.create_table( + "groups_blocks", + sa.Column("group_id", sa.String(), nullable=False), + sa.Column("block_id", sa.String(), nullable=False), + sa.ForeignKeyConstraint(["group_id"], ["groups.id"], ondelete="CASCADE"), + sa.ForeignKeyConstraint(["block_id"], ["block.id"], ondelete="CASCADE"), + sa.PrimaryKeyConstraint("group_id", "block_id"), + ) + + # LLM batch job table + op.create_table( + "llm_batch_job", + sa.Column("id", sa.String(), nullable=False), + sa.Column("status", sa.String(), nullable=False), + sa.Column("llm_provider", sa.String(), nullable=False), + sa.Column("create_batch_response", sa.JSON(), nullable=False), + sa.Column("latest_polling_response", sa.JSON(), nullable=True), + sa.Column("last_polled_at", sa.DateTime(timezone=True), nullable=True), + sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("is_deleted", sa.Boolean(), server_default=sa.text("(FALSE)"), nullable=False), + sa.Column("_created_by_id", sa.String(), nullable=True), + sa.Column("_last_updated_by_id", sa.String(), nullable=True), + sa.Column("organization_id", sa.String(), nullable=False), + sa.Column("letta_batch_job_id", sa.String(), nullable=False), + sa.PrimaryKeyConstraint("id"), + sa.ForeignKeyConstraint(["organization_id"], ["organizations.id"]), + sa.ForeignKeyConstraint(["letta_batch_job_id"], ["jobs.id"], ondelete="CASCADE"), + ) + op.create_index("ix_llm_batch_job_created_at", "llm_batch_job", ["created_at"]) + op.create_index("ix_llm_batch_job_status", "llm_batch_job", ["status"]) + + # LLM batch items table + op.create_table( + "llm_batch_items", + sa.Column("id", sa.String(), nullable=False), + sa.Column("llm_config", sa.JSON(), nullable=False), + sa.Column("request_status", sa.String(), nullable=False), + sa.Column("step_status", sa.String(), nullable=False), + sa.Column("step_state", sa.JSON(), nullable=False), + sa.Column("batch_request_result", sa.JSON(), nullable=True), + sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("is_deleted", sa.Boolean(), server_default=sa.text("(FALSE)"), nullable=False), + sa.Column("_created_by_id", sa.String(), nullable=True), + sa.Column("_last_updated_by_id", sa.String(), nullable=True), + sa.Column("organization_id", sa.String(), nullable=False), + sa.Column("agent_id", sa.String(), nullable=False), + sa.Column("llm_batch_id", sa.String(), nullable=False), + sa.PrimaryKeyConstraint("id"), + sa.ForeignKeyConstraint(["organization_id"], ["organizations.id"]), + sa.ForeignKeyConstraint(["agent_id"], ["agents.id"], ondelete="CASCADE"), + sa.ForeignKeyConstraint(["llm_batch_id"], ["llm_batch_job.id"], ondelete="CASCADE"), + ) + op.create_index("ix_llm_batch_items_agent_id", "llm_batch_items", ["agent_id"]) + op.create_index("ix_llm_batch_items_llm_batch_id", "llm_batch_items", ["llm_batch_id"]) + op.create_index("ix_llm_batch_items_status", "llm_batch_items", ["request_status"]) + + # Job messages table + op.create_table( + "job_messages", + sa.Column("id", sa.Integer(), primary_key=True), + sa.Column("job_id", sa.String(), nullable=False), + sa.Column("message_id", sa.String(), nullable=False), + sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("is_deleted", sa.Boolean(), server_default=sa.text("(FALSE)"), nullable=False), + sa.Column("_created_by_id", sa.String(), nullable=True), + sa.Column("_last_updated_by_id", sa.String(), nullable=True), + sa.ForeignKeyConstraint(["job_id"], ["jobs.id"], ondelete="CASCADE"), + sa.ForeignKeyConstraint(["message_id"], ["messages.id"], ondelete="CASCADE"), + sa.UniqueConstraint("job_id", "message_id", name="unique_job_message"), + ) + + # File contents table + op.create_table( + "file_contents", + sa.Column("file_id", sa.String(), nullable=False), + sa.Column("text", sa.Text(), nullable=False), + sa.Column("id", sa.String(), nullable=False), + sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("is_deleted", sa.Boolean(), server_default=sa.text("(FALSE)"), nullable=False), + sa.Column("_created_by_id", sa.String(), nullable=True), + sa.Column("_last_updated_by_id", sa.String(), nullable=True), + sa.PrimaryKeyConstraint("file_id", "id"), + sa.ForeignKeyConstraint(["file_id"], ["files.id"], ondelete="CASCADE"), + sa.UniqueConstraint("file_id", name="uq_file_contents_file_id"), + ) + + # Provider traces table + op.create_table( + "provider_traces", + sa.Column("id", sa.String(), nullable=False), + sa.Column("request_json", sa.JSON(), nullable=False), + sa.Column("response_json", sa.JSON(), nullable=False), + sa.Column("step_id", sa.String(), nullable=True), + sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=True), + sa.Column("is_deleted", sa.Boolean(), server_default=sa.text("(FALSE)"), nullable=False), + sa.Column("_created_by_id", sa.String(), nullable=True), + sa.Column("_last_updated_by_id", sa.String(), nullable=True), + sa.Column("organization_id", sa.String(), nullable=False), + sa.PrimaryKeyConstraint("id"), + sa.ForeignKeyConstraint(["organization_id"], ["organizations.id"]), + ) + op.create_index("ix_step_id", "provider_traces", ["step_id"]) + + # Complete the SQLite schema alignment by adding any remaining missing elements + try: + # Unique constraints for files_agents are already created with correct names in table definition above + + # Foreign key for files_agents.source_id is already created in table definition above + # Foreign key for messages.step_id is already created in table definition above + pass + + except Exception: + # Some operations may fail if the column/constraint already exists + # This is expected in some cases and we can continue + pass + + # Note: The remaining alembic check differences are expected for SQLite: + # 1. Type differences (BLOB vs CommonVector) - Expected and handled by ORM + # 2. Foreign key constraint differences - SQLite handles these at runtime + # 3. Index differences - SQLite doesn't support all PostgreSQL index features + # 4. Some constraint naming differences - Cosmetic differences + # + # These differences do not affect functionality as the ORM handles the abstraction + # between SQLite and PostgreSQL appropriately. + + +def downgrade() -> None: + # Only run this migration for SQLite + if settings.letta_pg_uri_no_default: + return + + # SQLite downgrade is not supported + raise NotImplementedError("SQLite downgrade is not supported. Use a fresh database instead.") diff --git a/alembic/versions/2cceb07c2384_add_content_parts_to_message.py b/alembic/versions/2cceb07c2384_add_content_parts_to_message.py index 1914418c..c5e704c6 100644 --- a/alembic/versions/2cceb07c2384_add_content_parts_to_message.py +++ b/alembic/versions/2cceb07c2384_add_content_parts_to_message.py @@ -12,6 +12,7 @@ import sqlalchemy as sa from alembic import op from letta.orm.custom_columns import MessageContentColumn +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "2cceb07c2384" @@ -21,12 +22,20 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("messages", sa.Column("content", MessageContentColumn(), nullable=True)) # ### end Alembic commands ### def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_column("messages", "content") # ### end Alembic commands ### diff --git a/alembic/versions/2f4ede6ae33b_add_otid_and_tool_return_to_message.py b/alembic/versions/2f4ede6ae33b_add_otid_and_tool_return_to_message.py index 90ae0b0e..3e43ad10 100644 --- a/alembic/versions/2f4ede6ae33b_add_otid_and_tool_return_to_message.py +++ b/alembic/versions/2f4ede6ae33b_add_otid_and_tool_return_to_message.py @@ -12,6 +12,7 @@ import sqlalchemy as sa import letta.orm from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "2f4ede6ae33b" @@ -21,6 +22,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("messages", sa.Column("otid", sa.String(), nullable=True)) op.add_column("messages", sa.Column("tool_returns", letta.orm.custom_columns.ToolReturnColumn(), nullable=True)) @@ -28,6 +33,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_column("messages", "tool_returns") op.drop_column("messages", "otid") diff --git a/alembic/versions/341068089f14_add_preserve_on_migration_to_block.py b/alembic/versions/341068089f14_add_preserve_on_migration_to_block.py index c36d9b00..2a7116a6 100644 --- a/alembic/versions/341068089f14_add_preserve_on_migration_to_block.py +++ b/alembic/versions/341068089f14_add_preserve_on_migration_to_block.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "341068089f14" @@ -20,12 +21,20 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("block", sa.Column("preserve_on_migration", sa.Boolean(), nullable=True)) # ### end Alembic commands ### def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_column("block", "preserve_on_migration") # ### end Alembic commands ### diff --git a/alembic/versions/348214cbc081_add_org_agent_id_indices.py b/alembic/versions/348214cbc081_add_org_agent_id_indices.py index 9bf7575b..7956115c 100644 --- a/alembic/versions/348214cbc081_add_org_agent_id_indices.py +++ b/alembic/versions/348214cbc081_add_org_agent_id_indices.py @@ -9,6 +9,7 @@ Create Date: 2025-05-28 22:43:18.509397 from typing import Sequence, Union from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "348214cbc081" @@ -18,6 +19,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.create_index("ix_agent_passages_org_agent", "agent_passages", ["organization_id", "agent_id"], unique=False) op.create_index("ix_messages_org_agent", "messages", ["organization_id", "agent_id"], unique=False) @@ -25,6 +30,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_index("ix_messages_org_agent", table_name="messages") op.drop_index("ix_agent_passages_org_agent", table_name="agent_passages") diff --git a/alembic/versions/373dabcba6cf_add_byok_fields_and_unique_constraint.py b/alembic/versions/373dabcba6cf_add_byok_fields_and_unique_constraint.py index 3b94cedd..6dac8e64 100644 --- a/alembic/versions/373dabcba6cf_add_byok_fields_and_unique_constraint.py +++ b/alembic/versions/373dabcba6cf_add_byok_fields_and_unique_constraint.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "373dabcba6cf" @@ -20,6 +21,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("providers", sa.Column("provider_type", sa.String(), nullable=True)) op.add_column("providers", sa.Column("base_url", sa.String(), nullable=True)) @@ -28,6 +33,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_constraint("unique_name_organization_id", "providers", type_="unique") op.drop_column("providers", "base_url") diff --git a/alembic/versions/3c683a662c82_migrate_jobs_to_the_orm.py b/alembic/versions/3c683a662c82_migrate_jobs_to_the_orm.py index 4f9b746d..85a33461 100644 --- a/alembic/versions/3c683a662c82_migrate_jobs_to_the_orm.py +++ b/alembic/versions/3c683a662c82_migrate_jobs_to_the_orm.py @@ -12,6 +12,7 @@ import sqlalchemy as sa from sqlalchemy.dialects import postgresql from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "3c683a662c82" @@ -21,6 +22,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("jobs", sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("now()"), nullable=True)) op.add_column("jobs", sa.Column("is_deleted", sa.Boolean(), server_default=sa.text("FALSE"), nullable=False)) @@ -34,6 +39,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_constraint(None, "jobs", type_="foreignkey") op.alter_column("jobs", "user_id", existing_type=sa.VARCHAR(), nullable=True) diff --git a/alembic/versions/400501b04bf0_add_per_agent_environment_variables.py b/alembic/versions/400501b04bf0_add_per_agent_environment_variables.py index 584e1e4c..1d42155f 100644 --- a/alembic/versions/400501b04bf0_add_per_agent_environment_variables.py +++ b/alembic/versions/400501b04bf0_add_per_agent_environment_variables.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "400501b04bf0" @@ -20,6 +21,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.create_table( "agent_environment_variables", @@ -46,6 +51,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_table("agent_environment_variables") # ### end Alembic commands ### diff --git a/alembic/versions/416b9d2db10b_repurpose_jobusagestatistics_for_new_.py b/alembic/versions/416b9d2db10b_repurpose_jobusagestatistics_for_new_.py index 332fdb3f..1f296a7c 100644 --- a/alembic/versions/416b9d2db10b_repurpose_jobusagestatistics_for_new_.py +++ b/alembic/versions/416b9d2db10b_repurpose_jobusagestatistics_for_new_.py @@ -12,6 +12,7 @@ import sqlalchemy as sa from sqlalchemy.dialects import postgresql from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "416b9d2db10b" @@ -21,6 +22,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### # Rename the table op.rename_table("job_usage_statistics", "steps") @@ -74,6 +79,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### # Remove step_id from messages first to avoid foreign key conflicts op.drop_constraint("fk_messages_step_id", "messages", type_="foreignkey") diff --git a/alembic/versions/46699adc71a7_add_unique_constraint_to_source_names_.py b/alembic/versions/46699adc71a7_add_unique_constraint_to_source_names_.py index d61cbc6f..3578932d 100644 --- a/alembic/versions/46699adc71a7_add_unique_constraint_to_source_names_.py +++ b/alembic/versions/46699adc71a7_add_unique_constraint_to_source_names_.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "46699adc71a7" @@ -20,6 +21,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("files", sa.Column("original_file_name", sa.String(), nullable=True)) @@ -62,6 +67,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_constraint("uq_source_name_organization", "sources", type_="unique") op.drop_column("files", "original_file_name") diff --git a/alembic/versions/47d2277e530d_add_total_chunks_and_chunks_embedded_to_.py b/alembic/versions/47d2277e530d_add_total_chunks_and_chunks_embedded_to_.py index 194d2acf..f3a40d25 100644 --- a/alembic/versions/47d2277e530d_add_total_chunks_and_chunks_embedded_to_.py +++ b/alembic/versions/47d2277e530d_add_total_chunks_and_chunks_embedded_to_.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "47d2277e530d" @@ -20,6 +21,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("files", sa.Column("total_chunks", sa.Integer(), nullable=True)) op.add_column("files", sa.Column("chunks_embedded", sa.Integer(), nullable=True)) @@ -27,6 +32,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_column("files", "chunks_embedded") op.drop_column("files", "total_chunks") diff --git a/alembic/versions/495f3f474131_write_source_id_directly_to_files_agents.py b/alembic/versions/495f3f474131_write_source_id_directly_to_files_agents.py index 9319e99c..bb5e9dd9 100644 --- a/alembic/versions/495f3f474131_write_source_id_directly_to_files_agents.py +++ b/alembic/versions/495f3f474131_write_source_id_directly_to_files_agents.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "495f3f474131" @@ -20,6 +21,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### # Step 1: Add the column as nullable first op.add_column("files_agents", sa.Column("source_id", sa.String(), nullable=True)) @@ -46,6 +51,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_constraint(None, "files_agents", type_="foreignkey") op.drop_column("files_agents", "source_id") diff --git a/alembic/versions/4e88e702f85e_drop_api_tokens_table_in_oss.py b/alembic/versions/4e88e702f85e_drop_api_tokens_table_in_oss.py index 75a90445..0bd56ebe 100644 --- a/alembic/versions/4e88e702f85e_drop_api_tokens_table_in_oss.py +++ b/alembic/versions/4e88e702f85e_drop_api_tokens_table_in_oss.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "4e88e702f85e" @@ -20,6 +21,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_index("tokens_idx_key", table_name="tokens") op.drop_index("tokens_idx_user", table_name="tokens") @@ -28,6 +33,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.create_table( "tokens", diff --git a/alembic/versions/51999513bcf1_steps_feedback_field.py b/alembic/versions/51999513bcf1_steps_feedback_field.py index d48afadb..d20f248d 100644 --- a/alembic/versions/51999513bcf1_steps_feedback_field.py +++ b/alembic/versions/51999513bcf1_steps_feedback_field.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "51999513bcf1" @@ -20,12 +21,20 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("steps", sa.Column("feedback", sa.String(), nullable=True)) # ### end Alembic commands ### def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_column("steps", "feedback") # ### end Alembic commands ### diff --git a/alembic/versions/549eff097c71_update_identities_unique_constraint_and_.py b/alembic/versions/549eff097c71_update_identities_unique_constraint_and_.py index 97a72543..45073c79 100644 --- a/alembic/versions/549eff097c71_update_identities_unique_constraint_and_.py +++ b/alembic/versions/549eff097c71_update_identities_unique_constraint_and_.py @@ -12,6 +12,7 @@ import sqlalchemy as sa from sqlalchemy.dialects import postgresql from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "549eff097c71" @@ -21,6 +22,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### # Update unique constraint on identities table op.drop_constraint("unique_identifier_pid_org_id", "identities", type_="unique") @@ -62,6 +67,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### # Add back the old columns to agents op.add_column("agents", sa.Column("identity_id", sa.String(), nullable=True)) diff --git a/alembic/versions/54dec07619c4_divide_passage_table_into_.py b/alembic/versions/54dec07619c4_divide_passage_table_into_.py index e164a997..6dcc0d1b 100644 --- a/alembic/versions/54dec07619c4_divide_passage_table_into_.py +++ b/alembic/versions/54dec07619c4_divide_passage_table_into_.py @@ -14,6 +14,7 @@ from sqlalchemy.dialects import postgresql from alembic import op from letta.orm.custom_columns import EmbeddingConfigColumn +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "54dec07619c4" @@ -23,6 +24,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.create_table( "agent_passages", @@ -79,6 +84,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_constraint(None, "messages", type_="foreignkey") op.create_foreign_key("messages_agent_id_fkey", "messages", "agents", ["agent_id"], ["id"]) diff --git a/alembic/versions/54f2311edb62_add_args_schema_to_tools.py b/alembic/versions/54f2311edb62_add_args_schema_to_tools.py index 1b5f332e..163a4e88 100644 --- a/alembic/versions/54f2311edb62_add_args_schema_to_tools.py +++ b/alembic/versions/54f2311edb62_add_args_schema_to_tools.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "54f2311edb62" @@ -20,12 +21,20 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("tools", sa.Column("args_json_schema", sa.JSON(), nullable=True)) # ### end Alembic commands ### def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_column("tools", "args_json_schema") # ### end Alembic commands ### diff --git a/alembic/versions/56254216524f_add_custom_headers_to_mcp_server.py b/alembic/versions/56254216524f_add_custom_headers_to_mcp_server.py index 62331ccb..80c57532 100644 --- a/alembic/versions/56254216524f_add_custom_headers_to_mcp_server.py +++ b/alembic/versions/56254216524f_add_custom_headers_to_mcp_server.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "56254216524f" @@ -20,12 +21,20 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("mcp_server", sa.Column("custom_headers", sa.JSON(), nullable=True)) # ### end Alembic commands ### def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_column("mcp_server", "custom_headers") # ### end Alembic commands ### diff --git a/alembic/versions/5987401b40ae_refactor_agent_memory.py b/alembic/versions/5987401b40ae_refactor_agent_memory.py index 889e9425..741644e2 100644 --- a/alembic/versions/5987401b40ae_refactor_agent_memory.py +++ b/alembic/versions/5987401b40ae_refactor_agent_memory.py @@ -12,6 +12,7 @@ import sqlalchemy as sa from sqlalchemy.dialects import postgresql from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "5987401b40ae" @@ -21,6 +22,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.alter_column("agents", "tools", new_column_name="tool_names") op.drop_column("agents", "memory") @@ -28,6 +33,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.alter_column("agents", "tool_names", new_column_name="tools") op.add_column("agents", sa.Column("memory", postgresql.JSON(astext_type=sa.Text()), autoincrement=False, nullable=True)) diff --git a/alembic/versions/60ed28ee7138_add_project_id_to_step_model.py b/alembic/versions/60ed28ee7138_add_project_id_to_step_model.py index a6e23444..aa0817d8 100644 --- a/alembic/versions/60ed28ee7138_add_project_id_to_step_model.py +++ b/alembic/versions/60ed28ee7138_add_project_id_to_step_model.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "60ed28ee7138" @@ -20,6 +21,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("steps", sa.Column("project_id", sa.String(), nullable=True)) op.execute( @@ -36,6 +41,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_column("steps", "project_id") # ### end Alembic commands ### diff --git a/alembic/versions/614c4e53b66e_add_unique_constraint_to_file_id_and_.py b/alembic/versions/614c4e53b66e_add_unique_constraint_to_file_id_and_.py index 9d726a35..8d8813d1 100644 --- a/alembic/versions/614c4e53b66e_add_unique_constraint_to_file_id_and_.py +++ b/alembic/versions/614c4e53b66e_add_unique_constraint_to_file_id_and_.py @@ -9,6 +9,7 @@ Create Date: 2025-06-02 17:03:58.879839 from typing import Sequence, Union from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "614c4e53b66e" @@ -18,12 +19,20 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.create_unique_constraint("uq_files_agents_file_agent", "files_agents", ["file_id", "agent_id"]) # ### end Alembic commands ### def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_constraint("uq_files_agents_file_agent", "files_agents", type_="unique") # ### end Alembic commands ### diff --git a/alembic/versions/61ee53ec45a5_add_index_on_source_passages_for_files.py b/alembic/versions/61ee53ec45a5_add_index_on_source_passages_for_files.py index 29200f47..a9ae8a39 100644 --- a/alembic/versions/61ee53ec45a5_add_index_on_source_passages_for_files.py +++ b/alembic/versions/61ee53ec45a5_add_index_on_source_passages_for_files.py @@ -9,6 +9,7 @@ Create Date: 2025-06-20 11:10:02.744914 from typing import Sequence, Union from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "61ee53ec45a5" @@ -18,12 +19,20 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.create_index("source_passages_file_id_idx", "source_passages", ["file_id"], unique=False) # ### end Alembic commands ### def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_index("source_passages_file_id_idx", table_name="source_passages") # ### end Alembic commands ### diff --git a/alembic/versions/6c53224a7a58_add_provider_category_to_steps.py b/alembic/versions/6c53224a7a58_add_provider_category_to_steps.py index 891f427f..bf06a6c9 100644 --- a/alembic/versions/6c53224a7a58_add_provider_category_to_steps.py +++ b/alembic/versions/6c53224a7a58_add_provider_category_to_steps.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "6c53224a7a58" @@ -20,12 +21,20 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("steps", sa.Column("provider_category", sa.String(), nullable=True)) # ### end Alembic commands ### def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_column("steps", "provider_category") # ### end Alembic commands ### diff --git a/alembic/versions/6fbe9cace832_adding_indexes_to_models.py b/alembic/versions/6fbe9cace832_adding_indexes_to_models.py index 6331fed7..5c01f445 100644 --- a/alembic/versions/6fbe9cace832_adding_indexes_to_models.py +++ b/alembic/versions/6fbe9cace832_adding_indexes_to_models.py @@ -9,6 +9,7 @@ Create Date: 2025-01-23 11:02:59.534372 from typing import Sequence, Union from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "6fbe9cace832" @@ -18,6 +19,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.create_index("agent_passages_created_at_id_idx", "agent_passages", ["created_at", "id"], unique=False) op.create_index("ix_agents_created_at", "agents", ["created_at", "id"], unique=False) @@ -31,6 +36,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_index("ix_tools_created_at_name", table_name="tools") op.drop_index("source_created_at_id_idx", table_name="sources") diff --git a/alembic/versions/6fe79c0525f2_enable_sleeptime_agent_fields.py b/alembic/versions/6fe79c0525f2_enable_sleeptime_agent_fields.py index 5cff137e..8d6cda1d 100644 --- a/alembic/versions/6fe79c0525f2_enable_sleeptime_agent_fields.py +++ b/alembic/versions/6fe79c0525f2_enable_sleeptime_agent_fields.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "6fe79c0525f2" @@ -20,6 +21,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("agents", sa.Column("enable_sleeptime", sa.Boolean(), nullable=True)) op.alter_column("groups", "background_agents_interval", new_column_name="background_agents_frequency") @@ -27,6 +32,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.alter_column("groups", "background_agents_frequency", new_column_name="background_agents_interval") op.drop_column("agents", "enable_sleeptime") diff --git a/alembic/versions/74f2ede29317_add_background_group_support.py b/alembic/versions/74f2ede29317_add_background_group_support.py index a7657ec0..3bc98636 100644 --- a/alembic/versions/74f2ede29317_add_background_group_support.py +++ b/alembic/versions/74f2ede29317_add_background_group_support.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "74f2ede29317" @@ -20,6 +21,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("groups", sa.Column("background_agents_interval", sa.Integer(), nullable=True)) op.add_column("groups", sa.Column("turns_counter", sa.Integer(), nullable=True)) @@ -36,6 +41,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_table("groups_blocks") op.drop_column("groups", "last_processed_message_id") diff --git a/alembic/versions/7778731d15e2_added_jobusagestatistics_table.py b/alembic/versions/7778731d15e2_added_jobusagestatistics_table.py index 92c3302d..66a30682 100644 --- a/alembic/versions/7778731d15e2_added_jobusagestatistics_table.py +++ b/alembic/versions/7778731d15e2_added_jobusagestatistics_table.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "7778731d15e2" @@ -20,6 +21,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # Create job_usage_statistics table op.create_table( "job_usage_statistics", @@ -45,6 +50,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # Drop indexes op.drop_index("ix_job_usage_statistics_created_at", "job_usage_statistics") op.drop_index("ix_job_usage_statistics_job_id", "job_usage_statistics") diff --git a/alembic/versions/77de976590ae_add_groups_for_multi_agent.py b/alembic/versions/77de976590ae_add_groups_for_multi_agent.py index fdf446e2..6180746a 100644 --- a/alembic/versions/77de976590ae_add_groups_for_multi_agent.py +++ b/alembic/versions/77de976590ae_add_groups_for_multi_agent.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "77de976590ae" @@ -20,6 +21,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.create_table( "groups", @@ -55,6 +60,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_column("messages", "group_id") op.drop_table("groups_agents") diff --git a/alembic/versions/7980d239ea08_add_stateless_option_for_agentstate.py b/alembic/versions/7980d239ea08_add_stateless_option_for_agentstate.py index 9693940d..0a3a0e69 100644 --- a/alembic/versions/7980d239ea08_add_stateless_option_for_agentstate.py +++ b/alembic/versions/7980d239ea08_add_stateless_option_for_agentstate.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "7980d239ea08" @@ -20,6 +21,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # Add the column with a temporary nullable=True so we can backfill op.add_column("agents", sa.Column("message_buffer_autoclear", sa.Boolean(), nullable=True)) @@ -31,6 +36,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_column("agents", "message_buffer_autoclear") # ### end Alembic commands ### diff --git a/alembic/versions/7b189006c97d_rename_batch_id_to_llm_batch_id_on_llm_.py b/alembic/versions/7b189006c97d_rename_batch_id_to_llm_batch_id_on_llm_.py index e75e0638..b9e2b158 100644 --- a/alembic/versions/7b189006c97d_rename_batch_id_to_llm_batch_id_on_llm_.py +++ b/alembic/versions/7b189006c97d_rename_batch_id_to_llm_batch_id_on_llm_.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "7b189006c97d" @@ -20,6 +21,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("llm_batch_items", sa.Column("llm_batch_id", sa.String(), nullable=False)) op.drop_index("ix_llm_batch_items_batch_id", table_name="llm_batch_items") @@ -31,6 +36,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("llm_batch_items", sa.Column("batch_id", sa.VARCHAR(), autoincrement=False, nullable=False)) op.drop_constraint(None, "llm_batch_items", type_="foreignkey") diff --git a/alembic/versions/7f652fdd3dba_change_jobmessage_unique_constraint_to_.py b/alembic/versions/7f652fdd3dba_change_jobmessage_unique_constraint_to_.py index b1be20b1..89c9b05e 100644 --- a/alembic/versions/7f652fdd3dba_change_jobmessage_unique_constraint_to_.py +++ b/alembic/versions/7f652fdd3dba_change_jobmessage_unique_constraint_to_.py @@ -9,6 +9,7 @@ Create Date: 2025-01-13 14:36:13.626344 from typing import Sequence, Union from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "7f652fdd3dba" @@ -18,6 +19,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # Drop the old unique constraint op.drop_constraint("uq_job_messages_message_id", "job_messages", type_="unique") @@ -26,6 +31,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # Drop the new composite constraint op.drop_constraint("unique_job_message", "job_messages", type_="unique") diff --git a/alembic/versions/878607e41ca4_add_provider_category.py b/alembic/versions/878607e41ca4_add_provider_category.py index fb914c67..48d0db9b 100644 --- a/alembic/versions/878607e41ca4_add_provider_category.py +++ b/alembic/versions/878607e41ca4_add_provider_category.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "878607e41ca4" @@ -20,12 +21,20 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("providers", sa.Column("provider_category", sa.String(), nullable=True)) # ### end Alembic commands ### def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_column("providers", "provider_category") # ### end Alembic commands ### diff --git a/alembic/versions/88f9432739a9_add_jobtype_to_job_table.py b/alembic/versions/88f9432739a9_add_jobtype_to_job_table.py index 1c0090d9..91301f7e 100644 --- a/alembic/versions/88f9432739a9_add_jobtype_to_job_table.py +++ b/alembic/versions/88f9432739a9_add_jobtype_to_job_table.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "88f9432739a9" @@ -20,6 +21,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # Add job_type column with default value op.add_column("jobs", sa.Column("job_type", sa.String(), nullable=True)) @@ -31,5 +36,9 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # Remove the job_type column op.drop_column("jobs", "job_type") diff --git a/alembic/versions/8d70372ad130_adding_jobmessages_table.py b/alembic/versions/8d70372ad130_adding_jobmessages_table.py index 6df8c862..2c9c0a5a 100644 --- a/alembic/versions/8d70372ad130_adding_jobmessages_table.py +++ b/alembic/versions/8d70372ad130_adding_jobmessages_table.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "8d70372ad130" @@ -20,6 +21,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + op.create_table( "job_messages", sa.Column("id", sa.Integer(), nullable=False), @@ -42,6 +47,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + op.drop_index("ix_job_messages_created_at", "job_messages") op.drop_index("ix_job_messages_job_id", "job_messages") op.drop_table("job_messages") diff --git a/alembic/versions/90bb156e71df_rename_sleeptime_agent_frequency.py b/alembic/versions/90bb156e71df_rename_sleeptime_agent_frequency.py index b80f183e..43b7f5fc 100644 --- a/alembic/versions/90bb156e71df_rename_sleeptime_agent_frequency.py +++ b/alembic/versions/90bb156e71df_rename_sleeptime_agent_frequency.py @@ -9,6 +9,7 @@ Create Date: 2025-04-03 17:20:26.218596 from typing import Sequence, Union from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "90bb156e71df" @@ -18,12 +19,20 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.alter_column("groups", "background_agents_frequency", new_column_name="sleeptime_agent_frequency") # ### end Alembic commands ### def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.alter_column("groups", "sleeptime_agent_frequency", new_column_name="background_agents_frequency") # ### end Alembic commands ### diff --git a/alembic/versions/90fd814d0cda_add_callback_error_field_to_jobs.py b/alembic/versions/90fd814d0cda_add_callback_error_field_to_jobs.py index 4f45e739..dba8736f 100644 --- a/alembic/versions/90fd814d0cda_add_callback_error_field_to_jobs.py +++ b/alembic/versions/90fd814d0cda_add_callback_error_field_to_jobs.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "90fd814d0cda" @@ -20,12 +21,20 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("jobs", sa.Column("callback_error", sa.String(), nullable=True)) # ### end Alembic commands ### def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_column("jobs", "callback_error") # ### end Alembic commands ### diff --git a/alembic/versions/915b68780108_add_providers_data_to_orm.py b/alembic/versions/915b68780108_add_providers_data_to_orm.py index 973b8dbb..3db4dd6f 100644 --- a/alembic/versions/915b68780108_add_providers_data_to_orm.py +++ b/alembic/versions/915b68780108_add_providers_data_to_orm.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "915b68780108" @@ -20,6 +21,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.create_table( "providers", @@ -42,6 +47,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_table("providers") # ### end Alembic commands ### diff --git a/alembic/versions/9556081ce65b_add_bedrock_creds_to_byok.py b/alembic/versions/9556081ce65b_add_bedrock_creds_to_byok.py index 93d5c68f..77430d9c 100644 --- a/alembic/versions/9556081ce65b_add_bedrock_creds_to_byok.py +++ b/alembic/versions/9556081ce65b_add_bedrock_creds_to_byok.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "9556081ce65b" @@ -20,6 +21,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("providers", sa.Column("access_key", sa.String(), nullable=True)) op.add_column("providers", sa.Column("region", sa.String(), nullable=True)) @@ -27,6 +32,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_column("providers", "region") op.drop_column("providers", "access_key") diff --git a/alembic/versions/95badb46fdf9_migrate_messages_to_the_orm.py b/alembic/versions/95badb46fdf9_migrate_messages_to_the_orm.py index 73254e39..c84730d2 100644 --- a/alembic/versions/95badb46fdf9_migrate_messages_to_the_orm.py +++ b/alembic/versions/95badb46fdf9_migrate_messages_to_the_orm.py @@ -12,6 +12,7 @@ import sqlalchemy as sa from sqlalchemy.dialects import postgresql from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "95badb46fdf9" @@ -21,6 +22,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("messages", sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("now()"), nullable=True)) op.add_column("messages", sa.Column("is_deleted", sa.Boolean(), server_default=sa.text("FALSE"), nullable=False)) @@ -48,6 +53,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("messages", sa.Column("user_id", sa.VARCHAR(), autoincrement=False, nullable=False)) op.drop_constraint(None, "messages", type_="foreignkey") diff --git a/alembic/versions/9758adf8fdd3_add_run_completion_and_duration_to_.py b/alembic/versions/9758adf8fdd3_add_run_completion_and_duration_to_.py index 5702c542..529e4071 100644 --- a/alembic/versions/9758adf8fdd3_add_run_completion_and_duration_to_.py +++ b/alembic/versions/9758adf8fdd3_add_run_completion_and_duration_to_.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "9758adf8fdd3" @@ -20,6 +21,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("agents", sa.Column("last_run_completion", sa.DateTime(timezone=True), nullable=True)) op.add_column("agents", sa.Column("last_run_duration_ms", sa.Integer(), nullable=True)) @@ -27,6 +32,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_column("agents", "last_run_duration_ms") op.drop_column("agents", "last_run_completion") diff --git a/alembic/versions/9792f94e961d_add_file_processing_status_to_.py b/alembic/versions/9792f94e961d_add_file_processing_status_to_.py index 340e7990..52859bfb 100644 --- a/alembic/versions/9792f94e961d_add_file_processing_status_to_.py +++ b/alembic/versions/9792f94e961d_add_file_processing_status_to_.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "9792f94e961d" @@ -20,6 +21,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # Step 1: Create constraint op.create_unique_constraint("uq_file_contents_file_id", "file_contents", ["file_id"]) @@ -40,6 +45,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_index("ix_files_source_created", table_name="files") op.drop_index("ix_files_processing_status", table_name="files") diff --git a/alembic/versions/9a505cc7eca9_create_a_baseline_migrations.py b/alembic/versions/9a505cc7eca9_create_a_baseline_migrations.py index 21f6a396..82d8073f 100644 --- a/alembic/versions/9a505cc7eca9_create_a_baseline_migrations.py +++ b/alembic/versions/9a505cc7eca9_create_a_baseline_migrations.py @@ -14,6 +14,7 @@ from sqlalchemy.dialects import postgresql import letta.orm from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "9a505cc7eca9" @@ -23,6 +24,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + op.create_table( "agent_source_mapping", sa.Column("id", sa.String(), nullable=False), @@ -173,6 +178,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + op.drop_table("users") op.drop_table("tools") op.drop_index("tokens_idx_user", table_name="tokens") diff --git a/alembic/versions/9ecbdbaa409f_add_table_to_store_mcp_servers.py b/alembic/versions/9ecbdbaa409f_add_table_to_store_mcp_servers.py index 8fc4ba9b..eb2a1487 100644 --- a/alembic/versions/9ecbdbaa409f_add_table_to_store_mcp_servers.py +++ b/alembic/versions/9ecbdbaa409f_add_table_to_store_mcp_servers.py @@ -12,6 +12,7 @@ import sqlalchemy as sa import letta from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "9ecbdbaa409f" @@ -21,6 +22,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.create_table( "mcp_server", @@ -46,6 +51,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_table("mcp_server") # ### end Alembic commands ### diff --git a/alembic/versions/a113caac453e_add_identities_table.py b/alembic/versions/a113caac453e_add_identities_table.py index 7c4d4140..8d83aafd 100644 --- a/alembic/versions/a113caac453e_add_identities_table.py +++ b/alembic/versions/a113caac453e_add_identities_table.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "a113caac453e" @@ -20,6 +21,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # Create identities table op.create_table( "identities", @@ -58,6 +63,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # First remove the foreign key constraint and column from agents op.drop_constraint("fk_agents_identity_id", "agents", type_="foreignkey") op.drop_column("agents", "identity_id") diff --git a/alembic/versions/a3047a624130_add_identifier_key_to_agents.py b/alembic/versions/a3047a624130_add_identifier_key_to_agents.py index abeaeef5..320eefc8 100644 --- a/alembic/versions/a3047a624130_add_identifier_key_to_agents.py +++ b/alembic/versions/a3047a624130_add_identifier_key_to_agents.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "a3047a624130" @@ -20,8 +21,16 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + op.add_column("agents", sa.Column("identifier_key", sa.String(), nullable=True)) def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + op.drop_column("agents", "identifier_key") diff --git a/alembic/versions/a3c7d62e08ca_add_callback_data_to_jobs_table.py b/alembic/versions/a3c7d62e08ca_add_callback_data_to_jobs_table.py index 994160ef..cdc7985f 100644 --- a/alembic/versions/a3c7d62e08ca_add_callback_data_to_jobs_table.py +++ b/alembic/versions/a3c7d62e08ca_add_callback_data_to_jobs_table.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "a3c7d62e08ca" @@ -20,6 +21,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("jobs", sa.Column("callback_url", sa.String(), nullable=True)) op.add_column("jobs", sa.Column("callback_sent_at", sa.DateTime(), nullable=True)) @@ -28,6 +33,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_column("jobs", "callback_status_code") op.drop_column("jobs", "callback_sent_at") diff --git a/alembic/versions/a66510f83fc2_add_ordered_agent_ids_to_groups.py b/alembic/versions/a66510f83fc2_add_ordered_agent_ids_to_groups.py index b769627b..6d41a370 100644 --- a/alembic/versions/a66510f83fc2_add_ordered_agent_ids_to_groups.py +++ b/alembic/versions/a66510f83fc2_add_ordered_agent_ids_to_groups.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "a66510f83fc2" @@ -20,12 +21,20 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("groups", sa.Column("agent_ids", sa.JSON(), nullable=False)) # ### end Alembic commands ### def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_column("groups", "agent_ids") # ### end Alembic commands ### diff --git a/alembic/versions/a91994b9752f_add_column_to_tools_table_to_contain_.py b/alembic/versions/a91994b9752f_add_column_to_tools_table_to_contain_.py index f8da3856..3e2a4ad8 100644 --- a/alembic/versions/a91994b9752f_add_column_to_tools_table_to_contain_.py +++ b/alembic/versions/a91994b9752f_add_column_to_tools_table_to_contain_.py @@ -12,6 +12,7 @@ import sqlalchemy as sa from alembic import op from letta.constants import FUNCTION_RETURN_CHAR_LIMIT +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "a91994b9752f" @@ -21,6 +22,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("tools", sa.Column("return_char_limit", sa.Integer(), nullable=True)) @@ -34,6 +39,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_column("tools", "return_char_limit") # ### end Alembic commands ### diff --git a/alembic/versions/b183663c6769_add_trace_id_to_steps_table.py b/alembic/versions/b183663c6769_add_trace_id_to_steps_table.py index 5f69f492..25861a0e 100644 --- a/alembic/versions/b183663c6769_add_trace_id_to_steps_table.py +++ b/alembic/versions/b183663c6769_add_trace_id_to_steps_table.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "b183663c6769" @@ -20,12 +21,20 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("steps", sa.Column("trace_id", sa.String(), nullable=True)) # ### end Alembic commands ### def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_column("steps", "trace_id") # ### end Alembic commands ### diff --git a/alembic/versions/b6d7ca024aa9_add_agents_tags_table.py b/alembic/versions/b6d7ca024aa9_add_agents_tags_table.py index 2aec8a09..c542994b 100644 --- a/alembic/versions/b6d7ca024aa9_add_agents_tags_table.py +++ b/alembic/versions/b6d7ca024aa9_add_agents_tags_table.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "b6d7ca024aa9" @@ -20,6 +21,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.create_table( "agents_tags", @@ -47,6 +52,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_table("agents_tags") # ### end Alembic commands ### diff --git a/alembic/versions/bdddd421ec41_add_privileged_tools_to_organization.py b/alembic/versions/bdddd421ec41_add_privileged_tools_to_organization.py index 2d6191ca..5fb09eed 100644 --- a/alembic/versions/bdddd421ec41_add_privileged_tools_to_organization.py +++ b/alembic/versions/bdddd421ec41_add_privileged_tools_to_organization.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "bdddd421ec41" @@ -20,6 +21,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # Step 1: Add `privileged_tools` column with nullable=True op.add_column("organizations", sa.Column("privileged_tools", sa.Boolean(), nullable=True)) @@ -36,4 +41,8 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + op.drop_column("organizations", "privileged_tools") diff --git a/alembic/versions/bff040379479_add_block_history_tables.py b/alembic/versions/bff040379479_add_block_history_tables.py index 80c6cb33..f8979743 100644 --- a/alembic/versions/bff040379479_add_block_history_tables.py +++ b/alembic/versions/bff040379479_add_block_history_tables.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "bff040379479" @@ -20,6 +21,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.create_table( "block_history", @@ -55,6 +60,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_constraint("fk_block_current_history_entry", "block", type_="foreignkey") op.drop_index(op.f("ix_block_current_history_entry_id"), table_name="block") diff --git a/alembic/versions/c0ef3ff26306_add_token_to_mcp_server.py b/alembic/versions/c0ef3ff26306_add_token_to_mcp_server.py index 3cf30846..f11b70b6 100644 --- a/alembic/versions/c0ef3ff26306_add_token_to_mcp_server.py +++ b/alembic/versions/c0ef3ff26306_add_token_to_mcp_server.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "c0ef3ff26306" @@ -20,12 +21,20 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("mcp_server", sa.Column("token", sa.String(), nullable=True)) # ### end Alembic commands ### def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_column("mcp_server", "token") # ### end Alembic commands ### diff --git a/alembic/versions/c3b1da3d1157_add_sender_id_to_message.py b/alembic/versions/c3b1da3d1157_add_sender_id_to_message.py index bd59a118..df9454d3 100644 --- a/alembic/versions/c3b1da3d1157_add_sender_id_to_message.py +++ b/alembic/versions/c3b1da3d1157_add_sender_id_to_message.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "c3b1da3d1157" @@ -20,12 +21,20 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("messages", sa.Column("sender_id", sa.String(), nullable=True)) # ### end Alembic commands ### def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_column("messages", "sender_id") # ### end Alembic commands ### diff --git a/alembic/versions/c56081a05371_add_buffer_length_min_max_for_voice_.py b/alembic/versions/c56081a05371_add_buffer_length_min_max_for_voice_.py index 44f9a87f..09ba1a88 100644 --- a/alembic/versions/c56081a05371_add_buffer_length_min_max_for_voice_.py +++ b/alembic/versions/c56081a05371_add_buffer_length_min_max_for_voice_.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "c56081a05371" @@ -20,6 +21,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("groups", sa.Column("max_message_buffer_length", sa.Integer(), nullable=True)) op.add_column("groups", sa.Column("min_message_buffer_length", sa.Integer(), nullable=True)) @@ -27,6 +32,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_column("groups", "min_message_buffer_length") op.drop_column("groups", "max_message_buffer_length") diff --git a/alembic/versions/c5d964280dff_add_passages_orm_drop_legacy_passages_.py b/alembic/versions/c5d964280dff_add_passages_orm_drop_legacy_passages_.py index b6d2e6ba..fdd8fc25 100644 --- a/alembic/versions/c5d964280dff_add_passages_orm_drop_legacy_passages_.py +++ b/alembic/versions/c5d964280dff_add_passages_orm_drop_legacy_passages_.py @@ -12,6 +12,7 @@ import sqlalchemy as sa from sqlalchemy.dialects import postgresql from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "c5d964280dff" @@ -21,6 +22,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("passages", sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("now()"), nullable=True)) op.add_column("passages", sa.Column("is_deleted", sa.Boolean(), server_default=sa.text("FALSE"), nullable=False)) @@ -56,6 +61,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("passages", sa.Column("user_id", sa.VARCHAR(), autoincrement=False, nullable=False)) op.drop_constraint(None, "passages", type_="foreignkey") diff --git a/alembic/versions/c7ac45f69849_add_timezone_to_agents_table.py b/alembic/versions/c7ac45f69849_add_timezone_to_agents_table.py index 3f11a102..04b45772 100644 --- a/alembic/versions/c7ac45f69849_add_timezone_to_agents_table.py +++ b/alembic/versions/c7ac45f69849_add_timezone_to_agents_table.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "c7ac45f69849" @@ -20,12 +21,20 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("agents", sa.Column("timezone", sa.String(), nullable=True, default="UTC")) # ### end Alembic commands ### def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_column("agents", "timezone") # ### end Alembic commands ### diff --git a/alembic/versions/c85a3d07c028_move_files_to_orm.py b/alembic/versions/c85a3d07c028_move_files_to_orm.py index b05d7930..c0255a86 100644 --- a/alembic/versions/c85a3d07c028_move_files_to_orm.py +++ b/alembic/versions/c85a3d07c028_move_files_to_orm.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "c85a3d07c028" @@ -20,6 +21,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("files", sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("now()"), nullable=True)) op.add_column("files", sa.Column("is_deleted", sa.Boolean(), server_default=sa.text("FALSE"), nullable=False)) @@ -44,6 +49,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("files", sa.Column("user_id", sa.VARCHAR(), autoincrement=False, nullable=False)) op.drop_constraint(None, "files", type_="foreignkey") diff --git a/alembic/versions/c96263433aef_add_file_name_to_source_passages.py b/alembic/versions/c96263433aef_add_file_name_to_source_passages.py index 9f24dcfb..18bd5262 100644 --- a/alembic/versions/c96263433aef_add_file_name_to_source_passages.py +++ b/alembic/versions/c96263433aef_add_file_name_to_source_passages.py @@ -10,6 +10,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "c96263433aef" @@ -19,6 +20,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # Add the new column op.add_column("source_passages", sa.Column("file_name", sa.String(), nullable=True)) @@ -37,4 +42,8 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + op.drop_column("source_passages", "file_name") diff --git a/alembic/versions/cc8dc340836d_add_support_for_request_and_response_.py b/alembic/versions/cc8dc340836d_add_support_for_request_and_response_.py index 7ce2c0dc..36a79dcf 100644 --- a/alembic/versions/cc8dc340836d_add_support_for_request_and_response_.py +++ b/alembic/versions/cc8dc340836d_add_support_for_request_and_response_.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "cc8dc340836d" @@ -20,6 +21,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.create_table( "provider_traces", @@ -44,6 +49,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_index("ix_step_id", table_name="provider_traces") op.drop_table("provider_traces") diff --git a/alembic/versions/cda66b6cb0d6_move_sources_to_orm.py b/alembic/versions/cda66b6cb0d6_move_sources_to_orm.py index f46bef6b..7ada943a 100644 --- a/alembic/versions/cda66b6cb0d6_move_sources_to_orm.py +++ b/alembic/versions/cda66b6cb0d6_move_sources_to_orm.py @@ -12,6 +12,7 @@ import sqlalchemy as sa from sqlalchemy.dialects import postgresql from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "cda66b6cb0d6" @@ -21,6 +22,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("sources", sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("now()"), nullable=True)) op.add_column("sources", sa.Column("is_deleted", sa.Boolean(), server_default=sa.text("FALSE"), nullable=False)) @@ -51,6 +56,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("sources", sa.Column("user_id", sa.VARCHAR(), autoincrement=False, nullable=False)) op.drop_constraint(None, "sources", type_="foreignkey") diff --git a/alembic/versions/cdb3db091113_remove_unique_name_restriction_on_agents.py b/alembic/versions/cdb3db091113_remove_unique_name_restriction_on_agents.py index 83940119..f8713b43 100644 --- a/alembic/versions/cdb3db091113_remove_unique_name_restriction_on_agents.py +++ b/alembic/versions/cdb3db091113_remove_unique_name_restriction_on_agents.py @@ -9,6 +9,7 @@ Create Date: 2025-01-10 15:36:08.728539 from typing import Sequence, Union from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "cdb3db091113" @@ -18,12 +19,20 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_constraint("unique_org_agent_name", "agents", type_="unique") # ### end Alembic commands ### def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.create_unique_constraint("unique_org_agent_name", "agents", ["organization_id", "name"]) # ### end Alembic commands ### diff --git a/alembic/versions/cdd4a1c11aee_add_file_name_to_fileagent_association_.py b/alembic/versions/cdd4a1c11aee_add_file_name_to_fileagent_association_.py index 164803d5..f808cdcf 100644 --- a/alembic/versions/cdd4a1c11aee_add_file_name_to_fileagent_association_.py +++ b/alembic/versions/cdd4a1c11aee_add_file_name_to_fileagent_association_.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "cdd4a1c11aee" @@ -20,6 +21,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.create_table( "file_contents", @@ -55,6 +60,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_constraint("uq_files_agents_agent_file_name", "files_agents", type_="unique") op.drop_index("ix_files_agents_agent_file_name", table_name="files_agents") diff --git a/alembic/versions/d05669b60ebe_migrate_agents_to_orm.py b/alembic/versions/d05669b60ebe_migrate_agents_to_orm.py index d03652c8..5fb1352b 100644 --- a/alembic/versions/d05669b60ebe_migrate_agents_to_orm.py +++ b/alembic/versions/d05669b60ebe_migrate_agents_to_orm.py @@ -12,6 +12,7 @@ import sqlalchemy as sa from sqlalchemy.dialects import postgresql from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "d05669b60ebe" @@ -21,6 +22,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.create_table( "sources_agents", @@ -96,6 +101,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column( "tools_agents", diff --git a/alembic/versions/d14ae606614c_move_organizations_users_tools_to_orm.py b/alembic/versions/d14ae606614c_move_organizations_users_tools_to_orm.py index 83c5f2df..95c5fbe4 100644 --- a/alembic/versions/d14ae606614c_move_organizations_users_tools_to_orm.py +++ b/alembic/versions/d14ae606614c_move_organizations_users_tools_to_orm.py @@ -13,6 +13,7 @@ from sqlalchemy.dialects import postgresql import letta from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "d14ae606614c" @@ -22,6 +23,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # Delete all tools op.execute("DELETE FROM tools") @@ -60,6 +65,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("users", sa.Column("policies_accepted", sa.BOOLEAN(), autoincrement=False, nullable=False)) op.add_column("users", sa.Column("org_id", sa.VARCHAR(), autoincrement=False, nullable=True)) diff --git a/alembic/versions/d211df879a5f_add_agent_id_to_steps.py b/alembic/versions/d211df879a5f_add_agent_id_to_steps.py index d857fca4..6d5e57ad 100644 --- a/alembic/versions/d211df879a5f_add_agent_id_to_steps.py +++ b/alembic/versions/d211df879a5f_add_agent_id_to_steps.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "d211df879a5f" @@ -20,12 +21,20 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("steps", sa.Column("agent_id", sa.String(), nullable=True)) # ### end Alembic commands ### def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_column("steps", "agent_id") # ### end Alembic commands ### diff --git a/alembic/versions/d6632deac81d_add_composite_index_to_messages_table.py b/alembic/versions/d6632deac81d_add_composite_index_to_messages_table.py index 68ceec88..2deb10f8 100644 --- a/alembic/versions/d6632deac81d_add_composite_index_to_messages_table.py +++ b/alembic/versions/d6632deac81d_add_composite_index_to_messages_table.py @@ -9,6 +9,7 @@ Create Date: 2024-12-18 13:38:56.511701 from typing import Sequence, Union from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "d6632deac81d" @@ -18,12 +19,20 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.create_index("ix_messages_agent_created_at", "messages", ["agent_id", "created_at"], unique=False) # ### end Alembic commands ### def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_index("ix_messages_agent_created_at", table_name="messages") # ### end Alembic commands ### diff --git a/alembic/versions/dd049fbec729_add_index_on_agent_id_for_agent_env_var.py b/alembic/versions/dd049fbec729_add_index_on_agent_id_for_agent_env_var.py index e995caee..fd4e567f 100644 --- a/alembic/versions/dd049fbec729_add_index_on_agent_id_for_agent_env_var.py +++ b/alembic/versions/dd049fbec729_add_index_on_agent_id_for_agent_env_var.py @@ -9,6 +9,7 @@ Create Date: 2025-05-23 17:41:48.235405 from typing import Sequence, Union from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "dd049fbec729" @@ -18,12 +19,20 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.create_index("idx_agent_environment_variables_agent_id", "agent_environment_variables", ["agent_id"], unique=False) # ### end Alembic commands ### def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_index("idx_agent_environment_variables_agent_id", table_name="agent_environment_variables") # ### end Alembic commands ### diff --git a/alembic/versions/dfafcf8210ca_add_model_endpoint_to_steps_table.py b/alembic/versions/dfafcf8210ca_add_model_endpoint_to_steps_table.py index df3b4278..a4502932 100644 --- a/alembic/versions/dfafcf8210ca_add_model_endpoint_to_steps_table.py +++ b/alembic/versions/dfafcf8210ca_add_model_endpoint_to_steps_table.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "dfafcf8210ca" @@ -20,12 +21,20 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("steps", sa.Column("model_endpoint", sa.String(), nullable=True)) # ### end Alembic commands ### def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_column("steps", "model_endpoint") # ### end Alembic commands ### diff --git a/alembic/versions/e1a625072dbf_tweak_created_at_field_for_messages.py b/alembic/versions/e1a625072dbf_tweak_created_at_field_for_messages.py index fb425db3..8a8b6566 100644 --- a/alembic/versions/e1a625072dbf_tweak_created_at_field_for_messages.py +++ b/alembic/versions/e1a625072dbf_tweak_created_at_field_for_messages.py @@ -11,6 +11,7 @@ from typing import Sequence, Union from sqlalchemy.dialects import postgresql from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "e1a625072dbf" @@ -20,12 +21,20 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.alter_column("messages", "created_at", existing_type=postgresql.TIMESTAMP(timezone=True), nullable=True) # ### end Alembic commands ### def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.alter_column("messages", "created_at", existing_type=postgresql.TIMESTAMP(timezone=True), nullable=False) # ### end Alembic commands ### diff --git a/alembic/versions/e20573fe9b86_add_tool_types.py b/alembic/versions/e20573fe9b86_add_tool_types.py index 2bd64f2f..deff4368 100644 --- a/alembic/versions/e20573fe9b86_add_tool_types.py +++ b/alembic/versions/e20573fe9b86_add_tool_types.py @@ -14,6 +14,7 @@ from sqlalchemy.dialects import postgresql from alembic import op from letta.constants import BASE_MEMORY_TOOLS, BASE_TOOLS from letta.orm.enums import ToolType +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "e20573fe9b86" @@ -23,6 +24,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # Step 1: Add the column as nullable with no default op.add_column("tools", sa.Column("tool_type", sa.String(), nullable=True)) @@ -64,6 +69,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # Revert the changes made during the upgrade op.alter_column("tools", "json_schema", existing_type=postgresql.JSON(astext_type=sa.Text()), nullable=False) op.drop_column("tools", "tool_type") diff --git a/alembic/versions/e78b4e82db30_add_cascading_deletes_for_sources_to_.py b/alembic/versions/e78b4e82db30_add_cascading_deletes_for_sources_to_.py index dd59f2a0..3afa28b6 100644 --- a/alembic/versions/e78b4e82db30_add_cascading_deletes_for_sources_to_.py +++ b/alembic/versions/e78b4e82db30_add_cascading_deletes_for_sources_to_.py @@ -9,6 +9,7 @@ Create Date: 2024-12-20 16:30:17.095888 from typing import Sequence, Union from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "e78b4e82db30" @@ -18,6 +19,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_constraint("sources_agents_agent_id_fkey", "sources_agents", type_="foreignkey") op.drop_constraint("sources_agents_source_id_fkey", "sources_agents", type_="foreignkey") @@ -27,6 +32,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_constraint(None, "sources_agents", type_="foreignkey") op.drop_constraint(None, "sources_agents", type_="foreignkey") diff --git a/alembic/versions/e991d2e3b428_add_monotonically_increasing_ids_to_.py b/alembic/versions/e991d2e3b428_add_monotonically_increasing_ids_to_.py index 3f028c71..2b2370ef 100644 --- a/alembic/versions/e991d2e3b428_add_monotonically_increasing_ids_to_.py +++ b/alembic/versions/e991d2e3b428_add_monotonically_increasing_ids_to_.py @@ -12,6 +12,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "e991d2e3b428" @@ -38,6 +39,10 @@ def print_flush(message): def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + """Adds sequence_id, backfills data, adds constraints and index.""" print_flush(f"\n--- Starting upgrade for revision {revision} ---") @@ -118,6 +123,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + """Reverses the changes made in the upgrade function.""" print_flush(f"\n--- Starting downgrade from revision {revision} ---") diff --git a/alembic/versions/f2f78d62005c_add_letta_batch_job_id_to_llm_batch_job.py b/alembic/versions/f2f78d62005c_add_letta_batch_job_id_to_llm_batch_job.py index f0eb8454..5309d0fa 100644 --- a/alembic/versions/f2f78d62005c_add_letta_batch_job_id_to_llm_batch_job.py +++ b/alembic/versions/f2f78d62005c_add_letta_batch_job_id_to_llm_batch_job.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "f2f78d62005c" @@ -20,6 +21,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("llm_batch_job", sa.Column("letta_batch_job_id", sa.String(), nullable=False)) op.create_foreign_key(None, "llm_batch_job", "jobs", ["letta_batch_job_id"], ["id"], ondelete="CASCADE") @@ -27,6 +32,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_constraint(None, "llm_batch_job", type_="foreignkey") op.drop_column("llm_batch_job", "letta_batch_job_id") diff --git a/alembic/versions/f595e0e8013e_adding_request_config_to_job_table.py b/alembic/versions/f595e0e8013e_adding_request_config_to_job_table.py index d53a30a2..ce798112 100644 --- a/alembic/versions/f595e0e8013e_adding_request_config_to_job_table.py +++ b/alembic/versions/f595e0e8013e_adding_request_config_to_job_table.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "f595e0e8013e" @@ -20,12 +21,20 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("jobs", sa.Column("request_config", sa.JSON, nullable=True)) # ### end Alembic commands ### def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_column("jobs", "request_config") # ### end Alembic commands ### diff --git a/alembic/versions/f7507eab4bb9_migrate_blocks_to_orm_model.py b/alembic/versions/f7507eab4bb9_migrate_blocks_to_orm_model.py index 9e7fa270..7e1b0305 100644 --- a/alembic/versions/f7507eab4bb9_migrate_blocks_to_orm_model.py +++ b/alembic/versions/f7507eab4bb9_migrate_blocks_to_orm_model.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "f7507eab4bb9" @@ -20,6 +21,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("block", sa.Column("is_template", sa.Boolean(), nullable=True)) # Populate `is_template` column @@ -58,6 +63,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("block", sa.Column("user_id", sa.VARCHAR(), autoincrement=False, nullable=True)) op.add_column("block", sa.Column("template", sa.BOOLEAN(), autoincrement=False, nullable=True)) diff --git a/alembic/versions/f81ceea2c08d_create_sandbox_config_and_sandbox_env_.py b/alembic/versions/f81ceea2c08d_create_sandbox_config_and_sandbox_env_.py index 55332bfc..40d64670 100644 --- a/alembic/versions/f81ceea2c08d_create_sandbox_config_and_sandbox_env_.py +++ b/alembic/versions/f81ceea2c08d_create_sandbox_config_and_sandbox_env_.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "f81ceea2c08d" @@ -20,6 +21,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.create_table( "sandbox_configs", @@ -67,6 +72,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_table("sandbox_environment_variables") op.drop_table("sandbox_configs") diff --git a/alembic/versions/f895232c144a_backfill_composio_tools.py b/alembic/versions/f895232c144a_backfill_composio_tools.py index a1c08c71..defc2367 100644 --- a/alembic/versions/f895232c144a_backfill_composio_tools.py +++ b/alembic/versions/f895232c144a_backfill_composio_tools.py @@ -10,6 +10,7 @@ from typing import Sequence, Union from alembic import op from letta.orm.enums import ToolType +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "f895232c144a" @@ -19,6 +20,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### # Define the value for EXTERNAL_COMPOSIO external_composio_value = ToolType.EXTERNAL_COMPOSIO.value @@ -36,6 +41,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### custom_value = ToolType.CUSTOM.value diff --git a/alembic/versions/f922ca16e42c_add_project_and_template_id_to_agent.py b/alembic/versions/f922ca16e42c_add_project_and_template_id_to_agent.py index e2f6d9ba..169a6d77 100644 --- a/alembic/versions/f922ca16e42c_add_project_and_template_id_to_agent.py +++ b/alembic/versions/f922ca16e42c_add_project_and_template_id_to_agent.py @@ -11,6 +11,7 @@ from typing import Sequence, Union import sqlalchemy as sa from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "f922ca16e42c" @@ -20,6 +21,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.add_column("agents", sa.Column("project_id", sa.String(), nullable=True)) op.add_column("agents", sa.Column("template_id", sa.String(), nullable=True)) @@ -28,6 +33,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_column("agents", "base_template_id") op.drop_column("agents", "template_id") diff --git a/alembic/versions/fdcdafdb11cf_identity_properties_jsonb_to_json.py b/alembic/versions/fdcdafdb11cf_identity_properties_jsonb_to_json.py index c249f880..b553ecdc 100644 --- a/alembic/versions/fdcdafdb11cf_identity_properties_jsonb_to_json.py +++ b/alembic/versions/fdcdafdb11cf_identity_properties_jsonb_to_json.py @@ -12,6 +12,7 @@ import sqlalchemy as sa from sqlalchemy.dialects import postgresql from alembic import op +from letta.settings import settings # revision identifiers, used by Alembic. revision: str = "fdcdafdb11cf" @@ -21,6 +22,10 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.alter_column( "identities", @@ -41,6 +46,10 @@ def upgrade() -> None: def downgrade() -> None: + # Skip this migration for SQLite + if not settings.letta_pg_uri_no_default: + return + # ### commands auto generated by Alembic - please adjust! ### op.drop_constraint("unique_identifier_key_project_id_organization_id", "identities", type_="unique") op.create_unique_constraint( diff --git a/letta/orm/identity.py b/letta/orm/identity.py index 5f6e5606..ac83e952 100644 --- a/letta/orm/identity.py +++ b/letta/orm/identity.py @@ -23,6 +23,8 @@ class Identity(SqlalchemyBase, OrganizationMixin): "organization_id", name="unique_identifier_key_project_id_organization_id", postgresql_nulls_not_distinct=True, + # For SQLite compatibility, we'll need to handle the NULL case differently + # in the service layer since SQLite doesn't support postgresql_nulls_not_distinct ), ) diff --git a/letta/orm/message.py b/letta/orm/message.py index 89d6cc15..ad4ed743 100644 --- a/letta/orm/message.py +++ b/letta/orm/message.py @@ -86,16 +86,140 @@ class Message(SqlalchemyBase, OrganizationMixin, AgentMixin): # listener +@event.listens_for(Session, "before_flush") +def set_sequence_id_for_sqlite_bulk(session, flush_context, instances): + # Handle bulk inserts for SQLite + if not settings.letta_pg_uri_no_default: + # Find all new Message objects that need sequence IDs + new_messages = [obj for obj in session.new if isinstance(obj, Message) and obj.sequence_id is None] + + if new_messages: + # Create a sequence table if it doesn't exist for atomic increments + session.execute( + text( + """ + CREATE TABLE IF NOT EXISTS message_sequence ( + id INTEGER PRIMARY KEY, + next_val INTEGER NOT NULL DEFAULT 1 + ) + """ + ) + ) + + # Initialize the sequence table if empty + session.execute( + text( + """ + INSERT OR IGNORE INTO message_sequence (id, next_val) + SELECT 1, COALESCE(MAX(sequence_id), 0) + 1 + FROM messages + """ + ) + ) + + # Get the number of records being inserted + records_count = len(new_messages) + + # Atomically reserve a range of sequence values for this batch + result = session.execute( + text( + """ + UPDATE message_sequence + SET next_val = next_val + :count + WHERE id = 1 + RETURNING next_val - :count + """ + ), + {"count": records_count}, + ) + + start_sequence_id = result.scalar() + if start_sequence_id is None: + # Fallback if RETURNING doesn't work (older SQLite versions) + session.execute( + text( + """ + UPDATE message_sequence + SET next_val = next_val + :count + WHERE id = 1 + """ + ), + {"count": records_count}, + ) + start_sequence_id = session.execute( + text( + """ + SELECT next_val - :count FROM message_sequence WHERE id = 1 + """ + ), + {"count": records_count}, + ).scalar() + + # Assign sequential IDs to each record + for i, obj in enumerate(new_messages): + obj.sequence_id = start_sequence_id + i + + @event.listens_for(Message, "before_insert") def set_sequence_id_for_sqlite(mapper, connection, target): # TODO: Kind of hacky, used to detect if we are using sqlite or not if not settings.letta_pg_uri_no_default: - session = Session.object_session(target) + # For SQLite, we need to generate sequence_id manually + # Use a database-level atomic operation to avoid race conditions - if not hasattr(session, "_sequence_id_counter"): - # Initialize counter for this flush - max_seq = connection.scalar(text("SELECT MAX(sequence_id) FROM messages")) - session._sequence_id_counter = max_seq or 0 + # Create a sequence table if it doesn't exist for atomic increments + connection.execute( + text( + """ + CREATE TABLE IF NOT EXISTS message_sequence ( + id INTEGER PRIMARY KEY, + next_val INTEGER NOT NULL DEFAULT 1 + ) + """ + ) + ) - session._sequence_id_counter += 1 - target.sequence_id = session._sequence_id_counter + # Initialize the sequence table if empty + connection.execute( + text( + """ + INSERT OR IGNORE INTO message_sequence (id, next_val) + SELECT 1, COALESCE(MAX(sequence_id), 0) + 1 + FROM messages + """ + ) + ) + + # Atomically get the next sequence value + result = connection.execute( + text( + """ + UPDATE message_sequence + SET next_val = next_val + 1 + WHERE id = 1 + RETURNING next_val - 1 + """ + ) + ) + + sequence_id = result.scalar() + if sequence_id is None: + # Fallback if RETURNING doesn't work (older SQLite versions) + connection.execute( + text( + """ + UPDATE message_sequence + SET next_val = next_val + 1 + WHERE id = 1 + """ + ) + ) + sequence_id = connection.execute( + text( + """ + SELECT next_val - 1 FROM message_sequence WHERE id = 1 + """ + ) + ).scalar() + + target.sequence_id = sequence_id diff --git a/letta/orm/sqlalchemy_base.py b/letta/orm/sqlalchemy_base.py index 6555365f..d1a79eb6 100644 --- a/letta/orm/sqlalchemy_base.py +++ b/letta/orm/sqlalchemy_base.py @@ -353,10 +353,12 @@ class SqlalchemyBase(CommonSqlalchemyMetaMixins, Base): if before_obj and after_obj: # Window-based query - get records between before and after - conditions = [ - or_(cls.created_at < before_obj.created_at, and_(cls.created_at == before_obj.created_at, cls.id < before_obj.id)), - or_(cls.created_at > after_obj.created_at, and_(cls.created_at == after_obj.created_at, cls.id > after_obj.id)), - ] + conditions.append( + or_(cls.created_at < before_obj.created_at, and_(cls.created_at == before_obj.created_at, cls.id < before_obj.id)) + ) + conditions.append( + or_(cls.created_at > after_obj.created_at, and_(cls.created_at == after_obj.created_at, cls.id > after_obj.id)) + ) else: # Pure pagination query if before_obj: diff --git a/letta/server/db.py b/letta/server/db.py index a6ffcd4f..a5ff37dd 100644 --- a/letta/server/db.py +++ b/letta/server/db.py @@ -7,7 +7,7 @@ from typing import Any, AsyncGenerator, Generator from rich.console import Console from rich.panel import Panel from rich.text import Text -from sqlalchemy import Engine, NullPool, QueuePool, create_engine +from sqlalchemy import Engine, NullPool, QueuePool, create_engine, event from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession, async_sessionmaker, create_async_engine from sqlalchemy.orm import sessionmaker @@ -36,6 +36,15 @@ def print_sqlite_schema_error(): console.print(Panel(error_text, border_style="red")) +@event.listens_for(Engine, "connect") +def enable_sqlite_foreign_keys(dbapi_connection, connection_record): + """Enable foreign key constraints for SQLite connections.""" + if "sqlite" in str(dbapi_connection): + cursor = dbapi_connection.cursor() + cursor.execute("PRAGMA foreign_keys=ON") + cursor.close() + + @contextmanager def db_error_handler(): """Context manager for handling database errors""" @@ -43,6 +52,14 @@ def db_error_handler(): yield except Exception as e: # Handle other SQLAlchemy errors + error_str = str(e) + + # Don't exit for expected constraint violations that should be handled by the application + if "UNIQUE constraint failed" in error_str or "FOREIGN KEY constraint failed" in error_str: + # These are application-level errors that should be handled by the ORM + raise + + # For other database errors, print error and exit print(e) print_sqlite_schema_error() # raise ValueError(f"SQLite DB error: {str(e)}") @@ -130,6 +147,13 @@ class DatabaseRegistry: self.logger.info("Creating sqlite engine " + engine_path) async_engine = create_async_engine(engine_path, **self._build_sqlalchemy_engine_args(is_async=True)) + # Enable foreign keys for SQLite async connections + @event.listens_for(async_engine.sync_engine, "connect") + def enable_sqlite_foreign_keys_async(dbapi_connection, connection_record): + cursor = dbapi_connection.cursor() + cursor.execute("PRAGMA foreign_keys=ON") + cursor.close() + # Create async session factory self._async_engines["default"] = async_engine diff --git a/letta/services/agent_manager.py b/letta/services/agent_manager.py index 12d9de46..87bc7d97 100644 --- a/letta/services/agent_manager.py +++ b/letta/services/agent_manager.py @@ -91,6 +91,7 @@ from letta.services.message_manager import MessageManager from letta.services.passage_manager import PassageManager from letta.services.source_manager import SourceManager from letta.services.tool_manager import ToolManager +from letta.settings import settings from letta.utils import enforce_types, united_diff logger = get_logger(__name__) @@ -1021,7 +1022,6 @@ class AgentManager: if limit: query = query.limit(limit) - result = await session.execute(query) agents = result.scalars().all() return await asyncio.gather(*[agent.to_pydantic_async(include_relationships=include_relationships) for agent in agents]) @@ -2732,7 +2732,12 @@ class AgentManager: ) if query_text: - query = query.filter(AgentsTags.tag.ilike(f"%{query_text}%")) + if settings.letta_pg_uri_no_default: + # PostgreSQL: Use ILIKE for case-insensitive search + query = query.filter(AgentsTags.tag.ilike(f"%{query_text}%")) + else: + # SQLite: Use LIKE with LOWER for case-insensitive search + query = query.filter(func.lower(AgentsTags.tag).like(func.lower(f"%{query_text}%"))) if after: query = query.filter(AgentsTags.tag > after) @@ -2768,7 +2773,12 @@ class AgentManager: ) if query_text: - query = query.where(AgentsTags.tag.ilike(f"%{query_text}%")) + if settings.letta_pg_uri_no_default: + # PostgreSQL: Use ILIKE for case-insensitive search + query = query.where(AgentsTags.tag.ilike(f"%{query_text}%")) + else: + # SQLite: Use LIKE with LOWER for case-insensitive search + query = query.where(func.lower(AgentsTags.tag).like(func.lower(f"%{query_text}%"))) if after: query = query.where(AgentsTags.tag > after) diff --git a/letta/services/helpers/agent_manager_helper.py b/letta/services/helpers/agent_manager_helper.py index 09178419..62b85657 100644 --- a/letta/services/helpers/agent_manager_helper.py +++ b/letta/services/helpers/agent_manager_helper.py @@ -551,6 +551,9 @@ async def _apply_pagination_async( result = (await session.execute(select(sort_column, AgentModel.id).where(AgentModel.id == after))).first() if result: after_sort_value, after_id = result + # SQLite does not support as granular timestamping, so we need to round the timestamp + if not settings.letta_pg_uri_no_default and isinstance(after_sort_value, datetime): + after_sort_value = after_sort_value.strftime("%Y-%m-%d %H:%M:%S") query = query.where( _cursor_filter(sort_column, AgentModel.id, after_sort_value, after_id, forward=ascending, nulls_last=sort_nulls_last) ) @@ -559,6 +562,9 @@ async def _apply_pagination_async( result = (await session.execute(select(sort_column, AgentModel.id).where(AgentModel.id == before))).first() if result: before_sort_value, before_id = result + # SQLite does not support as granular timestamping, so we need to round the timestamp + if not settings.letta_pg_uri_no_default and isinstance(before_sort_value, datetime): + before_sort_value = before_sort_value.strftime("%Y-%m-%d %H:%M:%S") query = query.where( _cursor_filter(sort_column, AgentModel.id, before_sort_value, before_id, forward=not ascending, nulls_last=sort_nulls_last) ) @@ -649,7 +655,12 @@ def _apply_filters( query = query.where(AgentModel.name == name) # Apply a case-insensitive partial match for the agent's name. if query_text: - query = query.where(AgentModel.name.ilike(f"%{query_text}%")) + if settings.letta_pg_uri_no_default: + # PostgreSQL: Use ILIKE for case-insensitive search + query = query.where(AgentModel.name.ilike(f"%{query_text}%")) + else: + # SQLite: Use LIKE with LOWER for case-insensitive search + query = query.where(func.lower(AgentModel.name).like(func.lower(f"%{query_text}%"))) # Filter agents by project ID. if project_id: query = query.where(AgentModel.project_id == project_id) diff --git a/letta/services/identity_manager.py b/letta/services/identity_manager.py index abf637ba..8bd82297 100644 --- a/letta/services/identity_manager.py +++ b/letta/services/identity_manager.py @@ -6,12 +6,14 @@ from sqlalchemy.exc import NoResultFound from letta.orm.agent import Agent as AgentModel from letta.orm.block import Block as BlockModel +from letta.orm.errors import UniqueConstraintViolationError from letta.orm.identity import Identity as IdentityModel from letta.otel.tracing import trace_method from letta.schemas.identity import Identity as PydanticIdentity from letta.schemas.identity import IdentityCreate, IdentityProperty, IdentityType, IdentityUpdate, IdentityUpsert from letta.schemas.user import User as PydanticUser from letta.server.db import db_registry +from letta.settings import settings from letta.utils import enforce_types @@ -64,6 +66,26 @@ class IdentityManager: async def _create_identity_async(self, db_session, identity: IdentityCreate, actor: PydanticUser) -> PydanticIdentity: new_identity = IdentityModel(**identity.model_dump(exclude={"agent_ids", "block_ids"}, exclude_unset=True)) new_identity.organization_id = actor.organization_id + + # For SQLite compatibility: check for unique constraint violation manually + # since SQLite doesn't support postgresql_nulls_not_distinct=True + if not settings.letta_pg_uri_no_default: # Using SQLite + # Check if an identity with the same identifier_key, project_id, and organization_id exists + query = select(IdentityModel).where( + IdentityModel.identifier_key == new_identity.identifier_key, + IdentityModel.project_id == new_identity.project_id, + IdentityModel.organization_id == new_identity.organization_id, + ) + result = await db_session.execute(query) + existing_identity = result.scalar_one_or_none() + if existing_identity is not None: + raise UniqueConstraintViolationError( + f"A unique constraint was violated for Identity. " + f"An identity with identifier_key='{new_identity.identifier_key}', " + f"project_id='{new_identity.project_id}', and " + f"organization_id='{new_identity.organization_id}' already exists." + ) + await self._process_relationship_async( db_session=db_session, identity=new_identity, diff --git a/letta/services/job_manager.py b/letta/services/job_manager.py index afd26b80..fddad2cf 100644 --- a/letta/services/job_manager.py +++ b/letta/services/job_manager.py @@ -1,3 +1,4 @@ +from datetime import datetime from functools import partial, reduce from operator import add from typing import List, Literal, Optional, Union @@ -27,6 +28,7 @@ from letta.schemas.step import Step as PydanticStep from letta.schemas.usage import LettaUsageStatistics from letta.schemas.user import User as PydanticUser from letta.server.db import db_registry +from letta.settings import settings from letta.utils import enforce_types logger = get_logger(__name__) @@ -292,24 +294,90 @@ class JobManager: source_id: Optional[str] = None, ) -> List[PydanticJob]: """List all jobs with optional pagination and status filter.""" + from sqlalchemy import and_, or_, select + async with db_registry.async_session() as session: - filter_kwargs = {"user_id": actor.id, "job_type": job_type} + # build base query + query = select(JobModel).where(JobModel.user_id == actor.id).where(JobModel.job_type == job_type) - # Add status filter if provided + # add status filter if provided if statuses: - filter_kwargs["status"] = statuses + query = query.where(JobModel.status.in_(statuses)) + # add source_id filter if provided if source_id: - filter_kwargs["metadata_.source_id"] = source_id + column = getattr(JobModel, "metadata_") + column = column.op("->>")("source_id") + query = query.where(column == source_id) + + # handle cursor-based pagination + if before or after: + # get cursor objects + before_obj = None + after_obj = None + + if before: + before_obj = await session.get(JobModel, before) + if not before_obj: + raise ValueError(f"Job with id {before} not found") + + if after: + after_obj = await session.get(JobModel, after) + if not after_obj: + raise ValueError(f"Job with id {after} not found") + + # validate cursors + if before_obj and after_obj: + if before_obj.created_at < after_obj.created_at: + raise ValueError("'before' reference must be later than 'after' reference") + elif before_obj.created_at == after_obj.created_at and before_obj.id < after_obj.id: + raise ValueError("'before' reference must be later than 'after' reference") + + # build cursor conditions + conditions = [] + if before_obj: + # records before this cursor (older) + + before_timestamp = before_obj.created_at + # SQLite does not support as granular timestamping, so we need to round the timestamp + if not settings.letta_pg_uri_no_default and isinstance(before_timestamp, datetime): + before_timestamp = before_timestamp.strftime("%Y-%m-%d %H:%M:%S") + + conditions.append( + or_( + JobModel.created_at < before_timestamp, + and_(JobModel.created_at == before_timestamp, JobModel.id < before_obj.id), + ) + ) + + if after_obj: + # records after this cursor (newer) + after_timestamp = after_obj.created_at + # SQLite does not support as granular timestamping, so we need to round the timestamp + if not settings.letta_pg_uri_no_default and isinstance(after_timestamp, datetime): + after_timestamp = after_timestamp.strftime("%Y-%m-%d %H:%M:%S") + + conditions.append( + or_(JobModel.created_at > after_timestamp, and_(JobModel.created_at == after_timestamp, JobModel.id > after_obj.id)) + ) + + if conditions: + query = query.where(and_(*conditions)) + + # apply ordering + if ascending: + query = query.order_by(JobModel.created_at.asc(), JobModel.id.asc()) + else: + query = query.order_by(JobModel.created_at.desc(), JobModel.id.desc()) + + # apply limit + if limit: + query = query.limit(limit) + + # execute query + result = await session.execute(query) + jobs = result.scalars().all() - jobs = await JobModel.list_async( - db_session=session, - before=before, - after=after, - limit=limit, - ascending=ascending, - **filter_kwargs, - ) return [job.to_pydantic() for job in jobs] @enforce_types diff --git a/letta/services/message_manager.py b/letta/services/message_manager.py index 8ce15610..af4ce2c6 100644 --- a/letta/services/message_manager.py +++ b/letta/services/message_manager.py @@ -18,6 +18,7 @@ from letta.schemas.user import User as PydanticUser from letta.server.db import db_registry from letta.services.file_manager import FileManager from letta.services.helpers.agent_manager_helper import validate_agent_exists_async +from letta.settings import settings from letta.utils import enforce_types logger = get_logger(__name__) @@ -454,17 +455,23 @@ class MessageManager: if group_id: query = query.filter(MessageModel.group_id == group_id) - # If query_text is provided, filter messages using subquery + json_array_elements. + # If query_text is provided, filter messages using database-specific JSON search. if query_text: - content_element = func.json_array_elements(MessageModel.content).alias("content_element") - query = query.filter( - exists( - select(1) - .select_from(content_element) - .where(text("content_element->>'type' = 'text' AND content_element->>'text' ILIKE :query_text")) - .params(query_text=f"%{query_text}%") + if settings.letta_pg_uri_no_default: + # PostgreSQL: Use json_array_elements and ILIKE + content_element = func.json_array_elements(MessageModel.content).alias("content_element") + query = query.filter( + exists( + select(1) + .select_from(content_element) + .where(text("content_element->>'type' = 'text' AND content_element->>'text' ILIKE :query_text")) + .params(query_text=f"%{query_text}%") + ) ) - ) + else: + # SQLite: Use JSON_EXTRACT with individual array indices for case-insensitive search + # Since SQLite doesn't support $[*] syntax, we'll use a different approach + query = query.filter(text("JSON_EXTRACT(content, '$') LIKE :query_text")).params(query_text=f"%{query_text}%") # If role(s) are provided, filter messages by those roles. if roles: @@ -551,17 +558,23 @@ class MessageManager: if group_id: query = query.where(MessageModel.group_id == group_id) - # If query_text is provided, filter messages using subquery + json_array_elements. + # If query_text is provided, filter messages using database-specific JSON search. if query_text: - content_element = func.json_array_elements(MessageModel.content).alias("content_element") - query = query.where( - exists( - select(1) - .select_from(content_element) - .where(text("content_element->>'type' = 'text' AND content_element->>'text' ILIKE :query_text")) - .params(query_text=f"%{query_text}%") + if settings.letta_pg_uri_no_default: + # PostgreSQL: Use json_array_elements and ILIKE + content_element = func.json_array_elements(MessageModel.content).alias("content_element") + query = query.where( + exists( + select(1) + .select_from(content_element) + .where(text("content_element->>'type' = 'text' AND content_element->>'text' ILIKE :query_text")) + .params(query_text=f"%{query_text}%") + ) ) - ) + else: + # SQLite: Use JSON_EXTRACT with individual array indices for case-insensitive search + # Since SQLite doesn't support $[*] syntax, we'll use a different approach + query = query.where(text("JSON_EXTRACT(content, '$') LIKE :query_text")).params(query_text=f"%{query_text}%") # If role(s) are provided, filter messages by those roles. if roles: diff --git a/poetry.lock b/poetry.lock index f455ed90..e0be4803 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.1.3 and should not be changed by hand. [[package]] name = "aioboto3" @@ -6,6 +6,8 @@ version = "14.3.0" description = "Async boto3 wrapper" optional = true python-versions = "<4.0,>=3.8" +groups = ["main"] +markers = "extra == \"bedrock\"" files = [ {file = "aioboto3-14.3.0-py3-none-any.whl", hash = "sha256:aec5de94e9edc1ffbdd58eead38a37f00ddac59a519db749a910c20b7b81bca7"}, {file = "aioboto3-14.3.0.tar.gz", hash = "sha256:1d18f88bb56835c607b62bb6cb907754d717bedde3ddfff6935727cb48a80135"}, @@ -25,6 +27,8 @@ version = "2.22.0" description = "Async client for aws services using botocore and aiohttp" optional = true python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"bedrock\"" files = [ {file = "aiobotocore-2.22.0-py3-none-any.whl", hash = "sha256:b4e6306f79df9d81daff1f9d63189a2dbee4b77ce3ab937304834e35eaaeeccf"}, {file = "aiobotocore-2.22.0.tar.gz", hash = "sha256:11091477266b75c2b5d28421c1f2bc9a87d175d0b8619cb830805e7a113a170b"}, @@ -50,6 +54,8 @@ version = "24.1.0" description = "File support for asyncio." optional = true python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"bedrock\"" files = [ {file = "aiofiles-24.1.0-py3-none-any.whl", hash = "sha256:b4ec55f4195e3eb5d7abd1bf7e061763e864dd4954231fb8539a0ef8bb8260e5"}, {file = "aiofiles-24.1.0.tar.gz", hash = "sha256:22a075c9e5a3810f0c2e48f3008c94d68c65d763b9b03857924c99e57355166c"}, @@ -61,6 +67,7 @@ version = "2.6.1" description = "Happy Eyeballs for asyncio" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "aiohappyeyeballs-2.6.1-py3-none-any.whl", hash = "sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8"}, {file = "aiohappyeyeballs-2.6.1.tar.gz", hash = "sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558"}, @@ -72,6 +79,7 @@ version = "3.11.16" description = "Async http client/server framework (asyncio)" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "aiohttp-3.11.16-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:fb46bb0f24813e6cede6cc07b1961d4b04f331f7112a23b5e21f567da4ee50aa"}, {file = "aiohttp-3.11.16-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:54eb3aead72a5c19fad07219acd882c1643a1027fbcdefac9b502c267242f955"}, @@ -167,7 +175,7 @@ propcache = ">=0.2.0" yarl = ">=1.17.0,<2.0" [package.extras] -speedups = ["Brotli", "aiodns (>=3.2.0)", "brotlicffi"] +speedups = ["Brotli ; platform_python_implementation == \"CPython\"", "aiodns (>=3.2.0) ; sys_platform == \"linux\" or sys_platform == \"darwin\"", "brotlicffi ; platform_python_implementation != \"CPython\""] [[package]] name = "aiohttp-retry" @@ -175,6 +183,8 @@ version = "2.9.1" description = "Simple retry client for aiohttp" optional = true python-versions = ">=3.7" +groups = ["main"] +markers = "extra == \"pinecone\" or extra == \"all\"" files = [ {file = "aiohttp_retry-2.9.1-py3-none-any.whl", hash = "sha256:66d2759d1921838256a05a3f80ad7e724936f083e35be5abb5e16eed6be6dc54"}, {file = "aiohttp_retry-2.9.1.tar.gz", hash = "sha256:8eb75e904ed4ee5c2ec242fefe85bf04240f685391c4879d8f541d6028ff01f1"}, @@ -189,6 +199,8 @@ version = "0.12.0" description = "itertools and builtins for AsyncIO and mixed iterables" optional = true python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"bedrock\"" files = [ {file = "aioitertools-0.12.0-py3-none-any.whl", hash = "sha256:fc1f5fac3d737354de8831cbba3eb04f79dd649d8f3afb4c5b114925e662a796"}, {file = "aioitertools-0.12.0.tar.gz", hash = "sha256:c2a9055b4fbb7705f561b9d86053e8af5d10cc845d22c32008c43490b2d8dd6b"}, @@ -204,13 +216,14 @@ version = "0.9.1" description = "AsyncIO version of the standard multiprocessing module" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "aiomultiprocess-0.9.1-py3-none-any.whl", hash = "sha256:3a7b3bb3c38dbfb4d9d1194ece5934b6d32cf0280e8edbe64a7d215bba1322c6"}, {file = "aiomultiprocess-0.9.1.tar.gz", hash = "sha256:f0231dbe0291e15325d7896ebeae0002d95a4f2675426ca05eb35f24c60e495b"}, ] [package.extras] -dev = ["attribution (==1.7.1)", "black (==24.4.0)", "coverage (==7.4.4)", "flake8 (==7.0.0)", "flake8-bugbear (==24.4.21)", "flit (==3.9.0)", "mypy (==1.9.0)", "usort (==1.0.8.post1)", "uvloop (==0.19.0)"] +dev = ["attribution (==1.7.1)", "black (==24.4.0)", "coverage (==7.4.4)", "flake8 (==7.0.0)", "flake8-bugbear (==24.4.21)", "flit (==3.9.0)", "mypy (==1.9.0)", "usort (==1.0.8.post1)", "uvloop (==0.19.0) ; sys_platform != \"win32\""] docs = ["sphinx (==7.3.7)", "sphinx-mdinclude (==0.6.0)"] [[package]] @@ -219,6 +232,7 @@ version = "1.3.2" description = "aiosignal: a list of registered asynchronous callbacks" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "aiosignal-1.3.2-py2.py3-none-any.whl", hash = "sha256:45cde58e409a301715980c2b01d0c28bdde3770d8290b5eb2173759d9acb31a5"}, {file = "aiosignal-1.3.2.tar.gz", hash = "sha256:a8c255c66fafb1e499c9351d0bf32ff2d8a0321595ebac3b93713656d2436f54"}, @@ -227,12 +241,32 @@ files = [ [package.dependencies] frozenlist = ">=1.1.0" +[[package]] +name = "aiosqlite" +version = "0.21.0" +description = "asyncio bridge to the standard sqlite3 module" +optional = false +python-versions = ">=3.9" +groups = ["sqlite"] +files = [ + {file = "aiosqlite-0.21.0-py3-none-any.whl", hash = "sha256:2549cf4057f95f53dcba16f2b64e8e2791d7e1adedb13197dd8ed77bb226d7d0"}, + {file = "aiosqlite-0.21.0.tar.gz", hash = "sha256:131bb8056daa3bc875608c631c678cda73922a2d4ba8aec373b19f18c17e7aa3"}, +] + +[package.dependencies] +typing_extensions = ">=4.0" + +[package.extras] +dev = ["attribution (==1.7.1)", "black (==24.3.0)", "build (>=1.2)", "coverage[toml] (==7.6.10)", "flake8 (==7.0.0)", "flake8-bugbear (==24.12.12)", "flit (==3.10.1)", "mypy (==1.14.1)", "ufmt (==2.5.1)", "usort (==1.0.8.post1)"] +docs = ["sphinx (==8.1.3)", "sphinx-mdinclude (==0.6.1)"] + [[package]] name = "alembic" version = "1.15.2" description = "A database migration tool for SQLAlchemy." optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "alembic-1.15.2-py3-none-any.whl", hash = "sha256:2e76bd916d547f6900ec4bb5a90aeac1485d2c92536923d0b138c02b126edc53"}, {file = "alembic-1.15.2.tar.gz", hash = "sha256:1c72391bbdeffccfe317eefba686cb9a3c078005478885413b95c3b26c57a8a7"}, @@ -252,6 +286,7 @@ version = "0.7.0" description = "Reusable constraint types to use with typing.Annotated" optional = false python-versions = ">=3.8" +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"}, @@ -263,6 +298,7 @@ version = "0.49.0" description = "The official Python library for the anthropic API" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "anthropic-0.49.0-py3-none-any.whl", hash = "sha256:bbc17ad4e7094988d2fa86b87753ded8dce12498f4b85fe5810f208f454a8375"}, {file = "anthropic-0.49.0.tar.gz", hash = "sha256:c09e885b0f674b9119b4f296d8508907f6cff0009bc20d5cf6b35936c40b4398"}, @@ -287,6 +323,7 @@ version = "4.9.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "anyio-4.9.0-py3-none-any.whl", hash = "sha256:9f76d541cad6e36af7beb62e978876f3b41e3e04f2c1fbf0884604c0a9c4d93c"}, {file = "anyio-4.9.0.tar.gz", hash = "sha256:673c0c244e15788651a4ff38710fea9675823028a6f08a5eda409e0c9840a028"}, @@ -300,7 +337,7 @@ typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] doc = ["Sphinx (>=8.2,<9.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] -test = ["anyio[trio]", "blockbuster (>=1.5.23)", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] +test = ["anyio[trio]", "blockbuster (>=1.5.23)", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "trustme", "truststore (>=0.9.1) ; python_version >= \"3.10\"", "uvloop (>=0.21) ; platform_python_implementation == \"CPython\" and platform_system != \"Windows\" and python_version < \"3.14\""] trio = ["trio (>=0.26.1)"] [[package]] @@ -309,6 +346,8 @@ version = "0.1.4" description = "Disable App Nap on macOS >= 10.9" optional = false python-versions = ">=3.6" +groups = ["dev"] +markers = "platform_system == \"Darwin\"" files = [ {file = "appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c"}, {file = "appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee"}, @@ -320,6 +359,7 @@ version = "3.11.0" description = "In-process task scheduler with Cron-like capabilities" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "APScheduler-3.11.0-py3-none-any.whl", hash = "sha256:fc134ca32e50f5eadcc4938e3a4545ab19131435e851abb40b34d63d5141c6da"}, {file = "apscheduler-3.11.0.tar.gz", hash = "sha256:4c622d250b0955a65d5d0eb91c33e6d43fd879834bf541e0a18661ae60460133"}, @@ -336,7 +376,7 @@ mongodb = ["pymongo (>=3.0)"] redis = ["redis (>=3.0)"] rethinkdb = ["rethinkdb (>=2.4.0)"] sqlalchemy = ["sqlalchemy (>=1.4)"] -test = ["APScheduler[etcd,mongodb,redis,rethinkdb,sqlalchemy,tornado,zookeeper]", "PySide6", "anyio (>=4.5.2)", "gevent", "pytest", "pytz", "twisted"] +test = ["APScheduler[etcd,mongodb,redis,rethinkdb,sqlalchemy,tornado,zookeeper]", "PySide6 ; platform_python_implementation == \"CPython\" and python_version < \"3.14\"", "anyio (>=4.5.2)", "gevent ; python_version < \"3.14\"", "pytest", "pytz", "twisted ; python_version < \"3.14\""] tornado = ["tornado (>=4.3)"] twisted = ["twisted"] zookeeper = ["kazoo"] @@ -347,6 +387,7 @@ version = "3.6.2" description = "Bash tab completion for argparse" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "argcomplete-3.6.2-py3-none-any.whl", hash = "sha256:65b3133a29ad53fb42c48cf5114752c7ab66c1c38544fdf6460f450c09b42591"}, {file = "argcomplete-3.6.2.tar.gz", hash = "sha256:d0519b1bc867f5f4f4713c41ad0aba73a4a5f007449716b16f385f2166dc6adf"}, @@ -361,6 +402,8 @@ version = "1.5.1" description = "Fast ASN.1 parser and serializer with definitions for private keys, public keys, certificates, CRL, OCSP, CMS, PKCS#3, PKCS#7, PKCS#8, PKCS#12, PKCS#5, X.509 and TSP" optional = true python-versions = "*" +groups = ["main"] +markers = "extra == \"postgres\" or extra == \"desktop\" or extra == \"all\"" files = [ {file = "asn1crypto-1.5.1-py2.py3-none-any.whl", hash = "sha256:db4e40728b728508912cbb3d44f19ce188f218e9eba635821bb4b68564f8fd67"}, {file = "asn1crypto-1.5.1.tar.gz", hash = "sha256:13ae38502be632115abf8a24cbe5f4da52e3b5231990aff31123c805306ccb9c"}, @@ -372,10 +415,12 @@ version = "3.0.0" description = "Annotate AST trees with source code positions" optional = false python-versions = ">=3.8" +groups = ["main", "dev"] files = [ {file = "asttokens-3.0.0-py3-none-any.whl", hash = "sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2"}, {file = "asttokens-3.0.0.tar.gz", hash = "sha256:0dcd8baa8d62b0c1d118b399b2ddba3c4aff271d0d7a9e0d4c1681c79035bbc7"}, ] +markers = {main = "extra == \"dev\" or extra == \"all\""} [package.extras] astroid = ["astroid (>=2,<4)"] @@ -385,8 +430,10 @@ test = ["astroid (>=2,<4)", "pytest", "pytest-cov", "pytest-xdist"] name = "async-timeout" version = "4.0.3" description = "Timeout context manager for asyncio programs" -optional = false +optional = true python-versions = ">=3.7" +groups = ["main"] +markers = "(extra == \"redis\" or extra == \"all\") and python_full_version < \"3.11.3\" or python_version == \"3.10\"" files = [ {file = "async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f"}, {file = "async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028"}, @@ -398,6 +445,8 @@ version = "0.30.0" description = "An asyncio PostgreSQL driver" optional = true python-versions = ">=3.8.0" +groups = ["main"] +markers = "extra == \"postgres\"" files = [ {file = "asyncpg-0.30.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bfb4dd5ae0699bad2b233672c8fc5ccbd9ad24b89afded02341786887e37927e"}, {file = "asyncpg-0.30.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dc1f62c792752a49f88b7e6f774c26077091b44caceb1983509edc18a2222ec0"}, @@ -455,8 +504,8 @@ async-timeout = {version = ">=4.0.3", markers = "python_version < \"3.11.0\""} [package.extras] docs = ["Sphinx (>=8.1.3,<8.2.0)", "sphinx-rtd-theme (>=1.2.2)"] -gssauth = ["gssapi", "sspilib"] -test = ["distro (>=1.9.0,<1.10.0)", "flake8 (>=6.1,<7.0)", "flake8-pyi (>=24.1.0,<24.2.0)", "gssapi", "k5test", "mypy (>=1.8.0,<1.9.0)", "sspilib", "uvloop (>=0.15.3)"] +gssauth = ["gssapi ; platform_system != \"Windows\"", "sspilib ; platform_system == \"Windows\""] +test = ["distro (>=1.9.0,<1.10.0)", "flake8 (>=6.1,<7.0)", "flake8-pyi (>=24.1.0,<24.2.0)", "gssapi ; platform_system == \"Linux\"", "k5test ; platform_system == \"Linux\"", "mypy (>=1.8.0,<1.9.0)", "sspilib ; platform_system == \"Windows\"", "uvloop (>=0.15.3) ; platform_system != \"Windows\" and python_version < \"3.14.0\""] [[package]] name = "attrs" @@ -464,18 +513,19 @@ version = "25.3.0" description = "Classes Without Boilerplate" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3"}, {file = "attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b"}, ] [package.extras] -benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +benchmark = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"] +cov = ["cloudpickle ; platform_python_implementation == \"CPython\"", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"] +dev = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier"] -tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] +tests = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"] +tests-mypy = ["mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\""] [[package]] name = "autoflake" @@ -483,6 +533,8 @@ version = "2.3.1" description = "Removes unused imports and unused variables" optional = true python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"dev\" or extra == \"all\"" files = [ {file = "autoflake-2.3.1-py3-none-any.whl", hash = "sha256:3ae7495db9084b7b32818b4140e6dc4fc280b712fb414f5b8fe57b0a8e85a840"}, {file = "autoflake-2.3.1.tar.gz", hash = "sha256:c98b75dc5b0a86459c4f01a1d32ac7eb4338ec4317a4469515ff1e687ecd909e"}, @@ -498,6 +550,7 @@ version = "2.1.1" description = "A prompt programming language" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "banks-2.1.1-py3-none-any.whl", hash = "sha256:06e4ee46a0ff2fcdf5f64a5f028a7b7ceb719d5c7b9339f5aa90b24936fbb7f5"}, {file = "banks-2.1.1.tar.gz", hash = "sha256:95ec9c8f3c173c9f1c21eb2451ba0e21dda87f1ceb738854fabadb54bc387b86"}, @@ -519,6 +572,7 @@ version = "4.3.0" description = "Modern password hashing for your software and your servers" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "bcrypt-4.3.0-cp313-cp313t-macosx_10_12_universal2.whl", hash = "sha256:f01e060f14b6b57bbb72fc5b4a83ac21c443c9a2ee708e04a10e9192f90a6281"}, {file = "bcrypt-4.3.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5eeac541cefd0bb887a371ef73c62c3cd78535e4887b310626036a7c0a817bb"}, @@ -583,6 +637,7 @@ version = "4.13.3" description = "Screen-scraping library" optional = false python-versions = ">=3.7.0" +groups = ["main"] files = [ {file = "beautifulsoup4-4.13.3-py3-none-any.whl", hash = "sha256:99045d7d3f08f91f0d656bc9b7efbae189426cd913d830294a15eefa0ea4df16"}, {file = "beautifulsoup4-4.13.3.tar.gz", hash = "sha256:1bd32405dacc920b42b83ba01644747ed77456a65760e285fbc47633ceddaf8b"}, @@ -605,6 +660,8 @@ version = "0.23.1" description = "The bidirectional mapping library for Python." optional = true python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"dev\" or extra == \"desktop\" or extra == \"all\"" files = [ {file = "bidict-0.23.1-py3-none-any.whl", hash = "sha256:5dae8d4d79b552a71cbabc7deb25dfe8ce710b17ff41711e13010ead2abfc3e5"}, {file = "bidict-0.23.1.tar.gz", hash = "sha256:03069d763bc387bbd20e7d49914e75fc4132a41937fa3405417e1a5a2d006d71"}, @@ -616,6 +673,7 @@ version = "24.10.0" description = "The uncompromising code formatter." optional = false python-versions = ">=3.9" +groups = ["main", "dev"] files = [ {file = "black-24.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6668650ea4b685440857138e5fe40cde4d652633b1bdffc62933d0db4ed9812"}, {file = "black-24.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1c536fcf674217e87b8cc3657b81809d3c085d7bf3ef262ead700da345bfa6ea"}, @@ -664,6 +722,8 @@ version = "1.9.0" description = "Fast, simple object-to-object and broadcast signaling" optional = true python-versions = ">=3.9" +groups = ["main"] +markers = "extra == \"dev\" or extra == \"desktop\" or extra == \"all\"" files = [ {file = "blinker-1.9.0-py3-none-any.whl", hash = "sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc"}, {file = "blinker-1.9.0.tar.gz", hash = "sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf"}, @@ -675,6 +735,8 @@ version = "1.37.3" description = "The AWS SDK for Python" optional = true python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"bedrock\"" files = [ {file = "boto3-1.37.3-py3-none-any.whl", hash = "sha256:2063b40af99fd02f6228ff52397b552ff3353831edaf8d25cc04801827ab9794"}, {file = "boto3-1.37.3.tar.gz", hash = "sha256:21f3ce0ef111297e63a6eb998a25197b8c10982970c320d4c6e8db08be2157be"}, @@ -694,6 +756,8 @@ version = "1.37.3" description = "Low-level, data-driven core of boto 3." optional = true python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"bedrock\"" files = [ {file = "botocore-1.37.3-py3-none-any.whl", hash = "sha256:d01bd3bf4c80e61fa88d636ad9f5c9f60a551d71549b481386c6b4efe0bb2b2e"}, {file = "botocore-1.37.3.tar.gz", hash = "sha256:fe8403eb55a88faf9b0f9da6615e5bee7be056d75e17af66c3c8f0a3b0648da4"}, @@ -713,6 +777,7 @@ version = "1.1.0" description = "Python bindings for the Brotli compression library" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "Brotli-1.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e1140c64812cb9b06c922e77f1c26a75ec5e3f0fb2bf92cc8c58720dec276752"}, {file = "Brotli-1.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c8fd5270e906eef71d4a8d19b7c6a43760c6abcfcc10c9101d14eb2357418de9"}, @@ -724,6 +789,10 @@ files = [ {file = "Brotli-1.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a37b8f0391212d29b3a91a799c8e4a2855e0576911cdfb2515487e30e322253d"}, {file = "Brotli-1.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e84799f09591700a4154154cab9787452925578841a94321d5ee8fb9a9a328f0"}, {file = "Brotli-1.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f66b5337fa213f1da0d9000bc8dc0cb5b896b726eefd9c6046f699b169c41b9e"}, + {file = "Brotli-1.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5dab0844f2cf82be357a0eb11a9087f70c5430b2c241493fc122bb6f2bb0917c"}, + {file = "Brotli-1.1.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e4fe605b917c70283db7dfe5ada75e04561479075761a0b3866c081d035b01c1"}, + {file = "Brotli-1.1.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:1e9a65b5736232e7a7f91ff3d02277f11d339bf34099a56cdab6a8b3410a02b2"}, + {file = "Brotli-1.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:58d4b711689366d4a03ac7957ab8c28890415e267f9b6589969e74b6e42225ec"}, {file = "Brotli-1.1.0-cp310-cp310-win32.whl", hash = "sha256:be36e3d172dc816333f33520154d708a2657ea63762ec16b62ece02ab5e4daf2"}, {file = "Brotli-1.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:0c6244521dda65ea562d5a69b9a26120769b7a9fb3db2fe9545935ed6735b128"}, {file = "Brotli-1.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a3daabb76a78f829cafc365531c972016e4aa8d5b4bf60660ad8ecee19df7ccc"}, @@ -736,8 +805,14 @@ files = [ {file = "Brotli-1.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:19c116e796420b0cee3da1ccec3b764ed2952ccfcc298b55a10e5610ad7885f9"}, {file = "Brotli-1.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:510b5b1bfbe20e1a7b3baf5fed9e9451873559a976c1a78eebaa3b86c57b4265"}, {file = "Brotli-1.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a1fd8a29719ccce974d523580987b7f8229aeace506952fa9ce1d53a033873c8"}, + {file = "Brotli-1.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c247dd99d39e0338a604f8c2b3bc7061d5c2e9e2ac7ba9cc1be5a69cb6cd832f"}, + {file = "Brotli-1.1.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1b2c248cd517c222d89e74669a4adfa5577e06ab68771a529060cf5a156e9757"}, + {file = "Brotli-1.1.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:2a24c50840d89ded6c9a8fdc7b6ed3692ed4e86f1c4a4a938e1e92def92933e0"}, + {file = "Brotli-1.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f31859074d57b4639318523d6ffdca586ace54271a73ad23ad021acd807eb14b"}, {file = "Brotli-1.1.0-cp311-cp311-win32.whl", hash = "sha256:39da8adedf6942d76dc3e46653e52df937a3c4d6d18fdc94a7c29d263b1f5b50"}, {file = "Brotli-1.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:aac0411d20e345dc0920bdec5548e438e999ff68d77564d5e9463a7ca9d3e7b1"}, + {file = "Brotli-1.1.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:32d95b80260d79926f5fab3c41701dbb818fde1c9da590e77e571eefd14abe28"}, + {file = "Brotli-1.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b760c65308ff1e462f65d69c12e4ae085cff3b332d894637f6273a12a482d09f"}, {file = "Brotli-1.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:316cc9b17edf613ac76b1f1f305d2a748f1b976b033b049a6ecdfd5612c70409"}, {file = "Brotli-1.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:caf9ee9a5775f3111642d33b86237b05808dafcd6268faa492250e9b78046eb2"}, {file = "Brotli-1.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70051525001750221daa10907c77830bc889cb6d865cc0b813d9db7fefc21451"}, @@ -748,8 +823,24 @@ files = [ {file = "Brotli-1.1.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:4093c631e96fdd49e0377a9c167bfd75b6d0bad2ace734c6eb20b348bc3ea180"}, {file = "Brotli-1.1.0-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:7e4c4629ddad63006efa0ef968c8e4751c5868ff0b1c5c40f76524e894c50248"}, {file = "Brotli-1.1.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:861bf317735688269936f755fa136a99d1ed526883859f86e41a5d43c61d8966"}, + {file = "Brotli-1.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:87a3044c3a35055527ac75e419dfa9f4f3667a1e887ee80360589eb8c90aabb9"}, + {file = "Brotli-1.1.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:c5529b34c1c9d937168297f2c1fde7ebe9ebdd5e121297ff9c043bdb2ae3d6fb"}, + {file = "Brotli-1.1.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:ca63e1890ede90b2e4454f9a65135a4d387a4585ff8282bb72964fab893f2111"}, + {file = "Brotli-1.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e79e6520141d792237c70bcd7a3b122d00f2613769ae0cb61c52e89fd3443839"}, {file = "Brotli-1.1.0-cp312-cp312-win32.whl", hash = "sha256:5f4d5ea15c9382135076d2fb28dde923352fe02951e66935a9efaac8f10e81b0"}, {file = "Brotli-1.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:906bc3a79de8c4ae5b86d3d75a8b77e44404b0f4261714306e3ad248d8ab0951"}, + {file = "Brotli-1.1.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8bf32b98b75c13ec7cf774164172683d6e7891088f6316e54425fde1efc276d5"}, + {file = "Brotli-1.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7bc37c4d6b87fb1017ea28c9508b36bbcb0c3d18b4260fcdf08b200c74a6aee8"}, + {file = "Brotli-1.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c0ef38c7a7014ffac184db9e04debe495d317cc9c6fb10071f7fefd93100a4f"}, + {file = "Brotli-1.1.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91d7cc2a76b5567591d12c01f019dd7afce6ba8cba6571187e21e2fc418ae648"}, + {file = "Brotli-1.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a93dde851926f4f2678e704fadeb39e16c35d8baebd5252c9fd94ce8ce68c4a0"}, + {file = "Brotli-1.1.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f0db75f47be8b8abc8d9e31bc7aad0547ca26f24a54e6fd10231d623f183d089"}, + {file = "Brotli-1.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6967ced6730aed543b8673008b5a391c3b1076d834ca438bbd70635c73775368"}, + {file = "Brotli-1.1.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:7eedaa5d036d9336c95915035fb57422054014ebdeb6f3b42eac809928e40d0c"}, + {file = "Brotli-1.1.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:d487f5432bf35b60ed625d7e1b448e2dc855422e87469e3f450aa5552b0eb284"}, + {file = "Brotli-1.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:832436e59afb93e1836081a20f324cb185836c617659b07b129141a8426973c7"}, + {file = "Brotli-1.1.0-cp313-cp313-win32.whl", hash = "sha256:43395e90523f9c23a3d5bdf004733246fba087f2948f87ab28015f12359ca6a0"}, + {file = "Brotli-1.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:9011560a466d2eb3f5a6e4929cf4a09be405c64154e12df0dd72713f6500e32b"}, {file = "Brotli-1.1.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:a090ca607cbb6a34b0391776f0cb48062081f5f60ddcce5d11838e67a01928d1"}, {file = "Brotli-1.1.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2de9d02f5bda03d27ede52e8cfe7b865b066fa49258cbab568720aa5be80a47d"}, {file = "Brotli-1.1.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2333e30a5e00fe0fe55903c8832e08ee9c3b1382aacf4db26664a16528d51b4b"}, @@ -759,6 +850,10 @@ files = [ {file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:fd5f17ff8f14003595ab414e45fce13d073e0762394f957182e69035c9f3d7c2"}, {file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:069a121ac97412d1fe506da790b3e69f52254b9df4eb665cd42460c837193354"}, {file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:e93dfc1a1165e385cc8239fab7c036fb2cd8093728cbd85097b284d7b99249a2"}, + {file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_2_aarch64.whl", hash = "sha256:aea440a510e14e818e67bfc4027880e2fb500c2ccb20ab21c7a7c8b5b4703d75"}, + {file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_2_i686.whl", hash = "sha256:6974f52a02321b36847cd19d1b8e381bf39939c21efd6ee2fc13a28b0d99348c"}, + {file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_2_ppc64le.whl", hash = "sha256:a7e53012d2853a07a4a79c00643832161a910674a893d296c9f1259859a289d2"}, + {file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_2_x86_64.whl", hash = "sha256:d7702622a8b40c49bffb46e1e3ba2e81268d5c04a34f460978c6b5517a34dd52"}, {file = "Brotli-1.1.0-cp36-cp36m-win32.whl", hash = "sha256:a599669fd7c47233438a56936988a2478685e74854088ef5293802123b5b2460"}, {file = "Brotli-1.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:d143fd47fad1db3d7c27a1b1d66162e855b5d50a89666af46e1679c496e8e579"}, {file = "Brotli-1.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:11d00ed0a83fa22d29bc6b64ef636c4552ebafcef57154b4ddd132f5638fbd1c"}, @@ -770,6 +865,10 @@ files = [ {file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:919e32f147ae93a09fe064d77d5ebf4e35502a8df75c29fb05788528e330fe74"}, {file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:23032ae55523cc7bccb4f6a0bf368cd25ad9bcdcc1990b64a647e7bbcce9cb5b"}, {file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:224e57f6eac61cc449f498cc5f0e1725ba2071a3d4f48d5d9dffba42db196438"}, + {file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:cb1dac1770878ade83f2ccdf7d25e494f05c9165f5246b46a621cc849341dc01"}, + {file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:3ee8a80d67a4334482d9712b8e83ca6b1d9bc7e351931252ebef5d8f7335a547"}, + {file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:5e55da2c8724191e5b557f8e18943b1b4839b8efc3ef60d65985bcf6f587dd38"}, + {file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:d342778ef319e1026af243ed0a07c97acf3bad33b9f29e7ae6a1f68fd083e90c"}, {file = "Brotli-1.1.0-cp37-cp37m-win32.whl", hash = "sha256:587ca6d3cef6e4e868102672d3bd9dc9698c309ba56d41c2b9c85bbb903cdb95"}, {file = "Brotli-1.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:2954c1c23f81c2eaf0b0717d9380bd348578a94161a65b3a2afc62c86467dd68"}, {file = "Brotli-1.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:efa8b278894b14d6da122a72fefcebc28445f2d3f880ac59d46c90f4c13be9a3"}, @@ -782,6 +881,10 @@ files = [ {file = "Brotli-1.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ab4fbee0b2d9098c74f3057b2bc055a8bd92ccf02f65944a241b4349229185a"}, {file = "Brotli-1.1.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:141bd4d93984070e097521ed07e2575b46f817d08f9fa42b16b9b5f27b5ac088"}, {file = "Brotli-1.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fce1473f3ccc4187f75b4690cfc922628aed4d3dd013d047f95a9b3919a86596"}, + {file = "Brotli-1.1.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d2b35ca2c7f81d173d2fadc2f4f31e88cc5f7a39ae5b6db5513cf3383b0e0ec7"}, + {file = "Brotli-1.1.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:af6fa6817889314555aede9a919612b23739395ce767fe7fcbea9a80bf140fe5"}, + {file = "Brotli-1.1.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:2feb1d960f760a575dbc5ab3b1c00504b24caaf6986e2dc2b01c09c87866a943"}, + {file = "Brotli-1.1.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:4410f84b33374409552ac9b6903507cdb31cd30d2501fc5ca13d18f73548444a"}, {file = "Brotli-1.1.0-cp38-cp38-win32.whl", hash = "sha256:db85ecf4e609a48f4b29055f1e144231b90edc90af7481aa731ba2d059226b1b"}, {file = "Brotli-1.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:3d7954194c36e304e1523f55d7042c59dc53ec20dd4e9ea9d151f1b62b4415c0"}, {file = "Brotli-1.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5fb2ce4b8045c78ebbc7b8f3c15062e435d47e7393cc57c25115cfd49883747a"}, @@ -794,6 +897,10 @@ files = [ {file = "Brotli-1.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:949f3b7c29912693cee0afcf09acd6ebc04c57af949d9bf77d6101ebb61e388c"}, {file = "Brotli-1.1.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:89f4988c7203739d48c6f806f1e87a1d96e0806d44f0fba61dba81392c9e474d"}, {file = "Brotli-1.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:de6551e370ef19f8de1807d0a9aa2cdfdce2e85ce88b122fe9f6b2b076837e59"}, + {file = "Brotli-1.1.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0737ddb3068957cf1b054899b0883830bb1fec522ec76b1098f9b6e0f02d9419"}, + {file = "Brotli-1.1.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:4f3607b129417e111e30637af1b56f24f7a49e64763253bbc275c75fa887d4b2"}, + {file = "Brotli-1.1.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:6c6e0c425f22c1c719c42670d561ad682f7bfeeef918edea971a79ac5252437f"}, + {file = "Brotli-1.1.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:494994f807ba0b92092a163a0a283961369a65f6cbe01e8891132b7a320e61eb"}, {file = "Brotli-1.1.0-cp39-cp39-win32.whl", hash = "sha256:f0d8a7a6b5983c2496e364b969f0e526647a06b075d034f3297dc66f3b360c64"}, {file = "Brotli-1.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:cdad5b9014d83ca68c25d2e9444e28e967ef16e80f6b436918c700c117a85467"}, {file = "Brotli-1.1.0.tar.gz", hash = "sha256:81de08ac11bcb85841e440c13611c00b67d3bf82698314928d0b676362546724"}, @@ -805,6 +912,8 @@ version = "5.5.2" description = "Extensible memoizing collections and decorators" optional = true python-versions = ">=3.7" +groups = ["main"] +markers = "extra == \"google\"" files = [ {file = "cachetools-5.5.2-py3-none-any.whl", hash = "sha256:d26a22bcc62eb95c3beabd9f1ee5e820d3d2704fe2967cbe350e20c8ffcd3f0a"}, {file = "cachetools-5.5.2.tar.gz", hash = "sha256:1a661caa9175d26759571b2e19580f9d6393969e5dfca11fdb1f947a23e640d4"}, @@ -816,6 +925,7 @@ version = "2025.6.15" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "certifi-2025.6.15-py3-none-any.whl", hash = "sha256:2e0c7ce7cb5d8f8634ca55d2ba7e6ec2689a2fd6537d8dec1296a477a4910057"}, {file = "certifi-2025.6.15.tar.gz", hash = "sha256:d747aa5a8b9bbbb1bb8c22bb13e22bd1f18e9796defa16bab421f7f7a317323b"}, @@ -827,6 +937,7 @@ version = "1.17.1" description = "Foreign Function Interface for Python calling C code." optional = false python-versions = ">=3.8" +groups = ["main", "dev"] files = [ {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, @@ -896,6 +1007,7 @@ files = [ {file = "cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662"}, {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, ] +markers = {dev = "implementation_name == \"pypy\""} [package.dependencies] pycparser = "*" @@ -906,6 +1018,8 @@ version = "3.4.0" description = "Validate configuration and produce human readable error messages." optional = true python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"dev\" or extra == \"all\"" files = [ {file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"}, {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"}, @@ -917,6 +1031,7 @@ version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, @@ -1018,6 +1133,7 @@ version = "8.1.8" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" +groups = ["main", "dev"] files = [ {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, @@ -1032,6 +1148,7 @@ 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 = ["main", "dev", "dev,tests"] files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, @@ -1043,6 +1160,7 @@ version = "0.2.2" description = "Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc." optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "comm-0.2.2-py3-none-any.whl", hash = "sha256:e6fb86cb70ff661ee8c9c14e7d36d6de3b4066f1441be4063df9c5009f0a64d3"}, {file = "comm-0.2.2.tar.gz", hash = "sha256:3fd7a84065306e07bea1773df6eb8282de51ba82f77c72f9c85716ab11fe980e"}, @@ -1060,6 +1178,7 @@ version = "0.7.15" description = "Core package to act as a bridge between composio platform and other services." optional = false python-versions = "<4,>=3.9" +groups = ["main"] files = [ {file = "composio_core-0.7.15-py3-none-any.whl", hash = "sha256:3b4c19fcf8c084ed8b873b8e24ea55084495a046eb971af994e6aae6e1bfcea7"}, {file = "composio_core-0.7.15.tar.gz", hash = "sha256:6797c46f404b9c265cd05c07bd28b4104f425024ef683ac24092087e9590033d"}, @@ -1097,6 +1216,8 @@ version = "1.7.1" description = "A drop-in replacement for argparse that allows options to also be set via config files and/or environment variables." optional = true python-versions = ">=3.6" +groups = ["main"] +markers = "extra == \"dev\" or extra == \"desktop\" or extra == \"all\"" files = [ {file = "configargparse-1.7.1-py3-none-any.whl", hash = "sha256:8b586a31f9d873abd1ca527ffbe58863c99f36d896e2829779803125e83be4b6"}, {file = "configargparse-1.7.1.tar.gz", hash = "sha256:79c2ddae836a1e5914b71d58e4b9adbd9f7779d4e6351a637b7d2d9b6c46d3d9"}, @@ -1112,6 +1233,7 @@ version = "1.3.2" description = "Python library for calculating contours of 2D quadrilateral grids" optional = false python-versions = ">=3.10" +groups = ["main"] files = [ {file = "contourpy-1.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ba38e3f9f330af820c4b27ceb4b9c7feee5fe0493ea53a8720f4792667465934"}, {file = "contourpy-1.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dc41ba0714aa2968d1f8674ec97504a8f7e334f48eeacebcaa6256213acb0989"}, @@ -1188,6 +1310,7 @@ version = "44.0.2" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false python-versions = "!=3.9.0,!=3.9.1,>=3.7" +groups = ["main"] files = [ {file = "cryptography-44.0.2-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:efcfe97d1b3c79e486554efddeb8f6f53a4cdd4cf6086642784fa31fc384e1d7"}, {file = "cryptography-44.0.2-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29ecec49f3ba3f3849362854b7253a9f59799e3763b0c9d0826259a88efa02f1"}, @@ -1230,10 +1353,10 @@ files = [ cffi = {version = ">=1.12", markers = "platform_python_implementation != \"PyPy\""} [package.extras] -docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=3.0.0)"] +docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=3.0.0) ; python_version >= \"3.8\""] docstest = ["pyenchant (>=3)", "readme-renderer (>=30.0)", "sphinxcontrib-spelling (>=7.3.1)"] -nox = ["nox (>=2024.4.15)", "nox[uv] (>=2024.3.2)"] -pep8test = ["check-sdist", "click (>=8.0.1)", "mypy (>=1.4)", "ruff (>=0.3.6)"] +nox = ["nox (>=2024.4.15)", "nox[uv] (>=2024.3.2) ; python_version >= \"3.8\""] +pep8test = ["check-sdist ; python_version >= \"3.8\"", "click (>=8.0.1)", "mypy (>=1.4)", "ruff (>=0.3.6)"] sdist = ["build (>=1.0.0)"] ssh = ["bcrypt (>=3.1.5)"] test = ["certifi (>=2024)", "cryptography-vectors (==44.0.2)", "pretend (>=0.7)", "pytest (>=7.4.0)", "pytest-benchmark (>=4.0)", "pytest-cov (>=2.10.1)", "pytest-xdist (>=3.5.0)"] @@ -1245,6 +1368,7 @@ version = "0.12.1" description = "Composable style cycles" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30"}, {file = "cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c"}, @@ -1260,6 +1384,7 @@ version = "0.6.7" description = "Easily serialize dataclasses to and from JSON." optional = false python-versions = "<4.0,>=3.7" +groups = ["main"] files = [ {file = "dataclasses_json-0.6.7-py3-none-any.whl", hash = "sha256:0dbf33f26c8d5305befd61b39d2b3414e8a407bedc2834dea9b8d642666fb40a"}, {file = "dataclasses_json-0.6.7.tar.gz", hash = "sha256:b6b3e528266ea45b9535223bc53ca645f5208833c29229e847b3f26a1cc55fc0"}, @@ -1275,6 +1400,7 @@ version = "0.25.9" description = "Datamodel Code Generator" optional = false python-versions = "<4.0,>=3.7" +groups = ["main"] files = [ {file = "datamodel_code_generator-0.25.9-py3-none-any.whl", hash = "sha256:9e0324233123d6e39a35bc0004771956935889a974aacfd7a0651de11d2219a9"}, {file = "datamodel_code_generator-0.25.9.tar.gz", hash = "sha256:65ca9807d8edbd88a7f7931c10f4bc1c08bd9bbc5bb0508418a2b6a16590eb65"}, @@ -1290,9 +1416,9 @@ isort = ">=4.3.21,<6.0" jinja2 = ">=2.10.1,<4.0" packaging = "*" pydantic = [ - {version = ">=1.10.0,<2.4.0 || >2.4.0,<3.0", extras = ["email"], markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, - {version = ">=1.9.0,<2.4.0 || >2.4.0,<3.0", extras = ["email"], markers = "python_version >= \"3.10\" and python_version < \"3.11\""}, {version = ">=1.10.0,<2.0.0 || >2.0.0,<2.0.1 || >2.0.1,<2.4.0 || >2.4.0,<3.0", extras = ["email"], markers = "python_version >= \"3.12\" and python_version < \"4.0\""}, + {version = ">=1.10.0,<2.4.0 || >2.4.0,<3.0", extras = ["email"], markers = "python_version >= \"3.11\" and python_version < \"4.0\""}, + {version = ">=1.9.0,<2.4.0 || >2.4.0,<3.0", extras = ["email"], markers = "python_version == \"3.10\""}, ] pyyaml = ">=6.0.1" toml = {version = ">=0.10.0,<1.0.0", markers = "python_version < \"3.11\""} @@ -1309,6 +1435,7 @@ version = "1.8.13" description = "An implementation of the Debug Adapter Protocol for Python" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "debugpy-1.8.13-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:06859f68e817966723ffe046b896b1bd75c665996a77313370336ee9e1de3e90"}, {file = "debugpy-1.8.13-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb56c2db69fb8df3168bc857d7b7d2494fed295dfdbde9a45f27b4b152f37520"}, @@ -1344,10 +1471,12 @@ version = "5.2.1" description = "Decorators for Humans" optional = false python-versions = ">=3.8" +groups = ["main", "dev"] files = [ {file = "decorator-5.2.1-py3-none-any.whl", hash = "sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a"}, {file = "decorator-5.2.1.tar.gz", hash = "sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360"}, ] +markers = {main = "extra == \"dev\" or extra == \"all\""} [[package]] name = "demjson3" @@ -1355,6 +1484,7 @@ version = "3.0.6" description = "encoder, decoder, and lint/validator for JSON (JavaScript Object Notation) compliant with RFC 7159" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "demjson3-3.0.6.tar.gz", hash = "sha256:37c83b0c6eb08d25defc88df0a2a4875d58a7809a9650bd6eee7afd8053cdbac"}, ] @@ -1365,6 +1495,7 @@ version = "1.2.18" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" +groups = ["main"] files = [ {file = "Deprecated-1.2.18-py2.py3-none-any.whl", hash = "sha256:bd5011788200372a32418f888e326a09ff80d0214bd961147cfed01b5c018eec"}, {file = "deprecated-1.2.18.tar.gz", hash = "sha256:422b6f6d859da6f2ef57857761bfb392480502a64c3028ca9bbe86085d72115d"}, @@ -1374,7 +1505,7 @@ files = [ wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "setuptools", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "setuptools ; python_version >= \"3.12\"", "tox"] [[package]] name = "dirtyjson" @@ -1382,6 +1513,7 @@ version = "1.0.8" description = "JSON decoder for Python that can extract data from the muck" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "dirtyjson-1.0.8-py3-none-any.whl", hash = "sha256:125e27248435a58acace26d5c2c4c11a1c0de0a9c5124c5a94ba78e517d74f53"}, {file = "dirtyjson-1.0.8.tar.gz", hash = "sha256:90ca4a18f3ff30ce849d100dcf4a003953c79d3a2348ef056f1d9c22231a25fd"}, @@ -1393,6 +1525,8 @@ version = "0.3.9" description = "Distribution utilities" optional = true python-versions = "*" +groups = ["main"] +markers = "extra == \"dev\" or extra == \"all\"" files = [ {file = "distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87"}, {file = "distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403"}, @@ -1404,6 +1538,7 @@ version = "1.9.0" description = "Distro - an OS platform information API" optional = false python-versions = ">=3.6" +groups = ["main"] files = [ {file = "distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2"}, {file = "distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed"}, @@ -1415,6 +1550,7 @@ version = "2.7.0" description = "DNS toolkit" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "dnspython-2.7.0-py3-none-any.whl", hash = "sha256:b4c34b7d10b51bcc3a5071e7b8dee77939f1e878477eeecc965e9835f63c6c86"}, {file = "dnspython-2.7.0.tar.gz", hash = "sha256:ce9c432eda0dc91cf618a5cedf1a4e142651196bbcd2c80e89ed5a907e5cfaf1"}, @@ -1435,6 +1571,8 @@ version = "7.1.0" description = "A Python library for the Docker Engine API." optional = true python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"external-tools\" or extra == \"desktop\" or extra == \"all\"" files = [ {file = "docker-7.1.0-py3-none-any.whl", hash = "sha256:c96b93b7f0a746f9e77d325bcfb87422a3d8bd4f03136ae8a85b37f1898d5fc0"}, {file = "docker-7.1.0.tar.gz", hash = "sha256:ad8c70e6e3f8926cb8a92619b832b4ea5299e2831c14284663184e200546fa6c"}, @@ -1457,6 +1595,7 @@ version = "0.16" description = "Parse Python docstrings in reST, Google and Numpydoc format" optional = false python-versions = ">=3.6,<4.0" +groups = ["main"] files = [ {file = "docstring_parser-0.16-py3-none-any.whl", hash = "sha256:bf0a1387354d3691d102edef7ec124f219ef639982d096e26e3b60aeffa90637"}, {file = "docstring_parser-0.16.tar.gz", hash = "sha256:538beabd0af1e2db0146b6bd3caa526c35a34d61af9fd2887f3a8a27a739aa6e"}, @@ -1468,6 +1607,8 @@ version = "1.3.3" description = "E2B SDK that give agents cloud environments" optional = true python-versions = "<4.0,>=3.9" +groups = ["main"] +markers = "extra == \"cloud-tool-sandbox\"" files = [ {file = "e2b-1.3.3-py3-none-any.whl", hash = "sha256:1f851345fd22abc1f16fb82197e88786909323edfd140a7a17b8a6ed4bd4ef03"}, {file = "e2b-1.3.3.tar.gz", hash = "sha256:b0afb2e3b8edaade44a50d40dbf8934cbd9e2bc3c1c214ce11dbfd9e1d6815b0"}, @@ -1488,6 +1629,8 @@ version = "1.2.0" description = "E2B Code Interpreter - Stateful code execution" optional = true python-versions = "<4.0,>=3.9" +groups = ["main"] +markers = "extra == \"cloud-tool-sandbox\"" files = [ {file = "e2b_code_interpreter-1.2.0-py3-none-any.whl", hash = "sha256:4f94ba29eceada30ec7d379f76b243d69b76da6b67324b986778743346446505"}, {file = "e2b_code_interpreter-1.2.0.tar.gz", hash = "sha256:9e02d043ab5986232a684018d718014bd5038b421b04a8726952094ef0387e78"}, @@ -1504,6 +1647,7 @@ version = "2.2.0" description = "A robust email address syntax and deliverability validation library." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "email_validator-2.2.0-py3-none-any.whl", hash = "sha256:561977c2d73ce3611850a06fa56b414621e0c8faa9d66f2611407d87465da631"}, {file = "email_validator-2.2.0.tar.gz", hash = "sha256:cb690f344c617a714f22e66ae771445a1ceb46821152df8e165c5f9a364582b7"}, @@ -1519,6 +1663,7 @@ version = "0.2.2" description = "Like `typing._eval_type`, but lets older Python versions use newer typing features." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "eval_type_backport-0.2.2-py3-none-any.whl", hash = "sha256:cb6ad7c393517f476f96d456d0412ea80f0a8cf96f6892834cd9340149111b0a"}, {file = "eval_type_backport-0.2.2.tar.gz", hash = "sha256:f0576b4cf01ebb5bd358d02314d31846af5e07678387486e2c798af0e7d849c1"}, @@ -1533,6 +1678,8 @@ version = "1.2.2" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" +groups = ["main", "dev", "dev,tests"] +markers = "python_version == \"3.10\"" files = [ {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, @@ -1547,13 +1694,15 @@ version = "2.2.0" description = "Get the currently executing AST node of a frame, and other information" optional = false python-versions = ">=3.8" +groups = ["main", "dev"] files = [ {file = "executing-2.2.0-py2.py3-none-any.whl", hash = "sha256:11387150cad388d62750327a53d3339fad4888b39a6fe233c3afbb54ecffd3aa"}, {file = "executing-2.2.0.tar.gz", hash = "sha256:5d108c028108fe2551d1a7b2e8b713341e2cb4fc0aa7dcf966fa4327a5226755"}, ] +markers = {main = "extra == \"dev\" or extra == \"all\""} [package.extras] -tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"] +tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich ; python_version >= \"3.11\""] [[package]] name = "faker" @@ -1561,6 +1710,7 @@ version = "36.2.3" description = "Faker is a Python package that generates fake data for you." optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "Faker-36.2.3-py3-none-any.whl", hash = "sha256:7ca995d65ec08d013f3c1230da7f628cb2c169a77e89cd265d7a59f443f0febd"}, {file = "faker-36.2.3.tar.gz", hash = "sha256:1ed2d7a9c3a5657fc11a4298e8cf19f71d83740560d4ed0895b30399d482d538"}, @@ -1575,6 +1725,7 @@ version = "0.115.12" description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "fastapi-0.115.12-py3-none-any.whl", hash = "sha256:e94613d6c05e27be7ffebdd6ea5f388112e5e430c8f7d6494a9d1d88d43e814d"}, {file = "fastapi-0.115.12.tar.gz", hash = "sha256:1e2c2a2646905f9e83d32f04a3f86aff4a286669c6c950ca95b5fd68c2602681"}, @@ -1595,6 +1746,8 @@ version = "3.18.0" description = "A platform independent file lock." optional = true python-versions = ">=3.9" +groups = ["main"] +markers = "extra == \"dev\" or extra == \"all\"" files = [ {file = "filelock-3.18.0-py3-none-any.whl", hash = "sha256:c401f4f8377c4464e6db25fff06205fd89bdd83b65eb0488ed1b160f780e21de"}, {file = "filelock-3.18.0.tar.gz", hash = "sha256:adbc88eabb99d2fec8c9c1b229b171f18afa655400173ddc653d5d01501fb9f2"}, @@ -1603,7 +1756,7 @@ files = [ [package.extras] docs = ["furo (>=2024.8.6)", "sphinx (>=8.1.3)", "sphinx-autodoc-typehints (>=3)"] testing = ["covdefaults (>=2.3)", "coverage (>=7.6.10)", "diff-cover (>=9.2.1)", "pytest (>=8.3.4)", "pytest-asyncio (>=0.25.2)", "pytest-cov (>=6)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.28.1)"] -typing = ["typing-extensions (>=4.12.2)"] +typing = ["typing-extensions (>=4.12.2) ; python_version < \"3.11\""] [[package]] name = "filetype" @@ -1611,6 +1764,7 @@ version = "1.2.0" description = "Infer file type and MIME type of any file/buffer. No external dependencies." optional = false python-versions = "*" +groups = ["main"] files = [ {file = "filetype-1.2.0-py2.py3-none-any.whl", hash = "sha256:7ce71b6880181241cf7ac8697a2f1eb6a8bd9b429f7ad6d27b8db9ba5f1c2d25"}, {file = "filetype-1.2.0.tar.gz", hash = "sha256:66b56cd6474bf41d8c54660347d37afcc3f7d1970648de365c102ef77548aadb"}, @@ -1622,6 +1776,8 @@ version = "2.8.0" description = "Python SDK for Firecrawl API" optional = false python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"external-tools\"" files = [ {file = "firecrawl_py-2.8.0-py3-none-any.whl", hash = "sha256:f2e148086aa1ca42f603a56009577b4f66a2c23893eaa71f7c9c0082b4fdcf60"}, {file = "firecrawl_py-2.8.0.tar.gz", hash = "sha256:657795b6ddd63f0bd38b38bf0571187e0a66becda23d97c032801895257403c9"}, @@ -1641,6 +1797,8 @@ version = "3.1.0" description = "A simple framework for building complex web applications." optional = true python-versions = ">=3.9" +groups = ["main"] +markers = "extra == \"dev\" or extra == \"desktop\" or extra == \"all\"" files = [ {file = "flask-3.1.0-py3-none-any.whl", hash = "sha256:d667207822eb83f1c4b50949b1623c8fc8d51f2341d65f72e1a1815397551136"}, {file = "flask-3.1.0.tar.gz", hash = "sha256:5f873c5184c897c8d9d1b05df1e3d01b14910ce69607a117bd3277098a5836ac"}, @@ -1663,6 +1821,8 @@ version = "5.0.1" description = "A Flask extension simplifying CORS support" optional = true python-versions = "<4.0,>=3.9" +groups = ["main"] +markers = "extra == \"dev\" or extra == \"desktop\" or extra == \"all\"" files = [ {file = "flask_cors-5.0.1-py3-none-any.whl", hash = "sha256:fa5cb364ead54bbf401a26dbf03030c6b18fb2fcaf70408096a572b409586b0c"}, {file = "flask_cors-5.0.1.tar.gz", hash = "sha256:6ccb38d16d6b72bbc156c1c3f192bc435bfcc3c2bc864b2df1eb9b2d97b2403c"}, @@ -1678,6 +1838,8 @@ version = "0.6.3" description = "User authentication and session management for Flask." optional = true python-versions = ">=3.7" +groups = ["main"] +markers = "extra == \"dev\" or extra == \"desktop\" or extra == \"all\"" files = [ {file = "Flask-Login-0.6.3.tar.gz", hash = "sha256:5e23d14a607ef12806c699590b89d0f0e0d67baeec599d75947bf9c147330333"}, {file = "Flask_Login-0.6.3-py3-none-any.whl", hash = "sha256:849b25b82a436bf830a054e74214074af59097171562ab10bfa999e6b78aae5d"}, @@ -1693,6 +1855,7 @@ version = "4.57.0" description = "Tools to manipulate font files" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "fonttools-4.57.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:babe8d1eb059a53e560e7bf29f8e8f4accc8b6cfb9b5fd10e485bde77e71ef41"}, {file = "fonttools-4.57.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:81aa97669cd726349eb7bd43ca540cf418b279ee3caba5e2e295fb4e8f841c02"}, @@ -1747,18 +1910,18 @@ files = [ ] [package.extras] -all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "pycairo", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.1.0)", "xattr", "zopfli (>=0.1.4)"] +all = ["brotli (>=1.0.1) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\"", "fs (>=2.2.0,<3)", "lxml (>=4.0)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres ; platform_python_implementation == \"PyPy\"", "pycairo", "scipy ; platform_python_implementation != \"PyPy\"", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.1.0) ; python_version <= \"3.12\"", "xattr ; sys_platform == \"darwin\"", "zopfli (>=0.1.4)"] graphite = ["lz4 (>=1.7.4.2)"] -interpolatable = ["munkres", "pycairo", "scipy"] +interpolatable = ["munkres ; platform_python_implementation == \"PyPy\"", "pycairo", "scipy ; platform_python_implementation != \"PyPy\""] lxml = ["lxml (>=4.0)"] pathops = ["skia-pathops (>=0.5.0)"] plot = ["matplotlib"] repacker = ["uharfbuzz (>=0.23.0)"] symfont = ["sympy"] -type1 = ["xattr"] +type1 = ["xattr ; sys_platform == \"darwin\""] ufo = ["fs (>=2.2.0,<3)"] -unicode = ["unicodedata2 (>=15.1.0)"] -woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] +unicode = ["unicodedata2 (>=15.1.0) ; python_version <= \"3.12\""] +woff = ["brotli (>=1.0.1) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\"", "zopfli (>=0.1.4)"] [[package]] name = "frozenlist" @@ -1766,6 +1929,7 @@ version = "1.5.0" description = "A list-like structure which implements collections.abc.MutableSequence" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "frozenlist-1.5.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5b6a66c18b5b9dd261ca98dffcb826a525334b2f29e7caa54e182255c5f6a65a"}, {file = "frozenlist-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d1b3eb7b05ea246510b43a7e53ed1653e55c2121019a97e60cad7efb881a97bb"}, @@ -1867,6 +2031,7 @@ version = "2025.3.2" description = "File-system specification" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "fsspec-2025.3.2-py3-none-any.whl", hash = "sha256:2daf8dc3d1dfa65b6aa37748d112773a7a08416f6c70d96b264c96476ecaf711"}, {file = "fsspec-2025.3.2.tar.gz", hash = "sha256:e52c77ef398680bbd6a98c0e628fbc469491282981209907bbc8aea76a04fdc6"}, @@ -1906,6 +2071,7 @@ version = "1.3.0" description = "GenSON is a powerful, user-friendly JSON Schema generator." optional = false python-versions = "*" +groups = ["main"] files = [ {file = "genson-1.3.0-py3-none-any.whl", hash = "sha256:468feccd00274cc7e4c09e84b08704270ba8d95232aa280f65b986139cec67f7"}, {file = "genson-1.3.0.tar.gz", hash = "sha256:e02db9ac2e3fd29e65b5286f7135762e2cd8a986537c075b06fc5f1517308e37"}, @@ -1917,6 +2083,8 @@ version = "24.11.1" description = "Coroutine-based network library" optional = true python-versions = ">=3.9" +groups = ["main"] +markers = "extra == \"dev\" or extra == \"desktop\" or extra == \"all\"" files = [ {file = "gevent-24.11.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:92fe5dfee4e671c74ffaa431fd7ffd0ebb4b339363d24d0d944de532409b935e"}, {file = "gevent-24.11.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7bfcfe08d038e1fa6de458891bca65c1ada6d145474274285822896a858c870"}, @@ -1965,11 +2133,11 @@ greenlet = {version = ">=3.1.1", markers = "platform_python_implementation == \" "zope.interface" = "*" [package.extras] -dnspython = ["dnspython (>=1.16.0,<2.0)", "idna"] +dnspython = ["dnspython (>=1.16.0,<2.0) ; python_version < \"3.10\"", "idna ; python_version < \"3.10\""] docs = ["furo", "repoze.sphinx.autointerface", "sphinx", "sphinxcontrib-programoutput", "zope.schema"] -monitor = ["psutil (>=5.7.0)"] -recommended = ["cffi (>=1.17.1)", "dnspython (>=1.16.0,<2.0)", "idna", "psutil (>=5.7.0)"] -test = ["cffi (>=1.17.1)", "coverage (>=5.0)", "dnspython (>=1.16.0,<2.0)", "idna", "objgraph", "psutil (>=5.7.0)", "requests"] +monitor = ["psutil (>=5.7.0) ; sys_platform != \"win32\" or platform_python_implementation == \"CPython\""] +recommended = ["cffi (>=1.17.1) ; platform_python_implementation == \"CPython\"", "dnspython (>=1.16.0,<2.0) ; python_version < \"3.10\"", "idna ; python_version < \"3.10\"", "psutil (>=5.7.0) ; sys_platform != \"win32\" or platform_python_implementation == \"CPython\""] +test = ["cffi (>=1.17.1) ; platform_python_implementation == \"CPython\"", "coverage (>=5.0) ; sys_platform != \"win32\"", "dnspython (>=1.16.0,<2.0) ; python_version < \"3.10\"", "idna ; python_version < \"3.10\"", "objgraph", "psutil (>=5.7.0) ; sys_platform != \"win32\" or platform_python_implementation == \"CPython\"", "requests"] [[package]] name = "geventhttpclient" @@ -1977,6 +2145,8 @@ version = "2.3.3" description = "HTTP client library for gevent" optional = true python-versions = ">=3.9" +groups = ["main"] +markers = "extra == \"dev\" or extra == \"desktop\" or extra == \"all\"" files = [ {file = "geventhttpclient-2.3.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d61cad95f80d5bd599e28933c187b3c4eeb0b2f6306e06fa0edcac5c9c4bac0a"}, {file = "geventhttpclient-2.3.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7a00e130577c0cf9749d1143e71543c50c7103321b7f37afc42782ad1d3c0ef7"}, @@ -2075,6 +2245,8 @@ version = "2.38.0" description = "Google Authentication Library" optional = true python-versions = ">=3.7" +groups = ["main"] +markers = "extra == \"google\"" files = [ {file = "google_auth-2.38.0-py2.py3-none-any.whl", hash = "sha256:e7dae6694313f434a2727bf2906f27ad259bae090d7aa896590d86feec3d9d4a"}, {file = "google_auth-2.38.0.tar.gz", hash = "sha256:8285113607d3b80a3f1543b75962447ba8a09fe85783432a784fdeef6ac094c4"}, @@ -2099,6 +2271,8 @@ version = "1.15.0" description = "GenAI Python SDK" optional = true python-versions = ">=3.9" +groups = ["main"] +markers = "extra == \"google\"" files = [ {file = "google_genai-1.15.0-py3-none-any.whl", hash = "sha256:6d7f149cc735038b680722bed495004720514c234e2a445ab2f27967955071dd"}, {file = "google_genai-1.15.0.tar.gz", hash = "sha256:118bb26960d6343cd64f1aeb5c2b02144a36ad06716d0d1eb1fa3e0904db51f1"}, @@ -2119,6 +2293,7 @@ version = "1.69.2" description = "Common protobufs used in Google APIs" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "googleapis_common_protos-1.69.2-py3-none-any.whl", hash = "sha256:0b30452ff9c7a27d80bfc5718954063e8ab53dd3697093d3bc99581f5fd24212"}, {file = "googleapis_common_protos-1.69.2.tar.gz", hash = "sha256:3e1b904a27a33c821b4b749fd31d334c0c9c30e6113023d495e48979a3dc9c5f"}, @@ -2136,6 +2311,8 @@ version = "2.3.2" description = "A Rust HTTP server for Python applications" optional = true python-versions = ">=3.9" +groups = ["main"] +markers = "extra == \"experimental\" or extra == \"all\"" files = [ {file = "granian-2.3.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:d5d1554aae36fc324c1aac6e4675f328f30b1218054d74aac28cb584ddcda1de"}, {file = "granian-2.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df2287786224a35edc5e7cb0ab6e075544938b473e3997d276b74275bb72a1c"}, @@ -2228,8 +2405,8 @@ watchfiles = {version = ">=1.0,<2.0", optional = true, markers = "extra == \"rel all = ["granian[pname,reload]"] pname = ["setproctitle (>=1.3.3,<1.4.0)"] reload = ["watchfiles (>=1.0,<2.0)"] -rloop = ["rloop (>=0.1,<1.0)"] -uvloop = ["uvloop (>=0.18.0)"] +rloop = ["rloop (>=0.1,<1.0) ; sys_platform != \"win32\""] +uvloop = ["uvloop (>=0.18.0) ; platform_python_implementation == \"CPython\" and sys_platform != \"win32\""] [[package]] name = "greenlet" @@ -2237,6 +2414,8 @@ version = "3.1.1" description = "Lightweight in-process concurrent programming" optional = false python-versions = ">=3.7" +groups = ["main"] +markers = "platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\" or (extra == \"dev\" or extra == \"desktop\" or extra == \"all\") and platform_python_implementation == \"CPython\"" files = [ {file = "greenlet-3.1.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:0bbae94a29c9e5c7e4a2b7f0aae5c17e8e90acbfd3bf6270eeba60c39fce3563"}, {file = "greenlet-3.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fde093fb93f35ca72a556cf72c92ea3ebfda3d79fc35bb19fbe685853869a83"}, @@ -2323,6 +2502,7 @@ version = "1.7.2" description = "Signatures for entire Python programs. Extract the structure, the frame, the skeleton of your project, to generate API documentation or find breaking changes in your API." optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "griffe-1.7.2-py3-none-any.whl", hash = "sha256:1ed9c2e338a75741fc82083fe5a1bc89cb6142efe126194cc313e34ee6af5423"}, {file = "griffe-1.7.2.tar.gz", hash = "sha256:98d396d803fab3b680c2608f300872fd57019ed82f0672f5b5323a9ad18c540c"}, @@ -2337,6 +2517,7 @@ version = "1.71.0" description = "HTTP/2-based RPC framework" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "grpcio-1.71.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:c200cb6f2393468142eb50ab19613229dcc7829b5ccee8b658a36005f6669fdd"}, {file = "grpcio-1.71.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:b2266862c5ad664a380fbbcdbdb8289d71464c42a8c29053820ee78ba0119e5d"}, @@ -2400,6 +2581,7 @@ version = "1.71.0" description = "Protobuf code generator for gRPC" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "grpcio_tools-1.71.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:f4ad7f0d756546902597053d70b3af2606fbd70d7972876cd75c1e241d22ae00"}, {file = "grpcio_tools-1.71.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:64bdb291df61cf570b5256777ad5fe2b1db6d67bc46e55dc56a0a862722ae329"}, @@ -2465,6 +2647,7 @@ version = "0.14.0" description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, @@ -2476,6 +2659,7 @@ version = "2020.1.16" description = "Turn HTML into equivalent Markdown-structured text." optional = false python-versions = ">=3.5" +groups = ["main"] files = [ {file = "html2text-2020.1.16-py3-none-any.whl", hash = "sha256:c7c629882da0cf377d66f073329ccf34a12ed2adf0169b9285ae4e63ef54c82b"}, {file = "html2text-2020.1.16.tar.gz", hash = "sha256:e296318e16b059ddb97f7a8a1d6a5c1d7af4544049a01e261731d2d5cc277bbb"}, @@ -2487,6 +2671,7 @@ version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, @@ -2508,6 +2693,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"}, @@ -2520,7 +2706,7 @@ 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.*)"] @@ -2532,6 +2718,7 @@ version = "0.4.0" description = "Consume Server-Sent Event (SSE) messages with HTTPX." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "httpx-sse-0.4.0.tar.gz", hash = "sha256:1e81a3a3070ce322add1d3529ed42eb5f70817f45ed6ec915ab753f961139721"}, {file = "httpx_sse-0.4.0-py3-none-any.whl", hash = "sha256:f329af6eae57eaa2bdfd962b42524764af68075ea87370a2de920af5341e318f"}, @@ -2543,6 +2730,8 @@ version = "2.6.9" description = "File identification library for Python" optional = true python-versions = ">=3.9" +groups = ["main"] +markers = "extra == \"dev\" or extra == \"all\"" files = [ {file = "identify-2.6.9-py2.py3-none-any.whl", hash = "sha256:c98b4322da415a8e5a70ff6e51fbc2d2932c015532d77e9f8537b4ba7813b150"}, {file = "identify-2.6.9.tar.gz", hash = "sha256:d40dfe3142a1421d8518e3d3985ef5ac42890683e32306ad614a29490abeb6bf"}, @@ -2557,6 +2746,7 @@ version = "3.10" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.6" +groups = ["main"] files = [ {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, @@ -2571,6 +2761,7 @@ version = "8.5.0" description = "Read metadata from Python packages" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "importlib_metadata-8.5.0-py3-none-any.whl", hash = "sha256:45e54197d28b7a7f1559e60b95e7c567032b602131fbd588f1497f47880aa68b"}, {file = "importlib_metadata-8.5.0.tar.gz", hash = "sha256:71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7"}, @@ -2580,12 +2771,12 @@ files = [ zipp = ">=3.20" [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] enabler = ["pytest-enabler (>=2.2)"] perf = ["ipython"] -test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"] +test = ["flufl.flake8", "importlib-resources (>=1.3) ; python_version < \"3.9\"", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"] type = ["pytest-mypy"] [[package]] @@ -2594,6 +2785,7 @@ version = "5.6.2" description = "Correctly generate plurals, singular nouns, ordinals, indefinite articles; convert numbers to words" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "inflect-5.6.2-py3-none-any.whl", hash = "sha256:b45d91a4a28a4e617ff1821117439b06eaa86e2a4573154af0149e9be6687238"}, {file = "inflect-5.6.2.tar.gz", hash = "sha256:aadc7ed73928f5e014129794bbac03058cca35d0a973a5fc4eb45c7fa26005f9"}, @@ -2601,7 +2793,7 @@ files = [ [package.extras] docs = ["jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx"] -testing = ["pygments", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] +testing = ["pygments", "pytest (>=6)", "pytest-black (>=0.3.7) ; platform_python_implementation != \"PyPy\"", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1) ; platform_python_implementation != \"PyPy\""] [[package]] name = "inflection" @@ -2609,6 +2801,7 @@ version = "0.5.1" description = "A port of Ruby on Rails inflector to Python" optional = false python-versions = ">=3.5" +groups = ["main"] files = [ {file = "inflection-0.5.1-py2.py3-none-any.whl", hash = "sha256:f38b2b640938a4f35ade69ac3d053042959b62a0f1076a5bbaa1b9526605a8a2"}, {file = "inflection-0.5.1.tar.gz", hash = "sha256:1a29730d366e996aaacffb2f1f1cb9593dc38e2ddd30c91250c6dde09ea9b417"}, @@ -2620,10 +2813,12 @@ version = "2.1.0" description = "brain-dead simple config-ini parsing" optional = false python-versions = ">=3.8" +groups = ["main", "dev", "dev,tests"] files = [ {file = "iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760"}, {file = "iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7"}, ] +markers = {main = "extra == \"dev\" or extra == \"all\""} [[package]] name = "ipdb" @@ -2631,14 +2826,15 @@ version = "0.13.13" description = "IPython-enabled pdb" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +groups = ["dev"] files = [ {file = "ipdb-0.13.13-py3-none-any.whl", hash = "sha256:45529994741c4ab6d2388bfa5d7b725c2cf7fe9deffabdb8a6113aa5ed449ed4"}, {file = "ipdb-0.13.13.tar.gz", hash = "sha256:e3ac6018ef05126d442af680aad863006ec19d02290561ac88b8b1c0b0cfc726"}, ] [package.dependencies] -decorator = {version = "*", markers = "python_version > \"3.6\""} -ipython = {version = ">=7.31.1", markers = "python_version > \"3.6\""} +decorator = {version = "*", markers = "python_version >= \"3.11\""} +ipython = {version = ">=7.31.1", markers = "python_version >= \"3.11\""} tomli = {version = "*", markers = "python_version > \"3.6\" and python_version < \"3.11\""} [[package]] @@ -2647,6 +2843,7 @@ version = "6.29.5" description = "IPython Kernel for Jupyter" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "ipykernel-6.29.5-py3-none-any.whl", hash = "sha256:afdb66ba5aa354b09b91379bac28ae4afebbb30e8b39510c9690afb7a10421b5"}, {file = "ipykernel-6.29.5.tar.gz", hash = "sha256:f093a22c4a40f8828f8e330a9c297cb93dcab13bd9678ded6de8e5cf81c56215"}, @@ -2680,10 +2877,12 @@ version = "8.35.0" description = "IPython: Productive Interactive Computing" optional = false python-versions = ">=3.10" +groups = ["main", "dev"] files = [ {file = "ipython-8.35.0-py3-none-any.whl", hash = "sha256:e6b7470468ba6f1f0a7b116bb688a3ece2f13e2f94138e508201fad677a788ba"}, {file = "ipython-8.35.0.tar.gz", hash = "sha256:d200b7d93c3f5883fc36ab9ce28a18249c7706e51347681f80a0aef9895f2520"}, ] +markers = {main = "extra == \"dev\" or extra == \"all\""} [package.dependencies] colorama = {version = "*", markers = "sys_platform == \"win32\""} @@ -2701,7 +2900,7 @@ typing_extensions = {version = ">=4.6", markers = "python_version < \"3.12\""} [package.extras] all = ["ipython[black,doc,kernel,matplotlib,nbconvert,nbformat,notebook,parallel,qtconsole]", "ipython[test,test-extra]"] black = ["black"] -doc = ["docrepr", "exceptiongroup", "intersphinx_registry", "ipykernel", "ipython[test]", "matplotlib", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "sphinxcontrib-jquery", "tomli", "typing_extensions"] +doc = ["docrepr", "exceptiongroup", "intersphinx_registry", "ipykernel", "ipython[test]", "matplotlib", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "sphinxcontrib-jquery", "tomli ; python_version < \"3.11\"", "typing_extensions"] kernel = ["ipykernel"] matplotlib = ["matplotlib"] nbconvert = ["nbconvert"] @@ -2718,6 +2917,7 @@ version = "5.13.2" description = "A Python utility / library to sort Python imports." optional = false python-versions = ">=3.8.0" +groups = ["main"] files = [ {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, @@ -2732,6 +2932,8 @@ version = "2.2.0" description = "Safely pass data to untrusted environments and back." optional = true python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"dev\" or extra == \"desktop\" or extra == \"all\"" files = [ {file = "itsdangerous-2.2.0-py3-none-any.whl", hash = "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef"}, {file = "itsdangerous-2.2.0.tar.gz", hash = "sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173"}, @@ -2743,10 +2945,12 @@ version = "0.19.2" description = "An autocompletion tool for Python that can be used for text editors." optional = false python-versions = ">=3.6" +groups = ["main", "dev"] files = [ {file = "jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9"}, {file = "jedi-0.19.2.tar.gz", hash = "sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0"}, ] +markers = {main = "extra == \"dev\" or extra == \"all\""} [package.dependencies] parso = ">=0.8.4,<0.9.0" @@ -2762,6 +2966,7 @@ version = "3.1.6" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67"}, {file = "jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d"}, @@ -2779,6 +2984,7 @@ version = "0.9.0" description = "Fast iterable JSON parser." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "jiter-0.9.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:816ec9b60fdfd1fec87da1d7ed46c66c44ffec37ab2ef7de5b147b2fce3fd5ad"}, {file = "jiter-0.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9b1d3086f8a3ee0194ecf2008cf81286a5c3e540d977fa038ff23576c023c0ea"}, @@ -2864,6 +3070,8 @@ version = "1.0.1" description = "JSON Matching Expressions" optional = true python-versions = ">=3.7" +groups = ["main"] +markers = "extra == \"bedrock\"" files = [ {file = "jmespath-1.0.1-py3-none-any.whl", hash = "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980"}, {file = "jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe"}, @@ -2875,6 +3083,7 @@ version = "1.4.2" description = "Lightweight pipelining with Python functions" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "joblib-1.4.2-py3-none-any.whl", hash = "sha256:06d478d5674cbc267e7496a410ee875abd68e4340feff4490bcb7afb88060ae6"}, {file = "joblib-1.4.2.tar.gz", hash = "sha256:2382c5816b2636fbd20a09e0f4e9dad4736765fdfb7dca582943b9c1366b3f0e"}, @@ -2886,6 +3095,8 @@ version = "1.33" description = "Apply JSON-Patches (RFC 6902)" optional = true python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" +groups = ["main"] +markers = "extra == \"external-tools\" or extra == \"desktop\" or extra == \"all\"" files = [ {file = "jsonpatch-1.33-py2.py3-none-any.whl", hash = "sha256:0ae28c0cd062bbd8b8ecc26d7d164fbbea9652a1a3693f3b956c1eae5145dade"}, {file = "jsonpatch-1.33.tar.gz", hash = "sha256:9fcd4009c41e6d12348b4a0ff2563ba56a2923a7dfee731d004e212e1ee5030c"}, @@ -2900,6 +3111,8 @@ version = "3.0.0" description = "Identify specific nodes in a JSON document (RFC 6901)" optional = true python-versions = ">=3.7" +groups = ["main"] +markers = "extra == \"external-tools\" or extra == \"desktop\" or extra == \"all\"" files = [ {file = "jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942"}, {file = "jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef"}, @@ -2911,6 +3124,7 @@ version = "1.1.0" description = "jsonref is a library for automatic dereferencing of JSON Reference objects for Python." optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "jsonref-1.1.0-py3-none-any.whl", hash = "sha256:590dc7773df6c21cbf948b5dac07a72a251db28b0238ceecce0a2abfa8ec30a9"}, {file = "jsonref-1.1.0.tar.gz", hash = "sha256:32fe8e1d85af0fdefbebce950af85590b22b60f9e95443176adbde4e1ecea552"}, @@ -2922,6 +3136,7 @@ version = "4.23.0" description = "An implementation of JSON Schema validation for Python" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "jsonschema-4.23.0-py3-none-any.whl", hash = "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566"}, {file = "jsonschema-4.23.0.tar.gz", hash = "sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4"}, @@ -2943,6 +3158,7 @@ version = "2024.10.1" description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "jsonschema_specifications-2024.10.1-py3-none-any.whl", hash = "sha256:a09a0680616357d9a0ecf05c12ad234479f549239d0f5b55f3deea67475da9bf"}, {file = "jsonschema_specifications-2024.10.1.tar.gz", hash = "sha256:0f38b83639958ce1152d02a7f062902c41c8fd20d558b0c34344292d417ae272"}, @@ -2957,6 +3173,7 @@ version = "8.6.3" description = "Jupyter protocol implementation and client libraries" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "jupyter_client-8.6.3-py3-none-any.whl", hash = "sha256:e8a19cc986cc45905ac3362915f410f3af85424b4c0905e94fa5f2cb08e8f23f"}, {file = "jupyter_client-8.6.3.tar.gz", hash = "sha256:35b3a0947c4a6e9d589eb97d7d4cd5e90f910ee73101611f01283732bd6d9419"}, @@ -2971,7 +3188,7 @@ traitlets = ">=5.3" [package.extras] docs = ["ipykernel", "myst-parser", "pydata-sphinx-theme", "sphinx (>=4)", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] -test = ["coverage", "ipykernel (>=6.14)", "mypy", "paramiko", "pre-commit", "pytest (<8.2.0)", "pytest-cov", "pytest-jupyter[client] (>=0.4.1)", "pytest-timeout"] +test = ["coverage", "ipykernel (>=6.14)", "mypy", "paramiko ; sys_platform == \"win32\"", "pre-commit", "pytest (<8.2.0)", "pytest-cov", "pytest-jupyter[client] (>=0.4.1)", "pytest-timeout"] [[package]] name = "jupyter-core" @@ -2979,6 +3196,7 @@ version = "5.7.2" description = "Jupyter core package. A base package on which Jupyter projects rely." optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "jupyter_core-5.7.2-py3-none-any.whl", hash = "sha256:4f7315d2f6b4bcf2e3e7cb6e46772eba760ae459cd1f59d29eb57b0a01bd7409"}, {file = "jupyter_core-5.7.2.tar.gz", hash = "sha256:aa5f8d32bbf6b431ac830496da7392035d6f61b4f54872f15c4bd2a9c3f536d9"}, @@ -2999,6 +3217,7 @@ version = "1.4.8" description = "A fast implementation of the Cassowary constraint solver" optional = false python-versions = ">=3.10" +groups = ["main"] files = [ {file = "kiwisolver-1.4.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:88c6f252f6816a73b1f8c904f7bbe02fd67c09a69f7cb8a0eecdbf5ce78e63db"}, {file = "kiwisolver-1.4.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c72941acb7b67138f35b879bbe85be0f6c6a70cab78fe3ef6db9c024d9223e5b"}, @@ -3088,6 +3307,8 @@ version = "0.3.23" description = "Building applications with LLMs through composability" optional = true python-versions = "<4.0,>=3.9" +groups = ["main"] +markers = "extra == \"external-tools\" or extra == \"desktop\" or extra == \"all\"" files = [ {file = "langchain-0.3.23-py3-none-any.whl", hash = "sha256:084f05ee7e80b7c3f378ebadd7309f2a37868ce2906fa0ae64365a67843ade3d"}, {file = "langchain-0.3.23.tar.gz", hash = "sha256:d95004afe8abebb52d51d6026270248da3f4b53d93e9bf699f76005e0c83ad34"}, @@ -3128,6 +3349,8 @@ version = "0.3.21" description = "Community contributed LangChain integrations." optional = true python-versions = "<4.0,>=3.9" +groups = ["main"] +markers = "extra == \"external-tools\" or extra == \"desktop\" or extra == \"all\"" files = [ {file = "langchain_community-0.3.21-py3-none-any.whl", hash = "sha256:8cb9bbb7ef15e5eea776193528dd0e0e1299047146d0c78b6c696ae2dc62e81f"}, {file = "langchain_community-0.3.21.tar.gz", hash = "sha256:b87b9992cbeea7553ed93e3d39faf9893a8690318485f7dc861751c7878729f7"}, @@ -3153,6 +3376,8 @@ version = "0.3.51" description = "Building applications with LLMs through composability" optional = true python-versions = "<4.0,>=3.9" +groups = ["main"] +markers = "extra == \"external-tools\" or extra == \"desktop\" or extra == \"all\"" files = [ {file = "langchain_core-0.3.51-py3-none-any.whl", hash = "sha256:4bd71e8acd45362aa428953f2a91d8162318014544a2216e4b769463caf68e13"}, {file = "langchain_core-0.3.51.tar.gz", hash = "sha256:db76b9cc331411602cb40ba0469a161febe7a0663fbcaddbc9056046ac2d22f4"}, @@ -3176,6 +3401,8 @@ version = "0.3.8" description = "LangChain text splitting utilities" optional = true python-versions = "<4.0,>=3.9" +groups = ["main"] +markers = "extra == \"external-tools\" or extra == \"desktop\" or extra == \"all\"" files = [ {file = "langchain_text_splitters-0.3.8-py3-none-any.whl", hash = "sha256:e75cc0f4ae58dcf07d9f18776400cf8ade27fadd4ff6d264df6278bb302f6f02"}, {file = "langchain_text_splitters-0.3.8.tar.gz", hash = "sha256:116d4b9f2a22dda357d0b79e30acf005c5518177971c66a9f1ab0edfdb0f912e"}, @@ -3190,6 +3417,8 @@ version = "0.3.28" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = true python-versions = "<4.0,>=3.9" +groups = ["main"] +markers = "extra == \"external-tools\" or extra == \"desktop\" or extra == \"all\"" files = [ {file = "langsmith-0.3.28-py3-none-any.whl", hash = "sha256:54ac8815514af52d9c801ad7970086693667e266bf1db90fc453c1759e8407cd"}, {file = "langsmith-0.3.28.tar.gz", hash = "sha256:4666595207131d7f8d83418e54dc86c05e28562e5c997633e7c33fc18f9aeb89"}, @@ -3219,6 +3448,7 @@ version = "0.1.197" description = "" optional = false python-versions = "<4.0,>=3.8" +groups = ["main"] files = [ {file = "letta_client-0.1.197-py3-none-any.whl", hash = "sha256:b01eab01ff87a34e79622cd8d3a2f3da56b6bd730312a268d968576671f6cce0"}, {file = "letta_client-0.1.197.tar.gz", hash = "sha256:579571623ccec81422087cb7957d5f580fa0b7a53f8495596e5c56d0213220d8"}, @@ -3237,6 +3467,7 @@ version = "0.1.18" description = "" optional = false python-versions = "<4,>=3.8" +groups = ["main"] files = [ {file = "llama_cloud-0.1.18-py3-none-any.whl", hash = "sha256:5842722a0c3033afa930b4a50d43e6f1e77ff1dab12383a769dc51a15fb87c9b"}, {file = "llama_cloud-0.1.18.tar.gz", hash = "sha256:65cb88b1cb1a3a0e63e4438e8c8a2e6013dfdafbb4201d274c0459e5d04fb328"}, @@ -3253,6 +3484,7 @@ version = "0.6.10" description = "Tailored SDK clients for LlamaCloud services." optional = false python-versions = "<4.0,>=3.9" +groups = ["main"] files = [ {file = "llama_cloud_services-0.6.10-py3-none-any.whl", hash = "sha256:61d13ace89c6090274c118dfdb2a8d5d098ef39a4c0a58907cc255bc4c41a1ac"}, {file = "llama_cloud_services-0.6.10.tar.gz", hash = "sha256:86efc70546963ca0893da46effdcdd16d6c787b5412cbf26de17ce5750e8050f"}, @@ -3272,6 +3504,7 @@ version = "0.12.29" description = "Interface between LLMs and your data" optional = false python-versions = "<4.0,>=3.9" +groups = ["main"] files = [ {file = "llama_index-0.12.29-py3-none-any.whl", hash = "sha256:fc581374417a1ce787fc8580247dc3d36ef3c670a18ee77282662c17b72e380e"}, {file = "llama_index-0.12.29.tar.gz", hash = "sha256:2a07e1509550638964daab7ddd8f7c6a282a72c17bab60930f5a1059dd3caeac"}, @@ -3297,6 +3530,7 @@ version = "0.4.6" description = "llama-index agent openai integration" optional = false python-versions = "<4.0,>=3.9" +groups = ["main"] files = [ {file = "llama_index_agent_openai-0.4.6-py3-none-any.whl", hash = "sha256:4103e479c874cb3426aa59a13f91b6e2dc6b350c51457966631f8bdaf9a6a8e8"}, {file = "llama_index_agent_openai-0.4.6.tar.gz", hash = "sha256:4f66c1731836ab66c4b441255a95f33a51743e4993b8aa9daf430cb31aa7d48e"}, @@ -3313,6 +3547,7 @@ version = "0.4.1" description = "llama-index cli" optional = false python-versions = "<4.0,>=3.9" +groups = ["main"] files = [ {file = "llama_index_cli-0.4.1-py3-none-any.whl", hash = "sha256:6dfc931aea5b90c256e476b48dfac76f48fb2308fdf656bb02ee1e4f2cab8b06"}, {file = "llama_index_cli-0.4.1.tar.gz", hash = "sha256:3f97f1f8f5f401dfb5b6bc7170717c176dcd981538017430073ef12ffdcbddfa"}, @@ -3329,6 +3564,7 @@ version = "0.12.30" description = "Interface between LLMs and your data" optional = false python-versions = "<4.0,>=3.9" +groups = ["main"] files = [ {file = "llama_index_core-0.12.30-py3-none-any.whl", hash = "sha256:6e0b33158de52108debe66528adb84adb626aed5c6c7762874fb7a799d8c48a9"}, {file = "llama_index_core-0.12.30.tar.gz", hash = "sha256:dfbed9cdba18358750ad3895cd97fa1ea0dd0b856bbd623a4904ac61641e2765"}, @@ -3365,6 +3601,7 @@ version = "0.3.1" description = "llama-index embeddings openai integration" optional = false python-versions = "<4.0,>=3.9" +groups = ["main"] files = [ {file = "llama_index_embeddings_openai-0.3.1-py3-none-any.whl", hash = "sha256:f15a3d13da9b6b21b8bd51d337197879a453d1605e625a1c6d45e741756c0290"}, {file = "llama_index_embeddings_openai-0.3.1.tar.gz", hash = "sha256:1368aad3ce24cbaed23d5ad251343cef1eb7b4a06d6563d6606d59cb347fef20"}, @@ -3380,6 +3617,7 @@ version = "0.6.11" description = "llama-index indices llama-cloud integration" optional = false python-versions = "<4.0,>=3.9" +groups = ["main"] files = [ {file = "llama_index_indices_managed_llama_cloud-0.6.11-py3-none-any.whl", hash = "sha256:64e82e2ac178cd3721b76c0817edd57e05a3bd877c412b4148d3abbdeea62d59"}, {file = "llama_index_indices_managed_llama_cloud-0.6.11.tar.gz", hash = "sha256:925532f760cd2ebb2594828da311adac3d54cd2cae3dff2908491eebb2b8bd0f"}, @@ -3395,6 +3633,7 @@ version = "0.3.33" description = "llama-index llms openai integration" optional = false python-versions = "<4.0,>=3.9" +groups = ["main"] files = [ {file = "llama_index_llms_openai-0.3.33-py3-none-any.whl", hash = "sha256:d76eab8658d905514b2fa3de7702e47aecd9dbd70d34a0faac39e1ed50c116a5"}, {file = "llama_index_llms_openai-0.3.33.tar.gz", hash = "sha256:112942ca221c2233ed2cf995fdaf0865f2b7f9295d9b01c5a7fcaef373c1ac87"}, @@ -3410,6 +3649,7 @@ version = "0.4.3" description = "llama-index multi-modal-llms openai integration" optional = false python-versions = "<4.0,>=3.9" +groups = ["main"] files = [ {file = "llama_index_multi_modal_llms_openai-0.4.3-py3-none-any.whl", hash = "sha256:1ceb42716472ac8bd5130afa29b793869d367946aedd02e48a3b03184e443ad1"}, {file = "llama_index_multi_modal_llms_openai-0.4.3.tar.gz", hash = "sha256:5e6ca54069d3d18c2f5f7ca34f3720fba1d1b9126482ad38feb0c858f4feb63b"}, @@ -3425,6 +3665,7 @@ version = "0.3.1" description = "llama-index program openai integration" optional = false python-versions = "<4.0,>=3.9" +groups = ["main"] files = [ {file = "llama_index_program_openai-0.3.1-py3-none-any.whl", hash = "sha256:93646937395dc5318fd095153d2f91bd632b25215d013d14a87c088887d205f9"}, {file = "llama_index_program_openai-0.3.1.tar.gz", hash = "sha256:6039a6cdbff62c6388c07e82a157fe2edd3bbef0c5adf292ad8546bf4ec75b82"}, @@ -3441,6 +3682,7 @@ version = "0.3.0" description = "llama-index question_gen openai integration" optional = false python-versions = "<4.0,>=3.9" +groups = ["main"] files = [ {file = "llama_index_question_gen_openai-0.3.0-py3-none-any.whl", hash = "sha256:9b60ec114273a63b50349948666e5744a8f58acb645824e07c979041e8fec598"}, {file = "llama_index_question_gen_openai-0.3.0.tar.gz", hash = "sha256:efd3b468232808e9d3474670aaeab00e41b90f75f52d0c9bfbf11207e0963d62"}, @@ -3457,6 +3699,7 @@ version = "0.4.7" description = "llama-index readers file integration" optional = false python-versions = "<4.0,>=3.9" +groups = ["main"] files = [ {file = "llama_index_readers_file-0.4.7-py3-none-any.whl", hash = "sha256:dff86f9b6079bddad37896f26756b508be5a052096ced34c9917b76646cf0c02"}, {file = "llama_index_readers_file-0.4.7.tar.gz", hash = "sha256:89a765238a106af0f1e31ab8d4cb3ee33ac897080285bcce59101b420265ebd1"}, @@ -3478,6 +3721,7 @@ version = "0.4.0" description = "llama-index readers llama-parse integration" optional = false python-versions = "<4.0,>=3.9" +groups = ["main"] files = [ {file = "llama_index_readers_llama_parse-0.4.0-py3-none-any.whl", hash = "sha256:574e48386f28d2c86c3f961ca4a4906910312f3400dd0c53014465bfbc6b32bf"}, {file = "llama_index_readers_llama_parse-0.4.0.tar.gz", hash = "sha256:e99ec56f4f8546d7fda1a7c1ae26162fb9acb7ebcac343b5abdb4234b4644e0f"}, @@ -3493,6 +3737,7 @@ version = "0.6.9" description = "Parse files into RAG-Optimized formats." optional = false python-versions = "<4.0,>=3.9" +groups = ["main"] files = [ {file = "llama_parse-0.6.9-py3-none-any.whl", hash = "sha256:fb40d3ab8d6c03bdcde66cc897d72412242f6f7a3a0b991907038fb47e554d8e"}, {file = "llama_parse-0.6.9.tar.gz", hash = "sha256:37016bee67be8c9377ddf00afae0054903e934e54db7406ba3a422b7e9ad8259"}, @@ -3507,6 +3752,8 @@ version = "2.37.11" description = "Developer-friendly load testing framework" optional = true python-versions = ">=3.10" +groups = ["main"] +markers = "extra == \"dev\" or extra == \"desktop\" or extra == \"all\"" files = [ {file = "locust-2.37.11-py3-none-any.whl", hash = "sha256:b826f95fbfd5d9a32df6ab1b74672b88e65bbc33ec99fdc10af98079952ad517"}, {file = "locust-2.37.11.tar.gz", hash = "sha256:89c79bc599aa57160bd41dd3876e35d8b9dee5abded78e35008d01fd8f1640ed"}, @@ -3525,8 +3772,8 @@ psutil = ">=5.9.1" pywin32 = {version = "*", markers = "sys_platform == \"win32\""} pyzmq = ">=25.0.0" requests = [ - {version = ">=2.26.0", markers = "python_version <= \"3.11\""}, {version = ">=2.32.2", markers = "python_version > \"3.11\""}, + {version = ">=2.26.0", markers = "python_version <= \"3.11\""}, ] setuptools = ">=70.0.0" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} @@ -3539,6 +3786,8 @@ version = "1.24.2" description = "Locust Cloud" optional = true python-versions = ">=3.10" +groups = ["main"] +markers = "extra == \"dev\" or extra == \"desktop\" or extra == \"all\"" files = [ {file = "locust_cloud-1.24.2-py3-none-any.whl", hash = "sha256:64a5e6f2bf0a1a012d9805291d44fb57e57535c2b5c0fa5bc87ba0d7cce9ef9c"}, {file = "locust_cloud-1.24.2.tar.gz", hash = "sha256:a2656537ff367e6d4d4673477ba9e81ed73a8423a71573cd2512248740eded77"}, @@ -3558,6 +3807,7 @@ version = "1.3.10" description = "A super-fast templating language that borrows the best ideas from the existing templating languages." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "mako-1.3.10-py3-none-any.whl", hash = "sha256:baef24a52fc4fc514a0887ac600f9f1cff3d82c61d4d700a1fa84d597b88db59"}, {file = "mako-1.3.10.tar.gz", hash = "sha256:99579a6f39583fa7e5630a28c3c1f440e4e97a414b80372649c0ce338da2ea28"}, @@ -3577,6 +3827,7 @@ version = "3.0.0" description = "Python port of markdown-it. Markdown parsing, done right!" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, @@ -3601,6 +3852,7 @@ version = "3.0.2" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, @@ -3671,6 +3923,7 @@ version = "3.26.1" description = "A lightweight library for converting complex datatypes to and from native Python datatypes." optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "marshmallow-3.26.1-py3-none-any.whl", hash = "sha256:3350409f20a70a7e4e11a27661187b77cdcaeb20abca41c1454fe33636bea09c"}, {file = "marshmallow-3.26.1.tar.gz", hash = "sha256:e6d8affb6cb61d39d26402096dc0aee12d5a26d490a121f118d2e81dc0719dc6"}, @@ -3690,6 +3943,7 @@ version = "1.4.2" description = "SQLAlchemy integration with the marshmallow (de)serialization library" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "marshmallow_sqlalchemy-1.4.2-py3-none-any.whl", hash = "sha256:65aee301c4601e76a2fdb02764a65c18913afba2a3506a326c625d13ab405b40"}, {file = "marshmallow_sqlalchemy-1.4.2.tar.gz", hash = "sha256:6410304bf98ec26ea35f3f9d3cee82e51fd093c434612add32a0bdcdb5668f7c"}, @@ -3701,7 +3955,7 @@ SQLAlchemy = ">=1.4.40,<3.0" [package.extras] dev = ["marshmallow-sqlalchemy[tests]", "pre-commit (>=3.5,<5.0)", "tox"] -docs = ["furo (==2024.8.6)", "sphinx (==8.2.3)", "sphinx-copybutton (==0.5.2)", "sphinx-design (==0.6.1)", "sphinx-issues (==5.0.0)", "sphinxext-opengraph (==0.10.0)"] +docs = ["furo (==2024.8.6)", "sphinx (==8.2.3) ; python_version >= \"3.11\"", "sphinx-copybutton (==0.5.2)", "sphinx-design (==0.6.1)", "sphinx-issues (==5.0.0)", "sphinxext-opengraph (==0.10.0)"] tests = ["pytest (<9)", "pytest-lazy-fixtures"] [[package]] @@ -3710,6 +3964,7 @@ version = "3.10.1" description = "Python plotting package" optional = false python-versions = ">=3.10" +groups = ["main"] files = [ {file = "matplotlib-3.10.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:ff2ae14910be903f4a24afdbb6d7d3a6c44da210fc7d42790b87aeac92238a16"}, {file = "matplotlib-3.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0721a3fd3d5756ed593220a8b86808a36c5031fce489adb5b31ee6dbb47dd5b2"}, @@ -3767,10 +4022,12 @@ version = "0.1.7" description = "Inline Matplotlib backend for Jupyter" optional = false python-versions = ">=3.8" +groups = ["main", "dev"] files = [ {file = "matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca"}, {file = "matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90"}, ] +markers = {main = "extra == \"dev\" or extra == \"all\""} [package.dependencies] traitlets = "*" @@ -3781,6 +4038,7 @@ version = "1.9.4" description = "Model Context Protocol SDK" optional = false python-versions = ">=3.10" +groups = ["main"] files = [ {file = "mcp-1.9.4-py3-none-any.whl", hash = "sha256:7fcf36b62936adb8e63f89346bccca1268eeca9bf6dfb562ee10b1dfbda9dac0"}, {file = "mcp-1.9.4.tar.gz", hash = "sha256:cfb0bcd1a9535b42edaef89947b9e18a8feb49362e1cc059d6e7fc636f2cb09f"}, @@ -3810,6 +4068,7 @@ version = "0.1.2" description = "Markdown URL utilities" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, @@ -3821,6 +4080,7 @@ version = "1.8.1" description = "Python Client SDK for the Mistral AI API." optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "mistralai-1.8.1-py3-none-any.whl", hash = "sha256:badfc7e6832d894b3e9071d92ad621212b7cccd7df622c6cacdb525162ae338f"}, {file = "mistralai-1.8.1.tar.gz", hash = "sha256:b967ca443726b71ec45632cb33825ee2e55239a652e73c2bda11f7cc683bf6e5"}, @@ -3834,7 +4094,7 @@ python-dateutil = ">=2.8.2" typing-inspection = ">=0.4.0" [package.extras] -agents = ["authlib (>=1.5.2,<2.0)", "griffe (>=1.7.3,<2.0)", "mcp (>=1.0,<2.0)"] +agents = ["authlib (>=1.5.2,<2.0)", "griffe (>=1.7.3,<2.0)", "mcp (>=1.0,<2.0) ; python_version >= \"3.10\""] gcp = ["google-auth (>=2.27.0)", "requests (>=2.32.3)"] [[package]] @@ -3843,6 +4103,8 @@ version = "1.1.0" description = "MessagePack serializer" optional = true python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"dev\" or extra == \"desktop\" or extra == \"all\"" files = [ {file = "msgpack-1.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7ad442d527a7e358a469faf43fda45aaf4ac3249c8310a82f0ccff9164e5dccd"}, {file = "msgpack-1.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:74bed8f63f8f14d75eec75cf3d04ad581da6b914001b474a5d3cd3372c8cc27d"}, @@ -3916,6 +4178,7 @@ version = "6.4.2" description = "multidict implementation" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "multidict-6.4.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:48f775443154d99e1b1c727ea20137ddc1e4b29448a9b24875b2a348cc143b85"}, {file = "multidict-6.4.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3d17d8b2d4643d4f59629758b0dd229cda61e2319f81b470aa4a99717081ba0c"}, @@ -4032,6 +4295,7 @@ version = "1.0.0" description = "Type system extensions for programs checked with the mypy type checker." optional = false python-versions = ">=3.5" +groups = ["main", "dev"] files = [ {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, @@ -4043,6 +4307,7 @@ version = "1.6.0" description = "Patch asyncio to allow nested event loops" optional = false python-versions = ">=3.5" +groups = ["main", "dev"] files = [ {file = "nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c"}, {file = "nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe"}, @@ -4054,6 +4319,7 @@ version = "3.4.2" description = "Python package for creating and manipulating graphs and networks" optional = false python-versions = ">=3.10" +groups = ["main"] files = [ {file = "networkx-3.4.2-py3-none-any.whl", hash = "sha256:df5d4365b724cf81b8c6a7312509d0c22386097011ad1abe274afd5e9d3bbc5f"}, {file = "networkx-3.4.2.tar.gz", hash = "sha256:307c3669428c5362aab27c8a1260aa8f47c4e91d3891f48be0141738d8d053e1"}, @@ -4073,6 +4339,7 @@ version = "3.9.1" description = "Natural Language Toolkit" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "nltk-3.9.1-py3-none-any.whl", hash = "sha256:4fa26829c5b00715afe3061398a8989dc643b92ce7dd93fb4585a70930d168a1"}, {file = "nltk-3.9.1.tar.gz", hash = "sha256:87d127bd3de4bd89a4f81265e5fa59cb1b199b27440175370f7417d2bc7ae868"}, @@ -4098,6 +4365,8 @@ version = "1.9.1" description = "Node.js virtual environment builder" optional = true python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +groups = ["main"] +markers = "extra == \"dev\" or extra == \"all\" or extra == \"desktop\"" files = [ {file = "nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9"}, {file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"}, @@ -4109,6 +4378,7 @@ version = "1.26.4" description = "Fundamental package for array computing in Python" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0"}, {file = "numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a"}, @@ -4154,6 +4424,7 @@ version = "1.72.0" description = "The official Python library for the openai API" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "openai-1.72.0-py3-none-any.whl", hash = "sha256:34f5496ba5c8cb06c592831d69e847e2d164526a2fb92afdc3b5cf2891c328c3"}, {file = "openai-1.72.0.tar.gz", hash = "sha256:f51de971448905cc90ed5175a5b19e92fd94e31f68cde4025762f9f5257150db"}, @@ -4180,6 +4451,7 @@ version = "1.30.0" description = "OpenTelemetry Python API" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "opentelemetry_api-1.30.0-py3-none-any.whl", hash = "sha256:d5f5284890d73fdf47f843dda3210edf37a38d66f44f2b5aedc1e89ed455dc09"}, {file = "opentelemetry_api-1.30.0.tar.gz", hash = "sha256:375893400c1435bf623f7dfb3bcd44825fe6b56c34d0667c542ea8257b1a1240"}, @@ -4195,6 +4467,7 @@ version = "1.30.0" description = "OpenTelemetry Collector Exporters" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "opentelemetry_exporter_otlp-1.30.0-py3-none-any.whl", hash = "sha256:44e11054ec571ccfed73a83c6429dee5d334d061d0e0572e3160d6de97156dbc"}, {file = "opentelemetry_exporter_otlp-1.30.0.tar.gz", hash = "sha256:da7769f95cd5be5b09dd4188ac153a33709eda652217f2d10aed6518c8e60f0d"}, @@ -4210,6 +4483,7 @@ version = "1.30.0" description = "OpenTelemetry Protobuf encoding" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "opentelemetry_exporter_otlp_proto_common-1.30.0-py3-none-any.whl", hash = "sha256:5468007c81aa9c44dc961ab2cf368a29d3475977df83b4e30aeed42aa7bc3b38"}, {file = "opentelemetry_exporter_otlp_proto_common-1.30.0.tar.gz", hash = "sha256:ddbfbf797e518411857d0ca062c957080279320d6235a279f7b64ced73c13897"}, @@ -4224,6 +4498,7 @@ version = "1.30.0" description = "OpenTelemetry Collector Protobuf over gRPC Exporter" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "opentelemetry_exporter_otlp_proto_grpc-1.30.0-py3-none-any.whl", hash = "sha256:2906bcae3d80acc54fd1ffcb9e44d324e8631058b502ebe4643ca71d1ff30830"}, {file = "opentelemetry_exporter_otlp_proto_grpc-1.30.0.tar.gz", hash = "sha256:d0f10f0b9b9a383b7d04a144d01cb280e70362cccc613987e234183fd1f01177"}, @@ -4244,6 +4519,7 @@ version = "1.30.0" description = "OpenTelemetry Collector Protobuf over HTTP Exporter" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "opentelemetry_exporter_otlp_proto_http-1.30.0-py3-none-any.whl", hash = "sha256:9578e790e579931c5ffd50f1e6975cbdefb6a0a0a5dea127a6ae87df10e0a589"}, {file = "opentelemetry_exporter_otlp_proto_http-1.30.0.tar.gz", hash = "sha256:c3ae75d4181b1e34a60662a6814d0b94dd33b628bee5588a878bed92cee6abdc"}, @@ -4264,6 +4540,7 @@ version = "0.51b0" description = "Instrumentation Tools & Auto Instrumentation for OpenTelemetry Python" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "opentelemetry_instrumentation-0.51b0-py3-none-any.whl", hash = "sha256:c6de8bd26b75ec8b0e54dff59e198946e29de6a10ec65488c357d4b34aa5bdcf"}, {file = "opentelemetry_instrumentation-0.51b0.tar.gz", hash = "sha256:4ca266875e02f3988536982467f7ef8c32a38b8895490ddce9ad9604649424fa"}, @@ -4281,6 +4558,7 @@ version = "0.51b0" description = "OpenTelemetry requests instrumentation" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "opentelemetry_instrumentation_requests-0.51b0-py3-none-any.whl", hash = "sha256:0723aaafaeb2a825723f31c0bf644f9642377046063d1a52fc86571ced87feac"}, {file = "opentelemetry_instrumentation_requests-0.51b0.tar.gz", hash = "sha256:e7f4bd3ffcab6ebcce8a1c652af218e050354c8e7cac2c34814292d4de75167a"}, @@ -4301,6 +4579,7 @@ version = "1.30.0" description = "OpenTelemetry Python Proto" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "opentelemetry_proto-1.30.0-py3-none-any.whl", hash = "sha256:c6290958ff3ddacc826ca5abbeb377a31c2334387352a259ba0df37c243adc11"}, {file = "opentelemetry_proto-1.30.0.tar.gz", hash = "sha256:afe5c9c15e8b68d7c469596e5b32e8fc085eb9febdd6fb4e20924a93a0389179"}, @@ -4315,6 +4594,7 @@ version = "1.30.0" description = "OpenTelemetry Python SDK" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "opentelemetry_sdk-1.30.0-py3-none-any.whl", hash = "sha256:14fe7afc090caad881addb6926cec967129bd9260c4d33ae6a217359f6b61091"}, {file = "opentelemetry_sdk-1.30.0.tar.gz", hash = "sha256:c9287a9e4a7614b9946e933a67168450b9ab35f08797eb9bc77d998fa480fa18"}, @@ -4331,6 +4611,7 @@ version = "0.51b0" description = "OpenTelemetry Semantic Conventions" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "opentelemetry_semantic_conventions-0.51b0-py3-none-any.whl", hash = "sha256:fdc777359418e8d06c86012c3dc92c88a6453ba662e941593adb062e48c2eeae"}, {file = "opentelemetry_semantic_conventions-0.51b0.tar.gz", hash = "sha256:3fabf47f35d1fd9aebcdca7e6802d86bd5ebc3bc3408b7e3248dde6e87a18c47"}, @@ -4346,6 +4627,7 @@ version = "0.51b0" description = "Web util for OpenTelemetry" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "opentelemetry_util_http-0.51b0-py3-none-any.whl", hash = "sha256:0561d7a6e9c422b9ef9ae6e77eafcfcd32a2ab689f5e801475cbb67f189efa20"}, {file = "opentelemetry_util_http-0.51b0.tar.gz", hash = "sha256:05edd19ca1cc3be3968b1e502fd94816901a365adbeaab6b6ddb974384d3a0b9"}, @@ -4357,6 +4639,8 @@ version = "3.10.16" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = true python-versions = ">=3.9" +groups = ["main"] +markers = "(extra == \"external-tools\" or extra == \"desktop\" or extra == \"all\") and platform_python_implementation != \"PyPy\"" files = [ {file = "orjson-3.10.16-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4cb473b8e79154fa778fb56d2d73763d977be3dcc140587e07dbc545bbfc38f8"}, {file = "orjson-3.10.16-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:622a8e85eeec1948690409a19ca1c7d9fd8ff116f4861d261e6ae2094fe59a00"}, @@ -4434,6 +4718,7 @@ version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" +groups = ["main", "dev", "dev,tests"] files = [ {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, @@ -4445,6 +4730,7 @@ version = "2.2.3" description = "Powerful data structures for data analysis, time series, and statistics" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "pandas-2.2.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1948ddde24197a0f7add2bdc4ca83bf2b1ef84a1bc8ccffd95eda17fd836ecb5"}, {file = "pandas-2.2.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:381175499d3802cde0eabbaf6324cce0c4f5d52ca6f8c377c29ad442f50f6348"}, @@ -4492,9 +4778,9 @@ files = [ [package.dependencies] numpy = [ + {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, {version = ">=1.23.2", markers = "python_version == \"3.11\""}, {version = ">=1.22.4", markers = "python_version < \"3.11\""}, - {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, ] python-dateutil = ">=2.8.2" pytz = ">=2020.1" @@ -4531,6 +4817,7 @@ version = "3.5.1" description = "SSH2 protocol library" optional = false python-versions = ">=3.6" +groups = ["main"] files = [ {file = "paramiko-3.5.1-py3-none-any.whl", hash = "sha256:43b9a0501fc2b5e70680388d9346cf252cfb7d00b0667c39e80eb43a408b8f61"}, {file = "paramiko-3.5.1.tar.gz", hash = "sha256:b2c665bc45b2b215bd7d7f039901b14b067da00f3a11e6640995fd58f2664822"}, @@ -4542,8 +4829,8 @@ cryptography = ">=3.3" pynacl = ">=1.5" [package.extras] -all = ["gssapi (>=1.4.1)", "invoke (>=2.0)", "pyasn1 (>=0.1.7)", "pywin32 (>=2.1.8)"] -gssapi = ["gssapi (>=1.4.1)", "pyasn1 (>=0.1.7)", "pywin32 (>=2.1.8)"] +all = ["gssapi (>=1.4.1) ; platform_system != \"Windows\"", "invoke (>=2.0)", "pyasn1 (>=0.1.7)", "pywin32 (>=2.1.8) ; platform_system == \"Windows\""] +gssapi = ["gssapi (>=1.4.1) ; platform_system != \"Windows\"", "pyasn1 (>=0.1.7)", "pywin32 (>=2.1.8) ; platform_system == \"Windows\""] invoke = ["invoke (>=2.0)"] [[package]] @@ -4552,10 +4839,12 @@ version = "0.8.4" description = "A Python Parser" optional = false python-versions = ">=3.6" +groups = ["main", "dev"] files = [ {file = "parso-0.8.4-py2.py3-none-any.whl", hash = "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18"}, {file = "parso-0.8.4.tar.gz", hash = "sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d"}, ] +markers = {main = "extra == \"dev\" or extra == \"all\""} [package.extras] qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] @@ -4567,6 +4856,7 @@ version = "0.12.1" description = "Utility library for gitignore style pattern matching of file paths." optional = false python-versions = ">=3.8" +groups = ["main", "dev"] files = [ {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, @@ -4578,6 +4868,7 @@ version = "3.2.3" description = "pathvalidate is a Python library to sanitize/validate a string such as filenames/file-paths/etc." optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "pathvalidate-3.2.3-py3-none-any.whl", hash = "sha256:5eaf0562e345d4b6d0c0239d0f690c3bd84d2a9a3c4c73b99ea667401b27bee1"}, {file = "pathvalidate-3.2.3.tar.gz", hash = "sha256:59b5b9278e30382d6d213497623043ebe63f10e29055be4419a9c04c721739cb"}, @@ -4594,10 +4885,12 @@ version = "4.9.0" description = "Pexpect allows easy control of interactive console applications." optional = false python-versions = "*" +groups = ["main", "dev"] files = [ {file = "pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523"}, {file = "pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f"}, ] +markers = {main = "extra == \"dev\" or extra == \"all\"", dev = "sys_platform != \"win32\" and sys_platform != \"emscripten\" or extra == \"dev\" or extra == \"all\""} [package.dependencies] ptyprocess = ">=0.5" @@ -4608,6 +4901,8 @@ version = "1.31.2" description = "PostgreSQL interface library" optional = true python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"postgres\" or extra == \"desktop\" or extra == \"all\"" files = [ {file = "pg8000-1.31.2-py3-none-any.whl", hash = "sha256:436c771ede71af4d4c22ba867a30add0bc5c942d7ab27fadbb6934a487ecc8f6"}, {file = "pg8000-1.31.2.tar.gz", hash = "sha256:1ea46cf09d8eca07fe7eaadefd7951e37bee7fabe675df164f1a572ffb300876"}, @@ -4623,6 +4918,8 @@ version = "0.2.5" description = "pgvector support for Python" optional = true python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"postgres\" or extra == \"desktop\" or extra == \"all\"" files = [ {file = "pgvector-0.2.5-py2.py3-none-any.whl", hash = "sha256:5e5e93ec4d3c45ab1fa388729d56c602f6966296e19deee8878928c6d567e41b"}, ] @@ -4636,6 +4933,7 @@ version = "11.1.0" description = "Python Imaging Library (Fork)" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "pillow-11.1.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:e1abe69aca89514737465752b4bcaf8016de61b3be1397a8fc260ba33321b3a8"}, {file = "pillow-11.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c640e5a06869c75994624551f45e5506e4256562ead981cce820d5ab39ae2192"}, @@ -4715,7 +5013,7 @@ docs = ["furo", "olefile", "sphinx (>=8.1)", "sphinx-copybutton", "sphinx-inline fpx = ["olefile"] mic = ["olefile"] tests = ["check-manifest", "coverage (>=7.4.2)", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout", "trove-classifiers (>=2024.10.12)"] -typing = ["typing-extensions"] +typing = ["typing-extensions ; python_version < \"3.10\""] xmp = ["defusedxml"] [[package]] @@ -4724,6 +5022,8 @@ version = "7.3.0" description = "Pinecone client and SDK" optional = true python-versions = "<4.0,>=3.9" +groups = ["main"] +markers = "extra == \"pinecone\" or extra == \"all\"" files = [ {file = "pinecone-7.3.0-py3-none-any.whl", hash = "sha256:315b8fef20320bef723ecbb695dec0aafa75d8434d86e01e5a0e85933e1009a8"}, {file = "pinecone-7.3.0.tar.gz", hash = "sha256:307edc155621d487c20dc71b76c3ad5d6f799569ba42064190d03917954f9a7b"}, @@ -4738,13 +5038,13 @@ pinecone-plugin-interface = ">=0.0.7,<0.0.8" python-dateutil = ">=2.5.3" typing-extensions = ">=3.7.4" urllib3 = [ - {version = ">=1.26.0", markers = "python_version >= \"3.8\" and python_version < \"3.12\""}, {version = ">=1.26.5", markers = "python_version >= \"3.12\" and python_version < \"4.0\""}, + {version = ">=1.26.0", markers = "python_version >= \"3.8\" and python_version < \"3.12\""}, ] [package.extras] asyncio = ["aiohttp (>=3.9.0)", "aiohttp-retry (>=2.9.1,<3.0.0)"] -grpc = ["googleapis-common-protos (>=1.66.0)", "grpcio (>=1.44.0)", "grpcio (>=1.59.0)", "grpcio (>=1.68.0)", "lz4 (>=3.1.3)", "protobuf (>=5.29,<6.0)", "protoc-gen-openapiv2 (>=0.0.1,<0.0.2)"] +grpc = ["googleapis-common-protos (>=1.66.0)", "grpcio (>=1.44.0) ; python_version >= \"3.8\" and python_version < \"3.11\"", "grpcio (>=1.59.0) ; python_version >= \"3.11\" and python_version < \"4.0\"", "grpcio (>=1.68.0) ; python_version >= \"3.13\" and python_version < \"4.0\"", "lz4 (>=3.1.3)", "protobuf (>=5.29,<6.0)", "protoc-gen-openapiv2 (>=0.0.1,<0.0.2)"] [[package]] name = "pinecone-plugin-assistant" @@ -4752,6 +5052,8 @@ version = "1.7.0" description = "Assistant plugin for Pinecone SDK" optional = true python-versions = "<4.0,>=3.9" +groups = ["main"] +markers = "extra == \"pinecone\" or extra == \"all\"" files = [ {file = "pinecone_plugin_assistant-1.7.0-py3-none-any.whl", hash = "sha256:864cb8e7930588e6c2da97c6d44f0240969195f43fa303c5db76cbc12bf903a5"}, {file = "pinecone_plugin_assistant-1.7.0.tar.gz", hash = "sha256:e26e3ba10a8b71c3da0d777cff407668022e82963c4913d0ffeb6c552721e482"}, @@ -4767,6 +5069,8 @@ version = "0.0.7" description = "Plugin interface for the Pinecone python client" optional = true python-versions = "<4.0,>=3.8" +groups = ["main"] +markers = "extra == \"pinecone\" or extra == \"all\"" files = [ {file = "pinecone_plugin_interface-0.0.7-py3-none-any.whl", hash = "sha256:875857ad9c9fc8bbc074dbe780d187a2afd21f5bfe0f3b08601924a61ef1bba8"}, {file = "pinecone_plugin_interface-0.0.7.tar.gz", hash = "sha256:b8e6675e41847333aa13923cc44daa3f85676d7157324682dc1640588a982846"}, @@ -4778,6 +5082,7 @@ version = "4.3.7" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.9" +groups = ["main", "dev"] files = [ {file = "platformdirs-4.3.7-py3-none-any.whl", hash = "sha256:a03875334331946f13c549dbd8f4bac7a13a50a895a0eb1e8c6a8ace80d40a94"}, {file = "platformdirs-4.3.7.tar.gz", hash = "sha256:eb437d586b6a0986388f0d6f74aa0cde27b48d0e3d66843640bfb6bdcdb6e351"}, @@ -4794,10 +5099,12 @@ version = "1.5.0" description = "plugin and hook calling mechanisms for python" optional = false python-versions = ">=3.8" +groups = ["main", "dev", "dev,tests"] files = [ {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, ] +markers = {main = "extra == \"dev\" or extra == \"all\""} [package.extras] dev = ["pre-commit", "tox"] @@ -4809,6 +5116,8 @@ version = "3.8.0" description = "A framework for managing and maintaining multi-language pre-commit hooks." optional = true python-versions = ">=3.9" +groups = ["main"] +markers = "extra == \"dev\" or extra == \"all\"" files = [ {file = "pre_commit-3.8.0-py2.py3-none-any.whl", hash = "sha256:9a90a53bf82fdd8778d58085faf8d83df56e40dfe18f45b19446e26bf1b3a63f"}, {file = "pre_commit-3.8.0.tar.gz", hash = "sha256:8bb6494d4a20423842e198980c9ecf9f96607a07ea29549e180eef9ae80fe7af"}, @@ -4827,6 +5136,7 @@ version = "3.16.0" description = "A simple Python library for easily displaying tabular data in a visually appealing ASCII table format" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "prettytable-3.16.0-py3-none-any.whl", hash = "sha256:b5eccfabb82222f5aa46b798ff02a8452cf530a352c31bddfa29be41242863aa"}, {file = "prettytable-3.16.0.tar.gz", hash = "sha256:3c64b31719d961bf69c9a7e03d0c1e477320906a98da63952bc6698d6164ff57"}, @@ -4844,6 +5154,7 @@ version = "3.0.50" description = "Library for building powerful interactive command lines in Python" optional = false python-versions = ">=3.8.0" +groups = ["main", "dev"] files = [ {file = "prompt_toolkit-3.0.50-py3-none-any.whl", hash = "sha256:9b6427eb19e479d98acff65196a307c555eb567989e6d88ebbb1b509d9779198"}, {file = "prompt_toolkit-3.0.50.tar.gz", hash = "sha256:544748f3860a2623ca5cd6d2795e7a14f3d0e1c3c9728359013f79877fc89bab"}, @@ -4858,6 +5169,7 @@ version = "0.3.1" description = "Accelerated property cache" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "propcache-0.3.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f27785888d2fdd918bc36de8b8739f2d6c791399552333721b58193f68ea3e98"}, {file = "propcache-0.3.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4e89cde74154c7b5957f87a355bb9c8ec929c167b59c83d90654ea36aeb6180"}, @@ -4965,6 +5277,7 @@ version = "5.29.4" description = "" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "protobuf-5.29.4-cp310-abi3-win32.whl", hash = "sha256:13eb236f8eb9ec34e63fc8b1d6efd2777d062fa6aaa68268fb67cf77f6839ad7"}, {file = "protobuf-5.29.4-cp310-abi3-win_amd64.whl", hash = "sha256:bcefcdf3976233f8a502d265eb65ea740c989bacc6c30a58290ed0e519eb4b8d"}, @@ -4985,6 +5298,7 @@ version = "7.0.0" description = "Cross-platform lib for process and system monitoring in Python. NOTE: the syntax of this script MUST be kept compatible with Python 2.7." optional = false python-versions = ">=3.6" +groups = ["main", "dev"] files = [ {file = "psutil-7.0.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:101d71dc322e3cffd7cea0650b09b3d08b8e7c4109dd6809fe452dfd00e58b25"}, {file = "psutil-7.0.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:39db632f6bb862eeccf56660871433e111b6ea58f2caea825571951d4b6aa3da"}, @@ -4997,6 +5311,7 @@ files = [ {file = "psutil-7.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:4cf3d4eb1aa9b348dec30105c55cd9b7d4629285735a102beb4441e38db90553"}, {file = "psutil-7.0.0.tar.gz", hash = "sha256:7be9c3eba38beccb6495ea33afd982a44074b78f28c434a1f51cc07fd315c456"}, ] +markers = {main = "extra == \"dev\" or extra == \"desktop\" or extra == \"all\""} [package.extras] dev = ["abi3audit", "black (==24.10.0)", "check-manifest", "coverage", "packaging", "pylint", "pyperf", "pypinfo", "pytest", "pytest-cov", "pytest-xdist", "requests", "rstcheck", "ruff", "setuptools", "sphinx", "sphinx_rtd_theme", "toml-sort", "twine", "virtualenv", "vulture", "wheel"] @@ -5008,6 +5323,8 @@ version = "2.9.10" description = "psycopg2 - Python-PostgreSQL Database Adapter" optional = true python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"postgres\" or extra == \"desktop\" or extra == \"all\"" files = [ {file = "psycopg2-2.9.10-cp310-cp310-win32.whl", hash = "sha256:5df2b672140f95adb453af93a7d669d7a7bf0a56bcd26f1502329166f4a61716"}, {file = "psycopg2-2.9.10-cp310-cp310-win_amd64.whl", hash = "sha256:c6f7b8561225f9e711a9c47087388a97fdc948211c10a4bccbf0ba68ab7b3b5a"}, @@ -5015,6 +5332,7 @@ files = [ {file = "psycopg2-2.9.10-cp311-cp311-win_amd64.whl", hash = "sha256:0435034157049f6846e95103bd8f5a668788dd913a7c30162ca9503fdf542cb4"}, {file = "psycopg2-2.9.10-cp312-cp312-win32.whl", hash = "sha256:65a63d7ab0e067e2cdb3cf266de39663203d38d6a8ed97f5ca0cb315c73fe067"}, {file = "psycopg2-2.9.10-cp312-cp312-win_amd64.whl", hash = "sha256:4a579d6243da40a7b3182e0430493dbd55950c493d8c68f4eec0b302f6bbf20e"}, + {file = "psycopg2-2.9.10-cp313-cp313-win_amd64.whl", hash = "sha256:91fd603a2155da8d0cfcdbf8ab24a2d54bca72795b90d2a3ed2b6da8d979dee2"}, {file = "psycopg2-2.9.10-cp39-cp39-win32.whl", hash = "sha256:9d5b3b94b79a844a986d029eee38998232451119ad653aea42bb9220a8c5066b"}, {file = "psycopg2-2.9.10-cp39-cp39-win_amd64.whl", hash = "sha256:88138c8dedcbfa96408023ea2b0c369eda40fe5d75002c0964c78f46f11fa442"}, {file = "psycopg2-2.9.10.tar.gz", hash = "sha256:12ec0b40b0273f95296233e8750441339298e6a572f7039da5b260e3c8b60e11"}, @@ -5026,6 +5344,8 @@ version = "2.9.10" description = "psycopg2 - Python-PostgreSQL Database Adapter" optional = true python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"postgres\" or extra == \"desktop\" or extra == \"all\"" files = [ {file = "psycopg2-binary-2.9.10.tar.gz", hash = "sha256:4b3df0e6990aa98acda57d983942eff13d824135fe2250e6522edaa782a06de2"}, {file = "psycopg2_binary-2.9.10-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:0ea8e3d0ae83564f2fc554955d327fa081d065c8ca5cc6d2abb643e2c9c1200f"}, @@ -5074,6 +5394,7 @@ files = [ {file = "psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:bb89f0a835bcfc1d42ccd5f41f04870c1b936d8507c6df12b7737febc40f0909"}, {file = "psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f0c2d907a1e102526dd2986df638343388b94c33860ff3bbe1384130828714b1"}, {file = "psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f8157bed2f51db683f31306aa497311b560f2265998122abe1dce6428bd86567"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-win_amd64.whl", hash = "sha256:27422aa5f11fbcd9b18da48373eb67081243662f9b46e6fd07c3eb46e4535142"}, {file = "psycopg2_binary-2.9.10-cp38-cp38-macosx_12_0_x86_64.whl", hash = "sha256:eb09aa7f9cecb45027683bb55aebaaf45a0df8bf6de68801a6afdc7947bb09d4"}, {file = "psycopg2_binary-2.9.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b73d6d7f0ccdad7bc43e6d34273f70d587ef62f824d7261c4ae9b8b1b6af90e8"}, {file = "psycopg2_binary-2.9.10-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ce5ab4bf46a211a8e924d307c1b1fcda82368586a19d0a24f8ae166f5c784864"}, @@ -5102,10 +5423,12 @@ version = "0.7.0" description = "Run a subprocess in a pseudo terminal" optional = false python-versions = "*" +groups = ["main", "dev"] files = [ {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, ] +markers = {main = "extra == \"dev\" or extra == \"all\"", dev = "sys_platform != \"win32\" and sys_platform != \"emscripten\" or extra == \"dev\" or extra == \"all\""} [[package]] name = "pure-eval" @@ -5113,10 +5436,12 @@ version = "0.2.3" description = "Safely evaluate AST nodes without side effects" optional = false python-versions = "*" +groups = ["main", "dev"] files = [ {file = "pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0"}, {file = "pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42"}, ] +markers = {main = "extra == \"dev\" or extra == \"all\""} [package.extras] tests = ["pytest"] @@ -5127,6 +5452,8 @@ version = "0.6.1" description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)" optional = true python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"google\"" files = [ {file = "pyasn1-0.6.1-py3-none-any.whl", hash = "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629"}, {file = "pyasn1-0.6.1.tar.gz", hash = "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034"}, @@ -5138,6 +5465,8 @@ version = "0.4.2" description = "A collection of ASN.1-based protocols modules" optional = true python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"google\"" files = [ {file = "pyasn1_modules-0.4.2-py3-none-any.whl", hash = "sha256:29253a9207ce32b64c3ac6600edc75368f98473906e8fd1043bd6b5b1de2c14a"}, {file = "pyasn1_modules-0.4.2.tar.gz", hash = "sha256:677091de870a80aae844b1ca6134f54652fa2c8c5a52aa396440ac3106e941e6"}, @@ -5152,10 +5481,12 @@ version = "2.22" description = "C parser in Python" optional = false python-versions = ">=3.8" +groups = ["main", "dev"] files = [ {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, ] +markers = {dev = "implementation_name == \"pypy\""} [[package]] name = "pydantic" @@ -5163,6 +5494,7 @@ version = "2.11.3" description = "Data validation using Python type hints" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "pydantic-2.11.3-py3-none-any.whl", hash = "sha256:a082753436a07f9ba1289c6ffa01cd93db3548776088aa917cc43b63f68fa60f"}, {file = "pydantic-2.11.3.tar.gz", hash = "sha256:7471657138c16adad9322fe3070c0116dd6c3ad8d649300e3cbdfe91f4db4ec3"}, @@ -5177,7 +5509,7 @@ typing-inspection = ">=0.4.0" [package.extras] email = ["email-validator (>=2.0.0)"] -timezone = ["tzdata"] +timezone = ["tzdata ; python_version >= \"3.9\" and platform_system == \"Windows\""] [[package]] name = "pydantic-core" @@ -5185,6 +5517,7 @@ version = "2.33.1" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "pydantic_core-2.33.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3077cfdb6125cc8dab61b155fdd714663e401f0e6883f9632118ec12cf42df26"}, {file = "pydantic_core-2.33.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8ffab8b2908d152e74862d276cf5017c81a2f3719f14e8e3e8d6b83fda863927"}, @@ -5296,6 +5629,7 @@ version = "2.8.1" description = "Settings management using Pydantic" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "pydantic_settings-2.8.1-py3-none-any.whl", hash = "sha256:81942d5ac3d905f7f3ee1a70df5dfb62d5569c12f51a5a647defc1c3d9ee2e9c"}, {file = "pydantic_settings-2.8.1.tar.gz", hash = "sha256:d5c663dfbe9db9d5e1c646b2e161da12f0d734d422ee56f567d0ea2cee4e8585"}, @@ -5316,6 +5650,8 @@ version = "3.3.2" description = "passive checker of Python programs" optional = true python-versions = ">=3.9" +groups = ["main"] +markers = "extra == \"dev\" or extra == \"all\"" files = [ {file = "pyflakes-3.3.2-py2.py3-none-any.whl", hash = "sha256:5039c8339cbb1944045f4ee5466908906180f13cc99cc9949348d10f82a5c32a"}, {file = "pyflakes-3.3.2.tar.gz", hash = "sha256:6dfd61d87b97fba5dcfaaf781171ac16be16453be6d816147989e7f6e6a9576b"}, @@ -5327,6 +5663,7 @@ version = "2.19.1" description = "Pygments is a syntax highlighting package written in Python." optional = false python-versions = ">=3.8" +groups = ["main", "dev"] files = [ {file = "pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c"}, {file = "pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f"}, @@ -5341,6 +5678,7 @@ version = "3.8.0" description = "🐫 Convert strings (and dictionary keys) between snake case, camel case and pascal case in Python. Inspired by Humps for Node" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "pyhumps-3.8.0-py3-none-any.whl", hash = "sha256:060e1954d9069f428232a1adda165db0b9d8dfdce1d265d36df7fbff540acfd6"}, {file = "pyhumps-3.8.0.tar.gz", hash = "sha256:498026258f7ee1a8e447c2e28526c0bea9407f9a59c03260aee4bd6c04d681a3"}, @@ -5352,6 +5690,7 @@ version = "1.5.0" description = "Python binding to the Networking and Cryptography (NaCl) library" optional = false python-versions = ">=3.6" +groups = ["main"] files = [ {file = "PyNaCl-1.5.0-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1"}, {file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92"}, @@ -5378,6 +5717,7 @@ version = "3.2.3" description = "pyparsing module - Classes and methods to define and execute parsing grammars" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "pyparsing-3.2.3-py3-none-any.whl", hash = "sha256:a749938e02d6fd0b59b356ca504a24982314bb090c383e3cf201c95ef7e2bfcf"}, {file = "pyparsing-3.2.3.tar.gz", hash = "sha256:b9c13f1ab8b3b542f72e28f634bad4de758ab3ce4546e4301970ad6fa77c38be"}, @@ -5392,6 +5732,7 @@ version = "5.4.0" description = "A pure-python PDF library capable of splitting, merging, cropping, and transforming PDF files" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "pypdf-5.4.0-py3-none-any.whl", hash = "sha256:db994ab47cadc81057ea1591b90e5b543e2b7ef2d0e31ef41a9bfe763c119dab"}, {file = "pypdf-5.4.0.tar.gz", hash = "sha256:9af476a9dc30fcb137659b0dec747ea94aa954933c52cf02ee33e39a16fe9175"}, @@ -5414,6 +5755,7 @@ version = "1.9.0" description = "A cross-platform clipboard module for Python. (Only handles plain text for now.)" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "pyperclip-1.9.0.tar.gz", hash = "sha256:b7de0142ddc81bfc5c7507eea19da920b92252b548b96186caf94a5e2527d310"}, ] @@ -5424,6 +5766,8 @@ version = "1.1.399" description = "Command line wrapper for pyright" optional = true python-versions = ">=3.7" +groups = ["main"] +markers = "extra == \"dev\" or extra == \"desktop\" or extra == \"all\"" files = [ {file = "pyright-1.1.399-py3-none-any.whl", hash = "sha256:55f9a875ddf23c9698f24208c764465ffdfd38be6265f7faf9a176e1dc549f3b"}, {file = "pyright-1.1.399.tar.gz", hash = "sha256:439035d707a36c3d1b443aec980bc37053fbda88158eded24b8eedcf1c7b7a1b"}, @@ -5444,6 +5788,7 @@ version = "1.0.8" description = "Pusher websocket client for python, based on Erik Kulyk's PythonPusherClient" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "Pysher-1.0.8.tar.gz", hash = "sha256:7849c56032b208e49df67d7bd8d49029a69042ab0bb45b2ed59fa08f11ac5988"}, ] @@ -5458,10 +5803,12 @@ version = "8.3.5" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" +groups = ["main", "dev", "dev,tests"] files = [ {file = "pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820"}, {file = "pytest-8.3.5.tar.gz", hash = "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845"}, ] +markers = {main = "extra == \"dev\" or extra == \"all\""} [package.dependencies] colorama = {version = "*", markers = "sys_platform == \"win32\""} @@ -5480,6 +5827,8 @@ version = "0.24.0" description = "Pytest support for asyncio" optional = true python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"dev\" or extra == \"all\"" files = [ {file = "pytest_asyncio-0.24.0-py3-none-any.whl", hash = "sha256:a811296ed596b69bf0b6f3dc40f83bcaf341b155a269052d82efa2b25ac7037b"}, {file = "pytest_asyncio-0.24.0.tar.gz", hash = "sha256:d081d828e576d85f875399194281e92bf8a68d60d72d1a2faf2feddb6c46b276"}, @@ -5498,6 +5847,7 @@ version = "1.5.0" description = "A pytest plugin to report test results as JSON files" optional = false python-versions = "*" +groups = ["dev,tests"] files = [ {file = "pytest-json-report-1.5.0.tar.gz", hash = "sha256:2dde3c647851a19b5f3700729e8310a6e66efb2077d674f27ddea3d34dc615de"}, {file = "pytest_json_report-1.5.0-py3-none-any.whl", hash = "sha256:9897b68c910b12a2e48dd849f9a284b2c79a732a8a9cb398452ddd23d3c8c325"}, @@ -5513,6 +5863,7 @@ version = "3.1.1" description = "pytest plugin for test session metadata" optional = false python-versions = ">=3.8" +groups = ["dev,tests"] files = [ {file = "pytest_metadata-3.1.1-py3-none-any.whl", hash = "sha256:c8e0844db684ee1c798cfa38908d20d67d0463ecb6137c72e91f418558dd5f4b"}, {file = "pytest_metadata-3.1.1.tar.gz", hash = "sha256:d2a29b0355fbc03f168aa96d41ff88b1a3b44a3b02acbe491801c98a048017c8"}, @@ -5530,6 +5881,7 @@ version = "3.14.0" description = "Thin-wrapper around the mock package for easier use with pytest" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0"}, {file = "pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f"}, @@ -5547,6 +5899,8 @@ version = "1.3.0" description = "pytest plugin to run your tests in a specific order" optional = true python-versions = ">=3.7" +groups = ["main"] +markers = "extra == \"dev\" or extra == \"all\"" files = [ {file = "pytest_order-1.3.0-py3-none-any.whl", hash = "sha256:2cd562a21380345dd8d5774aa5fd38b7849b6ee7397ca5f6999bbe6e89f07f6e"}, {file = "pytest_order-1.3.0.tar.gz", hash = "sha256:51608fec3d3ee9c0adaea94daa124a5c4c1d2bb99b00269f098f414307f23dde"}, @@ -5561,6 +5915,7 @@ version = "7.3.2" description = "Advanced Python dictionaries with dot notation access" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "python_box-7.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d136163294fd61a1554db7dd203f2e3035064798d30c17d67d948f0de5c572de"}, {file = "python_box-7.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d72e96547d8e2c2c333909826e9fae338d9a7e4cde07d5c6058cdd468432c0"}, @@ -5587,7 +5942,7 @@ msgpack = ["msgpack"] pyyaml = ["PyYAML"] ruamel-yaml = ["ruamel.yaml (>=0.17)"] toml = ["toml"] -tomli = ["tomli", "tomli-w"] +tomli = ["tomli ; python_version < \"3.11\"", "tomli-w"] yaml = ["ruamel.yaml (>=0.17)"] [[package]] @@ -5596,6 +5951,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 = ["main", "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"}, @@ -5610,6 +5966,7 @@ version = "1.1.0" description = "Read key-value pairs from a .env file and set them as environment variables" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "python_dotenv-1.1.0-py3-none-any.whl", hash = "sha256:d7c01d9e2293916c18baf562d95698754b0dbbb5e74d457c45d4f6561fb9d55d"}, {file = "python_dotenv-1.1.0.tar.gz", hash = "sha256:41f90bc6f5f177fb41f53e87666db362025010eb28f60a01c9143bfa33a2b2d5"}, @@ -5624,6 +5981,8 @@ version = "4.12.2" description = "Engine.IO server and client for Python" optional = true python-versions = ">=3.6" +groups = ["main"] +markers = "extra == \"dev\" or extra == \"desktop\" or extra == \"all\"" files = [ {file = "python_engineio-4.12.2-py3-none-any.whl", hash = "sha256:8218ab66950e179dfec4b4bbb30aecf3f5d86f5e58e6fc1aa7fde2c698b2804f"}, {file = "python_engineio-4.12.2.tar.gz", hash = "sha256:e7e712ffe1be1f6a05ee5f951e72d434854a32fcfc7f6e4d9d3cae24ec70defa"}, @@ -5643,6 +6002,7 @@ version = "0.0.19" description = "A streaming multipart parser for Python" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "python_multipart-0.0.19-py3-none-any.whl", hash = "sha256:f8d5b0b9c618575bf9df01c684ded1d94a338839bdd8223838afacfb4bb2082d"}, {file = "python_multipart-0.0.19.tar.gz", hash = "sha256:905502ef39050557b7a6af411f454bc19526529ca46ae6831508438890ce12cc"}, @@ -5654,6 +6014,8 @@ version = "5.13.0" description = "Socket.IO server and client for Python" optional = true python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"dev\" or extra == \"desktop\" or extra == \"all\"" files = [ {file = "python_socketio-5.13.0-py3-none-any.whl", hash = "sha256:51f68d6499f2df8524668c24bcec13ba1414117cfb3a90115c559b601ab10caf"}, {file = "python_socketio-5.13.0.tar.gz", hash = "sha256:ac4e19a0302ae812e23b712ec8b6427ca0521f7c582d6abb096e36e24a263029"}, @@ -5676,6 +6038,7 @@ version = "2023.4" description = "World timezone definitions, modern and historical" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "pytz-2023.4-py2.py3-none-any.whl", hash = "sha256:f90ef520d95e7c46951105338d918664ebfd6f1d995bd7d153127ce90efafa6a"}, {file = "pytz-2023.4.tar.gz", hash = "sha256:31d4583c4ed539cd037956140d695e42c033a19e984bfce9964a3f7d59bc2b40"}, @@ -5687,6 +6050,7 @@ version = "310" description = "Python for Window Extensions" optional = false python-versions = "*" +groups = ["main", "dev"] files = [ {file = "pywin32-310-cp310-cp310-win32.whl", hash = "sha256:6dd97011efc8bf51d6793a82292419eba2c71cf8e7250cfac03bba284454abc1"}, {file = "pywin32-310-cp310-cp310-win_amd64.whl", hash = "sha256:c3e78706e4229b915a0821941a84e7ef420bf2b77e08c9dae3c76fd03fd2ae3d"}, @@ -5705,6 +6069,7 @@ files = [ {file = "pywin32-310-cp39-cp39-win32.whl", hash = "sha256:851c8d927af0d879221e616ae1f66145253537bbdd321a77e8ef701b443a9a1a"}, {file = "pywin32-310-cp39-cp39-win_amd64.whl", hash = "sha256:96867217335559ac619f00ad70e513c0fcf84b8a3af9fc2bba3b59b97da70475"}, ] +markers = {main = "(extra == \"external-tools\" or extra == \"desktop\" or extra == \"all\" or extra == \"dev\") and sys_platform == \"win32\"", dev = "sys_platform == \"win32\" and platform_python_implementation != \"PyPy\""} [[package]] name = "pyyaml" @@ -5712,6 +6077,7 @@ version = "6.0.2" description = "YAML parser and emitter for Python" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, @@ -5774,6 +6140,7 @@ version = "26.4.0" description = "Python bindings for 0MQ" optional = false python-versions = ">=3.8" +groups = ["main", "dev"] files = [ {file = "pyzmq-26.4.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:0329bdf83e170ac133f44a233fc651f6ed66ef8e66693b5af7d54f45d1ef5918"}, {file = "pyzmq-26.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:398a825d2dea96227cf6460ce0a174cf7657d6f6827807d4d1ae9d0f9ae64315"}, @@ -5869,6 +6236,7 @@ files = [ {file = "pyzmq-26.4.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:49b6ca2e625b46f499fb081aaf7819a177f41eeb555acb05758aa97f4f95d147"}, {file = "pyzmq-26.4.0.tar.gz", hash = "sha256:4bd13f85f80962f91a651a7356fe0472791a5f7a92f227822b5acf44795c626d"}, ] +markers = {main = "extra == \"dev\" or extra == \"desktop\" or extra == \"all\""} [package.dependencies] cffi = {version = "*", markers = "implementation_name == \"pypy\""} @@ -5879,6 +6247,7 @@ version = "2.1.0" description = "Python library to build pretty command line user prompts ⭐️" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "questionary-2.1.0-py3-none-any.whl", hash = "sha256:44174d237b68bc828e4878c763a9ad6790ee61990e0ae72927694ead57bab8ec"}, {file = "questionary-2.1.0.tar.gz", hash = "sha256:6302cdd645b19667d8f6e6634774e9538bfcd1aad9be287e743d96cacaf95587"}, @@ -5893,6 +6262,8 @@ version = "6.2.0" description = "Python client for Redis database and key-value store" optional = true python-versions = ">=3.9" +groups = ["main"] +markers = "extra == \"redis\" or extra == \"all\"" files = [ {file = "redis-6.2.0-py3-none-any.whl", hash = "sha256:c8ddf316ee0aab65f04a11229e94a64b2618451dab7a67cb2f77eb799d872d5e"}, {file = "redis-6.2.0.tar.gz", hash = "sha256:e821f129b75dde6cb99dd35e5c76e8c49512a5a0d8dfdc560b2fbd44b85ca977"}, @@ -5912,6 +6283,7 @@ version = "0.36.2" description = "JSON Referencing + Python" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "referencing-0.36.2-py3-none-any.whl", hash = "sha256:e8699adbbf8b5c7de96d8ffa0eb5c158b3beafce084968e2ea8bb08c6794dcd0"}, {file = "referencing-0.36.2.tar.gz", hash = "sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa"}, @@ -5928,6 +6300,7 @@ version = "2024.11.6" description = "Alternative regular expression module, to replace re." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, @@ -6031,6 +6404,7 @@ version = "2.32.3" description = "Python HTTP for Humans." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, @@ -6052,6 +6426,8 @@ version = "1.0.0" description = "A utility belt for advanced users of python-requests" optional = true python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +groups = ["main"] +markers = "extra == \"external-tools\" or extra == \"desktop\" or extra == \"all\"" files = [ {file = "requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6"}, {file = "requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06"}, @@ -6066,6 +6442,7 @@ version = "13.9.4" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" optional = false python-versions = ">=3.8.0" +groups = ["main"] files = [ {file = "rich-13.9.4-py3-none-any.whl", hash = "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90"}, {file = "rich-13.9.4.tar.gz", hash = "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098"}, @@ -6085,6 +6462,7 @@ version = "0.24.0" description = "Python bindings to Rust's persistent data structures (rpds)" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "rpds_py-0.24.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:006f4342fe729a368c6df36578d7a348c7c716be1da0a1a0f86e3021f8e98724"}, {file = "rpds_py-0.24.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2d53747da70a4e4b17f559569d5f9506420966083a31c5fbd84e764461c4444b"}, @@ -6208,6 +6586,8 @@ version = "4.9" description = "Pure-Python RSA implementation" optional = true python-versions = ">=3.6,<4" +groups = ["main"] +markers = "extra == \"google\"" files = [ {file = "rsa-4.9-py3-none-any.whl", hash = "sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7"}, {file = "rsa-4.9.tar.gz", hash = "sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21"}, @@ -6222,6 +6602,8 @@ version = "0.11.3" description = "An Amazon S3 Transfer Manager" optional = true python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"bedrock\"" files = [ {file = "s3transfer-0.11.3-py3-none-any.whl", hash = "sha256:ca855bdeb885174b5ffa95b9913622459d4ad8e331fc98eb01e6d5eb6a30655d"}, {file = "s3transfer-0.11.3.tar.gz", hash = "sha256:edae4977e3a122445660c7c114bba949f9d191bae3b34a096f18a1c8c354527a"}, @@ -6239,6 +6621,8 @@ version = "1.4.5" description = "An implementation of the SCRAM protocol." optional = true python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"postgres\" or extra == \"desktop\" or extra == \"all\"" files = [ {file = "scramp-1.4.5-py3-none-any.whl", hash = "sha256:50e37c464fc67f37994e35bee4151e3d8f9320e9c204fca83a5d313c121bbbe7"}, {file = "scramp-1.4.5.tar.gz", hash = "sha256:be3fbe774ca577a7a658117dca014e5d254d158cecae3dd60332dfe33ce6d78e"}, @@ -6253,6 +6637,7 @@ version = "3.0.4" description = "Python helper for Semantic Versioning (https://semver.org)" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "semver-3.0.4-py3-none-any.whl", hash = "sha256:9c824d87ba7f7ab4a1890799cec8596f15c1241cb473404ea1cb0c55e4b04746"}, {file = "semver-3.0.4.tar.gz", hash = "sha256:afc7d8c584a5ed0a11033af086e8af226a9c0b206f313e0301f8dd7b6b589602"}, @@ -6264,6 +6649,7 @@ version = "2.19.1" description = "Python client for Sentry (https://sentry.io)" optional = false python-versions = ">=3.6" +groups = ["main"] files = [ {file = "sentry_sdk-2.19.1-py2.py3-none-any.whl", hash = "sha256:b056e04b766f805fdf0aa620482cafe2ff000c8fcb51cb266cdb90873e93837b"}, {file = "sentry_sdk-2.19.1.tar.gz", hash = "sha256:6ad8507457a379b72f832aca55787b21e7391751892faef1fd8bace350aa5e17"}, @@ -6319,6 +6705,7 @@ version = "70.3.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "setuptools-70.3.0-py3-none-any.whl", hash = "sha256:fe384da74336c398e0d956d1cae0669bc02eed936cdb1d49b57de1990dc11ffc"}, {file = "setuptools-70.3.0.tar.gz", hash = "sha256:f171bab1dfbc86b132997f26a119f6056a57950d058587841a0082e8830f9dc5"}, @@ -6326,7 +6713,7 @@ files = [ [package.extras] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.10.0)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21) ; python_version >= \"3.9\" and sys_platform != \"cygwin\"", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.10.0)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf ; sys_platform != \"cygwin\"", "pytest-ruff (>=0.3.2) ; sys_platform != \"cygwin\"", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] [[package]] name = "shellingham" @@ -6334,6 +6721,7 @@ version = "1.5.4" description = "Tool to Detect Surrounding Shell" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686"}, {file = "shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de"}, @@ -6345,6 +6733,8 @@ version = "1.1.0" description = "Simple WebSocket server and client for Python" optional = true python-versions = ">=3.6" +groups = ["main"] +markers = "extra == \"dev\" or extra == \"desktop\" or extra == \"all\"" files = [ {file = "simple_websocket-1.1.0-py3-none-any.whl", hash = "sha256:4af6069630a38ed6c561010f0e11a5bc0d4ca569b36306eb257cd9a192497c8c"}, {file = "simple_websocket-1.1.0.tar.gz", hash = "sha256:7939234e7aa067c534abdab3a9ed933ec9ce4691b0713c78acb195560aa52ae4"}, @@ -6363,6 +6753,7 @@ version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["main", "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"}, @@ -6374,6 +6765,7 @@ version = "1.3.1" description = "Sniff out which async library your code is running under" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, @@ -6385,6 +6777,7 @@ version = "2.6" description = "A modern CSS selector implementation for Beautiful Soup." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9"}, {file = "soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb"}, @@ -6396,6 +6789,7 @@ version = "2.0.41" description = "Database Abstraction Library" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "SQLAlchemy-2.0.41-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6854175807af57bdb6425e47adbce7d20a4d79bbfd6f6d6519cd10bb7109a7f8"}, {file = "SQLAlchemy-2.0.41-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05132c906066142103b83d9c250b60508af556982a385d96c4eaa9fb9720ac2b"}, @@ -6491,6 +6885,7 @@ version = "0.7.0" description = "JSON type with nested change tracking for SQLAlchemy" optional = false python-versions = ">= 3.6" +groups = ["main"] files = [ {file = "sqlalchemy-json-0.7.0.tar.gz", hash = "sha256:620d0b26f648f21a8fa9127df66f55f83a5ab4ae010e5397a5c6989a08238561"}, {file = "sqlalchemy_json-0.7.0-py3-none-any.whl", hash = "sha256:27881d662ca18363a4ac28175cc47ea2a6f2bef997ae1159c151026b741818e6"}, @@ -6508,6 +6903,7 @@ version = "0.41.2" description = "Various utility functions for SQLAlchemy." optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "SQLAlchemy-Utils-0.41.2.tar.gz", hash = "sha256:bc599c8c3b3319e53ce6c5c3c471120bd325d0071fb6f38a10e924e3d07b9990"}, {file = "SQLAlchemy_Utils-0.41.2-py3-none-any.whl", hash = "sha256:85cf3842da2bf060760f955f8467b87983fb2e30f1764fd0e24a48307dc8ec6e"}, @@ -6525,8 +6921,8 @@ intervals = ["intervals (>=0.7.1)"] password = ["passlib (>=1.6,<2.0)"] pendulum = ["pendulum (>=2.0.5)"] phone = ["phonenumbers (>=5.9.2)"] -test = ["Jinja2 (>=2.3)", "Pygments (>=1.2)", "backports.zoneinfo", "docutils (>=0.10)", "flake8 (>=2.4.0)", "flexmock (>=0.9.7)", "isort (>=4.2.2)", "pg8000 (>=1.12.4)", "psycopg (>=3.1.8)", "psycopg2 (>=2.5.1)", "psycopg2cffi (>=2.8.1)", "pymysql", "pyodbc", "pytest (==7.4.4)", "python-dateutil (>=2.6)", "pytz (>=2014.2)"] -test-all = ["Babel (>=1.3)", "Jinja2 (>=2.3)", "Pygments (>=1.2)", "arrow (>=0.3.4)", "backports.zoneinfo", "colour (>=0.0.4)", "cryptography (>=0.6)", "docutils (>=0.10)", "flake8 (>=2.4.0)", "flexmock (>=0.9.7)", "furl (>=0.4.1)", "intervals (>=0.7.1)", "isort (>=4.2.2)", "passlib (>=1.6,<2.0)", "pendulum (>=2.0.5)", "pg8000 (>=1.12.4)", "phonenumbers (>=5.9.2)", "psycopg (>=3.1.8)", "psycopg2 (>=2.5.1)", "psycopg2cffi (>=2.8.1)", "pymysql", "pyodbc", "pytest (==7.4.4)", "python-dateutil", "python-dateutil (>=2.6)", "pytz (>=2014.2)"] +test = ["Jinja2 (>=2.3)", "Pygments (>=1.2)", "backports.zoneinfo ; python_version < \"3.9\"", "docutils (>=0.10)", "flake8 (>=2.4.0)", "flexmock (>=0.9.7)", "isort (>=4.2.2)", "pg8000 (>=1.12.4)", "psycopg (>=3.1.8)", "psycopg2 (>=2.5.1)", "psycopg2cffi (>=2.8.1)", "pymysql", "pyodbc", "pytest (==7.4.4)", "python-dateutil (>=2.6)", "pytz (>=2014.2)"] +test-all = ["Babel (>=1.3)", "Jinja2 (>=2.3)", "Pygments (>=1.2)", "arrow (>=0.3.4)", "backports.zoneinfo ; python_version < \"3.9\"", "colour (>=0.0.4)", "cryptography (>=0.6)", "docutils (>=0.10)", "flake8 (>=2.4.0)", "flexmock (>=0.9.7)", "furl (>=0.4.1)", "intervals (>=0.7.1)", "isort (>=4.2.2)", "passlib (>=1.6,<2.0)", "pendulum (>=2.0.5)", "pg8000 (>=1.12.4)", "phonenumbers (>=5.9.2)", "psycopg (>=3.1.8)", "psycopg2 (>=2.5.1)", "psycopg2cffi (>=2.8.1)", "pymysql", "pyodbc", "pytest (==7.4.4)", "python-dateutil", "python-dateutil (>=2.6)", "pytz (>=2014.2)"] timezone = ["python-dateutil"] url = ["furl (>=0.4.1)"] @@ -6536,6 +6932,7 @@ version = "0.0.16" description = "SQLModel, SQL databases in Python, designed for simplicity, compatibility, and robustness." optional = false python-versions = ">=3.7,<4.0" +groups = ["main"] files = [ {file = "sqlmodel-0.0.16-py3-none-any.whl", hash = "sha256:b972f5d319580d6c37ecc417881f6ec4d1ad3ed3583d0ac0ed43234a28bf605a"}, {file = "sqlmodel-0.0.16.tar.gz", hash = "sha256:966656f18a8e9a2d159eb215b07fb0cf5222acfae3362707ca611848a8a06bd1"}, @@ -6551,6 +6948,7 @@ version = "2.2.1" description = "SSE plugin for Starlette" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "sse_starlette-2.2.1-py3-none-any.whl", hash = "sha256:6410a3d3ba0c89e7675d4c273a301d64649c03a5ef1ca101f10b47f895fd0e99"}, {file = "sse_starlette-2.2.1.tar.gz", hash = "sha256:54470d5f19274aeed6b2d473430b08b4b379ea851d953b11d7f1c4a2c118b419"}, @@ -6570,10 +6968,12 @@ version = "0.6.3" description = "Extract data from python stack frames and tracebacks for informative displays" optional = false python-versions = "*" +groups = ["main", "dev"] files = [ {file = "stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695"}, {file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"}, ] +markers = {main = "extra == \"dev\" or extra == \"all\""} [package.dependencies] asttokens = ">=2.1.0" @@ -6589,6 +6989,7 @@ version = "0.46.1" description = "The little ASGI library that shines." optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "starlette-0.46.1-py3-none-any.whl", hash = "sha256:77c74ed9d2720138b25875133f3a2dae6d854af2ec37dceb56aef370c1d8a227"}, {file = "starlette-0.46.1.tar.gz", hash = "sha256:3c88d58ee4bd1bb807c0d1acb381838afc7752f9ddaec81bbe4383611d833230"}, @@ -6606,6 +7007,7 @@ version = "0.0.26" description = "A simple library to convert rtf to text" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "striprtf-0.0.26-py3-none-any.whl", hash = "sha256:8c8f9d32083cdc2e8bfb149455aa1cc5a4e0a035893bedc75db8b73becb3a1bb"}, {file = "striprtf-0.0.26.tar.gz", hash = "sha256:fdb2bba7ac440072d1c41eab50d8d74ae88f60a8b6575c6e2c7805dc462093aa"}, @@ -6617,6 +7019,7 @@ version = "25.4.0" description = "Structured Logging for Python" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "structlog-25.4.0-py3-none-any.whl", hash = "sha256:fe809ff5c27e557d14e613f45ca441aabda051d119ee5a0102aaba6ce40eed2c"}, {file = "structlog-25.4.0.tar.gz", hash = "sha256:186cd1b0a8ae762e29417095664adf1d6a31702160a46dacb7796ea82f7409e4"}, @@ -6631,6 +7034,7 @@ version = "0.7.2" description = "Python wrapper for the Tavily API" optional = false python-versions = ">=3.6" +groups = ["main"] files = [ {file = "tavily_python-0.7.2-py3-none-any.whl", hash = "sha256:0d7cc8b1a2f95ac10cf722094c3b5807aade67cc7750f7ca605edef7455d4c62"}, {file = "tavily_python-0.7.2.tar.gz", hash = "sha256:34f713002887df2b5e6b8d7db7bc64ae107395bdb5f53611e80a89dac9cbdf19"}, @@ -6647,6 +7051,7 @@ version = "9.1.2" description = "Retry code until it succeeds" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "tenacity-9.1.2-py3-none-any.whl", hash = "sha256:f77bf36710d8b73a50b2dd155c97b870017ad21afe6ab300326b0371b3b05138"}, {file = "tenacity-9.1.2.tar.gz", hash = "sha256:1169d376c297e7de388d18b4481760d478b0e99a777cad3a9c86e556f4b697cb"}, @@ -6662,6 +7067,7 @@ version = "0.9.0" description = "tiktoken is a fast BPE tokeniser for use with OpenAI's models" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "tiktoken-0.9.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:586c16358138b96ea804c034b8acf3f5d3f0258bd2bc3b0227af4af5d622e382"}, {file = "tiktoken-0.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d9c59ccc528c6c5dd51820b3474402f69d9a9e1d656226848ad68a8d5b2e5108"}, @@ -6709,6 +7115,8 @@ version = "6.1.0" description = "A wrapper around the stdlib `tokenize` which roundtrips." optional = false python-versions = ">=3.9" +groups = ["main"] +markers = "extra == \"dev\" or extra == \"all\"" files = [ {file = "tokenize_rt-6.1.0-py2.py3-none-any.whl", hash = "sha256:d706141cdec4aa5f358945abe36b911b8cbdc844545da99e811250c0cee9b6fc"}, {file = "tokenize_rt-6.1.0.tar.gz", hash = "sha256:e8ee836616c0877ab7c7b54776d2fefcc3bde714449a206762425ae114b53c86"}, @@ -6720,6 +7128,8 @@ version = "0.10.2" description = "Python Library for Tom's Obvious, Minimal Language" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +groups = ["main"] +markers = "python_version == \"3.10\"" files = [ {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, @@ -6731,6 +7141,8 @@ version = "2.2.1" description = "A lil' TOML parser" optional = false python-versions = ">=3.8" +groups = ["main", "dev", "dev,tests"] +markers = "python_version == \"3.10\"" files = [ {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, @@ -6772,6 +7184,7 @@ version = "6.4.2" description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "tornado-6.4.2-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e828cce1123e9e44ae2a50a9de3055497ab1d0aeb440c5ac23064d9e44880da1"}, {file = "tornado-6.4.2-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:072ce12ada169c5b00b7d92a99ba089447ccc993ea2143c9ede887e0937aa803"}, @@ -6792,6 +7205,7 @@ version = "4.67.1" description = "Fast, Extensible Progress Meter" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}, {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}, @@ -6813,10 +7227,12 @@ version = "5.14.3" description = "Traitlets Python configuration system" optional = false python-versions = ">=3.8" +groups = ["main", "dev"] files = [ {file = "traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f"}, {file = "traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7"}, ] +markers = {main = "extra == \"dev\" or extra == \"all\""} [package.extras] docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] @@ -6828,6 +7244,7 @@ version = "0.15.4" description = "Typer, build great CLIs. Easy to code. Based on Python type hints." optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "typer-0.15.4-py3-none-any.whl", hash = "sha256:eb0651654dcdea706780c466cf06d8f174405a659ffff8f163cfbfee98c0e173"}, {file = "typer-0.15.4.tar.gz", hash = "sha256:89507b104f9b6a0730354f27c39fae5b63ccd0c95b1ce1f1a6ba0cfd329997c3"}, @@ -6845,10 +7262,12 @@ version = "4.13.2" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" +groups = ["main", "dev", "sqlite"] 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"}, ] +markers = {dev = "python_version < \"3.12\""} [[package]] name = "typing-inspect" @@ -6856,6 +7275,7 @@ version = "0.9.0" description = "Runtime inspection utilities for typing module." optional = false python-versions = "*" +groups = ["main"] files = [ {file = "typing_inspect-0.9.0-py3-none-any.whl", hash = "sha256:9ee6fc59062311ef8547596ab6b955e1b8aa46242d854bfc78f4f6b0eff35f9f"}, {file = "typing_inspect-0.9.0.tar.gz", hash = "sha256:b23fc42ff6f6ef6954e4852c1fb512cdd18dbea03134f91f856a95ccc9461f78"}, @@ -6871,6 +7291,7 @@ version = "0.4.0" description = "Runtime typing introspection tools" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "typing_inspection-0.4.0-py3-none-any.whl", hash = "sha256:50e72559fcd2a6367a19f7a7e610e6afcb9fac940c650290eed893d61386832f"}, {file = "typing_inspection-0.4.0.tar.gz", hash = "sha256:9765c87de36671694a67904bf2c96e395be9c6439bb6c87b5142569dcdd65122"}, @@ -6885,6 +7306,7 @@ version = "2025.2" description = "Provider of IANA time zone data" optional = false python-versions = ">=2" +groups = ["main"] files = [ {file = "tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8"}, {file = "tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9"}, @@ -6896,6 +7318,7 @@ version = "5.3.1" description = "tzinfo object for the local timezone" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "tzlocal-5.3.1-py3-none-any.whl", hash = "sha256:eb1a66c3ef5847adf7a834f1be0800581b683b5608e74f86ecbcef8ab91bb85d"}, {file = "tzlocal-5.3.1.tar.gz", hash = "sha256:cceffc7edecefea1f595541dbd6e990cb1ea3d19bf01b2809f362a03dd7921fd"}, @@ -6913,13 +7336,14 @@ version = "2.4.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "urllib3-2.4.0-py3-none-any.whl", hash = "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813"}, {file = "urllib3-2.4.0.tar.gz", hash = "sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466"}, ] [package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""] h2 = ["h2 (>=4,<5)"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] @@ -6930,6 +7354,7 @@ version = "0.24.0.post1" description = "The lightning-fast ASGI server." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "uvicorn-0.24.0.post1-py3-none-any.whl", hash = "sha256:7c84fea70c619d4a710153482c0d230929af7bcf76c7bfa6de151f0a3a80121e"}, {file = "uvicorn-0.24.0.post1.tar.gz", hash = "sha256:09c8e5a79dc466bdf28dead50093957db184de356fcdc48697bad3bde4c2588e"}, @@ -6941,7 +7366,7 @@ h11 = ">=0.8" typing-extensions = {version = ">=4.0", markers = "python_version < \"3.11\""} [package.extras] -standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"] +standard = ["colorama (>=0.4) ; sys_platform == \"win32\"", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1) ; sys_platform != \"win32\" and sys_platform != \"cygwin\" and platform_python_implementation != \"PyPy\"", "watchfiles (>=0.13)", "websockets (>=10.4)"] [[package]] name = "uvloop" @@ -6949,6 +7374,8 @@ version = "0.21.0" description = "Fast implementation of asyncio event loop on top of libuv" optional = true python-versions = ">=3.8.0" +groups = ["main"] +markers = "extra == \"experimental\" or extra == \"all\"" files = [ {file = "uvloop-0.21.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ec7e6b09a6fdded42403182ab6b832b71f4edaf7f37a9a0e371a01db5f0cb45f"}, {file = "uvloop-0.21.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:196274f2adb9689a289ad7d65700d37df0c0930fd8e4e743fa4834e850d7719d"}, @@ -7000,6 +7427,8 @@ version = "20.30.0" description = "Virtual Python Environment builder" optional = true python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"dev\" or extra == \"all\"" files = [ {file = "virtualenv-20.30.0-py3-none-any.whl", hash = "sha256:e34302959180fca3af42d1800df014b35019490b119eba981af27f2fa486e5d6"}, {file = "virtualenv-20.30.0.tar.gz", hash = "sha256:800863162bcaa5450a6e4d721049730e7f2dae07720e0902b0e4040bd6f9ada8"}, @@ -7012,7 +7441,7 @@ platformdirs = ">=3.9.1,<5" [package.extras] docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] -test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] +test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8) ; platform_python_implementation == \"PyPy\" or platform_python_implementation == \"GraalVM\" or platform_python_implementation == \"CPython\" and sys_platform == \"win32\" and python_version >= \"3.13\"", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10) ; platform_python_implementation == \"CPython\""] [[package]] name = "watchfiles" @@ -7020,6 +7449,8 @@ version = "1.0.5" description = "Simple, modern and high performance file watching and code reload in python." optional = true python-versions = ">=3.9" +groups = ["main"] +markers = "extra == \"experimental\" or extra == \"all\"" files = [ {file = "watchfiles-1.0.5-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:5c40fe7dd9e5f81e0847b1ea64e1f5dd79dd61afbedb57759df06767ac719b40"}, {file = "watchfiles-1.0.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8c0db396e6003d99bb2d7232c957b5f0b5634bbd1b24e381a5afcc880f7373fb"}, @@ -7103,6 +7534,7 @@ version = "0.2.13" description = "Measures the displayed width of unicode strings in a terminal" optional = false python-versions = "*" +groups = ["main", "dev"] files = [ {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"}, {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, @@ -7114,6 +7546,7 @@ version = "1.8.0" description = "WebSocket client for Python with low level API options" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "websocket_client-1.8.0-py3-none-any.whl", hash = "sha256:17b44cc997f5c498e809b22cdf2d9c7a9e71c02c8cc2b6c56e7c2d1239bfa526"}, {file = "websocket_client-1.8.0.tar.gz", hash = "sha256:3239df9f44da632f96012472805d40a23281a991027ce11d2f45a6f24ac4c3da"}, @@ -7130,6 +7563,8 @@ version = "15.0.1" description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" optional = false python-versions = ">=3.9" +groups = ["main"] +markers = "extra == \"google\" or extra == \"external-tools\"" files = [ {file = "websockets-15.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d63efaa0cd96cf0c5fe4d581521d9fa87744540d4bc999ae6e08595a1014b45b"}, {file = "websockets-15.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ac60e3b188ec7574cb761b08d50fcedf9d77f1530352db4eef1707fe9dee7205"}, @@ -7208,6 +7643,8 @@ version = "3.1.3" description = "The comprehensive WSGI web application library." optional = true python-versions = ">=3.9" +groups = ["main"] +markers = "extra == \"dev\" or extra == \"desktop\" or extra == \"all\"" files = [ {file = "werkzeug-3.1.3-py3-none-any.whl", hash = "sha256:54b78bf3716d19a65be4fceccc0d1d7b89e608834989dfae50ea87564639213e"}, {file = "werkzeug-3.1.3.tar.gz", hash = "sha256:60723ce945c19328679790e3282cc758aa4a6040e4bb330f53d30fa546d44746"}, @@ -7225,6 +7662,8 @@ version = "1.4.0" description = "Wikipedia API for Python" optional = true python-versions = "*" +groups = ["main"] +markers = "extra == \"external-tools\" or extra == \"tests\" or extra == \"desktop\" or extra == \"all\"" files = [ {file = "wikipedia-1.4.0.tar.gz", hash = "sha256:db0fad1829fdd441b1852306e9856398204dc0786d2996dd2e0c8bb8e26133b2"}, ] @@ -7239,6 +7678,7 @@ version = "1.17.2" description = "Module for decorators, wrappers and monkey patching." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "wrapt-1.17.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3d57c572081fed831ad2d26fd430d565b76aa277ed1d30ff4d40670b1c0dd984"}, {file = "wrapt-1.17.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b5e251054542ae57ac7f3fba5d10bfff615b6c2fb09abeb37d2f1463f841ae22"}, @@ -7327,6 +7767,8 @@ version = "1.2.0" description = "WebSockets state-machine based protocol implementation" optional = true python-versions = ">=3.7.0" +groups = ["main"] +markers = "extra == \"dev\" or extra == \"desktop\" or extra == \"all\"" files = [ {file = "wsproto-1.2.0-py3-none-any.whl", hash = "sha256:b9acddd652b585d75b20477888c56642fdade28bdfd3579aa24a4d2c037dd736"}, {file = "wsproto-1.2.0.tar.gz", hash = "sha256:ad565f26ecb92588a3e43bc3d96164de84cd9902482b130d0ddbaa9664a85065"}, @@ -7341,6 +7783,7 @@ version = "1.19.0" description = "Yet another URL library" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "yarl-1.19.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0bae32f8ebd35c04d6528cedb4a26b8bf25339d3616b04613b97347f919b76d3"}, {file = "yarl-1.19.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8015a076daf77823e7ebdcba474156587391dab4e70c732822960368c01251e6"}, @@ -7442,17 +7885,18 @@ version = "3.21.0" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "zipp-3.21.0-py3-none-any.whl", hash = "sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931"}, {file = "zipp-3.21.0.tar.gz", hash = "sha256:2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] enabler = ["pytest-enabler (>=2.2)"] -test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] +test = ["big-O", "importlib-resources ; python_version < \"3.9\"", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] type = ["pytest-mypy"] [[package]] @@ -7461,6 +7905,8 @@ version = "5.0" description = "Very basic event publishing system" optional = true python-versions = ">=3.7" +groups = ["main"] +markers = "extra == \"dev\" or extra == \"desktop\" or extra == \"all\"" files = [ {file = "zope.event-5.0-py3-none-any.whl", hash = "sha256:2832e95014f4db26c47a13fdaef84cef2f4df37e66b59d8f1f4a8f319a632c26"}, {file = "zope.event-5.0.tar.gz", hash = "sha256:bac440d8d9891b4068e2b5a2c5e2c9765a9df762944bda6955f96bb9b91e67cd"}, @@ -7479,6 +7925,8 @@ version = "7.2" description = "Interfaces for Python" optional = true python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"dev\" or extra == \"desktop\" or extra == \"all\"" files = [ {file = "zope.interface-7.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ce290e62229964715f1011c3dbeab7a4a1e4971fd6f31324c4519464473ef9f2"}, {file = "zope.interface-7.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:05b910a5afe03256b58ab2ba6288960a2892dfeef01336dc4be6f1b9ed02ab0a"}, @@ -7533,6 +7981,8 @@ version = "0.23.0" description = "Zstandard bindings for Python" optional = true python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"external-tools\" or extra == \"desktop\" or extra == \"all\"" files = [ {file = "zstandard-0.23.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bf0a05b6059c0528477fba9054d09179beb63744355cab9f38059548fedd46a9"}, {file = "zstandard-0.23.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fc9ca1c9718cb3b06634c7c8dec57d24e9438b2aa9a0f02b8bb36bf478538880"}, @@ -7655,6 +8105,6 @@ server = ["fastapi", "uvicorn"] tests = ["wikipedia"] [metadata] -lock-version = "2.0" +lock-version = "2.1" python-versions = "<3.14,>=3.10" -content-hash = "c4fa225d582dac743e5eb8a1338a71c32bd8c8eb8283dec2331c28599bdf7698" +content-hash = "78dd3924afcef62f87fc4e03a33da6fbb1dc0f4f5fee435fef9ae02018414fd5" diff --git a/pyproject.toml b/pyproject.toml index 85844190..cfedeeff 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -125,6 +125,10 @@ pytest-mock = "^3.14.0" [tool.poetry.group."dev,tests".dependencies] pytest-json-report = "^1.5.0" + +[tool.poetry.group.sqlite.dependencies] +aiosqlite = "^0.21.0" + [tool.black] line-length = 140 target-version = ['py310', 'py311', 'py312', 'py313'] diff --git a/tests/test_client_legacy.py b/tests/test_client_legacy.py index c5dc2e89..3d0c264a 100644 --- a/tests/test_client_legacy.py +++ b/tests/test_client_legacy.py @@ -236,28 +236,6 @@ def test_humans_personas(client: RESTClient, agent: AgentState): assert human.value == "Human text", "Creating human failed" -def test_list_tools_pagination(client: RESTClient): - tools = client.list_tools() - visited_ids = {t.id: False for t in tools} - - cursor = None - # Choose 3 for uneven buckets (only 7 default tools) - num_tools = 3 - # Construct a complete pagination test to see if we can return all the tools eventually - for _ in range(0, len(tools), num_tools): - curr_tools = client.list_tools(cursor, num_tools) - assert len(curr_tools) <= num_tools - - for curr_tool in curr_tools: - assert curr_tool.id in visited_ids - visited_ids[curr_tool.id] = True - - cursor = curr_tools[-1].id - - # Assert that everything has been visited - assert all(visited_ids.values()) - - def test_organization(client: RESTClient): # create an organization org_name = "test-org" diff --git a/tests/test_managers.py b/tests/test_managers.py index f4590280..b25e5c80 100644 --- a/tests/test_managers.py +++ b/tests/test_managers.py @@ -119,6 +119,13 @@ async def async_session(): @pytest.fixture(autouse=True) async def _clear_tables(async_session): + from sqlalchemy import text + + # Temporarily disable foreign key constraints for SQLite only + engine_name = async_session.bind.dialect.name + if engine_name == "sqlite": + await async_session.execute(text("PRAGMA foreign_keys = OFF")) + for table in reversed(Base.metadata.sorted_tables): # Reverse to avoid FK issues # If this is the block_history table, skip it if table.name == "block_history": @@ -126,6 +133,10 @@ async def _clear_tables(async_session): await async_session.execute(table.delete()) # Truncate table await async_session.commit() + # Re-enable foreign key constraints for SQLite only + if engine_name == "sqlite": + await async_session.execute(text("PRAGMA foreign_keys = ON")) + @pytest.fixture async def default_organization(server: SyncServer): @@ -1667,6 +1678,12 @@ async def test_list_agents_by_tags_pagination(server: SyncServer, default_user, @pytest.mark.asyncio +@pytest.mark.skipif( + not hasattr(__import__("letta.settings"), "settings") + or not getattr(__import__("letta.settings").settings, "letta_pg_uri_no_default", None) + or USING_SQLITE, + reason="Skipping vector-related tests when using SQLite (vector search requires PostgreSQL)", +) async def test_list_agents_query_text_pagination(server: SyncServer, default_user, default_organization, event_loop): """Test listing agents with query text filtering and pagination.""" # Create test agents with specific names and descriptions @@ -2264,6 +2281,11 @@ async def test_agent_list_passages_filtering(server, default_user, sarah_agent, @pytest.mark.asyncio +@pytest.mark.skipif( + not hasattr(__import__("letta.settings"), "settings") + or not getattr(__import__("letta.settings").settings, "letta_pg_uri_no_default", None), + reason="Skipping vector-related tests when using SQLite (vector search requires PostgreSQL)", +) async def test_agent_list_passages_vector_search(server, default_user, sarah_agent, default_source, default_file, event_loop): """Test vector search functionality of agent passages""" embed_model = embedding_model(DEFAULT_EMBEDDING_CONFIG) @@ -2501,11 +2523,6 @@ async def test_passage_cascade_deletion( agentic_passages = await server.agent_manager.list_passages_async(actor=default_user, agent_id=sarah_agent.id, agent_only=True) assert len(agentic_passages) == 0 - # Delete source and verify its passages are deleted - await server.source_manager.delete_source(default_source.id, default_user) - with pytest.raises(NoResultFound): - server.passage_manager.get_passage_by_id(source_passage_fixture.id, default_user) - def test_create_agent_passage_specific(server: SyncServer, default_user, sarah_agent): """Test creating an agent passage using the new agent-specific method.""" @@ -5443,7 +5460,7 @@ async def test_upsert_file_content_basic(server: SyncServer, default_user, defau # Ensure `updated_at` is bumped orm_file = await async_session.get(FileMetadataModel, created.id) - assert orm_file.updated_at > orm_file.created_at + assert orm_file.updated_at >= orm_file.created_at @pytest.mark.asyncio @@ -5811,6 +5828,7 @@ async def test_list_jobs(server: SyncServer, default_user, event_loop): assert all(job.metadata["type"].startswith("test") for job in jobs) +@pytest.mark.asyncio async def test_list_jobs_with_metadata(server: SyncServer, default_user, event_loop): for i in range(3): job_data = PydanticJob(status=JobStatus.created, metadata={"source_id": f"source-test-{i}"}) @@ -6681,7 +6699,12 @@ async def test_update_batch_status(server, default_user, dummy_beta_message_batc updated = await server.batch_manager.get_llm_batch_job_by_id_async(batch.id, actor=default_user) assert updated.status == JobStatus.completed assert updated.latest_polling_response == dummy_beta_message_batch - assert updated.last_polled_at >= before + + # Handle timezone comparison: if last_polled_at is naive, assume it's UTC + last_polled_at = updated.last_polled_at + if last_polled_at.tzinfo is None: + last_polled_at = last_polled_at.replace(tzinfo=timezone.utc) + assert last_polled_at >= before @pytest.mark.asyncio @@ -6805,13 +6828,24 @@ async def test_list_running_batches(server, default_user, dummy_beta_message_bat recent_batches = await server.batch_manager.list_running_llm_batches_async(actor=default_user, weeks=1) assert len(recent_batches) == num_running assert all(batch.status == JobStatus.running for batch in recent_batches) - assert all(batch.created_at >= datetime.now(timezone.utc) - timedelta(weeks=1) for batch in recent_batches) + + # Handle timezone comparison: if created_at is naive, assume it's UTC + cutoff_time = datetime.now(timezone.utc) - timedelta(weeks=1) + assert all( + (batch.created_at.replace(tzinfo=timezone.utc) if batch.created_at.tzinfo is None else batch.created_at) >= cutoff_time + for batch in recent_batches + ) # Filter by size recent_batches = await server.batch_manager.list_running_llm_batches_async(actor=default_user, weeks=1, batch_size=2) assert len(recent_batches) == 2 assert all(batch.status == JobStatus.running for batch in recent_batches) - assert all(batch.created_at >= datetime.now(timezone.utc) - timedelta(weeks=1) for batch in recent_batches) + # Handle timezone comparison: if created_at is naive, assume it's UTC + cutoff_time = datetime.now(timezone.utc) - timedelta(weeks=1) + assert all( + (batch.created_at.replace(tzinfo=timezone.utc) if batch.created_at.tzinfo is None else batch.created_at) >= cutoff_time + for batch in recent_batches + ) # Should return nothing if filtering by a very small timeframe (e.g., 0 weeks) future_batches = await server.batch_manager.list_running_llm_batches_async(actor=default_user, weeks=0) diff --git a/tests/test_sources.py b/tests/test_sources.py index 758fc368..12effb2f 100644 --- a/tests/test_sources.py +++ b/tests/test_sources.py @@ -468,6 +468,11 @@ def test_agent_uses_open_close_file_correctly(disable_pinecone, client: LettaSDK print("✓ File successfully opened with different range - content differs as expected") +@pytest.mark.skipif( + not hasattr(__import__("letta.settings"), "settings") + or not getattr(__import__("letta.settings").settings, "letta_pg_uri_no_default", None), + reason="Skipping vector-related tests when using SQLite (vector search requires PostgreSQL)", +) def test_agent_uses_search_files_correctly(disable_pinecone, client: LettaSDKClient, agent_state: AgentState): # Create a new source source = client.sources.create(name="test_source", embedding="openai/text-embedding-3-small") @@ -839,6 +844,11 @@ def test_open_files_schema_descriptions(disable_pinecone, client: LettaSDKClient # --- Pinecone Tests --- +@pytest.mark.skipif( + not hasattr(__import__("letta.settings"), "settings") + or not getattr(__import__("letta.settings").settings, "letta_pg_uri_no_default", None), + reason="Skipping vector-related tests when using SQLite (vector search requires PostgreSQL)", +) def test_pinecone_search_files_tool(client: LettaSDKClient): """Test that search_files tool uses Pinecone when enabled""" from letta.helpers.pinecone_utils import should_use_pinecone @@ -890,6 +900,11 @@ def test_pinecone_search_files_tool(client: LettaSDKClient): ), f"Search results should contain relevant content: {search_results}" +@pytest.mark.skipif( + not hasattr(__import__("letta.settings"), "settings") + or not getattr(__import__("letta.settings").settings, "letta_pg_uri_no_default", None), + reason="Skipping vector-related tests when using SQLite (vector search requires PostgreSQL)", +) def test_pinecone_lifecycle_file_and_source_deletion(client: LettaSDKClient): """Test that file and source deletion removes records from Pinecone""" import asyncio