Why: - Plan 001 Phase 4 needs batched, concurrency-bounded embedding wired into the inline upload path, with process-wide capacity/timeout/chunk-limit guards (ADR-0017). - The BM25 analyzer and dense-model config are ported from the `emet` evaluation lab, which benchmarked them against the real Farsi corpus (bm25-fa-norm-stop; nomic-embed-text-v2-moe at 768-dim; text-embedding-3-large at native 3072-dim), closing open items in ADR-0001/ADR-0005. Changes: - New: embedding ports, orchestration (embed_chunks), request-bounds helpers, and dense/sparse adapters (analyzers.py, bm25.py, openai_compatible.py). - upload.py now parses/chunks/embeds inline behind INGESTION_MAX_CONCURRENCY (503), INGESTION_TIMEOUT_SECONDS (504), and the chunk-count ceiling (413); every failure path still writes a terminal job row. - Lifespan builds and warms both dense embedders at startup (fail-soft) and creates the sparse embedder and concurrency semaphore. - httpx moves from dev to main dependencies (adapters use it directly). Impact: - Qdrant point upserts are still Phase 5 -- chunks_indexed stays 0. - New EMBEDDING_* env vars documented in .env.example; safe defaults. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
95 lines
2.0 KiB
TOML
95 lines
2.0 KiB
TOML
[project]
|
|
name = "new-chatbot"
|
|
version = "0.1.0"
|
|
description = "Add your description here"
|
|
readme = "README.md"
|
|
requires-python = ">=3.13"
|
|
dependencies = [
|
|
"alembic>=1.19.1",
|
|
"anyio>=4.11.0",
|
|
"asyncpg>=0.31.0",
|
|
"fastapi[standard]==0.141.1",
|
|
"httpx>=0.28.1",
|
|
"langgraph>=1.2.10",
|
|
"minio>=7.2.20",
|
|
"openpyxl>=3.1.5",
|
|
"pydantic-settings>=2.15.0",
|
|
"python-docx>=1.2.0",
|
|
"qdrant-client>=1.19.0",
|
|
"sqlalchemy>=2.0.51",
|
|
"structlog>=26.1.0",
|
|
"tiktoken>=0.13.0",
|
|
]
|
|
|
|
[dependency-groups]
|
|
dev = [
|
|
"asgi-lifespan>=2.1.0",
|
|
"pytest>=8.3.5",
|
|
"pytest-asyncio>=0.25.3",
|
|
"pytest-cov>=6.0.0",
|
|
"pytest-timeout>=2.3.1",
|
|
"ruff>=0.16.2",
|
|
"testcontainers>=4.9.2",
|
|
"ty>=0.0.69",
|
|
]
|
|
|
|
[tool.pytest.ini_options]
|
|
testpaths = ["tests"]
|
|
asyncio_mode = "strict"
|
|
timeout = 10
|
|
markers = [
|
|
"unit: fast tests with no external services",
|
|
"integration: tests against a real disposable service",
|
|
"e2e: end-to-end vertical-slice tests",
|
|
"postgres: integration test using Postgres",
|
|
"minio: integration test using MinIO",
|
|
"qdrant: integration test using Qdrant",
|
|
"slow: test exceeds normal integration feedback time",
|
|
"live_provider: opt-in test that calls an external provider",
|
|
]
|
|
|
|
[tool.ruff]
|
|
line-length = 100
|
|
target-version = "py313"
|
|
|
|
[tool.ruff.lint]
|
|
select = [
|
|
# pycodestyle
|
|
"E",
|
|
# pyflakes
|
|
"F",
|
|
# isort
|
|
"I",
|
|
# pyupgrade
|
|
"UP",
|
|
# flake8-bugbear
|
|
"B",
|
|
# flake8-comprehensions
|
|
"C4",
|
|
# flake8-simplify
|
|
"SIM",
|
|
# Ruff-specific rules
|
|
"RUF",
|
|
]
|
|
|
|
[tool.ruff.format]
|
|
quote-style = "double"
|
|
indent-style = "space"
|
|
|
|
[tool.ty.environment]
|
|
python-version = "3.13"
|
|
|
|
[tool.ty.rules]
|
|
# High-value, currently ignore/warn by
|
|
possibly-unresolved-reference = "error"
|
|
missing-type-argument = "warn"
|
|
possibly-missing-attribute = "warn"
|
|
|
|
# Nice-to-have discipline:
|
|
unused-ignore-comment = "warn"
|
|
missing-override-decorator = "warn"
|
|
|
|
# Turn OFF or downgrade if noisy on your codebase:
|
|
possibly-missing-import = "ignore"
|
|
division-by-zero = "ignore"
|