Files
chatbot_v3/pyproject.toml
Ali Zarinkolah 5c0a5938f8 feat(ingestion): add bounded, benchmark-aligned embedding execution
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>
2026-08-19 17:13:32 +03:30

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"