batchCooking/services/tech-step-intent-service/pyproject.toml
Nicolas 18abae7b6a feat(recipes): migre la detection des tech steps de node-nlp vers un microservice Python spaCy
Remplace TechStepClassifierService's node-nlp (NlpManager) par
services/tech-step-intent-service, un microservice FastAPI/spaCy dedie
(PhraseMatcher pour le NER par synonymes, textcat pour la classification
d'intention). Corpus (TECH_STEP_TRAINING_DATA) toujours possede par
apps/api, pousse au service via POST /v1/train a chaque warm-up ; le
service ne touche jamais Postgres (meme posture que
services/tech-step-llm-worker).

Cote apps/api :
- intent-service-client.ts : client HTTP vers le nouveau service
- tech-step-matcher.ts : delegue NER + intent classification au client,
  logique pure (splitIntoClauses, seuil/fallback) inchangee
- env.ts : INTENT_SERVICE_BASE_URL/INTENT_SERVICE_SECRET (secret requis,
  service coeur non optionnel)
- server.ts : warm-up avec retry/backoff (service Python demarre a part)
- scripts/calibrate-tech-step-threshold.ts : recalibration empirique de
  CONFIDENCE_THRESHOLD contre le jeu d'eval existant
- node-nlp retire (package.json, node-nlp.d.ts, model.nlp du .gitignore)

docker-compose.yml : nouveau service tech-step-intent-service (pas de
port expose, healthcheck, app en depend). CI : job intent-service-test
(pytest) + le job test demarre le service en arriere-plan avant la suite
Mocha (jamais de mock d'un service interne, cf specs/dev-conventions.md).

Verifie : 26/26 tests pytest du service (dont les offsets caracteres
exacts de tech-step-matcher.test.ts), lint + build complets du monorepo,
smoke test HTTP reel bout en bout. La suite Mocha et docker compose
build/up n'ont pas pu etre executes dans cet environnement (pas de
Postgres/Docker disponibles ici) — a confirmer via la CI et en local.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-25 20:11:30 +02:00

53 lines
2.3 KiB
TOML

[project]
name = "tech-step-intent-service"
version = "0.1.0"
description = "Microservice de détection d'intention (technique de cuisine) — remplace node-nlp côté apps/api."
requires-python = ">=3.12"
dependencies = [
"fastapi>=0.115,<0.116",
"uvicorn[standard]>=0.32,<0.33",
"spacy>=3.8,<3.9",
# Fournit les tables de lookup ("lexeme_norm" notamment) que
# `nlp.initialize()` réclame pour l'anglais lors de l'entraînement du
# textcat (`en_core_web_md` ne les embarque pas lui-même, contrairement à
# `fr_core_news_md`) — sans ce paquet, entraîner un pipeline "en" lève
# `E955`.
"spacy-lookups-data>=1.0,<1.1",
"pydantic-settings>=2.6,<3",
# Modèles spaCy installés comme des dépendances pip normales, pinnées par
# URL de release GitHub (pas via `python -m spacy download`, qui résout
# "la dernière version compatible" et n'est pas verrouillable par
# `uv.lock`). `uv sync --frozen` installe donc déjà les modèles — aucune
# étape `spacy download` séparée, ni au Dockerfile ni en CI. Version
# 3.8.0 choisie pour matcher la ligne spaCy 3.8 pinnée ci-dessus (voir
# https://github.com/explosion/spacy-models/releases).
"fr_core_news_md @ https://github.com/explosion/spacy-models/releases/download/fr_core_news_md-3.8.0/fr_core_news_md-3.8.0-py3-none-any.whl",
"en_core_web_md @ https://github.com/explosion/spacy-models/releases/download/en_core_web_md-3.8.0/en_core_web_md-3.8.0-py3-none-any.whl",
]
[dependency-groups]
dev = [
"pytest>=8,<9",
# Requis par fastapi.testclient.TestClient (httpx en interne depuis FastAPI 0.110+).
"httpx>=0.27,<0.28",
]
[tool.uv]
# Les deux modèles ci-dessus sont publiés comme des builds "any" universels
# (pas de wheel spécifique par plateforme) — rien à déclarer de plus ici,
# contrairement à un paquet avec des extras natifs par OS/arch.
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.build.targets.wheel]
packages = ["intent_service"]
[tool.hatch.metadata]
# Requis par hatchling pour accepter des dépendances pinnées par URL directe
# (les wheels de modèles spaCy ci-dessus) plutôt qu'un nom+version résolu
# depuis un index PyPI — voir la note sur `pyproject.toml` dans le plan de
# migration pour pourquoi ces modèles sont déclarés ainsi plutôt que via
# `python -m spacy download`.
allow-direct-references = true