hammad-python 0.0.15__tar.gz → 0.0.16__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {hammad_python-0.0.15 → hammad_python-0.0.16}/PKG-INFO +8 -1
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/data/collections/collection.py +24 -10
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/data/collections/indexes/qdrant/index.py +228 -32
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/data/sql/types.py +5 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/genai/__init__.py +33 -0
- hammad_python-0.0.16/hammad/genai/agents/__init__.py +1 -0
- hammad_python-0.0.16/hammad/genai/agents/types/__init__.py +35 -0
- hammad_python-0.0.16/hammad/genai/agents/types/history.py +277 -0
- hammad_python-0.0.16/hammad/genai/agents/types/tool.py +490 -0
- hammad_python-0.0.16/hammad/genai/language_models/_streaming.py +622 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/genai/language_models/_utils/_requests.py +24 -2
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/genai/language_models/_utils/_structured_outputs.py +4 -2
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/genai/language_models/language_model.py +157 -19
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/genai/language_models/language_model_request.py +13 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/genai/language_models/language_model_response.py +0 -1
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/genai/language_models/run.py +33 -1
- hammad_python-0.0.16/hammad/genai/multimodal_models.py +48 -0
- hammad_python-0.0.16/hammad/genai/rerank_models.py +26 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/pyproject.toml +10 -2
- {hammad_python-0.0.15 → hammad_python-0.0.16}/uv.lock +1 -1
- hammad_python-0.0.15/hammad/genai/language_models/_streaming.py +0 -368
- {hammad_python-0.0.15 → hammad_python-0.0.16}/.gitignore +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/.python-version +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/LICENSE +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/README.md +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/ai/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/ai/_utils.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/ai/completions/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/ai/completions/client.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/ai/completions/create.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/ai/completions/settings.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/ai/completions/types.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/ai/completions/utils.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/ai/embeddings/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/ai/embeddings/client/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/ai/embeddings/client/base_embeddings_client.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/ai/embeddings/client/fastembed_text_embeddings_client.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/ai/embeddings/client/litellm_embeddings_client.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/ai/embeddings/create.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/ai/embeddings/types.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/cache/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/cache/base_cache.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/cache/cache.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/cache/decorators.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/cache/file_cache.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/cache/ttl_cache.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/cli/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/cli/animations.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/cli/plugins.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/cli/styles/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/cli/styles/settings.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/cli/styles/types.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/cli/styles/utils.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/data/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/data/collections/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/data/collections/base_collection.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/data/collections/collection.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/data/collections/searchable_collection.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/data/collections/vector_collection.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/data/configurations/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/data/configurations/configuration.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/data/databases/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/data/databases/database.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/data/models/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/data/models/base/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/data/models/base/fields.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/data/models/base/model.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/data/models/base/utils.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/data/models/pydantic/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/data/models/pydantic/converters.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/data/models/pydantic/models/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/data/models/pydantic/models/arbitrary_model.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/data/models/pydantic/models/cacheable_model.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/data/models/pydantic/models/fast_model.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/data/models/pydantic/models/function_model.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/data/models/pydantic/models/subscriptable_model.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/data/types/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/data/types/file.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/data/types/multimodal/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/data/types/multimodal/audio.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/data/types/multimodal/image.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/data/types/text.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/formatting/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/formatting/json/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/formatting/json/converters.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/formatting/text/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/formatting/text/converters.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/formatting/text/markdown.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/formatting/yaml/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/formatting/yaml/converters.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/logging/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/logging/decorators.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/logging/logger.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/mcp/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/mcp/client/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/mcp/client/client.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/mcp/client/client_service.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/mcp/client/settings.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/mcp/servers/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/mcp/servers/launcher.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/performance/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/performance/imports.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/performance/runtime/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/performance/runtime/decorators.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/performance/runtime/run.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/py.typed +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/service/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/service/create.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/service/decorators.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/typing/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/web/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/web/http/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/web/http/client.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/web/models.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/web/openapi/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/web/openapi/client.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/web/search/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/web/search/client.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/hammad/web/utils.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/tests/ai/completions/test_ai_completions_create.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/tests/ai/completions/test_ai_completions_types.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/tests/cache/test_performance_cache.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/tests/cli/test_cli_plugins_animate.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/tests/cli/test_cli_plugins_input.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/tests/cli/test_cli_plugins_print.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/tests/cli/test_cli_styles_utils.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/tests/data/collections/test_data_collections_searchable_collection.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/tests/data/collections/test_data_collections_vector_collection.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/tests/data/configuration/test_data_configuration.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/tests/data/databases/test_data_databases_database.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/tests/data/models/base/test_data_models_base_fields.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/tests/data/models/base/test_data_models_base_model.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/tests/data/models/pydantic/test_models_pydantic_converters.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/tests/data/models/pydantic/test_models_pydantic_models.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/tests/data/types/test_data_types_text.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/tests/formatting/json/test_json_converters.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/tests/formatting/text/test_text_utils_converters.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/tests/formatting/text/test_text_utils_markdown_converters.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/tests/logging/test_logging_decorators.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/tests/logging/test_logging_logger.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/tests/mcp/test_mcp_client_services.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/tests/mcp/test_mcp_server_services.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/tests/performance/runtime/test_performance_runtime_decorators.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/tests/performance/runtime/test_performance_runtime_run.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/tests/service/test_service_create_service.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/tests/service/test_service_serve_decorator.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/tests/service/test_service_serve_mcp_decorator.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/tests/typing/test_typing_utils.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/tests/web/test_web_toolkits_http_toolkit.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/tests/web/test_web_toolkits_openapi_toolkit.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/deprecated/tests/web/test_web_utils.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/_internal.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/cache/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/cache/base_cache.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/cache/cache.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/cache/decorators.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/cache/file_cache.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/cache/ttl_cache.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/cli/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/cli/_runner.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/cli/animations.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/cli/plugins.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/cli/styles/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/cli/styles/settings.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/cli/styles/types.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/cli/styles/utils.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/data/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/data/collections/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/data/collections/indexes/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/data/collections/indexes/qdrant/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/data/collections/indexes/qdrant/settings.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/data/collections/indexes/qdrant/utils.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/data/collections/indexes/tantivy/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/data/collections/indexes/tantivy/index.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/data/collections/indexes/tantivy/settings.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/data/collections/indexes/tantivy/utils.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/data/configurations/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/data/configurations/configuration.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/data/models/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/data/models/extensions/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/data/models/extensions/pydantic/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/data/models/extensions/pydantic/converters.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/data/models/fields.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/data/models/model.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/data/models/utils.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/data/sql/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/data/sql/database.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/data/types/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/data/types/file.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/data/types/multimodal/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/data/types/multimodal/audio.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/data/types/multimodal/image.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/data/types/text.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/formatting/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/formatting/json/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/formatting/json/converters.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/formatting/text/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/formatting/text/converters.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/formatting/text/markdown.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/formatting/yaml/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/formatting/yaml/converters.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/genai/embedding_models/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/genai/embedding_models/embedding_model.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/genai/embedding_models/embedding_model_name.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/genai/embedding_models/embedding_model_request.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/genai/embedding_models/embedding_model_response.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/genai/embedding_models/run.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/genai/language_models/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/genai/language_models/_types.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/genai/language_models/_utils/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/genai/language_models/_utils/_completions.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/genai/language_models/_utils/_messages.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/genai/language_models/language_model_response_chunk.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/logging/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/logging/decorators.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/logging/logger.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/mcp/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/mcp/client/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/mcp/client/client.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/mcp/client/client_service.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/mcp/client/settings.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/mcp/servers/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/mcp/servers/launcher.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/runtime/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/runtime/decorators.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/runtime/run.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/service/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/service/create.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/service/decorators.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/typing/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/web/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/web/http/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/web/http/client.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/web/models.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/web/openapi/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/web/openapi/client.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/web/search/__init__.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/web/search/client.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/web/utils.py +0 -0
- {hammad_python-0.0.15 → hammad_python-0.0.16}/mkdocs.yml +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: hammad-python
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.16
|
4
4
|
Author-email: Hammad Saeed <hammadaidev@gmail.com>
|
5
5
|
License: MIT License
|
6
6
|
|
@@ -39,6 +39,13 @@ Provides-Extra: ai
|
|
39
39
|
Requires-Dist: instructor>=1.9.0; extra == 'ai'
|
40
40
|
Requires-Dist: litellm>=1.73.6; extra == 'ai'
|
41
41
|
Requires-Dist: qdrant-client>=1.14.3; extra == 'ai'
|
42
|
+
Provides-Extra: all
|
43
|
+
Requires-Dist: fastapi>=0.115.6; extra == 'all'
|
44
|
+
Requires-Dist: instructor>=1.9.0; extra == 'all'
|
45
|
+
Requires-Dist: litellm>=1.73.6; extra == 'all'
|
46
|
+
Requires-Dist: mcp>=1.10.1; extra == 'all'
|
47
|
+
Requires-Dist: qdrant-client>=1.14.3; extra == 'all'
|
48
|
+
Requires-Dist: uvicorn>=0.34.0; extra == 'all'
|
42
49
|
Provides-Extra: mcp
|
43
50
|
Requires-Dist: mcp>=1.10.1; extra == 'mcp'
|
44
51
|
Provides-Extra: serve
|
@@ -17,7 +17,7 @@ from pathlib import Path
|
|
17
17
|
|
18
18
|
if TYPE_CHECKING:
|
19
19
|
from .indexes.tantivy.index import TantivyCollectionIndex
|
20
|
-
from .indexes.qdrant.index import QdrantCollectionIndex
|
20
|
+
from .indexes.qdrant.index import QdrantCollectionIndex, VectorSearchResult
|
21
21
|
from .indexes.tantivy.settings import (
|
22
22
|
TantivyCollectionIndexSettings,
|
23
23
|
TantivyCollectionIndexQuerySettings,
|
@@ -31,11 +31,12 @@ if TYPE_CHECKING:
|
|
31
31
|
from ...genai.embedding_models.embedding_model_name import EmbeddingModelName
|
32
32
|
else:
|
33
33
|
from .indexes.tantivy.index import TantivyCollectionIndex
|
34
|
-
from .indexes.qdrant.index import QdrantCollectionIndex
|
34
|
+
from .indexes.qdrant.index import QdrantCollectionIndex, VectorSearchResult
|
35
35
|
|
36
36
|
|
37
37
|
__all__ = (
|
38
38
|
"Collection",
|
39
|
+
"VectorSearchResult",
|
39
40
|
)
|
40
41
|
|
41
42
|
|
@@ -76,16 +77,20 @@ class Collection:
|
|
76
77
|
schema: Optional[Type["DatabaseItemType"]] = None,
|
77
78
|
ttl: Optional[int] = None,
|
78
79
|
path: Optional[Union[Path, str]] = None,
|
79
|
-
vector: Literal[True],
|
80
|
-
vector_size: int,
|
80
|
+
vector: Literal[True] = True,
|
81
|
+
vector_size: Optional[int] = None,
|
81
82
|
# Vector/Qdrant-specific parameters
|
82
83
|
distance_metric: "DistanceMetric" = "dot",
|
83
84
|
settings: Optional["QdrantCollectionIndexSettings"] = None,
|
84
85
|
query_settings: Optional["QdrantCollectionIndexQuerySettings"] = None,
|
85
|
-
embedding_model: Optional["EmbeddingModelName"] =
|
86
|
+
embedding_model: Optional["EmbeddingModelName"] = "openai/text-embedding-3-small",
|
86
87
|
embedding_dimensions: Optional[int] = None,
|
87
88
|
embedding_api_key: Optional[str] = None,
|
88
89
|
embedding_base_url: Optional[str] = None,
|
90
|
+
# Rerank-specific parameters
|
91
|
+
rerank_model: Optional[str] = None,
|
92
|
+
rerank_api_key: Optional[str] = None,
|
93
|
+
rerank_base_url: Optional[str] = None,
|
89
94
|
) -> "QdrantCollectionIndex": ...
|
90
95
|
|
91
96
|
def __new__(
|
@@ -104,10 +109,14 @@ class Collection:
|
|
104
109
|
query_settings: Optional[Union["TantivyCollectionIndexQuerySettings", "QdrantCollectionIndexQuerySettings"]] = None,
|
105
110
|
# Vector/Qdrant-specific parameters
|
106
111
|
distance_metric: "DistanceMetric" = "dot",
|
107
|
-
embedding_model: Optional["EmbeddingModelName"] =
|
112
|
+
embedding_model: Optional["EmbeddingModelName"] = "openai/text-embedding-3-small",
|
108
113
|
embedding_dimensions: Optional[int] = None,
|
109
114
|
embedding_api_key: Optional[str] = None,
|
110
115
|
embedding_base_url: Optional[str] = None,
|
116
|
+
# Rerank-specific parameters
|
117
|
+
rerank_model: Optional[str] = None,
|
118
|
+
rerank_api_key: Optional[str] = None,
|
119
|
+
rerank_base_url: Optional[str] = None,
|
111
120
|
) -> Union["TantivyCollectionIndex", "QdrantCollectionIndex"]:
|
112
121
|
"""
|
113
122
|
Create a collection of the specified type.
|
@@ -134,14 +143,16 @@ class Collection:
|
|
134
143
|
embedding_api_key: API key for the embedding service
|
135
144
|
embedding_base_url: Base URL for the embedding service
|
136
145
|
|
146
|
+
# Rerank parameters (for vector collections):
|
147
|
+
rerank_model: The rerank model to use (e.g., 'cohere/rerank-english-v3.0')
|
148
|
+
rerank_api_key: API key for the rerank service
|
149
|
+
rerank_base_url: Base URL for the rerank service
|
150
|
+
|
137
151
|
Returns:
|
138
152
|
A TantivyCollectionIndex or QdrantCollectionIndex instance
|
139
153
|
"""
|
140
154
|
if vector:
|
141
155
|
# Vector collection using Qdrant
|
142
|
-
if vector_size is None:
|
143
|
-
raise ValueError("vector_size is required for vector collections")
|
144
|
-
|
145
156
|
return QdrantCollectionIndex(
|
146
157
|
name=name,
|
147
158
|
vector_size=vector_size,
|
@@ -155,6 +166,9 @@ class Collection:
|
|
155
166
|
embedding_dimensions=embedding_dimensions,
|
156
167
|
embedding_api_key=embedding_api_key,
|
157
168
|
embedding_base_url=embedding_base_url,
|
169
|
+
rerank_model=rerank_model,
|
170
|
+
rerank_api_key=rerank_api_key,
|
171
|
+
rerank_base_url=rerank_base_url,
|
158
172
|
)
|
159
173
|
else:
|
160
174
|
# Text search collection using Tantivy
|
@@ -191,7 +205,7 @@ def create_collection(
|
|
191
205
|
ttl: Optional[int] = None,
|
192
206
|
path: Optional[Union[Path, str]] = None,
|
193
207
|
vector: Literal[True],
|
194
|
-
vector_size: int,
|
208
|
+
vector_size: Optional[int] = None,
|
195
209
|
# Vector/Qdrant-specific parameters
|
196
210
|
distance_metric: "DistanceMetric" = "dot",
|
197
211
|
settings: Optional["QdrantCollectionIndexSettings"] = None,
|
{hammad_python-0.0.15 → hammad_python-0.0.16}/hammad/data/collections/indexes/qdrant/index.py
RENAMED
@@ -10,12 +10,14 @@ from typing import (
|
|
10
10
|
Type,
|
11
11
|
Union,
|
12
12
|
final,
|
13
|
-
TYPE_CHECKING
|
13
|
+
TYPE_CHECKING,
|
14
|
+
Tuple,
|
15
|
+
NamedTuple
|
14
16
|
)
|
15
17
|
|
16
18
|
if TYPE_CHECKING:
|
17
19
|
from .....genai.embedding_models.embedding_model_name import EmbeddingModelName
|
18
|
-
import uuid
|
20
|
+
# import uuid # Unused import
|
19
21
|
from pathlib import Path
|
20
22
|
import json
|
21
23
|
|
@@ -32,8 +34,15 @@ from .settings import (
|
|
32
34
|
DistanceMetric,
|
33
35
|
)
|
34
36
|
|
37
|
+
class VectorSearchResult(NamedTuple):
|
38
|
+
"""Result from vector search containing item and similarity score."""
|
39
|
+
item: 'DatabaseItem[DatabaseItemType]'
|
40
|
+
score: float
|
41
|
+
|
42
|
+
|
35
43
|
__all__ = (
|
36
44
|
"QdrantCollectionIndex",
|
45
|
+
"VectorSearchResult",
|
37
46
|
)
|
38
47
|
|
39
48
|
|
@@ -51,7 +60,7 @@ class QdrantCollectionIndex:
|
|
51
60
|
self,
|
52
61
|
*,
|
53
62
|
name: str = "default",
|
54
|
-
vector_size: int =
|
63
|
+
vector_size: Optional[int] = None,
|
55
64
|
schema: Optional[Type[DatabaseItemType]] = None,
|
56
65
|
ttl: Optional[int] = None,
|
57
66
|
path: Optional[Path | str] = None,
|
@@ -62,6 +71,9 @@ class QdrantCollectionIndex:
|
|
62
71
|
embedding_dimensions: Optional[int] = None,
|
63
72
|
embedding_api_key: Optional[str] = None,
|
64
73
|
embedding_base_url: Optional[str] = None,
|
74
|
+
rerank_model: Optional[str] = None,
|
75
|
+
rerank_api_key: Optional[str] = None,
|
76
|
+
rerank_base_url: Optional[str] = None,
|
65
77
|
) -> None:
|
66
78
|
"""
|
67
79
|
Initialize a new QdrantCollectionIndex.
|
@@ -79,9 +91,13 @@ class QdrantCollectionIndex:
|
|
79
91
|
embedding_dimensions: Number of dimensions for embeddings.
|
80
92
|
embedding_api_key: API key for the embedding service.
|
81
93
|
embedding_base_url: Base URL for the embedding service.
|
94
|
+
rerank_model: The rerank model to use (e.g., 'cohere/rerank-english-v3.0').
|
95
|
+
rerank_api_key: API key for the rerank service.
|
96
|
+
rerank_base_url: Base URL for the rerank service.
|
82
97
|
"""
|
83
98
|
self.name = name
|
84
99
|
self.vector_size = vector_size
|
100
|
+
self._vector_size_determined = vector_size is not None
|
85
101
|
self.schema = schema
|
86
102
|
self.ttl = ttl
|
87
103
|
self.embedding_model = embedding_model
|
@@ -89,6 +105,11 @@ class QdrantCollectionIndex:
|
|
89
105
|
self.embedding_api_key = embedding_api_key
|
90
106
|
self.embedding_base_url = embedding_base_url
|
91
107
|
self._embedding_function = None
|
108
|
+
|
109
|
+
# Rerank model configuration
|
110
|
+
self.rerank_model = rerank_model
|
111
|
+
self.rerank_api_key = rerank_api_key
|
112
|
+
self.rerank_base_url = rerank_base_url
|
92
113
|
|
93
114
|
if path is not None and not isinstance(path, Path):
|
94
115
|
path = Path(path)
|
@@ -102,7 +123,7 @@ class QdrantCollectionIndex:
|
|
102
123
|
qdrant_path = str(self.path / f"{name}_qdrant")
|
103
124
|
|
104
125
|
settings = QdrantCollectionIndexSettings(
|
105
|
-
vector_size=vector_size,
|
126
|
+
vector_size=vector_size or 768, # Default fallback
|
106
127
|
distance_metric=distance_metric,
|
107
128
|
path=qdrant_path,
|
108
129
|
)
|
@@ -129,7 +150,9 @@ class QdrantCollectionIndex:
|
|
129
150
|
# Initialize Qdrant client (lazily to handle import errors gracefully)
|
130
151
|
self._client = None
|
131
152
|
self._client_wrapper = None
|
132
|
-
|
153
|
+
# Only initialize if vector_size is determined
|
154
|
+
if self._vector_size_determined:
|
155
|
+
self._init_qdrant_client()
|
133
156
|
|
134
157
|
def _init_qdrant_client(self) -> None:
|
135
158
|
"""Initialize Qdrant client and collection."""
|
@@ -178,15 +201,84 @@ class QdrantCollectionIndex:
|
|
178
201
|
|
179
202
|
return self._embedding_function
|
180
203
|
|
204
|
+
def _rerank_results(
|
205
|
+
self,
|
206
|
+
query: str,
|
207
|
+
results: List[Tuple[DatabaseItem[DatabaseItemType], float]],
|
208
|
+
top_n: Optional[int] = None
|
209
|
+
) -> List[Tuple[DatabaseItem[DatabaseItemType], float]]:
|
210
|
+
"""
|
211
|
+
Rerank search results using the configured rerank model.
|
212
|
+
|
213
|
+
Args:
|
214
|
+
query: The original search query
|
215
|
+
results: List of (DatabaseItem, similarity_score) tuples
|
216
|
+
top_n: Number of top results to return after reranking
|
217
|
+
|
218
|
+
Returns:
|
219
|
+
Reranked list of (DatabaseItem, rerank_score) tuples
|
220
|
+
"""
|
221
|
+
if not self.rerank_model or not results:
|
222
|
+
return results
|
223
|
+
|
224
|
+
try:
|
225
|
+
from .....genai.rerank_models import run_rerank_model
|
226
|
+
|
227
|
+
# Extract documents for reranking
|
228
|
+
documents = []
|
229
|
+
for db_item, _ in results:
|
230
|
+
# Convert item to string for reranking
|
231
|
+
if isinstance(db_item.item, dict):
|
232
|
+
doc_text = json.dumps(db_item.item)
|
233
|
+
else:
|
234
|
+
doc_text = str(db_item.item)
|
235
|
+
documents.append(doc_text)
|
236
|
+
|
237
|
+
# Perform reranking
|
238
|
+
rerank_response = run_rerank_model(
|
239
|
+
model=self.rerank_model,
|
240
|
+
query=query,
|
241
|
+
documents=documents,
|
242
|
+
top_n=top_n or len(results),
|
243
|
+
api_key=self.rerank_api_key,
|
244
|
+
api_base=self.rerank_base_url
|
245
|
+
)
|
246
|
+
|
247
|
+
# Reorder results based on rerank scores
|
248
|
+
reranked_results = []
|
249
|
+
for rerank_result in rerank_response.results:
|
250
|
+
original_index = rerank_result.index
|
251
|
+
rerank_score = rerank_result.relevance_score
|
252
|
+
db_item = results[original_index][0]
|
253
|
+
# Update the score on the DatabaseItem itself
|
254
|
+
db_item.score = rerank_score
|
255
|
+
reranked_results.append((db_item, rerank_score))
|
256
|
+
|
257
|
+
return reranked_results
|
258
|
+
|
259
|
+
except Exception:
|
260
|
+
# If reranking fails, return original results
|
261
|
+
return results
|
262
|
+
|
181
263
|
def _prepare_vector(self, item: Any) -> List[float]:
|
182
264
|
"""Prepare vector from item using embedding function or direct vector."""
|
183
265
|
embedding_function = self._get_embedding_function()
|
184
266
|
if embedding_function:
|
185
|
-
|
267
|
+
vector = embedding_function(item)
|
268
|
+
# Determine vector size from first embedding if not set
|
269
|
+
if not self._vector_size_determined:
|
270
|
+
self._determine_vector_size(len(vector))
|
271
|
+
return vector
|
186
272
|
elif isinstance(item, dict) and "vector" in item:
|
187
273
|
vector = item["vector"]
|
274
|
+
# Determine vector size from first vector if not set
|
275
|
+
if not self._vector_size_determined:
|
276
|
+
self._determine_vector_size(len(vector))
|
188
277
|
return utils.prepare_vector(vector, self.vector_size)
|
189
278
|
elif isinstance(item, (list, tuple)):
|
279
|
+
# Determine vector size from first vector if not set
|
280
|
+
if not self._vector_size_determined:
|
281
|
+
self._determine_vector_size(len(item))
|
190
282
|
return utils.prepare_vector(item, self.vector_size)
|
191
283
|
else:
|
192
284
|
raise utils.QdrantCollectionIndexError(
|
@@ -194,6 +286,19 @@ class QdrantCollectionIndex:
|
|
194
286
|
"or embedding_model must be provided"
|
195
287
|
)
|
196
288
|
|
289
|
+
def _determine_vector_size(self, size: int) -> None:
|
290
|
+
"""Determine and set vector size based on first embedding/vector."""
|
291
|
+
if not self._vector_size_determined:
|
292
|
+
self.vector_size = size
|
293
|
+
self._vector_size_determined = True
|
294
|
+
|
295
|
+
# Update settings with determined vector size
|
296
|
+
if self.settings:
|
297
|
+
self.settings.vector_size = size
|
298
|
+
|
299
|
+
# Initialize Qdrant client now that we have vector size
|
300
|
+
self._init_qdrant_client()
|
301
|
+
|
197
302
|
def _add_to_qdrant(
|
198
303
|
self,
|
199
304
|
item_id: str,
|
@@ -304,25 +409,32 @@ class QdrantCollectionIndex:
|
|
304
409
|
"""
|
305
410
|
return self._database.get(id, filters=filters)
|
306
411
|
|
307
|
-
def
|
412
|
+
def _vector_search(
|
308
413
|
self,
|
309
414
|
query_vector: Union[List[float], Any],
|
310
415
|
*,
|
311
416
|
filters: Optional[DatabaseItemFilters] = None,
|
312
417
|
limit: int = 10,
|
313
418
|
score_threshold: Optional[float] = None,
|
314
|
-
|
419
|
+
query_text: Optional[str] = None,
|
420
|
+
enable_rerank: bool = True,
|
421
|
+
return_scores: bool = False,
|
422
|
+
) -> Union[List[DatabaseItem[DatabaseItemType]], List[VectorSearchResult]]:
|
315
423
|
"""
|
316
|
-
|
424
|
+
Internal method to perform vector similarity search.
|
317
425
|
|
318
426
|
Args:
|
319
427
|
query_vector: Query vector for similarity search.
|
320
428
|
filters: Optional filters to apply.
|
321
429
|
limit: Maximum number of results.
|
322
430
|
score_threshold: Minimum similarity score threshold.
|
431
|
+
query_text: Optional original query text for reranking.
|
432
|
+
enable_rerank: Whether to enable reranking if rerank model is configured.
|
433
|
+
return_scores: Whether to return scores with results.
|
323
434
|
|
324
435
|
Returns:
|
325
|
-
List of matching database items sorted by similarity score
|
436
|
+
List of matching database items sorted by similarity score (and reranked if enabled),
|
437
|
+
or list of VectorSearchResult objects if return_scores is True.
|
326
438
|
"""
|
327
439
|
if not self._client:
|
328
440
|
# Qdrant not available, return empty results
|
@@ -346,15 +458,31 @@ class QdrantCollectionIndex:
|
|
346
458
|
with_vectors=False,
|
347
459
|
)
|
348
460
|
|
349
|
-
# Get item IDs from results and fetch from database
|
350
|
-
|
461
|
+
# Get item IDs from results and fetch from database with scores
|
462
|
+
db_items_with_scores = []
|
351
463
|
for result in results.points:
|
352
464
|
item_id = str(result.id)
|
353
465
|
db_item = self._database.get(item_id, filters=filters)
|
354
466
|
if db_item:
|
355
|
-
|
356
|
-
|
357
|
-
|
467
|
+
# Set the score on the DatabaseItem itself
|
468
|
+
db_item.score = result.score
|
469
|
+
db_items_with_scores.append((db_item, result.score))
|
470
|
+
|
471
|
+
# Apply reranking if enabled and configured
|
472
|
+
if enable_rerank and self.rerank_model and query_text:
|
473
|
+
db_items_with_scores = self._rerank_results(
|
474
|
+
query=query_text,
|
475
|
+
results=db_items_with_scores,
|
476
|
+
top_n=limit
|
477
|
+
)
|
478
|
+
|
479
|
+
# Return results with or without scores based on return_scores parameter
|
480
|
+
if return_scores:
|
481
|
+
return [VectorSearchResult(item=item, score=score) for item, score in db_items_with_scores]
|
482
|
+
else:
|
483
|
+
# Extract just the database items (without scores) for backward compatibility
|
484
|
+
db_items = [item for item, score in db_items_with_scores]
|
485
|
+
return db_items
|
358
486
|
|
359
487
|
except Exception:
|
360
488
|
# Vector search failed, return empty results
|
@@ -366,48 +494,116 @@ class QdrantCollectionIndex:
|
|
366
494
|
*,
|
367
495
|
filters: Optional[DatabaseItemFilters] = None,
|
368
496
|
limit: Optional[int] = None,
|
369
|
-
vector:
|
370
|
-
|
497
|
+
vector: bool = False,
|
498
|
+
rerank: bool = False,
|
499
|
+
query_vector: Optional[List[float]] = None,
|
500
|
+
return_scores: bool = False,
|
501
|
+
) -> Union[List[DatabaseItem[DatabaseItemType]], List[VectorSearchResult]]:
|
371
502
|
"""
|
372
503
|
Query items from the collection.
|
373
504
|
|
374
505
|
Args:
|
375
|
-
query: Search query string
|
506
|
+
query: Search query string.
|
376
507
|
filters: Optional filters to apply.
|
377
508
|
limit: Maximum number of results.
|
378
|
-
vector:
|
509
|
+
vector: Whether to use vector search (requires embedding_model to be configured).
|
510
|
+
rerank: Whether to use reranking (requires rerank_model to be configured).
|
511
|
+
query_vector: Optional pre-computed query vector for similarity search.
|
512
|
+
return_scores: Whether to return similarity scores with results (only applies to vector search).
|
379
513
|
|
380
514
|
Returns:
|
381
|
-
List of matching database items.
|
515
|
+
List of matching database items, or list of VectorSearchResult objects if return_scores is True.
|
382
516
|
"""
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
517
|
+
effective_limit = limit or self.query_settings.limit
|
518
|
+
|
519
|
+
# If explicit vector is provided, use it directly
|
520
|
+
if query_vector is not None:
|
521
|
+
return self._vector_search(
|
522
|
+
query_vector=query_vector,
|
387
523
|
filters=filters,
|
388
|
-
limit=
|
524
|
+
limit=effective_limit,
|
389
525
|
score_threshold=self.query_settings.score_threshold,
|
526
|
+
query_text=query,
|
527
|
+
enable_rerank=rerank,
|
528
|
+
return_scores=return_scores,
|
390
529
|
)
|
391
530
|
|
392
|
-
# If
|
393
|
-
if
|
531
|
+
# If vector=True, use vector search with embedding model
|
532
|
+
if vector:
|
533
|
+
if not query:
|
534
|
+
raise ValueError("Query string is required when vector=True")
|
535
|
+
|
536
|
+
embedding_function = self._get_embedding_function()
|
537
|
+
if not embedding_function:
|
538
|
+
raise ValueError("Embedding model not configured for vector search")
|
539
|
+
|
540
|
+
try:
|
541
|
+
query_vector = embedding_function(query)
|
542
|
+
return self._vector_search(
|
543
|
+
query_vector=query_vector,
|
544
|
+
filters=filters,
|
545
|
+
limit=effective_limit,
|
546
|
+
score_threshold=self.query_settings.score_threshold,
|
547
|
+
query_text=query,
|
548
|
+
enable_rerank=rerank,
|
549
|
+
return_scores=return_scores,
|
550
|
+
)
|
551
|
+
except Exception as e:
|
552
|
+
raise ValueError(f"Failed to generate embedding for query: {e}")
|
553
|
+
|
554
|
+
# If rerank=True but vector=False, perform both standard and vector search, then rerank
|
555
|
+
if rerank and query:
|
556
|
+
if not self.rerank_model:
|
557
|
+
raise ValueError("Rerank model not configured")
|
558
|
+
|
559
|
+
# Get results from both database and vector search (if possible)
|
560
|
+
db_results = self._database.query(
|
561
|
+
limit=effective_limit,
|
562
|
+
order_by="created_at",
|
563
|
+
ascending=False,
|
564
|
+
)
|
565
|
+
|
566
|
+
vector_results = []
|
394
567
|
embedding_function = self._get_embedding_function()
|
395
568
|
if embedding_function:
|
396
569
|
try:
|
397
570
|
query_vector = embedding_function(query)
|
398
|
-
|
571
|
+
vector_results = self._vector_search(
|
399
572
|
query_vector=query_vector,
|
400
573
|
filters=filters,
|
401
|
-
limit=
|
574
|
+
limit=effective_limit,
|
402
575
|
score_threshold=self.query_settings.score_threshold,
|
576
|
+
query_text=query,
|
577
|
+
enable_rerank=False, # We'll rerank combined results
|
578
|
+
return_scores=False, # We handle scores separately in rerank mode
|
403
579
|
)
|
404
580
|
except Exception:
|
405
|
-
# Embedding failed, fall back to database query
|
406
581
|
pass
|
582
|
+
|
583
|
+
# Combine and deduplicate results
|
584
|
+
combined_results = []
|
585
|
+
seen_ids = set()
|
586
|
+
|
587
|
+
for result in db_results + vector_results:
|
588
|
+
if result.id not in seen_ids:
|
589
|
+
combined_results.append((result, 0.0)) # Score placeholder
|
590
|
+
seen_ids.add(result.id)
|
591
|
+
|
592
|
+
# Apply reranking to combined results
|
593
|
+
if combined_results:
|
594
|
+
reranked_results = self._rerank_results(
|
595
|
+
query=query,
|
596
|
+
results=combined_results,
|
597
|
+
top_n=effective_limit
|
598
|
+
)
|
599
|
+
# Scores are already set on the DatabaseItem objects by _rerank_results
|
600
|
+
return [item for item, _ in reranked_results]
|
601
|
+
|
602
|
+
return [item for item, _ in combined_results]
|
407
603
|
|
408
|
-
#
|
604
|
+
# Default: fall back to database query
|
409
605
|
return self._database.query(
|
410
|
-
limit=
|
606
|
+
limit=effective_limit,
|
411
607
|
order_by="created_at",
|
412
608
|
ascending=False,
|
413
609
|
)
|
@@ -117,6 +117,11 @@ class DatabaseItem(Generic[DatabaseItemType]):
|
|
117
117
|
default="default"
|
118
118
|
)
|
119
119
|
"""The table/collection name where this item is stored."""
|
120
|
+
|
121
|
+
score: Optional[float] = field(
|
122
|
+
default=None
|
123
|
+
)
|
124
|
+
"""The similarity score for this item (used in vector search results)."""
|
120
125
|
|
121
126
|
def is_expired(self) -> bool:
|
122
127
|
"""Check if this item has expired based on its TTL."""
|
@@ -18,6 +18,23 @@ if TYPE_CHECKING:
|
|
18
18
|
run_language_model,
|
19
19
|
async_run_language_model,
|
20
20
|
)
|
21
|
+
from .rerank_models import (
|
22
|
+
run_rerank_model,
|
23
|
+
async_run_rerank_model,
|
24
|
+
)
|
25
|
+
from .multimodal_models import (
|
26
|
+
run_image_generation_model,
|
27
|
+
async_run_image_generation_model,
|
28
|
+
run_image_edit_model,
|
29
|
+
async_run_image_edit_model,
|
30
|
+
run_image_variation_model,
|
31
|
+
async_run_image_variation_model,
|
32
|
+
|
33
|
+
run_tts_model,
|
34
|
+
async_run_tts_model,
|
35
|
+
run_transcription_model,
|
36
|
+
async_run_transcription_model,
|
37
|
+
)
|
21
38
|
|
22
39
|
|
23
40
|
__all__ = (
|
@@ -34,6 +51,22 @@ __all__ = (
|
|
34
51
|
"LanguageModelResponse",
|
35
52
|
"run_language_model",
|
36
53
|
"async_run_language_model",
|
54
|
+
|
55
|
+
# hammad.genai.rerank_models
|
56
|
+
"run_rerank_model",
|
57
|
+
"async_run_rerank_model",
|
58
|
+
|
59
|
+
# hammad.genai.multimodal_models
|
60
|
+
"run_image_generation_model",
|
61
|
+
"async_run_image_generation_model",
|
62
|
+
"run_image_edit_model",
|
63
|
+
"async_run_image_edit_model",
|
64
|
+
"run_image_variation_model",
|
65
|
+
"async_run_image_variation_model",
|
66
|
+
"run_tts_model",
|
67
|
+
"async_run_tts_model",
|
68
|
+
"run_transcription_model",
|
69
|
+
"async_run_transcription_model",
|
37
70
|
)
|
38
71
|
|
39
72
|
|
@@ -0,0 +1 @@
|
|
1
|
+
"""hammad.genai.agents"""
|
@@ -0,0 +1,35 @@
|
|
1
|
+
"""hammad.genai.types
|
2
|
+
|
3
|
+
Contains functional types usable with various components within
|
4
|
+
the `hammad.genai` module."""
|
5
|
+
|
6
|
+
from typing import TYPE_CHECKING
|
7
|
+
from ...._internal import create_getattr_importer
|
8
|
+
|
9
|
+
|
10
|
+
if TYPE_CHECKING:
|
11
|
+
from .history import (
|
12
|
+
History,
|
13
|
+
)
|
14
|
+
from .tool import (
|
15
|
+
Tool,
|
16
|
+
ToolResponseMessage,
|
17
|
+
function_tool,
|
18
|
+
)
|
19
|
+
|
20
|
+
|
21
|
+
__all__ = (
|
22
|
+
# hammad.genai.types.history
|
23
|
+
"History",
|
24
|
+
# hammad.genai.types.tool
|
25
|
+
"Tool",
|
26
|
+
"function_tool",
|
27
|
+
"ToolResponseMessage",
|
28
|
+
)
|
29
|
+
|
30
|
+
|
31
|
+
__getattr__ = create_getattr_importer(__all__)
|
32
|
+
|
33
|
+
|
34
|
+
def __dir__() -> list[str]:
|
35
|
+
return __all__
|