L5.2 : plafonne la taille de reponse des trois outils de requete

Aucune borne de VOLUME n'existait sur query_wms_entities, call_query_api et
search_wms_data -- seulement une borne de LIGNES (MAX_QUERY_ROWS). Le modele
Writing serialise l'agregat complet (navigations, $id) : une seule ligne
Products y pese 95 288 caracteres, la ou la meme ligne Reading en fait ~4 500.
Toutes ces reponses depassaient le seuil de rejet du client MCP (D24), qui
renvoie un echec opaque plutot qu'un resultat partiel.

Plafond commun MAX_QUERY_RESPONSE_CHARS (defaut 25 000, meme ordre de grandeur
que MAX_LOG_SEARCH_CHARS), applique par src/services/response-limit.js : on
ecarte des LIGNES ENTIERES, jamais coupees au milieu, et on signale avec le
vocabulaire D24 (truncated / returned / omitted / hint). Le helper est partage
parce que les trois outils partagent le meme mecanisme -- ce que les mecanismes
de get_system_parameters et search_logs, eux, ne font pas. La recherche
dichotomique evite 200 reconstructions d'une charge utile de ~1 Mo.

Mesures avant/apres (protocole, LIMAGRAIN, longueur de content[0].text) :

  query_wms_entities Products limit 200   957 234 -> 24 432
    count 200, returned 5, omitted 195, truncated
  search_wms_data "PAL"                   847 543 -> 22 992
    totalFound 150, returned 4, omitted 146 ; reparti en tourniquet :
    Products 2, Containers 1, Tasks 1 -- sans quoi Products, en tete,
    consommerait tout le budget et les deux autres reviendraient a zero
    resultat sans que rien ne le dise
  call_query_api Products query_type 1      95 288 -> 738
    cas limite : returned 0, omitted 1, truncated, hint expliquant le
    volume Writing et renvoyant vers Reading

Sous le plafond, rien ne change -- verifie identique OCTET POUR OCTET contre
la version precedente :

  query_wms_entities Container limit 1     4 476 -> 4 476
  call_query_api Products limit 2          9 671 -> 9 671
  get_entity_schema Container             11 172 -> 11 172
  search_wms_data sous plafond            11 767 -> 11 767
  count_wms_entities Products                120 -> 120 (non concerne)

MAX_QUERY_ROWS et les limites par defaut des outils sont inchanges : le
correctif est le bornage signale, pas une reduction silencieuse. L'avertissement
de volume rejoint la description du parametre query_type (D25) de
query_wms_entities et call_query_api, pas celle de count_wms_entities dont la
reponse est un scalaire.

Baseline preservee : 23 outils, 6 resources.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Arthur Ria
2026-08-25 15:13:51 +02:00
parent 6f54d765c4
commit 54a6849563
6 changed files with 302 additions and 49 deletions
+23 -1
View File
@@ -64,7 +64,8 @@ src/
│ ├── workflow-service.js Workflows, lazy loading + cache
│ ├── ad-service.js Application Dictionary, 20 types, cache par type
│ ├── wms-query-service.js Construction d'expressions LINQ
── log-service.js Lecture et recherche dans les fichiers de logs
── log-service.js Lecture et recherche dans les fichiers de logs
│ └── response-limit.js Plafond de taille commun aux outils de requête (D24)
└── tools/ 23 outils MCP
├── wms-query-tools.js query_wms_entities, count_wms_entities,
│ get_entity_schema, search_wms_data
@@ -150,6 +151,11 @@ actif à chaque appel.
de `search_logs` — au-delà, des résultats entiers sont écartés et signalés
(`truncated`, D24).
**`MAX_QUERY_RESPONSE_CHARS`** (défaut 25 000) : même plafond pour
`query_wms_entities`, `call_query_api` et `search_wms_data` — au-delà, des
lignes entières sont écartées et signalées (D24). `count_wms_entities` n'est
pas concerné.
**Au runtime.** `profile-manager` est un singleton d'état global. Les services
s'abonnent via `onSwitch()` pour invalider ce qui dépend du tenant :
@@ -204,6 +210,22 @@ restent complètes, `dataTotalChars` est porté par toute réponse, et la tranch
est **verbatim** — concaténer les tranches dans l'ordre des offsets reconstitue
la définition à l'octet près. Ne la résumez pas, ne la « parsez » pas.
**Les trois outils de requête plafonnent leur volume** via
`src/services/response-limit.js` (`MAX_QUERY_RESPONSE_CHARS`) : au-delà, des
lignes entières sont écartées, jamais coupées au milieu. Sous le plafond, la
réponse est inchangée **octet pour octet** — c'est la contrainte à préserver si
vous y touchez.
| Outil | Unité écartée | Total porté |
|---|---|---|
| `query_wms_entities` | une ligne | `count` (déjà présent) |
| `call_query_api` | une ligne | `totalRows` (ajouté à la coupe) |
| `search_wms_data` | un résultat, réparti en tourniquet entre les entités | `totalFound` (déjà présent) |
Cas limite réel : **une seule ligne Writing dépasse le plafond** (95 288
caractères mesurés) — la réponse est alors `returned: 0`, `omitted: 1`,
`truncated: true`, avec un hint qui renvoie vers Reading.
---
## Écrire une requête WMS