kodit 0.4.1__tar.gz → 0.4.2__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.
- {kodit-0.4.1 → kodit-0.4.2}/PKG-INFO +1 -1
- {kodit-0.4.1 → kodit-0.4.2}/docs/reference/api/index.md +1 -1
- {kodit-0.4.1 → kodit-0.4.2}/docs/reference/api/openapi.json +1 -1
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/_version.py +2 -2
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/app.py +4 -2
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/application/factories/code_indexing_factory.py +54 -7
- kodit-0.4.2/src/kodit/application/factories/reporting_factory.py +27 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/application/services/auto_indexing_service.py +16 -4
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/application/services/code_indexing_application_service.py +115 -133
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/application/services/indexing_worker_service.py +18 -20
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/application/services/queue_service.py +12 -14
- kodit-0.4.2/src/kodit/application/services/reporting.py +86 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/application/services/sync_scheduler.py +21 -20
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/cli.py +14 -18
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/config.py +24 -1
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/database.py +2 -1
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/domain/protocols.py +9 -1
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/domain/services/bm25_service.py +1 -6
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/domain/services/index_service.py +22 -58
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/domain/value_objects.py +57 -9
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/api/v1/dependencies.py +23 -10
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/cloning/git/working_copy.py +36 -7
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/embedding/embedding_factory.py +8 -3
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/embedding/embedding_providers/litellm_embedding_provider.py +48 -55
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/git/git_utils.py +3 -2
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/mappers/index_mapper.py +1 -0
- kodit-0.4.2/src/kodit/infrastructure/reporting/__init__.py +1 -0
- kodit-0.4.2/src/kodit/infrastructure/reporting/log_progress.py +65 -0
- kodit-0.4.2/src/kodit/infrastructure/reporting/tdqm_progress.py +73 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/sqlalchemy/embedding_repository.py +47 -68
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/sqlalchemy/entities.py +28 -2
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/sqlalchemy/index_repository.py +274 -236
- kodit-0.4.2/src/kodit/infrastructure/sqlalchemy/task_repository.py +97 -0
- kodit-0.4.2/src/kodit/infrastructure/sqlalchemy/unit_of_work.py +59 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/mcp.py +10 -2
- {kodit-0.4.1 → kodit-0.4.2}/tests/conftest.py +14 -1
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/application/code_indexing_application_service_test.py +10 -35
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/application/services/indexing_worker_service_test.py +7 -17
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/application/services/queue_service_get_task_test.py +12 -6
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/application/services/queue_service_test.py +22 -12
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/application/services/sync_scheduler_test.py +4 -4
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/cli_test.py +30 -15
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/cloning/git_cloning/working_copy_test.py +5 -5
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/embedding/embedding_factory_test.py +13 -3
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/embedding/embedding_provider/litellm_embedding_provider_test.py +27 -29
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/embedding/local_vector_search_repository_test.py +58 -54
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/embedding/test_embedding_integration.py +329 -297
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/embedding/test_litellm_socket_providers.py +4 -4
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/sqlalchemy/embedding_repository_test.py +76 -68
- kodit-0.4.2/tests/kodit/infrastructure/sqlalchemy/index_repository_test.py +1190 -0
- kodit-0.4.2/tests/kodit/infrastructure/sqlalchemy/task_repository_test.py +375 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/performance/similarity.py +52 -47
- kodit-0.4.1/src/kodit/domain/interfaces.py +0 -27
- kodit-0.4.1/src/kodit/infrastructure/sqlalchemy/task_repository.py +0 -81
- kodit-0.4.1/src/kodit/infrastructure/ui/__init__.py +0 -1
- kodit-0.4.1/src/kodit/infrastructure/ui/progress.py +0 -170
- kodit-0.4.1/src/kodit/infrastructure/ui/spinner.py +0 -74
- kodit-0.4.1/src/kodit/reporting.py +0 -78
- {kodit-0.4.1 → kodit-0.4.2}/.claude/commands/debug.md +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/.claude/commands/new-requirement.md +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/.claude/commands/refactor.md +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/.claude/commands/update-docs.md +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/.claude/settings.json +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/.cursor/rules/kodit.mdc +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/.cursor/rules/style.mdc +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/.dockerignore +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/.github/CODE_OF_CONDUCT.md +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/.github/CONTRIBUTING.md +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/.github/dependabot.yml +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/.github/workflows/docker.yaml +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/.github/workflows/docs.yaml +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/.github/workflows/pull_request.yaml +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/.github/workflows/pypi-test.yaml +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/.github/workflows/pypi.yaml +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/.github/workflows/test.yaml +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/.gitignore +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/.python-version +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/.vscode/launch.json +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/.vscode/settings.json +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/CLAUDE.md +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/Dockerfile +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/LICENSE +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/Makefile +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/README.md +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/alembic.ini +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/docs/_index.md +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/docs/demos/_index.md +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/docs/demos/go-simple-microservice/index.md +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/docs/demos/knock-knock-auth/index.md +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/docs/developer/index.md +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/docs/getting-started/_index.md +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/docs/getting-started/installation/index.md +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/docs/getting-started/integration/index.md +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/docs/getting-started/quick-start/index.md +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/docs/reference/_index.md +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/docs/reference/api/templates/_content.md.j2 +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/docs/reference/api/templates/_example.md.j2 +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/docs/reference/api/templates/_object_schema.md.j2 +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/docs/reference/api/templates/_security_scheme.md.j2 +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/docs/reference/api/templates/api_doc_template.md.j2 +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/docs/reference/configuration/index.md +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/docs/reference/deployment/docker-compose.yaml +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/docs/reference/deployment/index.md +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/docs/reference/deployment/kubernetes.yaml +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/docs/reference/hosted-kodit/index.md +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/docs/reference/indexing/index.md +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/docs/reference/mcp/index.md +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/docs/reference/sync/index.md +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/docs/reference/telemetry/index.md +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/pyproject.toml +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/.gitignore +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/application/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/application/factories/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/application/services/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/cli_utils.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/domain/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/domain/entities.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/domain/errors.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/domain/services/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/domain/services/embedding_service.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/domain/services/enrichment_service.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/domain/services/index_query_service.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/api/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/api/client/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/api/client/base.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/api/client/exceptions.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/api/client/generated_endpoints.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/api/client/index_client.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/api/client/search_client.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/api/middleware/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/api/middleware/auth.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/api/v1/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/api/v1/routers/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/api/v1/routers/indexes.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/api/v1/routers/queue.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/api/v1/routers/search.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/api/v1/schemas/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/api/v1/schemas/context.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/api/v1/schemas/index.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/api/v1/schemas/queue.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/api/v1/schemas/search.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/bm25/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/bm25/bm25_factory.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/bm25/local_bm25_repository.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/bm25/vectorchord_bm25_repository.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/cloning/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/cloning/git/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/cloning/metadata.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/embedding/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/embedding/embedding_providers/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/embedding/embedding_providers/batching.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/embedding/embedding_providers/hash_embedding_provider.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/embedding/embedding_providers/local_embedding_provider.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/embedding/local_vector_search_repository.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/embedding/vectorchord_vector_search_repository.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/enrichment/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/enrichment/enrichment_factory.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/enrichment/litellm_enrichment_provider.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/enrichment/local_enrichment_provider.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/enrichment/null_enrichment_provider.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/enrichment/utils.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/git/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/ignore/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/ignore/ignore_pattern_provider.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/indexing/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/indexing/fusion_service.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/mappers/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/mappers/task_mapper.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/slicing/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/slicing/language_detection_service.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/slicing/slicer.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/infrastructure/sqlalchemy/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/log.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/middleware.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/migrations/README +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/migrations/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/migrations/env.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/migrations/script.py.mako +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/migrations/versions/4073b33f9436_add_file_processing_flag.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/migrations/versions/4552eb3f23ce_add_summary.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/migrations/versions/7c3bbc2ab32b_add_embeddings_table.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/migrations/versions/85155663351e_initial.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/migrations/versions/9cf0e87de578_add_queue.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/migrations/versions/9e53ea8bb3b0_add_authors.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/migrations/versions/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/migrations/versions/c3f5137d30f5_index_all_the_things.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/utils/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/utils/dump_openapi.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/utils/generate_api_paths.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/src/kodit/utils/path_utils.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/docker-smoke.sh +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/experiments/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/experiments/cline_prompt_tests/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/experiments/cline_prompt_tests/cline_prompt.txt +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/experiments/cline_prompt_tests/cline_prompt_test.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/app_test.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/application/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/application/services/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/application/services/auto_indexing_service_test.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/config_test.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/domain/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/domain/bm25_service_test.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/domain/embedding_service_test.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/domain/enrichment_service_test.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/domain/entities_test.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/domain/language_detection_service_test.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/domain/services/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/domain/services/index_service_test.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/domain/value_objects_test.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/e2e.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/bm25/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/bm25/local_bm25_repository_test.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/bm25/vectorchord_bm25_repository_test.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/cloning/git_cloning/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/embedding/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/embedding/batching_test.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/embedding/embedding_provider/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/embedding/embedding_provider/hash_embedding_provider_test.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/embedding/embedding_provider/local_embedding_provider_test.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/embedding/vectorchord_vector_search_repository_test.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/enrichment/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/enrichment/enrichment_factory_test.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/enrichment/enrichment_provider/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/enrichment/enrichment_provider/litellm_enrichment_provider_test.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/enrichment/enrichment_provider/local_enrichment_provider_test.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/enrichment/enrichment_provider/null_enrichment_provider_test.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/enrichment/utils_test.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/mappers/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/mappers/index_mapper_test.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/data/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/data/c/main.c +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/data/c/models.c +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/data/c/models.h +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/data/c/utils.c +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/data/c/utils.h +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/data/cpp/main.cpp +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/data/cpp/models.cpp +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/data/cpp/models.hpp +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/data/cpp/utils.cpp +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/data/cpp/utils.hpp +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/data/csharp/Main.cs +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/data/csharp/Models.cs +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/data/csharp/Utils.cs +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/data/css/components.css +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/data/css/main.css +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/data/css/utilities.css +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/data/go/main.go +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/data/go/models.go +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/data/go/utils.go +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/data/html/components.html +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/data/html/forms.html +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/data/html/main.html +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/data/java/Main.java +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/data/java/Models.java +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/data/java/Utils.java +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/data/javascript/main.js +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/data/javascript/models.js +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/data/javascript/utils.js +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/data/python/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/data/python/main.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/data/python/models.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/data/python/utils.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/data/rust/main.rs +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/data/rust/models.rs +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/data/rust/utils.rs +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/slicing/slicer_test.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/snippets/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/snippets/csharp.cs +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/snippets/golang.go +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/snippets/javascript.js +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/snippets/knock_knock_server.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/snippets/python.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/snippets/typescript.tsx +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/infrastructure/sqlalchemy/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/log_test.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/kodit/mcp_test.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/performance/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/smoke.sh +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/utils/__init__.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/utils/path_utils_test.py +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/tests/vectorchord-smoke.sh +0 -0
- {kodit-0.4.1 → kodit-0.4.2}/uv.lock +0 -0
|
@@ -12,7 +12,7 @@ look at the [hosted version](https://kodit.helix.ml/docs).
|
|
|
12
12
|
This is the REST API for the Kodit server. Please refer to the
|
|
13
13
|
[Kodit documentation](https://docs.helix.ml/kodit/) for more information.
|
|
14
14
|
|
|
15
|
-
Current version: 0.
|
|
15
|
+
Current version: 0.4.2
|
|
16
16
|
|
|
17
17
|
## Authentication
|
|
18
18
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"info": {
|
|
4
4
|
"title": "kodit API",
|
|
5
5
|
"description": "\nThis is the REST API for the Kodit server. Please refer to the\n[Kodit documentation](https://docs.helix.ml/kodit/) for more information.\n ",
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.4.2"
|
|
7
7
|
},
|
|
8
8
|
"paths": {
|
|
9
9
|
"/healthz": {
|
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '0.4.
|
|
32
|
-
__version_tuple__ = version_tuple = (0, 4,
|
|
31
|
+
__version__ = version = '0.4.2'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 4, 2)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
|
@@ -8,6 +8,7 @@ from fastapi import FastAPI, Response
|
|
|
8
8
|
from fastapi.responses import RedirectResponse
|
|
9
9
|
|
|
10
10
|
from kodit._version import version
|
|
11
|
+
from kodit.application.factories.reporting_factory import create_server_operation
|
|
11
12
|
from kodit.application.services.auto_indexing_service import AutoIndexingService
|
|
12
13
|
from kodit.application.services.indexing_worker_service import IndexingWorkerService
|
|
13
14
|
from kodit.application.services.sync_scheduler import SyncSchedulerService
|
|
@@ -34,20 +35,21 @@ async def app_lifespan(_: FastAPI) -> AsyncIterator[AppLifespanState]:
|
|
|
34
35
|
# App context has already been configured by the CLI.
|
|
35
36
|
app_context = AppContext()
|
|
36
37
|
db = await app_context.get_db()
|
|
38
|
+
operation = create_server_operation()
|
|
37
39
|
|
|
38
40
|
# Start the queue worker service
|
|
39
41
|
_indexing_worker_service = IndexingWorkerService(
|
|
40
42
|
app_context=app_context,
|
|
41
43
|
session_factory=db.session_factory,
|
|
42
44
|
)
|
|
43
|
-
await _indexing_worker_service.start()
|
|
45
|
+
await _indexing_worker_service.start(operation)
|
|
44
46
|
|
|
45
47
|
# Start auto-indexing service
|
|
46
48
|
_auto_indexing_service = AutoIndexingService(
|
|
47
49
|
app_context=app_context,
|
|
48
50
|
session_factory=db.session_factory,
|
|
49
51
|
)
|
|
50
|
-
await _auto_indexing_service.start_background_indexing()
|
|
52
|
+
await _auto_indexing_service.start_background_indexing(operation)
|
|
51
53
|
|
|
52
54
|
# Start sync scheduler service
|
|
53
55
|
if app_context.periodic_sync.enabled:
|
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
"""Factory for creating the unified code indexing application service."""
|
|
2
2
|
|
|
3
|
+
from collections.abc import Callable
|
|
4
|
+
|
|
3
5
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
4
6
|
|
|
7
|
+
from kodit.application.factories.reporting_factory import (
|
|
8
|
+
create_cli_operation,
|
|
9
|
+
create_noop_operation,
|
|
10
|
+
create_server_operation,
|
|
11
|
+
)
|
|
5
12
|
from kodit.application.services.code_indexing_application_service import (
|
|
6
13
|
CodeIndexingApplicationService,
|
|
7
14
|
)
|
|
15
|
+
from kodit.application.services.reporting import (
|
|
16
|
+
ProgressTracker,
|
|
17
|
+
)
|
|
8
18
|
from kodit.config import AppContext
|
|
9
19
|
from kodit.domain.services.bm25_service import BM25DomainService
|
|
10
20
|
from kodit.domain.services.embedding_service import EmbeddingDomainService
|
|
@@ -35,23 +45,31 @@ from kodit.infrastructure.slicing.language_detection_service import (
|
|
|
35
45
|
FileSystemLanguageDetectionService,
|
|
36
46
|
)
|
|
37
47
|
from kodit.infrastructure.sqlalchemy.embedding_repository import (
|
|
38
|
-
|
|
48
|
+
create_embedding_repository,
|
|
39
49
|
)
|
|
40
50
|
from kodit.infrastructure.sqlalchemy.entities import EmbeddingType
|
|
41
|
-
from kodit.infrastructure.sqlalchemy.index_repository import
|
|
51
|
+
from kodit.infrastructure.sqlalchemy.index_repository import (
|
|
52
|
+
create_index_repository,
|
|
53
|
+
)
|
|
42
54
|
|
|
43
55
|
|
|
44
56
|
def create_code_indexing_application_service(
|
|
45
57
|
app_context: AppContext,
|
|
46
58
|
session: AsyncSession,
|
|
59
|
+
session_factory: Callable[[], AsyncSession],
|
|
60
|
+
operation: ProgressTracker,
|
|
47
61
|
) -> CodeIndexingApplicationService:
|
|
48
62
|
"""Create a unified code indexing application service with all dependencies."""
|
|
49
63
|
# Create domain services
|
|
50
64
|
bm25_service = BM25DomainService(bm25_repository_factory(app_context, session))
|
|
51
|
-
code_search_service = embedding_domain_service_factory(
|
|
52
|
-
|
|
65
|
+
code_search_service = embedding_domain_service_factory(
|
|
66
|
+
"code", app_context, session, session_factory
|
|
67
|
+
)
|
|
68
|
+
text_search_service = embedding_domain_service_factory(
|
|
69
|
+
"text", app_context, session, session_factory
|
|
70
|
+
)
|
|
53
71
|
enrichment_service = enrichment_domain_service_factory(app_context)
|
|
54
|
-
index_repository =
|
|
72
|
+
index_repository = create_index_repository(session_factory=session_factory)
|
|
55
73
|
# Use the unified language mapping from the domain layer
|
|
56
74
|
language_map = LanguageMapping.get_extension_to_language_map()
|
|
57
75
|
|
|
@@ -78,17 +96,45 @@ def create_code_indexing_application_service(
|
|
|
78
96
|
text_search_service=text_search_service,
|
|
79
97
|
enrichment_service=enrichment_service,
|
|
80
98
|
session=session,
|
|
99
|
+
operation=operation,
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def create_cli_code_indexing_application_service(
|
|
104
|
+
app_context: AppContext,
|
|
105
|
+
session: AsyncSession,
|
|
106
|
+
session_factory: Callable[[], AsyncSession],
|
|
107
|
+
) -> CodeIndexingApplicationService:
|
|
108
|
+
"""Create a CLI code indexing application service."""
|
|
109
|
+
return create_code_indexing_application_service(
|
|
110
|
+
app_context,
|
|
111
|
+
session,
|
|
112
|
+
session_factory,
|
|
113
|
+
create_cli_operation(),
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def create_server_code_indexing_application_service(
|
|
118
|
+
app_context: AppContext,
|
|
119
|
+
session: AsyncSession,
|
|
120
|
+
session_factory: Callable[[], AsyncSession],
|
|
121
|
+
) -> CodeIndexingApplicationService:
|
|
122
|
+
"""Create a server code indexing application service."""
|
|
123
|
+
return create_code_indexing_application_service(
|
|
124
|
+
app_context, session, session_factory, create_server_operation()
|
|
81
125
|
)
|
|
82
126
|
|
|
83
127
|
|
|
84
128
|
def create_fast_test_code_indexing_application_service(
|
|
85
129
|
app_context: AppContext,
|
|
86
130
|
session: AsyncSession,
|
|
131
|
+
session_factory: Callable[[], AsyncSession],
|
|
87
132
|
) -> CodeIndexingApplicationService:
|
|
88
133
|
"""Create a fast test code indexing application service."""
|
|
89
134
|
# Create domain services
|
|
90
135
|
bm25_service = BM25DomainService(bm25_repository_factory(app_context, session))
|
|
91
|
-
embedding_repository =
|
|
136
|
+
embedding_repository = create_embedding_repository(session_factory=session_factory)
|
|
137
|
+
operation = create_noop_operation()
|
|
92
138
|
|
|
93
139
|
code_search_repository = LocalVectorSearchRepository(
|
|
94
140
|
embedding_repository=embedding_repository,
|
|
@@ -116,7 +162,7 @@ def create_fast_test_code_indexing_application_service(
|
|
|
116
162
|
enrichment_provider=NullEnrichmentProvider()
|
|
117
163
|
)
|
|
118
164
|
|
|
119
|
-
index_repository =
|
|
165
|
+
index_repository = create_index_repository(session_factory=session_factory)
|
|
120
166
|
# Use the unified language mapping from the domain layer
|
|
121
167
|
language_map = LanguageMapping.get_extension_to_language_map()
|
|
122
168
|
|
|
@@ -143,4 +189,5 @@ def create_fast_test_code_indexing_application_service(
|
|
|
143
189
|
text_search_service=text_search_service,
|
|
144
190
|
enrichment_service=enrichment_service,
|
|
145
191
|
session=session,
|
|
192
|
+
operation=operation,
|
|
146
193
|
)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""Reporting factory."""
|
|
2
|
+
|
|
3
|
+
from kodit.application.services.reporting import OperationType, ProgressTracker
|
|
4
|
+
from kodit.config import ReportingConfig
|
|
5
|
+
from kodit.infrastructure.reporting.log_progress import LoggingReportingModule
|
|
6
|
+
from kodit.infrastructure.reporting.tdqm_progress import TQDMReportingModule
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def create_noop_operation() -> ProgressTracker:
|
|
10
|
+
"""Create a noop reporter."""
|
|
11
|
+
return ProgressTracker(OperationType.ROOT.value)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def create_cli_operation(config: ReportingConfig | None = None) -> ProgressTracker:
|
|
15
|
+
"""Create a CLI reporter."""
|
|
16
|
+
shared_config = config or ReportingConfig()
|
|
17
|
+
s = ProgressTracker(OperationType.ROOT.value)
|
|
18
|
+
s.subscribe(TQDMReportingModule(shared_config))
|
|
19
|
+
return s
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def create_server_operation(config: ReportingConfig | None = None) -> ProgressTracker:
|
|
23
|
+
"""Create a server reporter."""
|
|
24
|
+
shared_config = config or ReportingConfig()
|
|
25
|
+
s = ProgressTracker(OperationType.ROOT.value)
|
|
26
|
+
s.subscribe(LoggingReportingModule(shared_config))
|
|
27
|
+
return s
|
|
@@ -11,7 +11,9 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
11
11
|
from kodit.application.factories.code_indexing_factory import (
|
|
12
12
|
create_code_indexing_application_service,
|
|
13
13
|
)
|
|
14
|
+
from kodit.application.factories.reporting_factory import create_noop_operation
|
|
14
15
|
from kodit.application.services.queue_service import QueueService
|
|
16
|
+
from kodit.application.services.reporting import ProgressTracker
|
|
15
17
|
from kodit.config import AppContext
|
|
16
18
|
from kodit.domain.entities import Task
|
|
17
19
|
from kodit.domain.value_objects import QueuePriority
|
|
@@ -31,8 +33,11 @@ class AutoIndexingService:
|
|
|
31
33
|
self.log = structlog.get_logger(__name__)
|
|
32
34
|
self._indexing_task: asyncio.Task | None = None
|
|
33
35
|
|
|
34
|
-
async def start_background_indexing(
|
|
36
|
+
async def start_background_indexing(
|
|
37
|
+
self, operation: ProgressTracker | None = None
|
|
38
|
+
) -> None:
|
|
35
39
|
"""Start background indexing of configured sources."""
|
|
40
|
+
operation = operation or create_noop_operation()
|
|
36
41
|
if (
|
|
37
42
|
not self.app_context.auto_indexing
|
|
38
43
|
or len(self.app_context.auto_indexing.sources) == 0
|
|
@@ -48,15 +53,22 @@ class AutoIndexingService:
|
|
|
48
53
|
|
|
49
54
|
auto_sources = [source.uri for source in self.app_context.auto_indexing.sources]
|
|
50
55
|
self.log.info("Starting background indexing", num_sources=len(auto_sources))
|
|
51
|
-
self._indexing_task = asyncio.create_task(
|
|
56
|
+
self._indexing_task = asyncio.create_task(
|
|
57
|
+
self._index_sources(auto_sources, operation)
|
|
58
|
+
)
|
|
52
59
|
|
|
53
|
-
async def _index_sources(
|
|
60
|
+
async def _index_sources(
|
|
61
|
+
self, sources: list[str], operation: ProgressTracker | None = None
|
|
62
|
+
) -> None:
|
|
54
63
|
"""Index all configured sources in the background."""
|
|
64
|
+
operation = operation or create_noop_operation()
|
|
55
65
|
async with self.session_factory() as session:
|
|
56
|
-
queue_service = QueueService(
|
|
66
|
+
queue_service = QueueService(session_factory=self.session_factory)
|
|
57
67
|
service = create_code_indexing_application_service(
|
|
58
68
|
app_context=self.app_context,
|
|
59
69
|
session=session,
|
|
70
|
+
session_factory=self.session_factory,
|
|
71
|
+
operation=operation,
|
|
60
72
|
)
|
|
61
73
|
|
|
62
74
|
for source in sources:
|
{kodit-0.4.1 → kodit-0.4.2}/src/kodit/application/services/code_indexing_application_service.py
RENAMED
|
@@ -6,8 +6,11 @@ from datetime import UTC, datetime
|
|
|
6
6
|
import structlog
|
|
7
7
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
8
8
|
|
|
9
|
+
from kodit.application.services.reporting import (
|
|
10
|
+
OperationType,
|
|
11
|
+
ProgressTracker,
|
|
12
|
+
)
|
|
9
13
|
from kodit.domain.entities import Index, Snippet
|
|
10
|
-
from kodit.domain.interfaces import ProgressCallback
|
|
11
14
|
from kodit.domain.protocols import IndexRepository
|
|
12
15
|
from kodit.domain.services.bm25_service import BM25DomainService
|
|
13
16
|
from kodit.domain.services.embedding_service import EmbeddingDomainService
|
|
@@ -25,7 +28,6 @@ from kodit.domain.value_objects import (
|
|
|
25
28
|
SnippetSearchFilters,
|
|
26
29
|
)
|
|
27
30
|
from kodit.log import log_event
|
|
28
|
-
from kodit.reporting import Reporter
|
|
29
31
|
|
|
30
32
|
|
|
31
33
|
class CodeIndexingApplicationService:
|
|
@@ -41,6 +43,7 @@ class CodeIndexingApplicationService:
|
|
|
41
43
|
text_search_service: EmbeddingDomainService,
|
|
42
44
|
enrichment_service: EnrichmentDomainService,
|
|
43
45
|
session: AsyncSession,
|
|
46
|
+
operation: ProgressTracker,
|
|
44
47
|
) -> None:
|
|
45
48
|
"""Initialize the code indexing application service."""
|
|
46
49
|
self.index_domain_service = indexing_domain_service
|
|
@@ -51,6 +54,7 @@ class CodeIndexingApplicationService:
|
|
|
51
54
|
self.text_search_service = text_search_service
|
|
52
55
|
self.enrichment_service = enrichment_service
|
|
53
56
|
self.session = session
|
|
57
|
+
self.operation = operation
|
|
54
58
|
self.log = structlog.get_logger(__name__)
|
|
55
59
|
|
|
56
60
|
async def does_index_exist(self, uri: str) -> bool:
|
|
@@ -60,107 +64,117 @@ class CodeIndexingApplicationService:
|
|
|
60
64
|
existing_index = await self.index_repository.get_by_uri(sanitized_uri)
|
|
61
65
|
return existing_index is not None
|
|
62
66
|
|
|
63
|
-
async def create_index_from_uri(
|
|
64
|
-
self, uri: str, progress_callback: ProgressCallback | None = None
|
|
65
|
-
) -> Index:
|
|
67
|
+
async def create_index_from_uri(self, uri: str) -> Index:
|
|
66
68
|
"""Create a new index for a source."""
|
|
67
69
|
log_event("kodit.index.create")
|
|
70
|
+
with self.operation.create_child(OperationType.CREATE_INDEX.value) as operation:
|
|
71
|
+
# Check if index already exists
|
|
72
|
+
sanitized_uri, _ = self.index_domain_service.sanitize_uri(uri)
|
|
73
|
+
self.log.info("Creating index from URI", uri=str(sanitized_uri))
|
|
74
|
+
existing_index = await self.index_repository.get_by_uri(sanitized_uri)
|
|
75
|
+
if existing_index:
|
|
76
|
+
self.log.debug(
|
|
77
|
+
"Index already exists",
|
|
78
|
+
uri=str(sanitized_uri),
|
|
79
|
+
index_id=existing_index.id,
|
|
80
|
+
)
|
|
81
|
+
return existing_index
|
|
68
82
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
if existing_index:
|
|
73
|
-
self.log.debug(
|
|
74
|
-
"Index already exists",
|
|
75
|
-
uri=str(sanitized_uri),
|
|
76
|
-
index_id=existing_index.id,
|
|
77
|
-
)
|
|
78
|
-
return existing_index
|
|
79
|
-
|
|
80
|
-
# Only prepare working copy if we need to create a new index
|
|
81
|
-
working_copy = await self.index_domain_service.prepare_index(
|
|
82
|
-
uri, progress_callback
|
|
83
|
-
)
|
|
83
|
+
# Only prepare working copy if we need to create a new index
|
|
84
|
+
self.log.info("Preparing working copy", uri=str(sanitized_uri))
|
|
85
|
+
working_copy = await self.index_domain_service.prepare_index(uri, operation)
|
|
84
86
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
# Create new index
|
|
88
|
+
self.log.info("Creating index", uri=str(sanitized_uri))
|
|
89
|
+
index = await self.index_repository.create(sanitized_uri, working_copy)
|
|
90
|
+
await self.session.commit()
|
|
91
|
+
return index
|
|
89
92
|
|
|
90
|
-
async def run_index(
|
|
91
|
-
self, index: Index, progress_callback: ProgressCallback | None = None
|
|
92
|
-
) -> None:
|
|
93
|
+
async def run_index(self, index: Index) -> None:
|
|
93
94
|
"""Run the complete indexing process for a specific index."""
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
# Refresh index to get snippets with IDs, required as a ref for subsequent steps
|
|
125
|
-
flushed_index = await self.index_repository.get(index.id)
|
|
126
|
-
if not flushed_index:
|
|
127
|
-
msg = f"Index {index.id} not found after snippet extraction"
|
|
128
|
-
raise ValueError(msg)
|
|
129
|
-
index = flushed_index
|
|
130
|
-
if len(index.snippets) == 0:
|
|
131
|
-
self.log.info("No snippets to index after extraction", index_id=index.id)
|
|
132
|
-
return
|
|
133
|
-
|
|
134
|
-
# Create BM25 index
|
|
135
|
-
self.log.info("Creating keyword index")
|
|
136
|
-
await self._create_bm25_index(index.snippets, progress_callback)
|
|
137
|
-
|
|
138
|
-
# Create code embeddings
|
|
139
|
-
self.log.info("Creating semantic code index")
|
|
140
|
-
await self._create_code_embeddings(index.snippets, progress_callback)
|
|
141
|
-
|
|
142
|
-
# Enrich snippets
|
|
143
|
-
self.log.info("Enriching snippets", num_snippets=len(index.snippets))
|
|
144
|
-
enriched_snippets = await self.index_domain_service.enrich_snippets_in_index(
|
|
145
|
-
snippets=index.snippets, progress_callback=progress_callback
|
|
146
|
-
)
|
|
147
|
-
# Update snippets in repository
|
|
148
|
-
await self.index_repository.update_snippets(index.id, enriched_snippets)
|
|
95
|
+
# Create a new operation
|
|
96
|
+
with self.operation.create_child(OperationType.RUN_INDEX.value) as operation:
|
|
97
|
+
# TODO(philwinder): Move this into a reporter # noqa: TD003, FIX002
|
|
98
|
+
log_event("kodit.index.run")
|
|
99
|
+
|
|
100
|
+
if not index or not index.id:
|
|
101
|
+
msg = f"Index has no ID: {index}"
|
|
102
|
+
raise ValueError(msg)
|
|
103
|
+
|
|
104
|
+
# Refresh working copy
|
|
105
|
+
with operation.create_child("Refresh working copy") as step:
|
|
106
|
+
index.source.working_copy = (
|
|
107
|
+
await self.index_domain_service.refresh_working_copy(
|
|
108
|
+
index.source.working_copy, step
|
|
109
|
+
)
|
|
110
|
+
)
|
|
111
|
+
if len(index.source.working_copy.changed_files()) == 0:
|
|
112
|
+
self.log.info("No new changes to index", index_id=index.id)
|
|
113
|
+
step.skip("No new changes to index")
|
|
114
|
+
return
|
|
115
|
+
|
|
116
|
+
# Delete the old snippets from the files that have changed
|
|
117
|
+
with operation.create_child("Delete old snippets") as step:
|
|
118
|
+
await self.index_repository.delete_snippets_by_file_ids(
|
|
119
|
+
[
|
|
120
|
+
file.id
|
|
121
|
+
for file in index.source.working_copy.changed_files()
|
|
122
|
+
if file.id
|
|
123
|
+
]
|
|
124
|
+
)
|
|
149
125
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
126
|
+
# Extract and create snippets (domain service handles progress)
|
|
127
|
+
with operation.create_child("Extract snippets") as step:
|
|
128
|
+
index = await self.index_domain_service.extract_snippets_from_index(
|
|
129
|
+
index=index, step=step
|
|
130
|
+
)
|
|
131
|
+
await self.index_repository.update(index)
|
|
132
|
+
|
|
133
|
+
# Refresh index to get snippets with IDs, required for subsequent steps
|
|
134
|
+
flushed_index = await self.index_repository.get(index.id)
|
|
135
|
+
if not flushed_index:
|
|
136
|
+
msg = f"Index {index.id} not found after snippet extraction"
|
|
137
|
+
raise ValueError(msg)
|
|
138
|
+
index = flushed_index
|
|
139
|
+
if len(index.snippets) == 0:
|
|
140
|
+
self.log.info(
|
|
141
|
+
"No snippets to index after extraction", index_id=index.id
|
|
142
|
+
)
|
|
143
|
+
step.skip("No snippets to index after extraction")
|
|
144
|
+
return
|
|
145
|
+
|
|
146
|
+
# Create BM25 index
|
|
147
|
+
self.log.info("Creating keyword index")
|
|
148
|
+
with operation.create_child("Create BM25 index") as step:
|
|
149
|
+
await self._create_bm25_index(index.snippets)
|
|
150
|
+
|
|
151
|
+
# Create code embeddings
|
|
152
|
+
with operation.create_child("Create code embeddings") as step:
|
|
153
|
+
await self._create_code_embeddings(index.snippets, step)
|
|
154
|
+
|
|
155
|
+
# Enrich snippets
|
|
156
|
+
with operation.create_child("Enrich snippets") as step:
|
|
157
|
+
enriched_snippets = (
|
|
158
|
+
await self.index_domain_service.enrich_snippets_in_index(
|
|
159
|
+
snippets=index.snippets,
|
|
160
|
+
reporting_step=step,
|
|
161
|
+
)
|
|
162
|
+
)
|
|
163
|
+
# Update snippets in repository
|
|
164
|
+
await self.index_repository.update_snippets(index.id, enriched_snippets)
|
|
153
165
|
|
|
154
|
-
|
|
155
|
-
|
|
166
|
+
# Create text embeddings (on enriched content)
|
|
167
|
+
with operation.create_child("Create text embeddings") as step:
|
|
168
|
+
await self._create_text_embeddings(enriched_snippets, step)
|
|
156
169
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
await self.index_repository.update(index)
|
|
170
|
+
# Update index timestamp
|
|
171
|
+
with operation.create_child("Update index timestamp") as step:
|
|
172
|
+
await self.index_repository.update_index_timestamp(index.id)
|
|
161
173
|
|
|
162
|
-
|
|
163
|
-
|
|
174
|
+
# After indexing, clear the file processing statuses
|
|
175
|
+
with operation.create_child("Clear file processing statuses") as step:
|
|
176
|
+
index.source.working_copy.clear_file_processing_statuses()
|
|
177
|
+
await self.index_repository.update(index)
|
|
164
178
|
|
|
165
179
|
async def search(self, request: MultiSearchRequest) -> list[MultiSearchResult]:
|
|
166
180
|
"""Search for relevant snippets across all indexes."""
|
|
@@ -312,15 +326,7 @@ class CodeIndexingApplicationService:
|
|
|
312
326
|
]
|
|
313
327
|
|
|
314
328
|
# FUTURE: BM25 index enriched content too
|
|
315
|
-
async def _create_bm25_index(
|
|
316
|
-
self, snippets: list[Snippet], progress_callback: ProgressCallback | None = None
|
|
317
|
-
) -> None:
|
|
318
|
-
reporter = Reporter(self.log, progress_callback)
|
|
319
|
-
await reporter.start("bm25_index", len(snippets), "Creating keyword index...")
|
|
320
|
-
|
|
321
|
-
for _snippet in snippets:
|
|
322
|
-
pass
|
|
323
|
-
|
|
329
|
+
async def _create_bm25_index(self, snippets: list[Snippet]) -> None:
|
|
324
330
|
await self.bm25_service.index_documents(
|
|
325
331
|
IndexRequest(
|
|
326
332
|
documents=[
|
|
@@ -331,16 +337,10 @@ class CodeIndexingApplicationService:
|
|
|
331
337
|
)
|
|
332
338
|
)
|
|
333
339
|
|
|
334
|
-
await reporter.done("bm25_index", "Keyword index created")
|
|
335
|
-
|
|
336
340
|
async def _create_code_embeddings(
|
|
337
|
-
self, snippets: list[Snippet],
|
|
341
|
+
self, snippets: list[Snippet], reporting_step: ProgressTracker
|
|
338
342
|
) -> None:
|
|
339
|
-
|
|
340
|
-
await reporter.start(
|
|
341
|
-
"code_embeddings", len(snippets), "Creating code embeddings..."
|
|
342
|
-
)
|
|
343
|
-
|
|
343
|
+
reporting_step.set_total(len(snippets))
|
|
344
344
|
processed = 0
|
|
345
345
|
async for result in self.code_search_service.index_documents(
|
|
346
346
|
IndexRequest(
|
|
@@ -352,23 +352,11 @@ class CodeIndexingApplicationService:
|
|
|
352
352
|
)
|
|
353
353
|
):
|
|
354
354
|
processed += len(result)
|
|
355
|
-
|
|
356
|
-
"code_embeddings",
|
|
357
|
-
processed,
|
|
358
|
-
len(snippets),
|
|
359
|
-
"Creating code embeddings...",
|
|
360
|
-
)
|
|
361
|
-
|
|
362
|
-
await reporter.done("code_embeddings")
|
|
355
|
+
reporting_step.set_current(processed)
|
|
363
356
|
|
|
364
357
|
async def _create_text_embeddings(
|
|
365
|
-
self, snippets: list[Snippet],
|
|
358
|
+
self, snippets: list[Snippet], reporting_step: ProgressTracker
|
|
366
359
|
) -> None:
|
|
367
|
-
reporter = Reporter(self.log, progress_callback)
|
|
368
|
-
await reporter.start(
|
|
369
|
-
"text_embeddings", len(snippets), "Creating text embeddings..."
|
|
370
|
-
)
|
|
371
|
-
|
|
372
360
|
# Only create text embeddings for snippets that have summary content
|
|
373
361
|
documents_with_summaries = []
|
|
374
362
|
for snippet in snippets:
|
|
@@ -384,22 +372,16 @@ class CodeIndexingApplicationService:
|
|
|
384
372
|
continue
|
|
385
373
|
|
|
386
374
|
if not documents_with_summaries:
|
|
387
|
-
|
|
375
|
+
reporting_step.skip("No snippets with summaries to create text embeddings")
|
|
388
376
|
return
|
|
389
377
|
|
|
378
|
+
reporting_step.set_total(len(documents_with_summaries))
|
|
390
379
|
processed = 0
|
|
391
380
|
async for result in self.text_search_service.index_documents(
|
|
392
381
|
IndexRequest(documents=documents_with_summaries)
|
|
393
382
|
):
|
|
394
383
|
processed += len(result)
|
|
395
|
-
|
|
396
|
-
"text_embeddings",
|
|
397
|
-
processed,
|
|
398
|
-
len(snippets),
|
|
399
|
-
"Creating text embeddings...",
|
|
400
|
-
)
|
|
401
|
-
|
|
402
|
-
await reporter.done("text_embeddings")
|
|
384
|
+
reporting_step.set_current(processed)
|
|
403
385
|
|
|
404
386
|
async def delete_index(self, index: Index) -> None:
|
|
405
387
|
"""Delete an index."""
|