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>
53 lines
2.3 KiB
TOML
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
|